inuinu blog(開発用)

BOT @wagagun の開発ノウハウや、IT向け?の雑記ブログです。

MastodonのAPIを使ってトゥートする

この記事では、MastodonAPIを使ってRubyでトゥート(Post)することを学びます。

Twitter社のAPI有料化するする詐欺(?)から、ずいぶんと時間が経過しましたが、具体的にいつ…というアナウンスは、未だになさそうです。

ただ、当初、POSTに制限をかける(無料は50ツイート/日まで)とアナウンスされたため、私が運営しているクローリングBOTはその約3倍のツイートをつぶやいている都合上、早めにMastodonへの引っ越しを考えることにしました。

準備からテストプログラムの実行まで

まずは、Mastodonアカウントを取得しましょう。
私はmstdn.jpに作成しました。
今なら、ご希望通りのアカウント名を取得できるチャンスですよ!

APIおなじみアクセストークンの設定等は、以下を参考にしました。
RubyにはMastodon用のgemがあるので助かります。

わずか数行のコードで利用できちゃう!Mastodon APIを活用してみた。 | 株式会社LIG(リグ)|DX支援・システム開発・Web制作

ほぼ、そのままでも行けますが、私のBOTシステムでは環境変数で管理はしていないので、get_access_token.rb環境変数(ENV['HOGE']の部分)は、MASTODON_HOSTと同様に仮に定数として実行しました。

すべて定数で行いたい場合、MASTODON_HOSTMASTODON_APP_NAMEMASTODON_USER_IDMASTODON_USER_PASSWORDをセットし、get_access_token.rbを実行。取得したclient_id、client_secret、access_tokenをtouch_mastodon.rbの定数にセットしtouch_mastodon.rbを実行…といった流れでしょうか(プログラムでは最低限access_tokenがあれば良いようですが…)。
アンチ環境変数派は、定数の箇所を外出ししてrequireするなり、iniファイルにするなりすれば良いと思います。

無事に、トゥートまでできればいいですね。

画像もアップロードできないか?

BOT作成者によっては、画像もTwitterのようにアップロードできないか?と考えているでしょうね。

はい、出来ます。

●toot_mastodon_with_image.rb

require 'bundler/setup'
require 'mastodon'
require 'oauth2'

MASTODON_HOST = 'https://mstdn.jp'
MASTODON_ACCESS_TOKEN= 'あなたのアクセストークン'

image_file = ["画像1ファイル名", "画像2ファイル名"]

# 接続
mstdn = Mastodon::REST::Client.new(base_url: MASTODON_HOST, bearer_token: MASTODON_ACCESS_TOKEN)

# イメージアップロード
media_ids = []
image_file[0..3].each do |fil|
  image_obj = open(fil)
  media_ids.push(mstdn.upload_media(image_obj).id)
end

# トゥート
mstdn.create_status('画像テスト', {media_ids: media_ids})

といった形でしょうか。
image_file[0..3]としたのは、Twitterの制限に併せて、無意識に実装したのですが…

トゥートの投稿 - Mastodon documentation

画像(PNG、JPG、GIF)は8MBまでです。画像は(1280x1280画像で表示できる)1.6メガピクセルに縮小されます。そして4つまで添付できます。

マストドンでも4枚までの制限になっているようですね。

参考までに、テスト結果。
mstdn.jp
はてなブログのハウツーページもそうなんですが、例示がハロメンなのは、なんなんでしょうね?笑

参考までにもとのブログです。
ameblo.jp

ただし…

Mastodon自体、運営は有志が行っているとのことで、画像でサーバー容量を消費しないように、私自身は画像のアップロードはやめています。

運用してみたところ…

現在、以下のBOTを運用中です。
(Macintoshなので、launchdにてバックグラウンド実行。)

mstdn.jp mstdn.jp

普段、特に怒られることは無いのですが、ごくたまに、以下のエラーがでます。

HTTP::TimeoutError
Read timed out after 5 seconds

gem内のRubyソースを見てもよくわかりませんでしたタイムアウト時間を制御するパラメータはなさそうです。
出現パターンとしては、API有料化が具体化して大騒ぎした翌日あたりに頻発したので、みなさん、慌ててAPIの実行テストでもしたのでしょうか?笑
現在もたまに、出現しますね。

この場合は、少しおいて再実行する等のロジックを組む事になりそうですね。