How can a Slack bot detect a direct message vs a message in a channel?

Roger picture Roger · Dec 13, 2016 · Viewed 11.1k times · Source

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.

Answer

Roger picture Roger · Feb 2, 2017

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