まえがき
本記事は Slack Advent Calendar 2018 の 5日目の記事です。
何故自作したの?
Slack の /remind
って便利ですよね!(仕事でもプライベートでも愛用しています)
「/remind
って何?」ってなった人はこちらの記事を読んでみてください
この時点で普段抱えている課題の解決に繋がったりするかもしれません。
ただ、実は微妙に痒いところに手が届かなかったりするんですよね。
そして、今回私は Slack API と AWS Lambda Function を使って敢えて Slack のリマインダーを自作することにしました。
/remind でできなくて困ったこと
では、私が「痒いところに手が届かない」と感じたポイントを整理します。
1. 投稿者が Slack bot になってしまう
/remind
は Slack bot の標準機能として提供されています。
なので、当たり前ではあるのですが Slack bot の投稿としてリマインドされてしまいます。
例えば下記のような /remind
を登録した場合
/remind @channel
忘年会の出欠連絡の締め切りは本日の 19:00 までです!
忘れずに 19:00 までにご連絡ください!
at 18:00 on today
リマインドは下記のように表示されます。
機能としては全然問題ないのですが
やっぱりアイコンもユーザー名も自分の好きなように設定したいじゃないですか。
2. チャンネル宛のリマインドはリマインド設定したことがバレてしまう
例えば #hoge チャンネル宛に下記のような /remind
を登録した場合
/remind #hoge @here
そろそろお昼にしませんか?
at 12:00 on every weekday
#hoge チャンネルには下記のようなメッセージが表示されます。
やっぱり機能としては問題ありませんが、
やっぱりリマインドを設定したことはチームメンバーにはサプライズにしたいじゃないですか。
3. 登録したリマインドを編集することができない
現在のところ /remind
で登録したリマインドの内容(文言や宛先や日時)を再編集することはできません。
登録した内容を削除して再登録することになります。
先程の #hoge チャンネルへの /remind
登録のときに
間違えて「そろそろお春にしませんか?」と登録してしまった場合は
- 間違えた文言のリマインドの登録メッセージがチャンネルに表示される
- 間違えたからリマインドの削除
- 正しい文言でリマインド再登録
- 再度リマインド登録メッセージがチャンネルに表示される
となりますね。
折角ならば痕跡を残さずにスマートにリマインドを運用したいじゃないですか。
え?気にしすぎ?
ですよね笑
なので、「敢えて」自作した話なのです。
それでは実際に作ったものをご紹介します。
実際に作ったもの
こちらのリボジトリに
- 今回必要な AWS 系のリソースを作成する CloudFormation のテンプレート
- Lambda Function の index.js
を格納しています。
自作した Slack リマインダーの仕組みは大体こんな感じです。
登場するエッセンス
-
CloudWatch Events
-
/remind
の at や on で指定する「いつリマインドするか」にあたる部分を設定 - スケジュールの設定方式についてはこちら
- 設定したスケジュールにしたがって、Lambda Function にイベントを通知する
-
-
Lambda Function
-
/remind
の「どのチャンネルにどんな内容でリマインドするか」に当たる部分を設定 - CloudWatch Events からのイベントが通知されると処理を行う
- 実際は Slack API を呼び出すだけ
-
-
Slack API
- Slack の Workspace の管理者がアプリを登録することで Slack API 用のトークンが払い出されるので、そのトークンを指定して Slack API を呼び出す
- トークンには呼び出せる API のスコープなどの認可情報が含まれている
- 今回は chat.postMessage という API を使用している
- Slack Workspace
- 今回リマインドを投稿したい対象のワークスペース
- 今回リマインドを投稿したい対象のワークスペース
もっとざっくり分けるならば
-
Slack にシステムからメッセージを投稿する仕組み
-
実行タイミングをスケジューリングできる仕組み
の組み合わせです。
では、それぞれの仕組みについてもう少しだけ詳しく見ていきましょう。
⬛️ Slack にシステムからメッセージを投稿する仕組み
基本的に下記の記事を参考にさせていただき、簡単に作ることができました。
では、実際の Lambda Function のコードを見てみましょう。
const axios = require('axios')
exports.handler = async (event, context) => {
try {
const url = `https://slack.com/api/chat.postMessage`;
const params = {
"channel": "*****", //投稿したいチャンネルのチャンネルID
"text": "リマインドだよ!",
"icon_emoji": ":slack:",
"username": "AdventCalendarReminder"
}
const config = {
headers:{
'Authorization': "Bearer *******", //Slack API のトークン
'Content-type': 'application/json'
}
}
await axios.post(url, params, config);
} catch (err) {
console.log(err);
}
};
チャンネルIDを取得する方法は下記の記事を参考にさせていただきました。
こちらの Lambda Function 単体実行で Slack にメッセージが投稿される状態が出来上がります。
⬛️ 実行タイミングをスケジューリングできる仕組み
これはもはや CloudWatch Events の機能そのものがカバーしているので
いつ実行するか?のスケジュールの設定と実行したい Lambda Function を指定すれば完了です。
自作したリマインダーでできるようになったこと
今回の自作リマインダーで解決したかったことは下記の3点でした。
- 投稿者が Slack bot になってしまう
- チャンネル宛のリマインドはリマインド設定したことがバレてしまう
- 登録したリマインドを編集することができない
そして、それぞれ
-
投稿者が Slack bot になってしまう
- Slack API::chat.postMessage の username と icon_emoji でカスタマイズ可能
-
チャンネル宛のリマインドはリマインド設定したことがバレてしまう
- 基本的に AWS 側に設定するだけだからバレない!
-
登録したリマインドを編集することができない
- 基本的に Lambda Function の実装を変更すれば後から編集可能
といったように解決されました。
また、Lambda Function で Slack API を呼び出すだけなので、
投稿内容や投稿先のチャンネル等々に条件分岐をつけたり、別の API で取得した内容を投稿するなど、できることはいっぱい増えた気がします。
(というかリマインダーに限定して考えなくてもいいですね笑)
自作したリマインダーでは(今のところ)できないこと
冒頭でも書いた通り、私は /remind
を仕事でもプライベートでも愛用しています。
理由は、ちょっとしたリマインド設定ならばほぼ間違いなく /remind
で事足りるからです。
(実際態々作らなくても・・・という場面はいっぱいあるので。)
そして、今回自作したリマインダーにはそれはそれで不便な点もあるのです。
- Slack の Workspace に Slack API のアプリを登録する権限を持っている必要がある
- AWS の環境が必要
-
リマインドのリスト機能、リマインドの削除機能がない
-
/remind list
でリマインド一覧を表示 => 不要なリマインドの削除機能は偉大
- この機能を自作しようと思うとそれなりに面倒ではあると思います
-
おわりに
今回の記事を書こうと思ったきっかけとしては
Slack の /remind
とても便利な割には意外に知られていないので、もっと知ってもらいたいという気持ちが大前提にありました。
その上で、"敢えて"同じようなことを実現してくれるものを自作してみたというお話を書かせていただきました。
Slack はアプリ連携が豊富な上、Slack API を提供してくれているのでハックが捗るエンジニアとしてはワクワクするチャットツールだと個人的に思っています。
この記事を読んでくださった皆様の Slack ライフがより楽しくなることを心から願っております!