LoginSignup
44

More than 3 years have passed since last update.

Slack アプリフレームワーク Bolt for JavaScript を Cloud Functions for Firebase で動かそう

Last updated at Posted at 2019-08-01

重要なお知らせ

Bolt for JavaScript を Google Cloud Functions や AWS Lambda で Bolt アプリを動かす際は以下のような問題に当たる可能性があります。

シンプルな応答をするだけのアプリであればおそらく問題なく動かすことができますが、Events API のハンドリング、非同期処理の開始を含むアプリの場合はご注意ください。

2020 年 6 月更新:Bolt for JS v2 から processBeforeResponse というオプションが導入されました。これを有効にしていれば FaaS でも期待通りに動作するようになりました。


この記事では Bolt⚡ という簡単に Slack 連携を実装するためのフレームワークを Cloud Functions for Firebase で動かす手順を紹介します。この記事時点で Bolt のバージョンは 1.2.0 です。

ちなみに 7/31-8/1 開催の Google Cloud Next ’19 in Tokyo に Slack Japan もブース出展しております。この記事を 2019/8/1 に読まれている方、私も会場におりますので、来場される方はぜひお立ち寄りください :pray:

tl;dr

Bolt⚡ とは何か

Slack と連携するアプリケーションをつくるとき、以下の二つのやりとりがあります。何か便利な Slack 連携をつくるとき、この両方を行うアプリケーションを作ることが多いでしょう。

  • 1) Slack に何か情報を送る(メッセージをポストする、ファイルをアップロードする、など)
  • 2) Slack 内で発生した情報をもらう(Slack 内で発生したイベント、コマンド・ダイアログ・ボタンなどのユーザによる操作の内容を受け取る)

JavaScript/TypeScript の場合 1) は slackapi/node-slack-sdk を使って実装することができます。2) について、この記事では Slack が提供している slackapi/bolt を紹介します。Bolt は Slack が今年 4 月末に公開したライブラリです。Bolt は 1) を簡単に行うためのユーティリティ(sayrespond)も提供しています。

Firebase プロジェクトを始める

この記事では Cloud Functions for Firebase についての説明は割愛します。

まず firebase init で functions のプロジェクトをつくって function の依存ライブラリに @slack/bolt を追加してください。

Bolt は 1.2.0 時点で Node 10.13.0 以上で動作します。 package.jsonengines.node を以下のように書き換えてください。

{
  "engines": {
    "node": "10"
  }
}

Slack アプリの設定を行う

https://api.slack.com/apps にアクセスして Slack アプリをつくってください。動作確認したいワークスペースを指定して作成します。

次に Slash Commands のページにアクセスして /echo-from-firebase というコマンドをつくります。Request URL はこの時点ではダミーでもよいのでとりあえず保存します(その場合は初回デプロイしたあとで更新してください)。

次に Bot Users のページにアクセスして、Bot ユーザを一つ作成してください。

最後に Install App からのこの Slack アプリをワークスペースにインストールしてください。これによって Bot User OAuth Access Token が発行されていますので、これを後ほど使用します。

index.js の完成形

まず、完成形は以下のようになります。/echo-from-firebase というスラッシュコマンドを処理するコードがこれだけの行数で実装できます。以下で個々の内容を説明していきます。

'use strict'
const functions = require('firebase-functions');
const config = functions.config();

const { App, ExpressReceiver } = require('@slack/bolt');
const expressReceiver = new ExpressReceiver({
    signingSecret: config.slack.signing_secret,
    endpoints: '/events',
    processBeforeResponse: true
});
const app = new App({
    receiver: expressReceiver,
    token: config.slack.bot_token,
    processBeforeResponse: true
});
app.error(console.log);

app.command('/echo-from-firebase', async ({ command, ack, say }) => {
    ack();
    say(`You said "${command.text}"`);
});

// https://{your domain}.cloudfunctions.net/slack/events
exports.slack = functions.https.onRequest(expressReceiver.app);

firebase functions:config

config を以下のように設定して

firebase functions:config:set slack.signing_secret=522777abcabcabcabcabcabcabcabc
firebase functions:config:set slack.bot_token=xoxb-1234567890-123456789012-abcabcabcabcabcabc

それを以下のコードで呼び出します。このサンプルではリクエストの検証に必要な Signing Secret と API の利用に必要な Bot OAuth Access Token を設定します。

const functions = require('firebase-functions');
const config = functions.config();

Signing Secret は Basic Information > App Credentials にあります。 Bot OAuth Access Token は Install App に Bot User OAuth Access Token として表示されています。

Bolt の初期化

Bolt はデフォルトの実装は Express を使っています。今回はあとから functions.https.onRequest に渡す Application インスタンスを取得するために ExpressReceiver を定義して App の初期化を行なっています。

const { App, ExpressReceiver } = require('@slack/bolt');
const expressReceiver = new ExpressReceiver({
    signingSecret: config.slack.signing_secret,
    endpoints: '/events',
    processBeforeResponse: true
});
const app = new App({
    receiver: expressReceiver,
    token: config.slack.bot_token,
    processBeforeResponse: true
});
app.error(console.log);

その必要がないケースでは、以下のようにさらにシンプルに App を初期化することもできます。

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

メインロジック

スラッシュコマンドを処理する関数を定義する場合は、以下のように app.command を使います。

app.command('/echo-from-firebase', async ({ command, ack, say }) => {
    ack();
    say(`You said "${command.text}"`);
});

app.eventapp.action など他のリクエストを処理するためのメソッドももちろん定義されているので、ドキュメントを参照してみてください。

Firebase 互換の関数を export する

最後に先ほど定義していた expressReceicerappfunctions.https.onRequest に渡して slack という名前で export します。これによって URL は https://{your domain}.cloudfunctions.net/slack/events のようになります。 URL の中の eventsendpoints: '/events' の部分を変えれば違うパスにも変更できます。

// https://{your domain}.cloudfunctions.net/slack/events
exports.slack = functions.https.onRequest(expressReceiver.app);

動作確認

最後にちゃんと動いているか、実際に確認してみましょう。

Firebase にデプロイ

以下の通り、firebase-cli でデプロイします。作ったばかりのプロジェクトであれば Billing Info の更新をお忘れなく。

firebase deploy --only functions

Slack 上でテスト

設定を行なった Slack ワークスペース内の動作確認を行いたいチャンネルにつくった Bot ユーザを invite してください。 /invite @user-name で招待するか、メンションしてください。

そして、 /echo-from-firebase hello と入力してみてください。 You said "hello" と応答してくれるはずです。

まとめ

簡単ですが Bolt を使った Slack 連携アプリを Cloud Functions for Firebase にデプロイする手順をご紹介しました。ぜひ試してみてください。

やってみて何かわからないことなどがあったら、以下のリンクからコミュニティに参加して、そこで質問をしてみてください!

:wave: Slack コミュニティ公式グループ community.slack.com に参加しませんか?(日本語は #lang-japanese チャンネルへどうぞ!)
https://qiita.com/girlie_mac/items/93538f9a69eb4015f951#comment-a983ea977482e78f209c

また、繰り返しとなりますが Slack Japan は 7/31 と 8/1 の Google Cloud Next ’19 in Tokyo にブース出展しております。この記事を 2019/8/1 に読まれた方でイベントに来場される方は、ぜひお立ち寄りください(私も Slack ブースにおります) :pray:

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
44