29

TL;DR: Via the Slack APIs, how can I differentiate between a message in a channel vs a direct message?

I have a working Slack bot using the RTM API, let's call it Edi. And it works great as long as all commands start with "@edi"; e.g. "@edi help". It currently responses to any channel it's a member of and direct messages. However, I'd like to update the bot so that when it's a direct message, there won't be a need to start a command with "@edi"; e.g. "@edi help" in a channel, but "help" in a direct message. I don't see anything specific to differentiate between the two, but I did try using the channel.info endpoint and counting the number of people in "members"; however, this method only works on public channel. For private channels and direct messages, the endpoint returns an "channel_not_found" error.

Thanks in advance.

Roger
  • 1,020
  • 1
  • 8
  • 13

4 Answers4

45

I talked to James at Slack and he gave me a simply way to determine if a message is a DM or not; if a channel ID begins with a:

  • C, it's a public channel
  • D, it's a DM with the user
  • G, it's either a private channel or multi-person DM

However, these values aren't set in stone and could change at some point, or be added to.

So if that syntax goes away, another way to detect a DM to use both channels.info and groups.info. If they both return “false” for the “ok” field, then you know it’s a DM.

Note:

  • channels.info is for public channels only
  • groups.info is for private channels and multi-person DMs only

Bonus info: Once you detect a that a message is a DM, use either the user ID or channel ID and search for it in the results of im.list; if you find it, then you’ll know it’s a DM to the bot.

  • “id” from im.list is the channel ID
  • “user” from im.list is the user ID from the person DM’ing with the bot
  • You don’t pass in the bot’s user ID, because it’s extracted from the token
Roger
  • 1,020
  • 1
  • 8
  • 13
4

Slack have added Conversations API some time ago. You should use it to differentiate between PM/channel instead of relying on prefix.

From Conversations API documentation:

Each channel has a unique-to-the-team ID that begins with a single letter prefix, either C, G, or D. When a channel is shared across teams (see Developing for Shared Channels), the prefix of the channel ID may be changed, e.g. a private channel with ID G0987654321 may become ID C0987654321.

This is one reason you should use the conversations methods instead of the previous API methods! You cannot rely on a private shared channel's unique ID remaining constant during its entire lifetime.

Get conversation info using conversations.info method and check is_im flag. is_im == true means that the conversation is a direct message between two distinguished individuals or a user and a bot.

Community
  • 1
  • 1
dvor
  • 86
  • 1
  • 4
3

FYI as of July 2017, for "message.im" events (via your app's Event Subscriptions), the event payload seems to now return additional fields to detect if the message is coming from your own bot (pasted in here from my logs):

    INFO[0012] got Slack message: (bot.SlackMessage) {
    SlackEvent: (bot.SlackEvent) {
        Type: (string) (len=7) "message",
        EventTs: (string) (len=17) "1501076832.063834",
        User: (string) ""
    },
    SubType: (string) (len=11) "bot_message",
    Channel: (string) (len=9) "D6CJWD132",
    Text: (string) (len=20) "this is my bot reply",
    Username: (string) (len=15) "Myapp Local",
    BotID: (string) (len=9) "B6DAZKTGG",
    Ts: (string) (len=17) "1501076832.063834"
}
seenickcode
  • 1,022
  • 1
  • 10
  • 18
0

The info function is also available for private channels with the Slack API method groups.info. This works also for direct message channels with multiple participants, since they are a special form of private channels.

You can use groups.list to get the IDs of all private channels incl. direct message channels with multiple participants.

Note that groups.list will only return private channels, that the user or bot that the access token belongs to has been invited to.

Erik Kalkoken
  • 30,467
  • 8
  • 79
  • 114
  • 1
    I tried groups.info on a DM and it returned the "channel_not_found" error. But your info has helped me find a solution. If both groups.info and channels.info return with an error, then it's a DM. I did a preliminary test and it seems to work. Thank you. – Roger Jan 31 '17 at 00:36