Every activity field in an action or a trigger needs to be populated with data. The data can be hard-coded or fetched through a dynamic source. The dynamic data is fetched from a remote source by making an API call to the third party app when the integration is created. In this article we will delve deeper into these dynamic fields and how to create their endpoint. The endpoint is the URL, which when executed will send us the requested data. 

When you are creating an activity field, select an activity field type that relies on a dynamic data source, for example, the dropdown type activity field. Its details will be similar to what is shown below.
 

From the Data Source Endpoint drop-down menu, select the Create a new Endpoint option. The endpoint creation form will appear. The basic procedure to fill the form is the same for all endpoint types, you can learn about it here. As we are making a call to an external API and requesting data so this is the Outgoing type. This is an outgoing request.

Some important points about Dynamic Source Endpoint

When we receive a response from after sending our request, the response of a dynamic field’s source endpoint must be formatted as follows:

[
 {
 "id": "{{ account.id }}",
 "value": "{{ account.name }}"},….
 }
]

The key thing about this response is that it is a JSON array of objects, with each object having two properties named id and value.
When rendering the corresponding drop-down menu, our integration widget uses these objects as options in the drop-down. The id of each object from this response becomes the value attribute of corresponding option whereas the value property of object becomes the label of that option. It is really important that we use the same naming convention otherwise the data will not be available to the widget drop-down. 

Suppose we received a list of GitHub repositories as shown below.

The Repo ID will be stored in id and the Repo Name will be saved in value. These values will be passed to the Repository field inside the widget and will appear as shown below.

A step-by-step example to Setup Dynamic Field Endpoint

Let us walk through an example for better understanding. We want to Create a Message in Basecamp. We need to specify the Account ID, Project ID and Message Board ID where the message will be posted. How do we get the values of these IDs dynamically?

When the user authenticates Integry on their behalf with Basecamp, we receive an authorization token. In case you do not know, a user can have multiple accounts inside Basecamp (they act like different organizations). Using this token we will fetch the account list of the user from which the user will choose the account to configure.
Below we are going to discuss two scenarios where we create this endpoint. The first example is a simple case whereas in the second case we discuss the scenario where two activity fields are dependent on each other.  

Scenario 1:

We want to display a drop-down menu in the Account field and populate it with the list of Basecamp user accounts in our widget. When the user authorizes, this is the first request sent to Basecamp, so they return us the list of accounts associated with the logged in user. Let us see the structure of our endpoint that will be executed.  

Request URL

As we learn from the Basecamp API Docs the following endpoint returns the account details of a user

GET https://launchpad.37signals.com/authorization.json

An authorized request is sent to retrieve user Accounts. This has to be the first request sent after authorization. Our URL will be the same as mentioned above. As the HTTP The response returned is as follows. 

{
   "expires_at": "2012-03-22T16:56:48-05:00",
   "identity": {
      "id": 9999999,
      "first_name": "Jason",
      "last_name": "Fried",
      "email_address": "jason@basecamp.com",
   },
   "accounts": [{
         "product": "bcx",
         "id": 88888888,
         "name": "Wayne Enterprises, Ltd.",
         "href": "https://basecamp.com/88888888/api/v1",
         "app_href": "https://basecamp.com/88888888"
      },

      {
         "product": "bc3",
         "id": 99999999,
         "name": "Honcho Design",
         "href": "https://3.basecampapi.com/99999999",
         "app_href": "https://3.basecamp.com/99999999"
      }
   ]
}

Response Template

As you can see from the response returned, under the account key there is an array of accounts. We need to simplify it and extract the values of account name and IDs. We will use Twig to transform the response as shown below.

{
   %
   for account in response.accounts %
} {
   "id": "{{ account.id }}",
   "value": "{{ account.name }}"
} {
   %
   if not loop.last %
}, {
   % endif %
} {
   % endfor %
}

The code above iterates through the list of accounts using the response object. The response object returns us the data received in response. The ID and names are extracted from the response and saved in id and value variables. A new JSON array is generated in the format required by Integry widget. 

Scenario 2 

Now we will send a request to Basecamp and fetch the list of projects associated with the account selected by the user. A drop-down menu in the widget will display a list of all projects. Let us see the endpoint that will be executed.

Request URL

From the Get all Projects endpoint we know the following URL returns the paginated list of projects

GET account_id/projects.json 

The project field in the widget will display the list of projects from the user account selected. The project and account fields follow a parent-child relationship. The account is the parent and the projects being the children. The list that will appear in the Project field drop-down menu is dependent on the Account value. Once, the user selects an account the projects are dynamically loaded from the field’s dynamic source. We will specify the account by appending the account ID to the URL.

