Skip to main content

Writing an Integration in YAML with Trigger Payloads, Inputs, and Outputs

Overview#

In this quickstart, we examine a sample integration written in YAML to showcase the ability to import integrations defined as code.

In addition to examining writing integrations as code, this quickstart covers:

  • Invoking an integration with a webhook that contains a payload body
  • Referencing the trigger payload, both as an input variable for a component and in a code component
  • Knitting inputs and outputs throughout an integration to create more maintainable code

Prior to reviewing this quickstart, we recommend you check out our article on Defining Integrations as Code.

"Incomplete TODO Items" Integration Source Code#

If you would like to import this integration yourself, or reference it in your own editor, download incomplete-todo-items.yaml. You can then run:

prism integrations:import --path path/to/incomplete-todo-items.yaml

What the "Incomplete TODO Items" Integration Does#

This integration is triggered with an ID for a fictitious user, and writes out a list of incomplete "TODO" items for that user to a file in Amazon S3. The integration is comprised of six steps (seven if you include the trigger):

  1. The integration is triggered by a POST to a webhook URL. The POST includes a payload body that specifies a userId for the user we're concerned about.

    curl 'https://hooks.prismatic.io/trigger/INTEGRATION_ID' \  --data '{"userId":5}' \  --header "Content-Type: application/json" \
  2. Next, an HTTP GET step pulls https://jsonplaceholder.typicode.com/todos, which contains a list of about 200 TODO items of the form:

    [  {    "userId": 5,    "id": 201,    "title": "clean the car",    "completed": false  }]
  3. After that a Text Manipulation - Join action takes the userId that was passed in and generates a URL to pull from, https://jsonplaceholder.typicode.com/users/userId:

  4. Next another HTTP GET component pulls down the URL that was generated and gets results that look like this:

    {  "id": 5,  "name": "Chelsey Dietrich",  "username": "Kamren"}

    The user's name and username will be referenced as inputs for upcoming steps.

  5. The next step is a code action. The code filters the TODO items from step #1 to only include incomplete tasks for the userId that was passed in, formatted as a set of strings like this:

    Chelsey Dietrich needs to clean the car.Chelsey Dietrich needs to pay the bills.
  6. Next, another Text Manipulation - Join action generates an S3 object name to use, and an S3 component action writes those TODO strings to a file in S3.

  7. Finally, we use the Amazon S3 component to post our TODO list to an S3 bucket.

Now that we have a sense of what the integration does, let's dive into the code.

Referencing Config Variables#

Config variables are defined under the requiredConfigVars header. This integration has three required config variables: AWS Region (like us-east-1), S3 Bucket Name, and AWS Credentials for writing to that S3 bucket. The last config variable lists credential types, since AWS actions only take API Key / Secret credentials:

requiredConfigVars:  - dataType: string    defaultValue: us-east-1    hasDivider: false    header: AWS Configuration    key: AWS Region  - dataType: string    defaultValue: my-s3-bucket-name    hasDivider: false    key: S3 Bucket Name  - credentialTypes:      - apiKeySecret    dataType: credential    defaultValue: ""    hasDivider: false    key: AWS Credentials

Those config variables can be referenced as inputs of steps:

- name: Save TODO list to S3  description: Save the user's incomplete tasks a file in S3  action:    key: putObject    componentKey: aws-s3  credential: AWS Credentials  inputs:    awsRegion:      type: configVar      value: AWS Region    bucket:      type: configVar      value: S3 Bucket Name    fileContents:      type: reference      value: listItemsForUser.results    objectKey:      type: reference      value: generateS3ObjectName.results # Save to {BUCKET}/todoitems/{USERNAME}.txt

Trigger Output as Step Input#

The trigger received userId as part of its webhook payload body. This ID was used to generate a url of the form https://jsonplaceholder.typicode.com/users/5 in the first Join step:

- name: Generate User URL  action:    key: join    componentKey: text-manipulation  inputs:    strings:      type: complex      value:        - type: value          value: https://jsonplaceholder.typicode.com/users/        - type: reference          value: todosTrigger.results.body.data.userId

Step Output in a Code Step#

The userId output is also referenced in the third step, the code component, to filter TODO items only applicable to the specific user:

module.exports = async (  context,  {    todosTrigger,    getAllTodoItems: { results: items },    getUserInfo: {      results: { name },    },  }) => {  const userId = todosTrigger.results.body.data.userId;};
note

The getAlltodoItems output is a JSON list that we reassigned to a variable named items using JavaScript destructuring.

userId, items, and the user's name are then all used in the code component to filter TODO items, and generate sentences of the form "Chelsey Dietrich needs to clean the car."

const incompleteTasks = items  .filter((item) => item.userId == userId)  .filter((item) => !item.completed)  .map(({ title }) => `${name} needs to ${title}.`)  .join("\r\n");

Defining Output in a Code Step#

The code component for the List items for user step generates output values that can be referenced. The return value of the code component's function reads:

return { data: incompleteTasks };

Subsequent steps can then reference listItemsForUser.results to access that list.

Step Output as Step Input#

The last step utilizes the userUsername output from the getUserInfo step to declare where to save a file in S3, and the incompleteTasks output from the listItemsForUser code component to declare the content of the file to be saved.

- name: Save TODO list to S3  description: Save the user's incomplete tasks a file in S3  action:    key: putObject    componentKey: aws-s3  credential: AWS Credentials  inputs:    awsRegion:      type: configVar      value: AWS Region    bucket:      type: configVar      value: S3 Bucket Name    fileContents:      type: reference      value: listItemsForUser.results    objectKey:      type: reference      value: generateS3ObjectName.results # Save to {BUCKET}/todoitems/{USERNAME}.txt

Binding Credentials to Steps#

The final step of our integration requires credentials, which are defined as a config variable:

- name: Save TODO list to S3  description: Save the user's incomplete tasks a file in S3  action:    key: putObject    componentKey: aws-s3  credential: AWS Credentials

This causes the step to reference the AWS Credentials config variable for credentials to use to interact with AWS.

Summary#

Congratulations! Through this quickstart you built an integration in code, invoked the integration with a header that had a body payload, and knitted together trigger and step outputs and inputs. Next we recommend you try modifying the sample YAML file, or build a simple integration yourself from scratch!