開始: Slack: メッセージ受信時

Start: Slack: Message Received

このアイテムは、Slack Bot がダイレクトメッセージかメンションされたメッセージを受信すると、プロセスを開始します。

Basic Configs
工程名
メモ
Auto Step icon
Configs for this Auto Step
conf_Secret
C1: Signing Secret を設定した認証設定 *
conf_Text
C2: メッセージを保存するデータ項目 *
conf_UserId
C3: Slack ユーザ ID を保存するデータ項目
conf_ChannelId
C4: チャンネル ID を保存するデータ項目
conf_ThreadId
C5: スレッド ID を保存するデータ項目

Notes

  • この開始イベントを利用するには、以下の手順が必要です
    1. [Slack アプリの作成とインストール] Slack のアプリ一覧ページ を開き、新しい Slack アプリを作成します
      • “From an app manifest” を選択し、このページの Appendix にあるマニフェストを貼り付けてください
      • 作成した Slack アプリをワークスペースにインストールするのを忘れないようにしてください
    2. [Questetra ワークフローアプリの作成とリリース] Questetra BPM Suite で「開始: Slack: メッセージ受信時」を使用したワークフローアプリを作成し、リリースします
      • C1 に設定する Signing Secret は、手順 1 で作成した Slack アプリの Basic Information に表示されます
    3. [イベント URL の変更] 「開始: Slack: メッセージ受信時」に表示されている URL をコピーし、手順 1 で作成した Slack アプリの Event Subscriptions に表示されている Request URL を、その URL で更新します
      • Request URL が verified ステータスになっていることを確認し、”Save Changes” をクリックします
  • Bot が投稿したメッセージでは、プロセスは開始されません

Capture

Appendix

Bot を作成するための Slack アプリのマニフェスト

メンションされたメッセージに反応する Bot
  • この Bot をチャンネルに追加してください
  • この Bot は、直接メンションされたメッセージにのみ反応します
    • @channel や @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
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)
  • 次のスクリプトが記述されている XML ファイルをダウンロードできます
    • 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;
};
%d