Twitter と Mastodon をいい感じに同期するやつ

2018-09-08   #Twitter  #Mastodon  #Python 

TL; DR

Twitter と Mastodon をいい感じに同期(双方向に重複なく転送)する Python スクリプトを書きました.cron 等により定期実行することで,自由な頻度で同期することが可能です1.画像付きポストの転送や,いわゆる「自己 RT/BT」「スレッド機能」にも対応しています.

ちょっと長い前置き

かれこれ6年以上の付き合いになる Twitter ですが,近年の迷走っぷりに愛想が尽きそうです.

ここ数年来の Twitter 社の横暴については,このエントリを読まれているような皆さんはよくご存知だと思うので,敢えて嫌なことを蒸し返すことはしませんが,とにかく Twitter 社の姿勢は実に傲慢でユーザ(特に開発者)を顧みないものだと私も感じます.特に,先月(8/16)の Users Streams API の停止でショックを受けた人は多いようです2

私個人は Users Streams API の停止に関しては非公開リストを使う回避策がうまく効いたのでそれほど影響を受けないのですが,何より〈いつもっとひどい変更を通知してくるかわからない Twitter 社〉に依存して生きるのは精神衛生上つらいので,Mastodon を活用していつでも Twitter をやめられるよう準備を整えておくことにしました:

もちろん,直ちに Mastodon に一本化して Twitter は放置できるかと言うとそういうわけにもいかなくて,まだ重い腰を上げ切れず Twitter に残っている大切なフォロワーが大半です.また,Mastodon はまだまだ黎明期の段階で,周辺補助ツールも Twitter ほどには充実していません.そういうわけで,当面は Twitter と Mastodon を併用することになりそうです.

Twitter と Mastodon の連携というと,IFTTT を用いて Twitter → Mastodon または Mastodon → Twitter の方向に投稿を転送する手法が知られています.しかし,これらの方法は一方向の転送しか実現できない3上,ポーリングを用いているためタイミングによっては10分以上のラグが生じてしまいます.

また,別の解決手段として Twitter と Mastodon に同時投稿するクライアントも存在しますが,それだと双方に同じ内容を投稿したい場合,必ずそのクライアントで投稿をしないといけなくなります.私の場合,Twitter にしても Mastodon にしても PC とスマホでは別々のクライアントを用いていますし,それぞれの公式サイトから投稿をすることもあります.他にもソーシャルボタンなど,Twitter・Mastodon に投稿を行う方法には多様性があり,これを狭めるような解決方法は理想的ではありません.

しかしながら,なかなか私の理想に叶う同期手法は見つからなかったので,Twitter ↔ Mastodon 双方向の転送をラグなく実現するための Python スクリプトを自作しました:

以下,この自作 Twitter・Mastodon 同期スクリプト twoot.py について紹介していきます.

特徴

twoot.py は Twitter のツイートを Mastodon へ,Mastodon のトゥートを Twitter に相互に転送するためのスクリプトで,以下のような特徴があります:

  • 1度転送した投稿は転送しない
  • 画像付き投稿の転送に対応(リンクではなく,それぞれネイティブにアップロード)
  • いわゆる自己 RT,スレッド機能(自身のツイートへの返信)に対応
  • 短縮 URL を自動的に展開してから転送
  • 複数の Twitter/Mastodon アカウントのペアの同期も可能

これにより,双方のタイムラインをかなり高い再現度で同期することができます.

一方で,他アカウントのポストの RT/BT4 や他アカウント宛のリプライは転送されません(他者に迷惑をかけるおそれがあるためです).

使い方

必要なもの

以下のものは各自でご用意ください.

  • twoot.py を定期実行するための環境(VPS など)
    • Python3 処理系
    • cron などの定期実行ツール
  • Twitter の API key

なお,Twitter の API key は以前は簡単に入手できたのですが,最近は Twitter developer account の取得が審査制になっており,少々手間がかかります5.頑張って取得してください.

インストール

同梱の setup.py を利用すると一発です:

$ python3 setup.py install

セットアップ

twoot.py は cron 等で自動的に定期実行(バッチ処理)することを目的に開発されたスクリプトですが,最初の1回は対話的に各種の設定を行う必要があるので手動で起動してください.

$ python3 twoot.py

初回実行の場合,これによりセットアップモードが起動します.以降,お手数ですが10項目ほどの質問にお答えください.

Welcome to Twoot! Please answer a few questions.

はじめに,アプリケーションそのものの設定を行います.これは Mastodon 側のアプリケーション設定に用いられる情報で,特にこだわりがなければ何も入力せず Enter を押しても大丈夫です6

#1 First, decide about your application.
Name (optional; empty for "twoot.py"): 
Website (optional; empty for "https://github.com/wtsnjp/twoot.py"): 

次に,同期したい Mastodon アカウントに関する情報を入力します.具体的には

  1. インスタンス(URL)
  2. 登録メールアドレス
  3. パスワード

をこの順番で入力します.twoot.py はこれらの情報を元に取得したアクセストークンのみを保存するので,入力したメールアドレスとパスワードが保存されることはありません.

