Stacks API Integrations
Stacks can integrate with APIs exposed over HTTP.
The functions get
and post
do HTTP calls. HTTP calls allow for the following parameters:
stack Stack do
card GetCard do
get_response = get("https://example.org/endpoint",
timeout: 60_000,
cache_ttl: 60_000,
query: [
["name", "@contact.name"],
["whatsapp_id", "@contact.whatsapp_id"]
])
end
card PostCard do
post_response = post("https://example.org/endpoint",
timeout: 60_000,
cache_ttl: 60_000,
body: """
{"username": @contact.whatsapp_id}
""",
headers: [["content-type", "application/json"]]
)
end
end
option | use |
---|---|
body | The body of the HTTP request |
cache_ttl | How long to cache a response for, in milliseconds (60_000 or 60000 is 60 seconds) |
headers | A list of lists with HTTP headers, [["X-Foo", "Bar"]] would add the X-Foo header to the HTTP request. |
mode | "sync" or "async" |
query | A list of lists with keys & values to use as query parameters [[key, value]] adds ?key=value to the request |
timeout | How long a request is allowed to take, in milliseconds |
url | The HTTP endpoint |
The HTTP headers and query parameters can be expressions that are evaluated.
RSS feed integration
Here is an example that reads the RSS feed for the BBC's Global News Podcast and allows users to navigate through the episodes and listen to them.
stack BBCWorldService, "BBC World Service" do
card Init, "⏮ Latest episode", then: Start do
# Initialize the cursor with a value of zero, this means we always start
# with the first, most recent, entry from the RSS feed
cursor = 0
# Use the public API at rss2json.com to convert the RSS feed that the
# BBC publishes for their world service podcast to a JSON file that
# we can read.
webhook =
get(
"https://api.rss2json.com/v1/api.json?rss_url=https%3A%2F%2Fpodcasts.files.bbci.co.uk%2Fp02nq0gn.rss"
)
items = webhook.body.items
# Keep track of the total number of items
total_items = count(items)
end
card Start do
# Read the current item
item = items[cursor]
# send the audio file first, since this is a _big_ file it takes longer to arrive
# on the phone than the messages we send later.
audio("@item.enclosure.link")
# generate the buttons
buttons([Init, NextCard]) do
# send the title as a caption
text("""
*@item.title*
@item.content
_Episode @(cursor + 1) of @(total_items)_
_Published at @(item.pubDate)_
""")
# The feed unfortunately doesn't have images and so we're just using a static
# image from the BBC website
image("https://ichef.bbci.co.uk/images/ic/480x270/p09kz0v5.jpg")
end
end
# We change the text on the button depending on whether or not we have any further
# episodes. If we do we display "Next episode ➡️", if we don't we display "⏮ First episode"
#
# Also if we reach the end of the total number of episodes, we reset the counter to 0
# which has us starting at the beginning again.
card NextCard, "@IF(cursor + 1 < total_items, \"Next episode ➡️\", \"⏮ First episode\")",
then: Start do
cursor = if cursor + 1 < total_items, do: cursor + 1, else: 0
end
end