Slack Integration
Receive webhooks from Slack for events, slash commands, and interactive components.
Setup
1. Create a Source in WebhookRelay
curl -X POST https://api.webhookrelay.com/api/organizations/{orgId}/sources \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Slack App",
"slug": "slack",
"verificationConfig": {
"type": "slack",
"secret": "your-signing-secret"
}
}'Save your webhook URL:
https://api.webhookrelay.com/ingest/{orgSlug}/slack2. Create a Slack App
- Go to Slack API
- Click Create New App
- Choose From scratch
- Name your app and select a workspace
- Click Create App
3. Configure Event Subscriptions
- In your Slack app settings, go to Event Subscriptions
- Toggle Enable Events to On
- Enter your WebhookRelay URL as the Request URL
- Slack will send a verification challenge (WebhookRelay handles this)
- Under Subscribe to bot events, add events like:
message.channelsmessage.imapp_mentionreaction_added
- Click Save Changes
4. Get Your Signing Secret
- Go to Basic Information in your Slack app
- Under App Credentials, find Signing Secret
- Copy this secret to your WebhookRelay source configuration
5. Install the App
- Go to Install App in your Slack app settings
- Click Install to Workspace
- Authorize the requested permissions
Signature Verification
Slack signs requests using HMAC-SHA256. The signature is sent in headers:
X-Slack-Request-Timestamp: 1531420618
X-Slack-Signature: v0=a2114d57b48eac39b9ad189dd8316235a7b4a8d21a10bd27519666489c69b503WebhookRelay verifies this automatically:
{
"verificationConfig": {
"type": "slack",
"secret": "your-signing-secret"
}
}Timestamp Tolerance
Slack signatures include a timestamp. WebhookRelay rejects requests older than 5 minutes to prevent replay attacks.
Event Types
Message Events
{
"token": "...",
"team_id": "T1234567",
"event": {
"type": "message",
"channel": "C1234567",
"user": "U1234567",
"text": "Hello world",
"ts": "1234567890.123456"
},
"type": "event_callback",
"event_id": "Ev1234567",
"event_time": 1234567890
}App Mention
{
"token": "...",
"team_id": "T1234567",
"event": {
"type": "app_mention",
"user": "U1234567",
"text": "<@U0LAN0Z89> help",
"channel": "C1234567",
"ts": "1234567890.123456"
},
"type": "event_callback"
}Reaction Added
{
"token": "...",
"team_id": "T1234567",
"event": {
"type": "reaction_added",
"user": "U1234567",
"reaction": "thumbsup",
"item": {
"type": "message",
"channel": "C1234567",
"ts": "1234567890.123456"
}
},
"type": "event_callback"
}Slash Commands
Setup
- Go to Slash Commands in your Slack app
- Click Create New Command
- Enter your command (e.g.,
/mycommand) - Set Request URL to your WebhookRelay URL
- Click Save
Payload Format
{
"command": "/mycommand",
"text": "argument text",
"user_id": "U1234567",
"user_name": "username",
"channel_id": "C1234567",
"channel_name": "general",
"team_id": "T1234567",
"response_url": "https://hooks.slack.com/commands/..."
}Responding to Commands
Your destination should respond within 3 seconds with:
{
"response_type": "in_channel",
"text": "Command received!"
}Or use the response_url for delayed responses.
Interactive Components
Setup
- Go to Interactivity & Shortcuts
- Toggle Interactivity to On
- Set Request URL to your WebhookRelay URL
- Click Save Changes
Button Click Payload
{
"type": "block_actions",
"user": {
"id": "U1234567",
"username": "user"
},
"actions": [{
"action_id": "button_click",
"block_id": "block_1",
"type": "button",
"value": "click_me_123"
}],
"response_url": "https://hooks.slack.com/actions/...",
"trigger_id": "1234567890.123456"
}Transform Examples
Log to Database
function transform(payload) {
if (payload.type !== 'event_callback') {
return payload;
}
const event = payload.event;
return {
event_type: event.type,
team_id: payload.team_id,
channel_id: event.channel,
user_id: event.user,
text: event.text,
timestamp: event.ts,
raw_event: payload
};
}Forward to Discord
function transform(payload) {
if (payload.type !== 'event_callback' || payload.event.type !== 'message') {
return null; // Skip non-message events
}
const event = payload.event;
return {
content: event.text,
username: `Slack (${event.user})`,
embeds: [{
color: 0x4A154B,
footer: {
text: `From Slack #${event.channel}`
},
timestamp: new Date(parseFloat(event.ts) * 1000).toISOString()
}]
};
}Extract Mentions
function transform(payload) {
if (payload.event?.type !== 'app_mention') {
return payload;
}
const event = payload.event;
const text = event.text.replace(/<@[A-Z0-9]+>\s*/g, '').trim();
return {
action: 'mention',
user: event.user,
channel: event.channel,
command: text,
timestamp: event.ts
};
}Filter Examples
Only Message Events
{
"name": "Messages Only",
"logic": "and",
"conditions": [
{
"field": "event.type",
"operator": "equals",
"value": "message"
}
]
}Exclude Bot Messages
{
"name": "Non-Bot Messages",
"logic": "and",
"conditions": [
{
"field": "event.bot_id",
"operator": "not_exists",
"value": ""
}
]
}Specific Channel
{
"name": "Alerts Channel",
"logic": "and",
"conditions": [
{
"field": "event.channel",
"operator": "equals",
"value": "C1234567"
}
]
}App Mentions Only
{
"name": "App Mentions",
"logic": "and",
"conditions": [
{
"field": "event.type",
"operator": "equals",
"value": "app_mention"
}
]
}URL Verification
When you first set up Event Subscriptions, Slack sends a verification challenge:
{
"type": "url_verification",
"challenge": "3eZbrw1aBm2rZgRNFdxV2595E9CY3gmdALWMmHkvFXO7tYXAYM8P",
"token": "..."
}WebhookRelay automatically responds with the challenge, so you don't need to handle this.
Best Practices
Respond quickly: Slack expects responses within 3 seconds for slash commands and interactions
Use response_url: For longer operations, acknowledge immediately and use
response_urlfor the actual responseHandle retries: Slack may retry failed requests; check for
X-Slack-Retry-NumheaderFilter bot messages: Exclude bot messages to prevent loops
Verify the signature: Always use signature verification in production
Troubleshooting
URL Verification Failed
- Ensure your source is configured with the correct signing secret
- Check that the WebhookRelay endpoint is accessible from the internet
- Verify the URL doesn't have extra characters or spaces
Events Not Arriving
- Check Event Subscriptions is enabled
- Verify the correct events are subscribed
- Ensure the app is installed to the workspace
- Check the app has required OAuth scopes
Signature Verification Failed
- Use the Signing Secret, not the Verification Token
- Verify the secret is copied correctly (no extra spaces)
- Check if the request timestamp is too old (>5 minutes)