RX100で撮り歩くブログ

RX100で撮った写真を中心によりよい生活を目指すブログ

Cloud FunctionsでSlackへメッセージ送信を定期実行する

FireStoreの練習で簡単なTodoっぽいものを作り、そのリストを定期的にSlackに送れるようにしようと初めてCloud Functionsを使ってみたのでメモ。

よくあるTodoとSlackを連携して定期リマインダーみたいにしてみます。最初の一歩で決まったワードを決まった時間にSlackに送ってみます。

前提としては、Slack APIは使える(Token取得済み)、Cloud Functionsの定期実行するためにBlazeプランにしていることです。

Cloud Functions使えるようにする

すでにCreate React Appを使って簡単なTodoは作ってたので、それにCloud Functionsを追加していくには以下を打つと、勝手にfunctionsディレクトリを作って初期化してくれました。

firebase init functions

ドキュメント参考にしました。ドキュメントはプロジェクト作るところから書かれてるので、最初から作る人は以下のサイトの手順でやってみるといいと思います。また、基本的なCloud Functions経由でFirebaseに追加するのも以下のドキュメントに書かれてます。

firebase.google.com

定期実行でslackにメッセージ飛ばす

定期実行はこちらのドキュメントをみると分かります。

firebase.google.com

ドキュメントに書かれてるように基本はこんな感じ。

// 5分ごと
exports.scheduledFunction = functions.pubsub.schedule('every 5 minutes').onRun((context) => {
  console.log('This will be run every 5 minutes!');
  return null;
});

時間指定したい時は以下のように。ただデフォルトのタイムゾーンがアメリカ時間なので、東京に変えておきます。以下だと19時5分に実行されます。

exports.scheduledFunctionCrontab = functions.pubsub.schedule('5 19 * * *')
  .timeZone('Asia/Tokyo') // Users can choose timezone - default is America/Los_Angeles
  .onRun((context) => {
  console.log('This will be run every day at 19:05 Eastern!');
  return null;
});

slackにメッセージを送るために@slack/web-apiを使ってメッセージを送ります。

import { WebClient } from '@slack/web-api'


exports.scheduledFunctionCrontab = functions.pubsub
  .schedule('5 19 * * *')
  .timeZone('Asia/Tokyo') // Users can choose timezone - default is America/Los_Angeles
  .onRun(async (context) => {
    const client = new WebClient(
      'slackで取得したToken'
    )
    const params = {
      channel: '#general',
      text: `定期実行テスト`,
    }

    await client.chat.postMessage(params)
    return null
  })

これでFunctionsをデプロイします。

firebase deploy --only functions

しかしエラーが...

Module '@slack/web-api' is not listed as dependency in package.json

@slack/web-apiを追加

@slack/web-apiはすでにルートのpackage.jsonにはあるのになんでだろうと思ったら、functionsディレクトリにCloud Functions用のpackage.jsonがあるので、個別にインストールする必要があるんですね。

functionsディレクトリ以下のpackage.jsonに@slack/web-apiを追加。yarnを実行(いらんかも?)

// 省略
  "main": "lib/index.js",
  "dependencies": {
    "firebase-admin": "^8.6.0",
    "firebase-functions": "^3.3.0",
    "@slack/web-api": "^5.8.1"
  },
}
// 省略

再びFunctionsをデプロイします。

firebase deploy --only functions

成功するはずです。

管理画面のFunctionsのダッシュボードに関数が登録されていればOK。時間になったらSlackにメッセージ飛んできます。

次はFirestoreからTodoを取得して、それをSlackに通知させるようにしてみます。