Skip to content

HTTP requests

To integrate your chatbot with external APIs you can use:

http_get

Below is an example of an HTTP GET request that uses httpbin. In this example, the returned body is a JSON object that contains all the requests parameters. As you can see, the JSON is automatically transformed to a Map.

dialog get do
  url = "http://httpbin.org/get"
  response = http_get "#{url}?foo=bar&test=123"
  say "#{response.body.args.foo} #{response.body.args.test}"
end

# response.status_code  200
# response.body.origin  51.15.41.99
# response.body.headers.User-Agent  hackney/1.10.1
# response.body.headers.Host  httpbin.org
# response.body.headers.Connection  close
# response.body.args.test 123
# response.body.args.foo  bar
  • status_code: HTTP Status code
  • body (this largely depends on what the server sends back):
  • headers: a key-value object with the structure "Header name" => value.

The following HTTP request methods are supported: http_get, http_post, http_put, http_patch, http_delete.

url encoding

When you pass captured information via the URL make sure you encode the information before sending it.

response = http_get "#{url}?param=#{url_encode(variable)}"

http_post

To make an HTTP POST request you can use:

dialog post_params do
  response = http_post "http://httpbin.org/post", [
    name: "Arjan",
    value: "#{3 * 3}"]
  say "#{response.body.json.name} #{response.body.json.value}"
end

When invoked will set the response variable with the following contents:

response.status_code  200
response.body.url http://httpbin.org/post
response.body.origin  51.15.41.99
response.body.json.value  9
response.body.json.name Arjan
response.body.headers.User-Agent  hackney/1.10.1
response.body.headers.Host  httpbin.org
response.body.headers.Content-Type  application/json
response.body.headers.Content-Length  28
response.body.headers.Connection  close
response.body.data  {"value":"9","name":"Arjan"}

As you can see the full response body is made available in response.body.data and also (when a decoder is matched) as decode structure. In this case the response body was identified as application/json and as such decoded into response.body.json.

http_post with form encoded data

dialog form_post_params do
  response = http_post "http://httpbin.org/post", form: [
    name: "Arjan",
    value: "#{3 * 3}"]
  say "#{response.body.form.name} #{response.body.form.value}"
end

http_post with json encoded data

dialog post_headers do
  response = http_post "http://httpbin.org/post",
    json: [
      name: "Arjan",
      value: "#{3 * 3}"],
    headers: [
      foo: "Foo",
      "Authorization": "Bar"
    ]
  say "hoi"
end

http_post with XML encoded data

dialog post_headers do
  xml = ["body", [class: "a"], "contents"]
  response = http_post "http://httpbin.org/post", xml: xml
end

This will encode the given xml variable as XML and set the appropriate content-type request header.

In the above example, the XML that is posted is: <body class="a">contents</body>.

http_post with raw body

You can also do a "raw" post request, e.g. for posting XML or some other data type.

dialog content_type do
  response = http_post(
    "http://httpbin.org/anything",
    raw: "<xml>payload</xml>",
    headers: ["Content-Type": "text/xml"]
  )
  say response.body.headers["Content-Type"]
  say response.body.data
end

In a raw request, when the content-type header is omitted, it defaults to application/octet-stream.

no redirects

By default, the HTTP request follows any redirect (up to a maximum of 3). To prevent this, pass redirect: false:

response = http_get "http://httpbin.org/redirect/2", redirect: false
say response.status_code

The output will be "302". The redirect URL will be in the Location header: response.headers["Location"].

Decoder

Sometimes parties don't set the correct response.body.headers["Content-Type"] and so the response is not decoded. To force a decoder use:

response = http_get "#{url}?foo=bar&test=123", decoder: :json

Currently the system support: :json, :raw and :form.

Timeout

It is possible to specify a custom timeout value for an HTTP request. The default timeout is 5 seconds, but when an API takes longer than 5 seconds to respond you can specify a timeout: option:

response = http_get "http://httpbin.org/delay/10", timeout: 5
say response.error  #  will be true
say response.reason #  will be "timeout"

Skipping SSL verification

To bypass SSL certificate validation, add insecure: true as a request option.

response = http_get "https://revoked.badssl.com/", insecure: true

A request to https://revoked.badssl.com/ would fail with a certificate error when insecure: true is not given.

Retrieving all header values

HTTP headers can be specified multiple times in a HTTP response. If this is the case, normally, only one of the values will be populated in the response.headers map. However, when you pass all_response_headers: true as an option to the HTTP statement, each header value will be a list of all the HTTP header values that were sent.

This way it is possible for instance to iterate over each Set-Cookie header value that was retrieved:

_result = http_get "https://www.nu.nl/", all_response_headers: true

repeat value in _result.headers["Set-Cookie"] do
  say value
end

Request signing (Amazon Signature V4)

It is possible to have the request signed using the Amazon Signature V4 algorithm. In order to do so, you need an Amazon access key, access secret, region and service name. If you have those, you can use them to construct an array for the :sign option:

# [:aws_v4, access_key, access_secret, region, service]
_sign = [:aws_v4, "my_key", "my_secret", "eu-west-1", "execute-api"]

# pass it as sign: option
_result = http_post my_amazon_url, sign: _sign

Outbound IP Address

All outgoing HTTP requests made by the DialoX platform, including webhook requests and requests done from Bubblescript, are always done from the following IP address:

34.91.172.214

Please add this IP address to your firewalls if this is required.