Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Cloud Functionsで作るSlack App
Search
mikan3rd
September 29, 2021
Programming
920
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Cloud Functionsで作るSlack App
mikan3rd
September 29, 2021
More Decks by mikan3rd
See All by mikan3rd
どうしてフロントエンドにReact/TypeScriptが必要なのか?〜そしてサーバーサイドへ〜
mikan3rd
1
1.2k
Other Decks in Programming
See All in Programming
AIキャラアプリkaiwaの低遅延音声通話基盤をどう作ったか - AWS Gravitonで支える低遅延・低コストAI Agent基盤
mogamit
0
170
えっ!!コードを読まずに開発を!?
hananouchi
0
220
エンジニア向け会社紹介/Findy Company Profile
findyinc
6
360k
AI時代の仕事技芸論〜ソフトウェア開発で「遊ぶように働く」職人的熟達のすすめ(スクフェス仙台 2026バージョン)
kuranuki
0
650
技術記事、 専門家としてのプログラマ、 言語化
mizchi
14
7.5k
使用 Meilisearch 建立新聞搜尋工具
johnroyer
0
150
Foundation Models frameworkで画像分析
ryodeveloper
1
120
Honoでのサプライチェーン侵害対策 〜 3つのライブラリに学ぶ
yusukebe
7
1.9k
なぜ型を書くのか? TSKaigi2026で改めて考える #tskaigi_smarthr
kajitack
0
380
Performance Engineering for Everyone
elenatanasoiu
0
270
言語を使う側から、作る側へ。 自作 Lisp で得た新たな気づき。
andpad
0
130
Go言語とトイモデルで学ぶTransformerの気持ち / fukuokago23-transformer
monochromegane
0
110
Featured
See All Featured
Chrome DevTools: State of the Union 2024 - Debugging React & Beyond
addyosmani
10
1.3k
Navigating the Design Leadership Dip - Product Design Week Design Leaders+ Conference 2024
apolaine
1
370
Stewardship and Sustainability of Urban and Community Forests
pwiseman
0
350
How People are Using Generative and Agentic AI to Supercharge Their Products, Projects, Services and Value Streams Today
helenjbeal
1
240
RailsConf 2023
tenderlove
30
1.5k
brightonSEO & MeasureFest 2025 - Christian Goodrich - Winning strategies for Black Friday CRO & PPC
cargoodrich
3
750
Agile that works and the tools we love
rasmusluckow
331
22k
Exploring the relationship between traditional SERPs and Gen AI search
raygrieselhuber
PRO
2
4.1k
Primal Persuasion: How to Engage the Brain for Learning That Lasts
tmiket
0
390
A Tale of Four Properties
chriscoyier
163
24k
Art, The Web, and Tiny UX
lynnandtonic
304
22k
Effective software design: The role of men in debugging patriarchy in IT @ Voxxed Days AMS
baasie
0
450
Transcript
Cloud Functionsで作る Slackアプリ 2021/09/29 mikan3rd
Who is mikan3rd? • Hiroki Ota ◦ 基本 mikan3rd という名前で活動してます
• 1992年生まれ、エンジニア5年目 ◦ JavaScript / TypeScript / Ruby / Python / Go ◦ TypeScript / React が特に得意 • 現在は株式会社ZENKIGEN所属 ◦ 採用向けweb面接「harutaka」 ◦ 録画面接のAI分析「harutaka エントリーファインダー」 ◦ ライブ面接のAIサポート「harutaka インタビューアセスメント」 ◦ エンジニア職も募集中!! • Google CloudのProfessional Cloud Developer認定 ◦ 弊社のインフラは GCPがメインです Twitter: @mikan_the_third
本題 Cloud Functionsで作る Slackアプリ
Q. こんなこと思ったことありませんか? • HTTPリクエストで呼び出せる処理を作りたい! • PubSubで非同期に実行させたい! • cronみたいに定期実行させたい! • (JavaScriptでいう)オブジェクトをそのまま
DBに保存したい! • CI経由で自動デプロイさせたい! • 1ヶ月あたり無料枠〜数十円におさまる範囲で動かしたい!
それ、 で Serverlessでできます!!
Firebaseとは? • mBaaS(mobile Backend as a Servie) • GCPのサービスのうちアプリ開発によく使う機能をまとめて使いやすくしたやつ ◦
データベースFirestore ◦ ストレージは Cloud Storage for Firebase ◦ ユーザー認証は Authentication ◦ サーバーレスコンピューティングは Cloud Function ◦ などなど(モバイルアプリ向けの機械学習もある) • インフラや一部バックエンドは GCPに任せてサーバーレスで開発できる! ◦ 上記の機能をフロントから使える
Cloud Functions for Firebaseの良いところ • 関数単位のちょっとした複数の処理をサーバーレスで用意できる ◦ フレームワーク不要、関数だけでバックエンドサーバーができる ◦ サーバー(の管理が)レス
• 様々なトリガーで関数を起動できる ◦ HTTPリクエスト ◦ PubSub ◦ Cloud Schedulerの自動PubSub連携(定期処理) ◦ フロント側からSDK経由で直接呼び出し ◦ Firestore / Storage にデータの変更があった場合 ◦ などなど • firebase-toolsを使用したデプロイが楽 ◦ `firebase deploy` だけ! ◦ Firestoreのセキュリティルールとかもまとめてデプロイ可能 • エミュレーターを使えばローカルでも動作確認可能
Firestoreのいいところ • 何も準備がいらないので楽 ◦ テーブルを追加する必要なし(ドキュメント追加と共に自動で作成される) • ちょっとしたクエリなら使える ◦ RedisなどのKey-Value型のDBではクエリが書けないが、 Firestoreはドキュメント型なので簡単なク
エリなら書ける • 少量の使用なら無料枠におさまる ◦ Cloud SQLなどマネージドDBは最低スペックでも 1ヶ月数千円かかる ◦ Google Compute EngineにMySQLサーバーを自前で立てることもできるが面倒
今回作ったやつ
Lively • LivelyはSlack上のコミュニケーションをより便利に楽しくするための機能を複数備えたアプリで す! • https://github.com/mikan3rd/lively • 様々なチャンネルから人気の投稿を探して通知します • 週間・月間で人気のあった投稿を振り返ります
• アプリのホームタブから簡単に設定ができます • 新しく作成された絵文字やチャンネルをお知らせします • privateチャンネルには関与しないようになっているため安心です
Livelyの構成 • TypeScript (Node.js) • Firebase ◦ Cloud Functions ◦
Firestore • Slack App ◦ OAuth Permission ◦ App Home ◦ Interactive Components ◦ Event Subscription
Slack App
Slack App とは? • Slack AppをSlackにメッセージを投げたり、Slackのデータを取得したり、SlackのUIを使って操 作したりできる • 無料!!
OAuth認証 • アプリを作成したworkspace以外でも使え るようにするためには、OAuth認証で他の workspaceの認証トークンを取得する必要 がある ◦ Slack Appを作成したworkspaceのみで使 用する場合は不要
• 使用したいAPIに応じてscopeを付与する必 要がある ◦ 今回のアプリでは privateチャンネルに対 するアクセス権はない • 認証用URLにリダイレクトするendpointと認 証処理用のendpointを用意
Interactive Component & App Home • Interactive ComponentとはSlackのメッセージにテキス トだけでなくボタンやセレクトボックスなどを表示できる 機能
◦ 各パーツはJSON形式で決まった構造で組み立てる必要が ある ◦ https://app.slack.com/block-kit-builder でプレビューでき る • App HomeをONにするとSlack上でアプリを選択した時 にHomeタブが表示できるようになる ◦ ここにもInteractive Componentを表示させることができる ◦ 今回の場合はここでアプリの設定ができるようにしている • Interactive Componentで選択された結果を受け取る endpointが必要
Event Subscription • 特定のイベントが発生した時にリクエストを送ってくれる webhook的なやつ ◦ 先ほどのApp Homeが開かれた時には `app_home_opened` というイベントが送られてくるので最新
のデータを反映した Interactive Componentを送っている ◦ `channel_created` `emoji_changed` のイベントが送られた 時にチャンネル作成の通知やスタンプ追加の通知をリアル タイムで送るようにしている(簡単) • イベントを受け取るための endpointが必要
実際に触ってみて分かった注意事項
• 外部へのアクセスなど一部の機能には従量課金プランに切り替えが必要 ◦ と言っても従量課金プランにも無料枠はあるのでそんなに気にすることはない • コールドスタート ◦ 実行環境はゼロから初期化されるため、関数の実行までその分の時間がかかる • タイムアウト
◦ 最大9分 ◦ そもそも呼び出し回数、メモリ、実行時間による従量課金なので長く重い処理には向かない • デプロイによる課金 ◦ `firebase deploy` は内部的に Cloud Build を使用しているため Cloud Buildの実行時間が課金対象となる(無料枠あるので そう超えないはず) ◦ 関数は無料枠のない Container Registry に保存されるため、その分のストレージ料金がかかる ◦ デプロイする度に古い Containerが削除されずに溜まっていって課金対象となってしまう • 使えるのは Node.js (JavaScript / TypeScript)だけ ◦ 普通のCloud FunctionはRuby / Python / Java / PHP / Go でも使えます ◦ https://firebase.google.com/docs/functions/functions-and-firebase ◦ `gcloud functions deploy` Cloud Functions for Firebaseを使う際の注意
Firestoreを使う際の注意 • 読み取り、書き込み、削除のドキュメントの数による従量課金 ◦ 頻繁に上記の処理が発生する場合や大量のデータを扱う場合は不向き ◦ ページングなどでドキュメントの合計数が欲しい場合もデータの読み取りとして課金される ◦ コンソール上で上記の処理を行った場合も課金対象 •
NoSQLなのでRDBでいうリレーションを再現し辛い ◦ 一応、サブコレクションや参照型など用意されているがクセがある • NoSQLなのでカラムごとに型を制限できない ◦ KeyとValueのように格納できるが型の制限はできないので想定外の値が入ってもエラーにならない ◦ またマイグレーションのような概念もない • 複数Keyを使ったクエリを書くには別途 indexを貼る必要がある
Slackアプリを使う際の注意 • レート制限 ◦ 同じAPIを呼べるのは1分間に20回までなどの制限がある ◦ OAuth認証であればトークンごとに回数が測定される • メッセージを指定して取得する APIが存在しない
◦ そもそもメッセージにサロゲートキーがない(ちなみにメッセージへのリンク取得 APIではチャンネル IDをタイムスタンプを指定して取得するのでこれが複合キーっぽい) ◦ 例えば1年前のとあるメッセージのチャンネル IDとタイムスタンプが特定できていても、 API経由で取 得するには1年前まで順番に遡るしかない ◦ メッセージを順番に取得する際にも件数を指定しないといけないので、ヤマカンででかい件数を指定 して繰り返す処理をしないといけない(レート制限にかからないように) • Event APIには3秒以内にレスポンスを返さないとリトライが走る ◦ 何か処理を行う時間がないので非同期にしないといけない ◦ リクエストヘッダーの `x-slack-retry-num` `x-slack-retry-reason` を見ればハンドリング可能
スタンプの多いメッセージを取得・通知するには? • 一定数以上のスタンプがついたメッセージを取得したいが、そのような APIはない ◦ メッセージの一覧を取得する APIで全件取得してスタンプ数でフィルタリングする処理を行っている ◦ ただしメッセージの一覧はチャンネルごとにしか取得できないので、チャンネル数だけメッセージの全 件取得を行わなかればいけない
◦ チャンネル数が多い場合はレート制限に引っかかってしまうため調整している ▪ Cloud Task ◦ 上記の処理を毎時実行する定期処理にしている ◦ また、一度通知したメッセージが重複して通知されないように、通知済みのメッセージのチャンネル ID とタイムスタンプは Firestoreに保存してチェックしている • 週間、月間で集計するには? ◦ 毎時の処理で取得したスタンプの多いメッセージを保存して流用したい ◦ しかし、メッセージを指定して取得できる APIがないため、上記の処理の取得期間を週間と月間に伸 ばして実行するチカラ技の処理となってしまっている・・・・
スタンプ数の多いスレッドも通知したい! • メッセージ一覧取得時にスレッドのデータは付与されない • スレッドの一覧はメッセージ指定でしか取得できない • つまり全てのメッセージに対してスレッド一覧取得を行うしかない ◦ 流石にやめた
伝えたいこと • ちょっとした用途のバックエンドにはCloud Functions for Firebase / Firestoreが便利!安い! • Slackアプリは簡単に作れる(けど制約があるので思い通りにな
らないことも) • 今回登場してないけどCloud Runも便利!
ご静聴 ありがとうございました! Qiitaでより詳しいコードの解説してます https://qiita.com/mikan3rd/items/b3f333314c15c866ab84