概要
GoogleAppsScript(以降GAS)とTwitterAPIでTwitter上で特定のツイートをしたらタイマーをセットし、指定時間にリプライを返すアプリを作ってみた。全部無料。
リポジトリも一応作った。ソースコードとGASのプロパティ情報とかも全部明記してます。
自分用に作ったので他の人に対してはタイマーは機能しないはず。動かしたい場合は自身でTwitterAPIを使えるようにしてシステム構築してください
なぜ作ったか
サーバレスなWebアプリを作ってみたかった。
定期実行を利用したアプリを作る場合は、cronを動かすために何らかのサーバを用意しないといけないけれど、それをサーバレスに実現するための選択肢にGASがあったので、今回それを試してみた。
GASには定期実行トリガーというものがあって、毎分とか、何時から何時みたいな特定の時間指定で自動でスクリプトを実行することができる。
今回のアプリはその定期実行トリガーを使用してタイマーを作った。
使用例
こんな感じ。自分のメンションリストを取得するのと、自分の名前しか許可してないはずなので、他のユーザが自分宛てに「@jiro_saburomaru timer 3m ラーメン」とかやっても多分動かないはず。動いてしまったら僕の実装バグです。
あとユーザ名に時刻が設定されているのもGASで作った全く別のアプリだけれど、それについては今回は触れない。
使用したサービス
- GoogleAppsScript (処理ロジック,定期実行トリガー)
- GoogleSpreadsheet (DB)
- TwitterAPI (画面表示)
処理フロー
処理イメージは下記のシーケンス図の通り。実装前に処理フローを整理しておきたかったのでPlantUMLで書いた。
処理の肝は3つの定期実行トリガー。
- (毎分)タイマーツイートで返信する時間をDB(GoogleSpreadsheet)に登録する
- (毎分)時間になった旨をツイートする
- (毎日午前2時)DBのクリーンアップ
タイマーツイートで返信する時間をDBに登録する
毎分自身のメンションリストを取得して、タイマーセット関連のツイートの有無をチェックする。
存在したらDBに「何時に時間になった旨をツイートするのか」の情報を登録する。
注意点は、GASのトリガーは最短でも毎分起動までしかできないので、秒指定のタイマーはセットできないこと。
時間になった旨をツイートする
毎分DBから論理削除フラグのたっていないレコードを取得して、タイマー系のレコードが存在するかをチェックする。
存在した場合に、GASの現在時刻(JST)がタイマー時刻より超過しているかをチェックする。
超過していた場合はリプライして、レコードに論理削除のフラグを立てる。
DBのクリーンアップ
DBから取ってこれるレコード数には上限があるので、定期的にDBに存在するリプライ済みのレコードを削除する必要がある。
毎日深夜2時に論理削除フラグのたっているレコードをDBから物理削除してしまう。
上記の画像のデータはdone_flagがtrueなので、明日の深夜2時には物理削除される。
所感
すべて無料かつサーバレスでDBとも連携してコンパクトなWebアプリが作れることがわかった。
GoogleSpreadsheetはDBとして非常に有用で、GASとすごく連携しやすい。
無料でcronとDBまで使えてしまうのでエンジニアの遊び場としてはすごく良い環境が整ってると感じた。
ただしGASはJavascriptでしかもES6をサポートしてないので比較的新しいJS記法を使えない。
この問題を解決するアプローチはググったら色々出てくるけれど、僕の場合は諦めて古い書き方を我慢する方針にしました。
まぁ、ブラウザのIEなどをサポートすることを徹底してる企業なのでES6をサポートするわけないか...
Google Javascriptコーディング規約和訳
このアプリの問題点
毎分TwitterAPIを2回叩くので1時間のTwitterAPIの使用回数上限をかなり圧迫する。
(数年前の記憶だけれど1時間あたり180くらいが上限だったかな...)
なので、一つのアカウントで他にもTwitterAPIを使うアプリが存在するとそっちに影響がでる可能性がある。