slackに毎日情報を流しているbotをcloudflare workersに移植してみる
前の記事で調べていた時にschedule triggerを使えば無料枠でもcron的な事ができそうだったので移植で素振りしてみる
cloudflare workersでslack botを動かすには@slack/bot
は動かないらしいので、以下の記事で紹介されているものを使う
各種slack用のトークンは上記の記事を参照
cron triggerについて
wrangler.yml
などにcron設定を書くとその設定に従って以下の用に定義した関数を実行してくれる
時間設定
wrangler.ymlに設定するのはこんな感じ(ドキュメントに書かれているサンプル)
[triggers] # Schedule cron triggers: # - At every 3rd minute # - At 3PM on first day of the month # - At 11:59PM on the last weekday of the month crons = [ "*/3 * * * *", "0 15 1 * *", "59 23 LW * *" ]
cronsに設定できる時間は3つまでらしい
実装
初期のテンプレートだとsrc/index.ts
にscheduled
関数を定義するとそれが実行される
export default { async scheduled(event: ScheduledEvent, env: SlackEdgeAppEnv, ctx: ExecutionContext): Promise<void> { // 処理 };
event
には実行された時間と発火したcronの設定値("*/3 * * * *"
のようなもの)が入っている。なのでevent.cron
の値を見て3つで出し分ける事も可能だと思う。
実際に作ってみる
実際に実行するときはcloudflareに環境変数として設定するがローカルでテストする時のために.dev.vars
にtoken設定などを書いておく
SLACK_BOT_TOKEN=xoxb-xxxxx SLACK_SIGNING_SECRET=xapp-xxxxx
scheduleのコードは以下。exec
関数でslackに投稿するデータの取得や組み立て、投稿までを行っている。
import { SlackApp, SlackEdgeAppEnv } from "slack-cloudflare-workers"; import * as xxx from "./features/xxx/index"; export default { async scheduled( _event: ScheduledEvent, env: SlackEdgeAppEnv, _ctx: ExecutionContext, ): Promise<void> { try { const app = new SlackApp({ env }); await xxx.exec(app); console.log("done"); } catch (e) { console.error(e); throw e; } }, }; // execの中のイメージ export function exec(app: SlackApp<SlackEdgeAppEnv>) { const data = await xxxApi(); const text = processing(data); await app.client.chat.postMessage({ channel: "random", text, });
これだけで簡単に投稿することができた
テスト
wrangler dev
を実行する際に--test-scheduled
というオプションを付けることでschedule発火用のエンドポイントが出てくる。
実行後以下のようにリクエストを投げることでscheduled関数を実行させることができる
curl "http://localhost:8787/__scheduled?cron=0+0+*+*+*"
疑問点
cron triggerで実行しconsole.log
でログを出すようにしてみたがどこで確認できるのかわからず、失敗した時のデバッグで困った。
またcronの設定のTZについてUTC固定?なので日本時間で実行する場合は+9時間後に実行される事に注意する必要がある。