開発環境
- Node: v10
- DB: Cloud Firestore
- 言語: TypeScript
やりたいこと
FirebaseのCloud Functionsのトリガー関数が呼ばれた際に、Slackで追加されたことを通知したい。
環境構築
Slackアプリケーションを作成する
こちらからSlackアプリケーションを作成します。
ページのCreate New Appボタンを押下します。
App Nameにアプリケーションの名前を、**Pick a workspace to develop your app in:**に通知したいSlackのワークスペースを選択して、Create Appボタンを押してアプリケーションを作成してください。
Webhook URLを作成する
画面左上にある、どのアプリケーションを選択しているかの項目に、作成したアプリの名前が表示されていることを確認してください。
Slackアプリケーションが作成できたら左のメニューからIncoming Webhooksをクリックします。
Incoming Webhooksの設定ページが開かれるので、Activate Incoming Webhooksのスイッチを有効にしてください。
有効にすると、Webhook URLs for Your Workspaceのページが開かれるので、下部にあるAdd New Webhook to Workspaceのボタンを押下してください。
そうすると、Slackの通知先のチャンネルを選択する画面が開かれます。
任意のチャンネルを選択し、許可するボタンを押下してください。
許可するとWebhook URLが作成されます。
こちらのURLにPOSTリクエストをすることで、選択したチャンネルに通知が飛ぶようになります。
試しに**Sample curl request to post to a channel:**のCopyボタンでURLをコピーして、ターミナルで実行してみましょう。
コマンドを実行するとOKと表示され、
Slackにも通知されていることが確認できます。
実装
それでは本題のCloud Firestoreのあるコレクションにドキュメントが追加された際に、Slackで通知を飛ばすように実装していきます。
パッケージインストール
SlackのAPIクライアントをパッケージに追加します。
npm i @slack/webhook
Cloud Functionsの環境変数にSlackのWebhookのURLを設定する
WebhookのURLは外に漏れると外部の人間から通知されるようになってしまいますので、Gitで管理してはいけません。
ということでCloud Functionsの環境変数からアクセスできるようにします。
下記のコマンドでWebhookのURLを環境変数に設定します。
// 環境変数設定のコマンド
firebase functions:config:set slack.web_hook_url={先ほど作成したWebhookのURL}
設定されているか確認するためには下記のコマンドを実行します。
// 環境変数確認のコマンド
firebase functions:config:get
// 出力結果
{
"slack": {
"web_hook_url": "https://hooks.slack.com/services/XXX/YYY/ZZZ"
}
}
エミュレーターでも環境変数を使いたい場合は、こちらの記事が参考になります。
Slackに通知を送る
Slackに通知を送る実装はこちらです。
import * as slack from '@slack/webhook';
export class SlackService {
/**
* Slackの通知を送信する
* @param webhookUrl WebhookのURL
* @param message 通知する内容
* @returns 通知送信のPromiss
*/
static sendMessage = (webhookUrl: string, message: string): Promise<slack.IncomingWebhookResult> => {
const webhook = new slack.IncomingWebhook(webhookUrl);
return webhook.send({
text: message,
});
};
}
引数のwebhookUrlのURLに、引数messageの内容の通知を送信します。
環境変数からWebhookのURLを取得する
環境変数からWebhookのURLを取得する実装はこちらです。
import * as functions from 'firebase-functions';
export class SlackWebHookUrl {
static webhookUrl = () => {
return functions.config().slack.web_hook_url;
}
}
functions.config()で環境変数にアクセスできます。
slack.web_hook_urlの部分は、先ほどコマンドで実行した際につけた名前です。
今後WebhookURLが追加された時にここに追加していく想定でクラスにしています。
ドキュメントが追加された際にSlack送信処理を呼び出す
今回はpostsコレクションにドキュメントが追加された想定で実装します。
コレクション名やimport文などは適宜変更してください。
import * as functions from 'firebase-functions';
import { Post } from '../entities/post';
import { SlackService } from '../services/slackService';
import { SlackWebHookUrl } from '../constants/slackWebHookUrl';
export const onCreatePost = functions.firestore.document(`posts/{postId}`).onCreate(async (snap, context) => {
// 追加されたドキュメント
const post = snap.data() as Post
// メッセージデータ作成
const messageData = {
'ID': snap.id,
'名前': post.name,
'リクエスト時刻': post.createdAt.toDate().toLocaleString(),
}
// メッセージを見やすくする
const message = JSON.stringify(messageData, null, '\t');
// Slackに通知を送信する
await SlackService.sendMessage(SlackWebHookUrl.webhookUrl(), message);
});
実行結果
実装できたらデプロイし、postsコレクションにドキュメントを追加し、Slackの通知が送信されることを確認します。
以上です。