Per-channel webhooks

Use cases:
  • Allow users to quickly generate a incoming webhook URL for a channel without having to write any code or be made a collaborator on an app
Works with:
  • Events API
  • Message Buttons
  • Internal integrations
Code samples:

A bot that generates a unique webhook URL for every channel that it is invited to. This allows people in a channel to quickly set up their own incoming webhooks without having to create a Slack app.

How it works

Watch as per-channel webhooks are hacked together this way

1. Find out when the bot joins a channel

To find out when a user or bot joins a channel you'll need to subscribe to the member_joined_channel event being sent out through the Events API. The Events API sends a POST request to a URL you've provided whenever certain events occur on your Slack team. In the case of member_joined_channel event, Slack will send an event when a member joins a public or private channel the bot is part of or being invited to. The event will include information about the member and the channel they joined.

Since we're only interested in the events that are related to the app's bot joining a channel, the app can ignore all events where the user_id of the member_joined_channel event doesn't match the bot's user ID. To get the bot's user ID, the app calls the auth.test method using the bot API token (xoxb-) and extracts the user_id. Since this user ID won't change, the app can safely cache it.

2. Generate a webhook URL for the channel

When the app receives a member_joined_channel for its bot, it'll take the channel_id from the event and checks whether it exists in its datastore. If it does, the bot has previously joined the channel and there is already a webhook URL for it. If the channel ID isn't found, the app will generate a nonce and save it in the datastore alongside the channel ID.

3. Send the webhook URL to the channel

By joining a common base URL with the nonce, the app is able to create a unique URL for the channel. By using a nonce, the app ensure that the URL can't be reverse engineered to allow users to post into channels they aren't part of. We send the channel's webhook URL into the channel using the chat.postMessage method.

4. A user sends a message to the webhook URL

When the app receives a POST request to its incoming webhook endpoint, it'll extract the nonce from the URL and use that to find the associated channel in the database. If the nonce exists, it'll chat.postMessage to send the JSON payload or the URL-encoded form from the incoming request through to Slack. If the nonce does not exist, the app returns a 404.


Effective comparentemnatizlation with per-channel webhooks

Customization suggestions

  • Invalidating the webhook URL if the bot is removed from a private channel
  • Whether incoming messages can have a custom icon/name as part of the message payload
  • Adding a way to return the webhook for a specific channel
  • Limit access to the webhook URL to specific people
  • Generate URLs that are unique per user

Related documentation

    Was this page helpful?