TwitterのリストタイムラインをSlackの任意のチャネルへ流す方法を模索してみる。
zapierのSlack Twitter integrationという選択肢もあったが、 今後Slackを使っていく上でに自由になるボットが一台居た方が今後何かと便利だろうという安易な理由から 自前でSlackボットを立てる事に決定。リストタイムラインの連携処理をやらせることにした。
- 2018/12/02 『DuctでSlack Botを作成する』 にてSlackボットを再構築。
 
ボット作成
chabonze(茶坊主)を作成。
Clojureで書いたJSR-356ベースのWebSocketクライアントアプリケーション。
Real Time Messaging APIでSlackと常時接続、以下のようなメンションかつスラッシュから始まるメッセージをコマンドとして認識する。
@<ボット名> /<コマンド> <コマンド引数>
Twitterのリストタイムライン連携を行うため、/twitter コマンドと以下のサブコマンド群を実装した。
| サブコマンド | 用途 | 
|---|---|
| auth | PINベースのOAuth処理 | 
| lists | Twitter上のリスト一覧を表示 | 
| watch | リストの購読処理 | 
| help | ヘルプの表示 | 
Slackの設定
chabonzeを動かすためにSlack側で必要な設定を行う。
Botユーザの登録
chabonzeをSlack Botユーザとして登録する。
https://my.slack.com/services/new/bot
- Username
 - ボット名を指定する。
例:chabo 
Add Bot Integeration で登録。
API Tokenはchabonzeの起動パラメータとして必要となるのでメモしておく。
Save Integration で保存。
Twitter Integration
Slack標準のTwitter Integrationにはメッセージ内にツイートのURLがあると内容を展開して表示する機能がある。
今回Slack上にツイートの内容を表示するためにこの機能を利用する。
からtwitterで検索し、Install
Add Twitter Integration でTwitter側の認可画面が表示されるので 連携アプリを認証
Integration Settings画面が表示されるがツイートの展開機能以外の機能は利用しないため何も設定せずに完了。
Twitterの設定
chabonzeを動かすためにTwitter側で必要な設定を行う。
アプリケーション登録
chabonzeからTwitterのAPIを利用するためにアプリケーション登録を行う。
https://apps.twitter.com/app/new
- Name
 - アプリケーション名
例:chabonze - Description
 - アプリケーション概要
例:A slack bot that watches twiter lists - Website
 - WEBサイトURL
例:https://blog.nijohando.jp - Callback URL
 - なし
 
Consumer Key と Consumer Secret はchabonzeの起動パラメータとして必要となるのでメモしておく。
GCEインスタンスの作成
chabonze実行用のインスタンスを作成する。
Google Compute Engineではバージニア州北部を除く米国リージョンのf1-microインスタンスは無料枠が設定されており1インスタンスまでなら期限なしで無料で利用できるため今回はこれを利用する。
(ちなみにAWSのEC2無料枠はアカウント作成から12ヶ月間に限定される)
プロジェクト作成
GCPコンソールを開き、画面上部のプロジェクト選択から新規プロジェクトを作成。
- プロジェクト名
 - chabonze
 
作成 でプロジェクトを作成する。
インスタンス作成
chabonzeプロジェクトでCompute Engineインスタンスを作成する。
- 名前
 bot- ゾーン
 us-west1-b- マシンタイプ
 micro- ブートディスク
 10G (Debian GNU/Linux 9)- IDとAPIへのアクセス
 デフォルトのアクセス権限を許可- ファイアウォール
 - HTTP/HTTPSともにトラフィックを許可しない
 
