Set up Slack
Slack uses two credentials because WOML connects through Socket Mode:
- a bot token (
xoxb-...) authorizes messages, channel lookup, and events; and - an app-level token (
xapp-...) opens the Socket Mode connection.
This setup does not require a public callback URL.
Create and configure the Slack app
- Open Slack API apps and select Create New App.
- Choose From an app manifest, select the workspace, and use this manifest:
{
"display_information": {
"name": "WOML",
"description": "Run and approve WOML workflows from Slack.",
"background_color": "#16a34a"
},
"features": {
"bot_user": {
"display_name": "WOML",
"always_online": false
}
},
"oauth_config": {
"scopes": {
"bot": [
"chat:write",
"chat:write.public",
"app_mentions:read",
"channels:read",
"groups:read",
"im:history"
]
}
},
"settings": {
"event_subscriptions": {
"bot_events": ["app_mention", "message.im"]
},
"interactivity": { "is_enabled": true },
"socket_mode_enabled": true,
"token_rotation_enabled": false
}
}- Open Event Subscriptions and confirm Enable Events is on. The bot events must include
app_mentionandmessage.im. - Open Interactivity & Shortcuts and confirm interactivity is enabled. Approval buttons depend on it.
- Open Socket Mode and confirm it is enabled.
- Open Basic Information → App-Level Tokens, create a token with the
connections:writescope, and copy the resultingxapp-...token. - Open OAuth & Permissions, install the app to the workspace, and copy the Bot User OAuth Token beginning with
xoxb-.
If scopes or event subscriptions change later, reinstall the app to the workspace and replace the stored bot token when Slack issues a new one.
Add the bot to the channel
Create or open a test channel such as #woml-testing, then run this inside the channel:
/invite @WOMLPrivate channels always require an explicit invite. Inviting the bot is also recommended for public channels.
Store the credentials
Run these commands from the project that will run the workflow:
woml secrets set SLACK_BOT_TOKEN
woml secrets set SLACK_APP_TOKENPaste the xoxb-... value into the first prompt and the xapp-... value into the second. Do not place either token directly in a .woml file or commit it to source control.
Test a Slack trigger
Save this as slack-test.woml:
<woml>
<workflow id="slack-test" name="Slack Test" version="1.0.0">
<triggers>
<slack
id="messageReceived"
events="app-mention,direct-message"
channels="woml-testing"
bot-token="{{secrets.SLACK_BOT_TOKEN}}"
app-token="{{secrets.SLACK_APP_TOKEN}}"
/>
</triggers>
<steps>
<step id="capture" name="Capture Slack message">
<script>
return {
text: context.payload.text,
senderId: context.payload.senderId,
conversationId: context.payload.conversationId
};
</script>
</step>
</steps>
</workflow>
</woml>Validate and start it:
woml check slack-test.woml
woml run slack-test.womlWait for Slack workspace ... is ready for triggers, then send @WOML hello in #woml-testing or send the bot a direct message. WOML should accept a Slack trigger, run capture, and print the normalized message data.
The trigger's channels attribute uses comma-separated names without #. Notification destinations use whitespace-separated aliases with #, for example:
<approval id="review" timeout="24h" on-timeout="reject">
<notify>
<slack
channels="#woml-testing"
bot-token="{{secrets.SLACK_BOT_TOKEN}}"
app-token="{{secrets.SLACK_APP_TOKEN}}"
/>
</notify>
<when-approved />
<when-rejected />
</approval>Diagnose Slack setup failures
- No events arrive: make sure Enable Events is on and the bot events include
app_mentionandmessage.im. - Authentication fails: verify that the bot token starts with
xoxb-, the app token starts withxapp-, and the app token hasconnections:write. - Channel lookup reports
missing_scope: addchannels:readandgroups:read, then reinstall the app.channels:historyis not a replacement forchannels:read. - A private channel is not found: invite
@WOMLto it or use its Slack conversation ID. - Messages send but buttons do nothing: enable Interactivity & Shortcuts.
- An updated app still behaves like the old configuration: reinstall it to the workspace and update the stored token.