あなたとわたしと Twitter。どうも、かわしんです。
今週の頭の日曜月曜火曜の 3 日間かけて Twilter というコマンド(?)サービス(?)を作ったので、その紹介をしたいと思います。
Github リポジトリはこちらです。star をつけていただけると喜びます。
また、良かったらご自身で運用してみてください。
なぜ Twilter を作ったのか
僕のツイッターライフ
僕は Twitter を情報収集と娯楽のために利用していますが、僕の性格として全ての情報を把握しておきたいため、フォローしている人の全てのツイートを読んでいます。
残念ながら Twitter の公式アプリは、勝手にツイートの順番を入れ替えたり、勝手にオススメのツイートだけをフィルタリングして上に表示したり、時間が経ってアプリを開くと勝手にスクロール位置を最新のツイートに変えてしまったりします。
余計なお世話にも程があります。僕はタイムラインの全てのツイートを確認したいのに勝手にスクロール位置やツイートの順番を変えられると、どこまで確認していたかがわからなくなってしまいます。
そこで、僕は Tweetbot という iOS アプリを利用してタイムラインの購読をしています。
このアプリは有料アプリですが、タイムラインの順番やスクロール位置を勝手に変えることはしません。また、複数の iOS デバイス間でスクロール位置を同期してくれるので、家で iPad で読んで通学途中で iPhone で読むみたいな場合でもシームレスにタイムラインの確認ができます。さらに、キャッシュなどの最適化を行なっているため通信状況が悪くてもツイートの確認ができるのもいいところです。
僕みたいな異常な完璧主義の方にオススメのアプリです。
さて、全てのツイートの監視をしている僕ですが時間は有限であるため、ツイートが増えるスピードがツイートを読むスピードを超えてしまうと未読のツイートが無限に増えてしまいます。
そのため、ツイート数とその人が垂れ流す情報の有用さのバランスを元にフォローしている人を定期的に整理して、ツイートの流速調整を行っていました。
今は 100 フォロー以下を目安にやっていますが、割ときつくて、70 ~ 80 フォローくらいがちょうどいい流速なのではないかと思っています。
迎える限界
そんなツイッターライフを送っていた僕ですが、ある日僕のルールの限界を感じさせるユーザーに出会います。
重曹 さんです。この方の代表作はこれです。死ぬほど面白い。複数のツイートに分割されているのでリプライを辿っていってください。
ゆるキャラグランプリ pic.twitter.com/DGR7NLsc1u
— 重曹 (@YTmoyashifes) April 19, 2019
「なかのやま」さん「NZK」さん「重曹」さんのセンスの塊の3名で構成される LINE グループのチャット内容を時々ツイートされるのですが、これが死ぬほど面白いのでフォローして LINE チャット画面を楽しみにしていました。
しかし、重曹さんの毎日のツイート数はかなり多く、僕のタイムラインが爆発してしまいました。LINE グループのツイートの数に比べてその他のツイートが多すぎるため僕のルールではフォローを外すしかないのですが、どうしてもこのセンスあふれる LINE グループの画像は見たいという板挟みの状態になってしまいました。
その時の僕の心の叫びがこれです。
あと、ツイートをフィルタリングしてくれるのも欲しいな。
— かわしん@ソフトウェアエンジニア (@kawasin73) May 30, 2019
この人の描く漫画は全部見たいけど普段のつぶやきは興味ないみたいな。
特定のユーザーのリンク付きツイートだけとか、画像ツイートだけとかでフィルタリングしたい。
ということで、Twilter を作ることにしました。
Twilter とは何か
Twilter は Twi t ter を F ilter してくれるサービスです。安直な名前なのですでに Twilter という名前のアプリは色々あるようです。しかし、それらはブラウザのエクステンションでツイッターのウェブサイトで表示を消す程度のことしかしてくれないようなので、自分で Twilter を作ることにしました。
機能としては以下の通りです。
というものです。その連携している Twitter アカウントだけを自分の Twitter アカウントからフォローすれば、フィルタリングされたツイートを自分のアカウントのタイムラインで確認することができます。
こんな形で使います。この設定では、重曹さんのリツイートでないオリジナルの画像ツイートのみをフィルタリングします。
$ export TWITTER_CONSUMER_KEY=xxxxxxxxxxxxxxxxxx $ export TWITTER_CONSUMER_SECRET=xxxxxxxxxxxxxxxxxx $ export TWITTER_ACCESS_TOKEN=xxxxxxxxxxxxxxxxxx $ export TWITTER_ACCESS_TOKEN_SECRET=xxxxxxxxxxxxxxxxxx $ export REDIS_URL=redis://user:password@host_name:6379 $ twilter -target "YTmoyashifes:and(photo,not(rt))"
このコマンド自体はフォアグラウンドで動きますので、デーモン化は docker
や systemd
などで行なってください。
docker イメージは https://hub.docker.com/r/kawasin73/twilter で公開しています。
注意事項
まず注意事項を記載しておきますが、リツイートを行うアカウントは 鍵アカウント(Private Account)にすることを強く推奨します。
相手ユーザーに多くのリツイートによる通知が表示されて迷惑になってしまうことを防ぐためです。鍵アカウントであれば相手ユーザーはリツイートされたことがわかりません。
また、監視できる対象ユーザーはツイートをリツイート可能なパブリックアカウントのみです。鍵アカウントは対象外ですので注意してください。
オプション一覧
オプションはこんな感じになっています。
$ twilter -h Usage of /usr/local/bin/twilter: -fallback int start filtering tweets fallback minutes ago if no checkpoint (minutes) (default 10) -interval int interval between monitoring (minutes) (default 10) -target value list of targets. target format = "<screen_name>:<filter>[/<filter>]" filter format = "<filter_name>[(<attribute>[,<attribute>])]" -timeout int timeout for each monitoring + retweet loop (minutes) (default 5)
本当は設定ファイルから読み込めたら便利なんですが、Docker で運用する場合に面倒になるのと、ファイルフォーマットの策定など諸々めんどくさかったので対応していません。
フィルターについて
フィルタ設定は、target
オプションによって設定します。複数の target
を設定することもできます。
target
は <twitter_id>:<filter>[/<filter>[/...]]
のフォーマットで指定します。フィルターは /
によって区切ることで複数設定できます。(本当は |
で区切りたかったけど、シェルのパイプと認識されてしまうため /
にしました)
これらのフィルターのうち1つでもマッチするものがあればリツイートされます。
フィルターは以下の種類があります。
rt
: リツイートされているツイートqt
: 引用リツイートされているツイートphoto
: 画像付きツイートvideo
: 動画付きツイートnot(<filter>)
: 引数のフィルターにマッチしないツイートand(<filter>[,<filter>[,...]])
: 引数のフィルターの全てにマッチするツイートor(<filter>[,<filter>[,...]])
: 引数のフィルターのどれか1つでもマッチするツイート
まだ実装していませんが、特定のキーワードやハッシュタグを含むツイートのフィルターも作る予定です。
ここで特に特徴的なのは、最後の not
、 and
、 or
フィルターの 3 つだと思っています。
この3つのフィルターを組み合わせることで比較的柔軟に色々な種類のフィルターを定義することができます。また、提供するフィルターの種類もプリミティブなものだけで済むので実装コストも抑えられるのもいいところです。
Redis との連携
Twilter はデフォルトでは起動時刻から fallback
に設定された分だけ前のツイートからフィルタリングを始めます。これは再起動した場合に停止していた間のツイートを取りこぼさないためです。
Twilter はオプション機能として、Redis を用意して環境変数の REDIS_URL
に接続情報を登録するとツイートの確認状況を Redis に保存します。再起動した場合は Redis に保存されているツイートより後のツイートからフィルタリングを始めます。これにより無駄にフィルタリングをせずに済みます。
Redis との連携機能はオプション機能なので、 Redis がなくても Twilter を利用することができます。
Rate Limit
Twitter にはリクエスト数の Rate Limit があり一定時間にできる API リクエストの数が決まっています。
Twilter ではリクエスト数制限に引っかかった場合でも自動で適切な時間待って再送する 再送処理を実装 していますが、これは一時的にバーストした場合のためのものなのであらかじめ適切にリクエスト数の見積もりと設定をする必要があります。
ユーザーごとのツイート一覧を取得する API のリクエスト数制限は 900 requests / 15 minutes
の制限と、 2019 年 6 月 19 日からは 100,000 requests / day
の制限があります。
GET statuses/user_timeline — Twitter Developers
Twilter では Twitter アカウントを監視する間隔を interval
オプションで指定できます。デフォルトは 10 分になっています。単位は minute
です。
ユーザーのツイート一覧取得は、1 回のリクエストあたり最大 200 ツイートを取得できるので、各自それに合わせて interval
の値を設定してください。
また、リツイート投稿 API のリクエスト数制限は 300 requests / 3 hours
です。リツイート投稿が多くならないようにユーザーの選定とフィルターの中身を設定してください。
POST statuses/retweet/:id — Twitter Developers
アクセストークンについて
Twitter のアクセストークンを取得するには開発者アカウントが必要です。
Twitter は気づいたら開発者アカウントを取得するために 200 字の作文を複数箇所行わなければならないようになってしまっていて、ハードルが上がっていて悲しいです。が、背に腹は変えられないので頑張って英語作文しましょう。
多分、インストール手順の中で Twitter の開発者アカウントを作成するのが一番難しいステップ です。本当に悲しい。
取得したアクセストークンは、TWITTER_CONSUMER_KEY
TWITTER_CONSUMER_SECRET
TWITTER_ACCESS_TOKEN
TWITTER_ACCESS_TOKEN_SECRET
の環境変数に設定して利用します。
TWITTER_CONSUMER_KEY
と TWITTER_CONSUMER_SECRET
には開発者アカウントの Consumer Key と Secret を登録してください。
TWITTER_ACCESS_TOKEN
と TWITTER_ACCESS_TOKEN_SECRET
には、開発者アカウントから発行されたリツイートを行う鍵アカウントの Access Token と Secret を登録してください。
多くの場合は開発者アカウントの Twitter アカウントとリツイートを行う Twitter アカウントは 別のもの を使うと思います。その場合はダッシュボードから TWITTER_ACCESS_TOKEN
と TWITTER_ACCESS_TOKEN_SECRET
を生成することができません。
twitter-auth というコマンドラインツールがアクセストークンの発行を簡単に行なってくれるため、利用することを推奨します。
最後に
と、まぁ、こんな感じです。
Twilter は自宅の kubernetes on Mac mini サーバーで運用しています。じわざわリツイートがタイムラインに流れてくるのを「ちゃんと動いているぞ」と思いながら眺めています。
情報をうまくフィルタリングして時間を有効活用できるようになりました。
Twilter では定期的にツイッターを監視するタスクスケジューリングの部分に一年前に 管理上手のうさちゃん を作った時に作ったタスクスケジューラ htask を使っています。
うまく汎用的なライブラリを再利用できて、ニヤニヤしてます。
では、良い Twitter ライフを !