作成 でインスタンスを作成する。
Cloud SDK のインストール
作成したGCEインスタンスにSSH/SCPするためにCloud SDKを自環境へインストールしておく。
curl https://sdk.cloud.google.com | bash
対話形式でインストールを進めていくが最後にパスの更新とコマンド補完について聞かれる。
Modify profile to update your $PATH and enable shell command
completion?
Do you want to continue (Y/n)?  Y
自環境ではfish shellを利用していたので一瞬たじろいでしまったがfishにも対応していた。 ($XDG_CONFIG_HOME/fish/config.fishにスクリプトが追加される)
最後に初期化を実施。
gcloud init
実行環境準備
先ほど作成したGCEインスタンスbotへSSHで接続し、chabonzeの実行環境を整える。
gcloud compute ssh bot
java実行環境をインストール
sudo apt-get install openjdk-8-jre
実行ユーザを作成
sudo adduser --system --home /opt/chabonze chabonze
envファイル作成
EnvironmentFileを作成。
sudo -u chabonze touch /opt/chabonze/env
sudo -u chabonze chmod 600 /opt/chabonze/env
/opt/chabonze/envの内容は以下。
CHABONZE_SLACK_API_TOKEN=<Slack側で発行したAPIトークン>
CHABONZE_STORE_PATH="/opt/chabonze/store.edn"
CHABONZE_TWITTER_CONSUMER_KEY=<Twitterコンシューマキー>
CHABONZE_TWITTER_CONSUMER_SECRET=<Twitterコンシューマシークレット>
ちなみにCHABONZE_STROE_PATHが指すednファイルはchabonzeの記憶領域でTwitterのトークンや購読中のリストの情報等が保存されている。
systemdユニットファイルを追加
chabonze用のユニット定義を追加
sudo touch /etc/systemd/system/chabonze.service
sudo chmod 664 /etc/systemd/system/chabonze.service
/etc/systemd/system/chabonze.service
[Unit]
Description=Chabonze
After=network-online.target
[Service]
WorkingDirectory=/opt/chabonze
EnvironmentFile=/opt/chabonze/env
ExecStart=/usr/bin/java -jar /opt/chabonze/chabonze-standalone.jar
User=chabonze
[Install]
WantedBy=network-online.target
有効化して確認。
sudo systemctl enable chabonze.service
sudo systemctl list-unit-files -t service
デプロイ
自環境でchabonzeのexecutable jarファイルを作成、botインスタスにscpする。
git clone https://github.com/nijohando/chabonze.git
cd chabonze
lein uberjar
gcloud compute scp target/chabonze-standalone.jar bot:~/
botインスタンスに接続し chabonze-standalone.jar を /opt/chabonze直下に配置。
gcloud compute ssh bot
sudo -u chabonze cp ~/chabonze-standalone.jar /opt/chabonze/
chabonze起動。
sudo systemctl start chabonze.service
ログは/opt/chabonze/chabonze.logへ出力される。
起動成功でSlack上chabonzeがオンライン状態になる。
chabonzeを操作する
chabonzeの操作は一般的なCLIコマンドと同じ要領で行う。
chabonzeを招待済みのチャネルまたはDMからコマンドを実行できる。
/twitterコマンドのサブコマンドhelpで利用可能なサブコマンド一覧を確認。
@chabo /twitter help
Usage: /twitter <command> [<args>]
COMMAND   DESCRIPTION
-------------------------------------------------
auth      Connect to a twitter account
lists     Show lists
watch     List, create, or delete watcher task
help      Show help
TwitterアカウントからChabonzeを認可する
初期状態のchabonzeはTwitterアカウントとの紐付けがされていないため、
authサブコマンドで任意のTwitterアカウントとの紐付け(認可)を行う必要がある。
authサブコマンドの使い方は-hオプションで確認できる。
@chabo /twitter auth -h
Usage: /twitter auth -r
   or: /twitter auth -p <PINCODE>
Options:
  -r, --request          request for issuing new pincode
  -p, --pincode PINCODE  authorize with pincode
  -h, --help
authサブコマンドの-rオプションでpincodeベースのOAuth処理を開始する。
@chabo /twitter auth -r
以下のような認可確認URLを返してくるのでブラウザでアクセスしchabonzeを認可しpincodeを取得する。
https://api.twitter.com/oauth/authorize?oauth_token=xxxxxxxxx
authサブコマンド-pオプションでpincodeをchabonzeに伝える。
@chabo /twitter auth -p 9999999
認可が完了すると以下のメッセージが返される。
OK. connected to twitter as <Twitterアカウント名>
Twitterリストを確認
listsサブコマンドでTwitterリスト一覧を確認。
@chabo /twitter lists
SLUG        MODE      MEMBERS   NAME
------------------------------------------
clojure     private   21        clojure
i           private   3         i
study       private   10        study
work        private   33        work
tech        private   34        tech
engineers   private   42        engineers
Twitterリストタイムラインの連携
watchサブコマンドで指定したTwitterリストのタイムラインを現在のチャネルに連携する。
watchサブコマンドの使い方は-hオプションで確認できる。
Usage: /twitter watch -l
   or: /twitter watch -a <SLUG> -i <INTERVAL>
   or: /twitter watch -d <TASK-ID>
Options:
  -l, --list                  show watch tasks
  -a, --add SLUG              add watch task
  -i, --interval MINUTES  10  watch interval
  -d, --delete TASK-ID        delete watch task
  -h, --help
連携したいチャネルにchabonzeを招待し、そのチャネル内で以下のようにwatchサブコマンド-aオプションでリストのWatchタスクを追加する。
@chabo /twitter watch -a tech -i 15
指定の間隔でリストのタイムラインを取得し新着ツイートをチャネルに表示するようになる。
最後に
以上でTwitterのリストタイムラインのSlack連携という当初要件は実現できた。
本当はコンテナ化までしてGKEベースで管理したかったがのだがそれまた別の機会に。