帰宅予定確認Botうちの家族チャットツールはSlackを使っています。家族連絡用にもっといろいろ上手いことやろうと、今回初めてSlackApp作ってみました。解説やドキュメントはしっかりあるものの実際の流れがよくわからなくて苦戦しましたので解説を交えて書いてみたいと思います。#以前はいわゆる「帰るコール」的なことをIFTTの位置情報と連携させてやっていました。ところが物理的に職場が変わったり、帰り始めたタイミングではなく、遅くなる場合にあらかじめいつぐらいになりそうか、を知りたいとのことでSlackAppを作ることにしました。#ある時間が来たら自分宛に帰宅時間がいつぐらいになりそうか尋ねるなんらかの答えを返して妻さんに伝わるようにする、その際の入力は楽なほうがいいというのが最低要件です。要はリマインドして、文字入力ではない簡単な返信がしたい。問題はこれをどうやって実装するか、なんですが、SlackAppのドキュメントや開発方法を調べてみるといろんな情報がでてきます。#前述のとおり調べてみてなんだかよくわからなかったのはSlackAppとBotってどう違うの?定時に尋ねる発言をするって、どうやってトリガーするの?対話的にやりとりするのってどうやるの?そもそも開発と実装ってサーバー立ててやる必要があるの?あたりがぼんやりとしていて、なにをどうしていいかわかりませんでした。App開発ガイド』が書かれていてPDF版でも頒布されてたのでこれ幸いと読んでみました。App開発ガイドです。Appを取り巻くものは流れが早くすでに非推奨(deprecated)になっているものも多いです。公式ドキュメントを読めば何が推奨されてのかはわかりますが、全貌を捉えるのが難しく入門する立場の人にとっては辛いのが現状でしょう。Appを作っていきます。その中で、開発手法に触れ慣れていくのが目的です。Functionを使って開発していくチュートリアル的な本です。Slack側の設定もGCF側の設定も記載されていますし、サンプルコードもあり、SlackAppの機能を一通り網羅してるので、これからSlackAppを開発しよう、という僕にはまさに渡りに船でした。結論から言うとナナメ読みするより頭からいったん写経しながら全部やってみるのが結果的に近道な気がしました。あとになってふりかえってみると、僕は必要そうなところだけピックアップしてナナメ読みしてしまったことがかえって理解度が上がらず遠回りしてしまった感があります。ボリューム的にはライトなので最初から通しでやってみるのをオススメします。#そんなこんなで最初のうちはなかなか理解度が上がらず、どう作っていいかの道筋ができませんでした。#基本同一と考えて良さそう。旧来、自動化されたものはBotと呼ばれてSlackもそう言われていました。そのBotを組み込む枠組みとしてSlackAppがあって、BotはAppとして扱われるアカウントのことをさすんだろうと思います。Slackの開発ドキュメントではBotUserとして、App用のアカウントにメンションを飛ばすとトリガーされるイベントがあるので、これと前述の広義の意味のBotが混乱を招いていた原因でした。#これはSlack外の何かを起点として使います。chat.scheduleMessageというものがありますが、定期的にという用途には適しません。そもそもそれをスケジュールする何かをトリガーしなければいけないですね。Cronのようなものと併用して、定時実行される関数を開発します。APIのメッセージを叩いてSlack内にメッセージを送信するのが良さそうです。#対話的な機能はSlackにはないです。Componentsなどを利用してユーザーがボタンを押したり、入力した項目に対してApp側で受けとれるように設定、実装をします。その返しとしてまたボタンや入力欄などを含めた返信をする、を交互にやりとりすれば事実上対話形式になります。Componentsという言葉がでてくるのが混乱ポイントです。言えば前者はSlackのメッセージを表示するためのJSONをBlockやSectionをつかってボタンやフォームを表示させる方法。後者はそのボタンや入力を受けとるための設定と実装です。#単純にリクエストを受けたらSlackに対してリクエストするものがあれば十分です。App開発ガイド』にもあるようにFaaSでやるのがシンプルだと思います。何かのサービスがあって、SlackAppとしてSlackと連携させたい、という場合ならサーバーでSlack用のリクエストをやりとりする実装をするのが良さそうです。FunctionとFireStoreで開発、運用していますが今のところ問題なく動いています。基本的にはJSONのやりとりだけなのでSlack用のフレームワークを使う必要性も感じませんでした。Webhooksだけ少し特殊でSlack外からURLを叩いて指定したチャンネルにメッセージを飛ばせます。それ以外はいずれもSlack内の特定の行動をトリガーとして、指定したURLにリクエストを投げる仕組みです。いうことで、指定時間に実行するケースはまずCronかなにかで指定した関数をキック。Messageのスタイルで発言します。Componentsでその返答を購読して、指定の関数をキックします。その関数の中でまた次のSlackメッセージをリクエストする、というような感じです。このピンポン的にやりとりする流れを最初に想像できなかったので苦戦しました。ちなみに今回の帰宅確認BotではSlashCommandやEvenSubscriptionは使ってません。返答結果や今の状態に関してはFireStoreでデータを持ち、更新や確認をしています。再確認などは定期的にCronで走らせてその永続化したステータス状況を元に処理ををわけている感じです。Functionだと定時実行しかありませんが、AWSならCloudWatchから動的に関数をキックする時刻が決めれそうでした。#こんな感じのものができあがりました。#今回、最初全然イメージが掴めなかったり、どう開発してどう実装して、どう使うのかがわからなかったです。実際に理解してみたらシンプルでした。SlackApp自体がいろんなことができるように幅を持たせてあること、いろんな独自の言葉が出てくることが混乱した要因かもしれません。悪手だったのは、ドキュメントをちゃんと読もうとしなかった事、必要そうなことだけ読んでなんとかしようとしたことが原因ですね。高機能なイメージから、全体像と仕組み、何ができて何ができないのかをきちんと理解できてなかったためです。一足飛びにやろうとしてくことに何が必要かを探そうとしたのがかえって遠回りになってしまいました。前述したとおり、まずは一通り機能を試すためにも愚直にチュートリアル的なもの作ってしまったほうが早そうです。その上で何をつかえばどのような事ができるかを理解した後で、実現しようとしたことに何が必要かを考えるほうがスムースに行きそうです。余談ですが、うちの家族チャットがLINEではなくSlackになったのは僕の希望でした。LINEは複数のPCから同時ログインができないことが凄く不便だったためです。