We have a Twig query variable so that you can access the values of activity fields (in the dynamic fields endpoint context). The data of the parent field is available under the query Twig variable in combination with the machine_name of that field. For this example, we will access the value of the account as query.basecamp_account assuming the machine_name of the Account field is basecamp_account. So our URL will look like this 

GET https://3.basecampapi.com/{{query.basecamp_account}}/projects.json

From the API Docs, we know the response is returned like shown below

[
   {
         "id": 2085958498,
         "status": "active",
         "created_at": "2016-09-20T14:34:10.467Z",
         "updated_at": "2016-09-20T14:50:48.007Z",
         "name": "The Leto Laptop",
         "description": "Laptop product launch.",
         "purpose": "topic",
         "bookmark_url": "https://3.basecampapi.com/195539477/my/bookmarks/BAh7CEkiCGdpZAY6BkVUSSIrZ2lkOi8vYmMzL0J1Y2tldC8yMDg1OTU4NDk4P2V4cGlyZXNfaW4GOwBUSSIMcHVycG9zZQY7AFRJIg1yZWFkYWJsZQY7AFRJIg9leHBpcmVzX2F0BjsAVDA=--c8e1a465de900eb9864fa79ae2f30345be158f71.json",
         "url": "https://3.basecampapi.com/195539477/projects/2085958498.json",
         "app_url": "https://3.basecamp.com/195539477/projects/2085958498",
         "dock": [{
            "id": 9007199254741446,
            "title": "Schedule",
            "name": "schedule",
            "enabled": true,
            "position": 4,
            "url": "https://3.basecampapi.com/195539477/buckets/2085958498/schedules/9007199254741446.json",
            "app_url": "https://3.basecamp.com/195539477/buckets/2085958498/schedules/9007199254741446"
         }],
         "bookmarked": false
      },
      {
         "id": 2085958500,
         "status": "active",
         "created_at": "2018-02-27T11:11:55.423Z",
         "updated_at": "2018-02-27T11:13:46.317Z",
         "name": "The Leto Locator",
         "description": "New software and hardware built for locating and securing Leto products.",
         "purpose": "topic",
         "bookmark_url": "https://3.basecampapi.com/195539477/my/bookmarks/BAh7CEkiCGdpZAY6BkVUSSIrZ2lkOi8vYmMzL0J1Y2tldC8yMDg1OTU4NTAwP2V4cGlyZXNfaW4GOwBUSSIMcHVycG9zZQY7AFRJIg1yZWFkYWJsZQY7AFRJIg9leHBpcmVzX2F0BjsAVDA=--0a4a96352e7a1f0a1ab7ed7fd35dfa9b41a28d06.json",
         "url": "https://3.basecampapi.com/195539477/projects/2085958500.json",
         "app_url": "https://3.basecamp.com/195539477/projects/2085958500",
         "client_company": {
            "id": 1033447819,
            "name": "Leto Brand"
         },
         "clientside": {
            "url": "https://3.basecampapi.com/195539477/buckets/2085958500/client/board.json",
            "app_url": "https://3.basecamp.com/195539477/buckets/2085958500/client/board"
         },
         "dock": [{
            "id": 1064091258,
            "title": "Campfire",
            "name": "chat",
            "enabled": true,
            "position": 1,
            "url": "https://3.basecampapi.com/195539477/buckets/2085958500/chats/1064091258.json",
            "app_url": "https://3.basecamp.com/195539477/buckets/2085958500/chats/1064091258"
         }],
         "bookmarked": false
      }
   ]

Response Template

As you can see from the response returned, there is an array of projects. We need to simplify it and extract the values of project name and IDs. We will use Twig to transform the response as shown below. 


[
   {
   %
   for project in response %
} {
   "id": "{{ project.id }}",
   "value": "{{ project.name }}"
} {
   %
   if not loop.last %
}, {
   % endif %
} {
   % endfor %
}
]

The code above iterates through the list of projects using the response object. The response object returns us the data received in reponse. The ID and names are extracted from the response and saved in “id” and “value” variables. A new JSON array is generated in the format required by Integry widget. 

Testing Endpoints

You can test the endpoints you create, right away. To learn how to test the endpoint, click here

The URLs, response formats and templates discussed in the article are Basecamp specific. They vary from app to app. Hopefully, you have configured your Dynamic Source Endpoint by now.

Did this answer your question?