There and back

Using link buttons and deep linking for a seamless flow between your service and Slack

Roach
Roach
Dec 11, 2017 · 6 min read
Image for post
Image for post

Slack apps allow teams to get quick tasks done, alongside their other work, without having to context switch into another product or browser window. But not every part of your service needs to be brought into Slack. “Deep work” that takes more than a few minutes — like setting up a project management board, building a wireframe, or creating a metrics dashboard — can sometimes be a better fit for your external service or web app.

Now with deep linking and link buttons — a new type of button that enables you to link out to an external webpage — you can build a user-friendly flow to guide people from Slack to your external service, then direct them back into a particular message in Slack to continue working. In this tutorial, we’ll show you how to do it.

About link buttons

Aside from promoting user engagement, link buttons offer a workaround for developers building apps behind a firewall. Features like message buttons, message menus and dialogs can help increase app engagement, but there’s a limitation: you need to add additional webhooks to your application. Because these features require a request URL, some developers — for instance, those running an app on their company’s internal network or a service behind a firewall — were previously blocked from building interactive Slack apps. For developers who have this limitation, link buttons offer an alternative: you can build an interactive app without the overhead of adding additional endpoints.

Using link buttons

You can break it down into a few steps. We’ll go through each in detail.

  1. Have your app post a message with a link button, leading to your external application or website
  2. The user loads the website and completes a workflow
  3. The user is directed to a “complete” page and the original Slack message is updated. A message permalink is fetched and shown to the user
  4. The user clicks back into Slack and resumes the conversation
Image for post
Image for post
A simple workflow initiated from a Slack message.

1. Post a message with a link button leading to your external app

# A dictionary to store `task_id` to message mappingsTASK_IDS = {}

Next, have your app post a message with a link button which will take the user out to the pending task. The button should be associated with a unique task, like a ticket number or another unique ID. For this demo, we’ll use `LB-2375`.

# Our task ID. This could be a ticket number or any other unique IDtask_id = 'LB-2375'

Adding a link button to a message is as simple as adding an attachment containing the URL you went to link to and the text you want on the button.

# Attachment JSON containing our link button
# For this demo app, The task ID should be the last segment of the URL
attach_json = [
{
"fallback": "Upgrade your Slack client to use messages like these.",
"color": "#CC0000",
"actions": [
{
"type": "button",
"text": ":red_circle: Complete Task: " + task_id,
"url": "https://roach.ngrok.io/workflow/" + task_id,
}
]
}
]

When the message is posted, Slack’s Web API will return some data about the message (see `res` below) such as the channel, timestamp and message content. We’re going to store the channel and timestamp to the map under the task ID.

# Post the message to Slack, storing the result as `res`
res = slack.api_call(
"chat.postMessage",
channel="#link-buttons",
text="Let's get started!",
attachments=attach_json
)
# Store the message `ts` and `channel`, so we can request the message
# permalink later when the user clicks the link button
TASK_IDS[task_id] = {
'channel': res['channel'],
'ts': res['message']['ts']
}

2. Guide the user through the task

For this very simplified demo, we’re going to show the user a form with one action. When the user submits this form, we will direct them to the /completed page.

# This is where our link button will link to, showing the user a
# task to complete before redirecting them to the `/complete` page
@app.route("/workflow/<task_id>", methods=['GET'])
def test(task_id):

task_form = """<form method="POST" action="/complete/{}">
<input type="submit" value="Do The Thing" />
</form>""".format(task_id)

return make_response(task_form, 200)

3. Update the message and bring them back to Slack

To update the Slack message containing the button, reference the channel and timestamp we saved in the map earlier, and call chat.update.

@app.route("/complete/<task_id>", methods=['POST'])
def complete(task_id):
"""
This is where your app's business logic would live.
Once the task has been complete, the user will be directed to this `/complete`
page, which shows a link back to their Slack conversation
"""

# When this page loads, we update the original Slack message to show that
# the pending task has been completed
attach_json = [
{
"fallback": "Upgrade your Slack client to use messages like these.",
"color": "#36a64f",
"text": ":white_check_mark: *Completed Task: {}*".format(task_id),
"mrkdwn_in": ["text"]
}
]
res = slack.api_call(
"chat.update",
channel=TASK_IDS[task_id]["channel"],
ts=TASK_IDS[task_id]["ts"],
text="Task Complete!",
attachments=attach_json
)

Once the message has been updated, fetch the permalink for it…

# Get the message permalink to redirect the user back to Slack
res = slack.api_call(
"chat.getPermalink",
channel=TASK_IDS[task_id]["channel"],
message_ts=TASK_IDS[task_id]["ts"]
)

…and show the “Return to Slack” link.

# Link the user back to the original message
slack_link = "<a href=\"{}\">Return to Slack</a>".format(res['permalink'])

# Redirect the user back to their Slack conversation
return make_response("Task Complete!<br/>" + slack_link, 200)

That’s it! 🎉

This simple flow using link buttons and deep linking enables your app’s users to complete “deep work” in your external service, then seamlessly return to where they started in Slack.

Here’s the complete code for this example:

https://github.com/slackapi/python-link-button-example/blob/master/example.py

To run this example, clone the repository or copy the code from above, and run:

export SLACK_API_TOKEN=”<YOUR SLACK BOT TOKEN>” 
python link-buttoms.py

Need help? Find us in the Bot Developer Hangout #slack-api channel, reach out on Twitter, or create an issue on GitHub.

Slack Platform Blog

Several bots are typing…

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store