七 月
22
土曜日

TwitterのリストタイムラインをSlackへ連携する

TwitterのリストタイムラインをSlackの任意のチャネルへ流す方法を模索してみる。

zapierSlack Twitter integrationという選択肢もあったが、 今後Slackを使っていく上でに自由になるボットが一台居た方が今後何かと便利だろうという安易な理由から 自前で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上にツイートの内容を表示するためにこの機能を利用する。

https://my.slack.com/apps

から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 KeyConsumer 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ベースで管理したかったがのだがそれまた別の機会に。