HTTP Requests

Making HTTP requests as part of a bot's response is incredibly simple. Use a $ to specify making a request before responding. These are best illustrated through examples. The following syntax is best suited for handling responses that are returned as JSON data.

While we still support old-school ^httpGetJSONValue() and ^httpPost() shortcodes, we encourage all bot creators to move to using $ in their scripts.

GET Requests

Say you had an API at http://myapi.com/weather/<zipcode> that returned the following JSON data object when passed a zip code:

{
  "forecast": {
    "temp_low": "56 degrees",
    "temp_high": "78 degrees"
  }
}

To use the data from this API in a bot's response, you could write something like:

+ weather *
$ GET http://myapi.com/weather/<star>
- In <star>, looks like we have a high of ${{forecast.temp_high}} and a low of ${{forecast.temp_low}}.

Adding this line:

$ GET http://myapi.com/weather/<star>

tells Dexter to make an API call after receiving the incoming message but before responding. And any instances of ${{data.field.to.retrieve}} found in the response will be substituted with the value found at that field.

If you wanted to make multiple GET requests, you can name each one:

+ weather *
$ GET:name1 http://myapi.com/weather/<star>
$ GET:name2 http://myapi.com/traffic/<star>
- In <star>, looks like we have a high of ${{name1.forecast.temp_high}} and a low of ${{name1.forecast.temp_low}}. The traffic report: ${{name2.data.traffic_report}}

You can also use ${{data}} substitution within conditionals and pass them into JavaScript macros for even more advanced data manipulation:

> object get_actual_temp javascript
return parseInt(args[0].split(' ')[0]);
< object
 
+ weather *
$ GET http://myapi.com/weather/<star>
* <call>get_actual_temp ${{forecast.temp_high}}</call> >= 85 => Wow it is hot!
* <call>get_actual_temp ${{forecast.temp_high}}</call> < 30 => Wow it is cold!
- ${{forecast.temp_high}} seems pretty pleasant.
We make use of mustache tags to parse values provided back in the JSON object.

This means that a mustache tag using array syntax, like so: `${{property[0].name}}` will not work. Instead, the accurate tag will be indexed like so: ${{property.0.name}}.

URI Encoding the <star> Variable

If you're looking to capture multiple words (separated by spaces) in your <star> wildcard, we recommend an additional step of encoding the <star> value in a macro first before passing it into your GET request:

> object encode_uri javascript
return encodeURIComponent(args[0])
< object
 
+ lookup *
$ GET http://api.myencyclopedia.com/lookup/<call>encode_uri <star></call>
- According to Encyclopedia Witannica,  means to ${{data.entry.text}}.

POST Requests

POST requests are equally as simple. Say you want to log the choice a user has selected to your own servers:

+ select *
$ POST http://myapi.com {"selection":"<star>"}
- Thanks for your response!

{"selection":"<star>"} in your $ POST request will be sent to your servers.


Custom Headers

If you want to add custom headers to your request, you must specify a headers and body in the data you send. You can use custom headers in both GET and POST requests.

+ details on *
$ GET http://myapi.com {"headers":{"Content-Type":"application/json", "Authorization": "Bearer 1234567abcdef"}}
- ${{data.0.product.name}} is priced at ${{data.0.product.price}} USD. There are only ${{data.0.product.inventory}} units left.
 
+ select *
$ POST http://myapi.com {"headers":{"Signature":"abcdef"}, "body": {"selection":"<star>"}}
- Thanks for your response!

Mustache Tags & Macros

Saving Mustache Tags to Variables

You can easily save the values in the mustache tags to variable names.

+ bookmark *
$ GET http://myapi.com/items/<star>
- <set bookmarked_item=${{data.0.product.name}}> Great,  has been added to your bookmarks.
Using Response Data in Macros

You can also use mustache tags as arguments within Javascript macros.

+ save * to cart
$ GET http://myapi.com/items/<star>
- <call> add_to_cart ${{data.0.product.id}}</call> Great, <star> has been added to your cart.
 
> object add_to_cart javascript
    var cart = rs.getUservar(rs.currentUser(), 'cart'); // this is an array
    var new_item = args[0];
    var new_cart = cart.push(new_item)
    rs.setUservar(rs.currentUser(), 'cart', new_cart);
< object
Response Text

To get the full response body from a request, you can use the ${{__text}} mustache tag.

This will return the full stringifed JSON object, which may be a little overwhelming to just display to the end user. Consider only using this if you need to do further manipulations on the JSON string in a macro that cannot be handled with mustache syntax or the conditional logic we show above.

+ number of users
$ GET http://myapi.com/users/
- <set json=${{__text}}> There are currently <call>count_users</call> users.
 
> object count_users javascript
    var json_obj = JSON.parse(rs.getUservar(rs.currentUser(), 'json'));
    var users_array = json_obj['users']
    return users_array.length
< object

This can also be applied to multiple GET requests by appending the nickname of the request to __text, like so: ${{data1.__text}}}

Response Status Code

Similar, you can get the status code of the response by using the ${{__status}} mustache tag.

Combine the status code with conditionals to have the bot respond differently depending on the result of the request.

+ who is user id *
$ GET http://myapi.com/users/
* ${{__status}} == 404 => This user does not exist.
- The user with id  is named ${{users.0.name}}.

Advanced: Using Multiple Requests

Being able to have your bot make smart responses based on responses from API calls opens up opportunities for the kinds of useful conversations you can have.

Consider using the responses from one request as input for another request, like we do in the following example:

// in banks topic
+ find (bank|banks) in *
$ GET https://api.superbank.com/banks/search/location/<star>
* ${{__status}} != 200 => Are you sure this is a real zipcode? Please try again with a different zipcode.
- The closest location in the <star> zip code is:
^ * Branch ${{banks.0.id}} at ${{banks.0.location}}\n
^ Text back HOURS if you would like to know the hours at this location. <set branch_id=${{banks.0.id}}>
 
+ hours
$ GET https://api.superbank.com/banks/branches/<get branch_id>
* ${{__status}} != 200 => That's not a valid branch id! Please try again with a valid branch id.
- The hours for the Superbank branch <get branch_id> is ${{branch.hours}}. Thanks for using Superbank! If you have any more questions, type HELP at any point.
Want more examples? Check out our new Onboarding Bot tutorial for an example of an API request in action.