
Start: Slack: Message Received
This item starts a process when Slack Bot has received a direct message or a mentioned message.
Basic Configs
- Step Name
- Note
Configs for this Auto Step
- conf_Secret
- C1: Authorization Setting in which Signing Secret is set *
- conf_Text
- C2: Data item to save Message *
- conf_UserId
- C3: Data item to save Slack user ID
- conf_ChannelId
- C4: Data item to save Channel ID
- conf_ThreadId
- C5: Data item to save Thread ID
Notes
- To activate this start event, follow the instructions below:
- [Create & Install Slack App] Open Your Apps and create a new Slack App using one of the manifests shown in the Appendix section of this page
- Remember to install your app onto your workspace
- [Create & Release Questetra Workflow App] Create a Workflow App on Questetra BPM Suite using “Start: Slack: Message Received”, and release it
- Your Signing Secret to set in C1 is shown on the Basic Information page of the Slack App created in the Step 1
- [Change Event URL] Copy the URL shown in “Start: Slack: Message Received”, and set it as Request URL on the Event Subscriptions page of the Slack App created in the Step 1
- Confirm that the Request URL is verified and click “Save Changes”
- [Create & Install Slack App] Open Your Apps and create a new Slack App using one of the manifests shown in the Appendix section of this page
- A process will not be started for the messages posted by a Bot
Capture

Appendix
Slack App Manifests to create a Bot
Bot to react to mentioned messages
- Add the Bot to the channel
- The Bot reacts only to the directly mentioned messages
- A process will not be started for the messages with @channel or @here
display_information:
name: Questetra Bot (Mentioned Messages)
features:
bot_user:
display_name: Questetra Bot (Mentioned Messages)
always_online: true
oauth_config:
redirect_urls:
- https://s.questetra.net/oauth2callback
scopes:
bot:
- app_mentions:read
- chat:write
- users:read
- users:read.email
settings:
event_subscriptions:
request_url: https://example.questetra.net/System/Event/Start/
bot_events:
- app_mention
org_deploy_enabled: false
socket_mode_enabled: false
token_rotation_enabled: false
Bot to react to direct messages
display_information:
name: Questetra Bot (Direct Messages)
features:
app_home:
home_tab_enabled: false
messages_tab_enabled: true
messages_tab_read_only_enabled: false
bot_user:
display_name: Questetra Bot (Direct Messages)
always_online: true
oauth_config:
redirect_urls:
- https://s.questetra.net/oauth2callback
scopes:
bot:
- chat:write
- im:history
- users:read
- users:read.email
settings:
event_subscriptions:
request_url: https://example.questetra.net/System/Event/Start/
bot_events:
- message.im
org_deploy_enabled: false
socket_mode_enabled: false
token_rotation_enabled: false
Script (click to open)
- An XML file that contains the code below is available to download
- slack-message-received.xml (C) Questetra, Inc. (MIT License)
- Just use it for a reference for the codes
- This file cannot be imported into a Workflow App as an Add-on
- slack-message-received.xml (C) Questetra, Inc. (MIT License)
const post = ({body, headers}) => {
const secret = configs.getObject('conf_Secret').getToken();
if (!verifyRequest(secret, {body, headers})) {
return {
status: 400
};
}
const json = JSON.parse(body);
switch (json.type) {
case 'url_verification':
engine.log(`succeed to verification`);
return {
'content-type': 'text/plain',
'body': json.challenge
};
case 'event_callback':
receive(json);
return {
'content-type': 'text/plain',
'body': ''
};
default:
engine.log(body);
return {
status: 400
};
}
};
/**
* event 受信処理
* @param json
*/
const receive = (json) => {
const {
type,
subtype,
channel,
user,
bot_id,
text,
ts,
thread_ts
} = json.event;
if (type !== 'message' && type !== 'app_mention') {
// event type が message または app_mention でないものは無視
engine.log(`ignore event. type: ${type}`);
return;
}
if ((subtype !== undefined && subtype !== 'thread_broadcast') || bot_id !== undefined) {
// ユーザのメッセージ投稿以外によるイベントを無視するため、subtype に thread_broadcast 以外が指定されているものを無視
// bot によるメッセージも無視
engine.log(`ignore event. type: ${type} subtype: ${subtype} bot_id: ${bot_id}`);
return;
}
saveData('conf_ChannelId', channel);
saveData('conf_UserId', user);
saveData('conf_Text', text);
saveData('conf_ThreadId', thread_ts === undefined ? ts : thread_ts);
engine.setStartProcess(true);
};
/**
* データ項目への保存
* @param configName
* @param data
*/
const saveData = (configName, data) => {
const def = configs.getObject(configName);
if (def === null) {
return;
}
engine.setData(def, data);
};
/**
* リクエストのチェック
* @param secret Singining Secret
* @param body リクエストボディ
* @param headers リクエストヘッダ
* @returns {boolean} false の場合、不正リクエスト
*/
const verifyRequest = (secret, {body, headers}) => {
const signature = headers.getFirst('X-Slack-Signature');
const timestamp = headers.getFirst('X-Slack-Request-Timestamp');
if (Date.now() - timestamp * 1000 > 5 * 60 * 1000) {
engine.log(`Timestamp: ${timestamp}`);
return false;
}
const baseString = `v0:${timestamp}:${body}`;
const calcString = hex.encodeToString(hmac.sha256(secret, baseString));
if ('v0=' + calcString !== signature) {
engine.log(`Failed to verification`);
engine.log(`Timestamp: ${timestamp}`);
engine.log(`Signature: ${signature}`);
engine.log(body);
engine.log(`hmac: ${calcString}`);
return false;
}
return true;
};