Closed6

Cloud Functions x Slack Bolt でオウム返し

sekitatssekitats

事前準備

Cloud Functions

Slack App

  • api.slack.com でSlackアプリの作成
  • App Credentials の signing secret を控える
  • OAuth & Permissions で User token か Bot token(xoxb) を控える
    • 画面下 Scopes で chat:write を追加する
  • Event Subscriptions
    • Request URL にデプロイ先に URL + "/events" を入力
    • message.channels リスナーを追加

参考: Slackアプリでチャンネルにメッセージを送信する方法 - Carpe Diem

sekitatssekitats

オウム返しするコードを書く

// index.ts
import {reciever} from "./slack/app";

export const helloWorld = functions.https.onRequest(reciever.app);
// slack/app.ts
import * as functions from "firebase-functions";
import {App, ExpressReceiver} from "@slack/bolt";

export const reciever = new ExpressReceiver({
  signingSecret: config.slack.secret,
  endpoints: "/evnets"
});

const app = new App({
  token: config.slack.token,
  reciever,
})

useSlackEvents(app);
import {App} from "@slack/bolt";

export const useSlackEvents = (app: App) => {
  app.message(/.*/, async ({message, say}) => {
    const msg = (message as GenericMessageEvent)
    say(`<@${msg.user}> ${msg.text}`);
  });
}

user, text のところで怒られる。

プロパティ 'user' は型 'KnownEventFromType<"message">' に存在しません。

参考:【Slack Bot開発】HubotとBoltを使用して感じたことまとめ

sekitatssekitats

ボタンを返却する

Block Kit Builder

https://app.slack.com/block-kit-builder/

app.message(/.*/, async ({message, say}) => {
    const msg = (message as GenericMessageEvent);
    if (msg.text) {
        await say({
            blocks: [
                {
                    "type": "section",
                    "text": {
                        "type": "mrkdwn",
                        "text": msg.text,
                    },
                },
                {
                    "type": "actions",
                    "elements": [
                        {
                        "type": "button",
                        "text": {
                            "type": "plain_text",
                            "text": "進む",
                        },
                        "style": "primary",
                        "value": "go",
                        "action_id": "button_go",
                        },
                        {
                        "type": "button",
                        "text": {
                            "type": "plain_text",
                            "text": "逃げる",
                        },
                        "style": "danger",
                        "value": "withdraw",
                        "action_id": "button_ withdraw",
                        },
                    ],
                },
            ]
        });
    }
});

sekitatssekitats

ボタンクリックのイベントを取得する

事前準備

  • Interactivity & Shortcuts

    • ONにする
    • Request URL に先に用意したPOSTのエンドポイントを入力
  • Cloud Functions のエンドポイントを追加する

    • ボタンをクリックによって、POSTリクエストが送られるの app.action でイベントリスナーを追加
    • eventTypeは blocks の block_idと合わせる
app.action("button_go", async ({body, ack, respond}) => {
    const blocks = [{
        "type": "section",
        "text": {
            "type": "plain_text",
            "text": "進むが押されました。",
            "emoji": true,
        },
    }];
    await ack();
    await respond({
        blocks,
        replace_original: true,
    });
});

app.action("button_withdraw", async ({ack, respond}) => {
    await ack();
    await respond({
        delete_original: true,
    });
});

イベントアクションに対するレスポンスにはrespond() メソッドを使う。

このスクラップは2023/02/12にクローズされました