How to add Slack message button to open direct chat with a user?

12.3k Views Asked by At

I have a Slack bot that needs to return a message that includes list of Slack users and a button to direct message each user.

I want the engagement experience to stay consistent for the user. If the user is interacting with the bot via a desktop Slack app then I want the user to stay within the app (not to be taken away to the web client -- where they likely aren't authenticated).

Something like:

Results:

User A - click link to view User A's profile in Slack
[Message] - click button to open direct message with user A

User B - click link to view User B's profile in Slack
[Message] - click button to open direct message with user B

I'm stuck on a couple of issues:

  1. How to link to a user's profile because I don't know if they are using the Slack app or Slack web (thus how to decide between showing slack://user?team=&id=.. or domain.slack.com/team/{id} approach? This is assuming I use either the title_link or author_link property.

  2. How to create a message button that will open a direct message to a user (and even better open it and pre-populate a message)? I've currently been playing with a link action but have not had any luck.

I imagine I could workaround it by having the bot send the DM and then @mention the original user. Not great from the UX perspective.

UPDATE

Thanks to comments from Adil and Erik I think I have the best possible solution. I ended up crafting a message attachment for each result as follows:

    {
        "fallback": `${user['name']} likes pizza`,
        "text": `<@${user['uid']}>`,
        "actions": [
          {
            "type": "button",
            "text": "View Pizza Profile",
            "url": url(`/directory/${user['id']}`),
            "style": "primary"
          },
          {
            "type": "button",
            "text": "Order Pizza",
            "url": `https://slack.com/app_redirect?channel=${user['uid']}`
          }
        ]
    }

This solution provides:

  • Text field which includes an @mention to the user (clicking it brings up the profile in the browser or native). It uses the text as the message header (and drops the author and title fields).
  • Link action button to open a direct message chat via app_redirect

There are a couple of serious limitations:

  1. For native, the direct message link causes a browser to open and then (if the user decides) redirects back to the app.
  2. The user MUST be using a browser window that is already authenticated to the same workspace as the native client (this is a huge problem for UX as many individuals have multiple workspaces open, in which case the redirect fails with a non-obvious error message).
2

There are 2 best solutions below

1
On BEST ANSWER

Adding to Adil's great answer about linking to a user profile

Here is how to provide a link to open a direct message between the current and another user:

You can use Slack's channel redirect feature to create a link that will open any channel for a user. This also works with direct message channels by providing the ID of the target user.

Example for user U12345678:

https://slack.com/app_redirect?channel=U12345678

You can provide this link via Link button or text link.

Note that this will always open a new browser tab/window though, even if the user is using a Slack native client (and no, there is no way to find out if the user it using a native client or the browser).

Another approach would be to just provide the user-mention in your message and let the user click on it to get a menu which includes "Direct Messages". This will work with every user and on every platform / client type:

Just include a standard user mention in your text with some instructions to the user:

<@U12345678>
1
On

To create a link to a user's profile, try following the steps on this page:

Create the link by combining your Workspace URL with members’ User IDs. Here’s how:

The first part of the link is the Workspace URL. For example, https://acmeco.slack.com. The second part of the link is the User ID. Multiple members' User IDs can be found using the users.list API method. Or, an individual's User ID can be found by clicking the More actions icon in a member's profile, then choosing Copy member ID. Append the User ID to the end of the Workspace URL. Here’s an example: https://acmeco.slack.com/team/U1H63D8SZ.

Using that same User ID, use the conversations.open API method to create a DM/multi-person message with the target user:

from slackclient import SlackClient

slack_token = os.environ["SLACK_API_TOKEN"]
sc = SlackClient(slack_token)

sc.api_call(
  "conversations.open",
  users=["W1234567890","U2345678901","U3456789012"]
)