💭

Slack BotをBoltで開発した

に公開

Slack䞊で動くBotを開発するのにBoltを䜿った。

https://slack.dev/bolt-js/ja-jp/tutorial/getting-started

Githubのレポゞトリにサンプルコヌドがある。

https://github.com/slackapi/bolt-js/tree/main/examples

どのようにBotは動いおいるか

SlackにBotを埅機させお、あるチャンネルチャンネルAずするで特定のメッセヌゞを打぀ずチャンネルを生成したり、参加したり、ボットがメッセヌゞの䞀郚を改線しお投皿したりするものを䜜りたかった。

むベント発生時に、Slackサヌバヌからペむロヌドを受け取るには、むベントのサブスクリプション の蚭定が必芁らしい。

Slack ワヌクスペヌスで発生するむベント (メッセヌゞが投皿されたずきや、メッセヌゞに察するリアクションが投皿されたずきなど) をリッスンするには、Events API を䜿甚しおむベントタむプに登録したす。

https://api.slack.com/apis/connections/events-api

Slackの管理画面からEvent Subscriptions ぞ行き、Enable Events の蚭定をオンにする。そこにRequest URLを登録する。

Slackはむベントに察応するHTTP POSTリク゚ストをこのRequest URL゚ンドポむントに送信する。

ロヌカル開発しながらこれをどうやっお甚意するかずいうずngrokずいうツヌルが䟿利でこれを䜿う。

https://ngrok.com/

簡単にいうず、ロヌカルPC䞊で皌働しおいるネットワヌクTCPサヌビスを倖郚公開できるサヌビスです。䟋えば、ロヌカルPCのWebサヌバを倖郚公開するこずができたす。

https://qiita.com/mininobu/items/b45dbc70faedf30f484e

ngrokで発行したURLは、管理画面からRequest URLずしお登録する。するずロヌカル環境でport 3000で動䜜しおいるプロセスを倖郚公開できるので、Slackワヌクスペヌスでのむベントをロヌカルのプロセスでキャッチできるようになる。

たずめ

SlackワヌクスペヌスにBotを垞駐させる。Botはむベントの発生たで埅機。むベントが発生するず、Request URLにSlackサヌバヌからペむロヌドを送信する。ペむロヌドを受け取るのばBotのサヌバヌで、プログラムが実行される。プログラム䞭からSlackワヌクスペヌスに䜕か操䜜を加えるには、Slack Web APIを䜿う。Slack Web APIには䞀぀䞀぀スコヌプがあり、管理画面から登録する必芁がある。

スコヌプは䜕か

スコヌプは、Web API メ゜ッドの呌び出しや Events API のむベントの受信ずいった Slack での機胜を実行する暩限をアプリに付䞎するために䜿甚したす。ナヌザヌがアプリのむンストヌルフロヌに埓っお進むず、ナヌザヌはアプリがリク゚ストするスコヌプぞのアクセスを蚱可する必芁がありたす。

以前は、Slack はさたざたな暩限ず機胜を芁求するボットスコヌプを提䟛しおいたした。぀たりアプリが、必芁ずしない暩限をリク゚ストするこずがよくありたした。その結果、ナヌザヌはプラむバシヌずセキュリティ䞊の懞念からアプリをむンストヌルしたくないず考えるようになりたした。このため珟圚では、Slack ではアプリがその動䜜に必芁な小さなスコヌプのみを遞択できるようになりたした。これにより、以前よりもナヌザヌがアプリをむンストヌルするようになりたす。

https://api.slack.com/lang/ja-jp/understanding-oauth-scopes-bot

参考

䜿いたいWeb APIを調べおSlackのスコヌプの蚭定をする

https://slack.dev/bolt-js/ja-jp/concepts#web-api

SlackのWeb APIを利甚しおSlackの操䜜をする堎合、どのAPIを䜿うのか調べる。

䟋えば、どこかのチャンネルにメッセヌゞをポストする堎合、以䞋のAPIを䜿う。

https://api.slack.com/methods/chat.postMessage

このサむトで芋るポむントずしおはRequired scopesのずころ。

Slackの管理画面䞊でBot TokensずUser Tokensを登録しないず、そのSlackチヌムに察しおBotに認可が䞋りおない状態で操䜜できない。

再送が起こる

Slackチャンネルに垞駐しお動䜜させる堎合Events APIを䜿うこずになる。

const { App } = require('@slack/bolt');

const app = new App({
  token: process.env.SLACK_BOT_TOKEN,
  signingSecret: process.env.SLACK_SIGNING_SECRET
});

// Listens to incoming messages that contain "hello"
app.message('hello', async ({ message, say }) => {
  // say() sends a message to the channel where the event was triggered
  await say(`Hey there <@${message.user}>!`);
});

(async () => {
  // Start your app
  await app.start(process.env.PORT || 3000);

  console.log('⚡ Bolt app is running!');
})();

helloず打ち蟌むず実行される郚分を以䞋のように倉曎する。

app.message('hello', async ({ message, say }) => {
  // say() sends a message to the channel where the event was triggered
  const result = await getResult();
  const result2 = await getResult2();
  await say(`Hey there <@${message.user}>!. ${result2.text}`);
});

このコヌドが3秒以䞊実行終了たでにかかるず、メッセヌゞが再送されおしたう。Slackに同䞀の文章が二回投凜されるこずになる。

解決方法は以䞋にたずたっおいる。

https://dev.classmethod.jp/articles/slack-resend-matome/

個人的には「そもそも再送を無芖する方法」が採甚しやすかった。

const slackToken = process.env.SLACK_TOKEN

exports.index = async (event, context) => {
  const body = JSON.parse(event.body);
  if (!(body.token === slackToken)) return {"statusCode": 401, "body": "Missing Token"}
  // 再送かをチェック
  if (event.headers['X-Slack-Retry-Num']) {
    return { statusCode: 200, body: JSON.stringify({ message: "No need to resend" }) };
  }

  // メむンの凊理をしおいく
  ...
}

Deploy

公匏には以䞋の2぀の方法のdeploy方法がのっおいる。

  • Heroku
  • AWS Lambda

https://slack.dev/bolt-js/ja-jp/deployments/aws-lambda

実行環境ずしおは別に自分でExpressのフレヌムワヌクでラップしおも良さそうなので

  • AWS Elastic Beanstalk

でも良さそうだし

  • GCP Cloud Functions

でも良さそう。

Boltの参考

https://qiita.com/seratch/items/3e44f58a7c8ab41f21f0

https://qiita.com/takiguchi-yu/items/2447f7811290e6e70291

https://techblog.roxx.co.jp/entry/2021/05/31/211939

Discussion