#2 Tell me about your Mastodon account.
Instance (e.g., https://mastodon.social): 
Login e-mail (never stored): 
Login password (never stored): 

続いて同期したい Twitter アカウントについての情報も入力します.こちらは基本的には Twitter developers から入手できるはずです.

#3 Tell me about your Twitter account.
cf. You can get keys and tokens from https://developer.twitter.com/
API key: 
API secret key: 
Access token: 
Access token secret: 

セットアップモードで行うべき操作は以上になります.

All configuration done. Thanks!

ここで入力した情報は $HOME/.twoot.py/default.json に保存されます.

設定内容を修正したい場合は $HOME/.twoot.py/default.json を直接編集するか,twoot.py を --setup (-s) オプション付きで実行して再度セットアップモードを立ち上げてください.

定期実行

上述のセットアップが無事完了したら,cron 等を用いてスクリプトを定期実行します.例えば,cron を用いて15秒ごとに同期を行いたい場合には次のようにします:

* * * * * for i in `seq 0 15 59`;do (sleep ${i}; python3 /path/to/twoot.py --log=/path/to/twoot.log) & done;

なお,Twitter のタイムライン取得に用いている API のレート制限は900回/15分なので,最大でも1秒に1回の実行までしかできません.あんまり頻繁に同期を実行してもリソースを無駄に消費するだけなので,10秒に1回以下の実行頻度にすることを推奨します.

また投稿数については別途レート制限があるのでご注意ください.いずれにしましても,この同期スクリプトを動かした状態で大量の投稿を行うと Twitter のみならず Mastodon インスタンスにも負荷をかけることになってしまうので,節度を持ったご利用をお願いいたします.

プロフィールを利用する

twoot.py の「プロフィール」という概念を用いると,複数ペアの Twitter・Mastodon アカウントを同期することが可能です.プロフィールを指定するには twoot.py の --profile (-p) オプションを使用します.

$ python3 twoot.py -p <name>

これにより,<name> プロフィールが使用されます7.プロフィールごとにセットアップモードを実行し,アカウントの登録を行ってください.

少しだけ裏話

Twitter, Mastodon について投稿やタイムラインの取得を行うだけならば簡単です.Python には既に両者の API をラップするライブラリが用意されており,twoot.py でもこれを利用しています:

私も,最初は個人用の小さなスクリプトを作って運用するつもりでいました.しかし,いざ書き始めると細かいことに凝り始めてしまい,コードが900行近いボリュームになってしまいました.デバッグの都合上,ロギング制御 (-v, -q) や dry run (-n) を行うオプションも実装して個人用のスクリプトとしては異常にリッチな作りとなったため,もったいないので公開することにしました.

Twitter ↔ Mastodon の相互転送をナイーブに行うと,Mastodon の投稿を Twitter に自身で転送したものが「新しい投稿」とみなされて再び Mastodon に転送され,二重投稿になってしまいます.そこで twoot.py では転送した投稿のペア(ツイート,トゥート)の ID 値を保存して8,すでに転送された投稿が再び転送されることのないように制御しています.また,この ID のペアを用いていわゆる「自己 RT/BT」や「スレッド」の同期も実現されています.

あとがき

公開こそしたものの,このスクリプトは基本的に私個人が利用することを目的として開発を行っているものなので,機能リクエストには必ずしも応えられない可能性があります(私も欲しい機能なら取り入れるかもしれませんが).その場合は各自フォークして改変していただければと思います.

それでもよろしければ,twoot.py を用いて快適な Twitter・Mastodon 同期ライフを送りつつ,来たるべき Twitter グッバイの日に備えませんか?


  1. API 制限の都合上,10秒に1回以下の頻度を推奨. [return]
  2. もしこのあたりの事情について詳しくないようでしたら,ばんくしさんがかつての Twitter の隆盛にも言及しつつ,歯切れのよい文章で経緯をまとめていらっしゃるので一読をおすすめします:https://vaaaaaanquish.hatenadiary.jp/entry/2018/08/14/115152[return]
  3. 試していませんが,もし Twitter → Mastodon と Mastodon → Twitter の転送を両方ナイーブに設定してしまうと,おそらく Mastodon 側には常に同じ内容が2重に投稿されることになるでしょう(Twitter は同一テキストの連続投稿を許可していないので大丈夫). [return]
  4. 引用 RT/BT はリンク付き投稿扱いで転送されます. [return]
  5. 私が twoot.py の運用のために取得した API key はもちろんあるのですが,OSS とする都合上 secret key を秘匿するのが困難な上,10/22以降はアプリ単位で3時間に300ツイートまでのレート制限が導入されるらしく,これを回避するためにも API key の提供は行いません. [return]
  6. Twitter 側のアプリケーション設定(アプリ名,URL など)は Twitter developers のページから行ってください. [return]
  7. プロフィールを指定しない場合 default プロフィールが自動的に選択されます. [return]
  8. 保存される投稿ペアはデフォルトでは直近2,000件です.この数を変更したい場合は設定ファイル <profile>.jsonmax_twoots を書き換えてください. [return]