Mastodon API gemを使って投稿する

  • 39
    いいね
  • 0
    コメント

Mastodon API Ruby Gemを使ってMastodonのインスタンスに投稿するCLIのサンプルです。

コード

mastodon-cli-sample.rb
#!/usr/bin/env ruby

require 'bundler/setup'
Bundler.require(:default)

require 'mastodon'
require 'highline/import'
require 'oauth2'
require 'dotenv'
require 'pp'

DEFAULT_APP_NAME = "mastodon-cli-sample"
DEFAULT_MASTODON_URL = 'https://mstdn.jp'
FULL_ACCESS_SCOPES = "read write follow"

Dotenv.load

if !ENV["MASTODON_URL"]
  ENV["MASTODON_URL"] = ask("Instance URL: "){|q| q.default = DEFAULT_MASTODON_URL}
  File.open(".env", "a+") do |f|
    f.write "MASTODON_URL = '#{ENV["MASTODON_URL"]}'\n"
  end
end

scopes = ENV["MASTODON_SCOPES"] || FULL_ACCESS_SCOPES
app_name = ENV["MASTODON_APP_NAME"] || DEFAULT_APP_NAME

if !ENV["MASTODON_CLIENT_ID"] || !ENV["MASTODON_CLIENT_SECRET"]
  client = Mastodon::REST::Client.new(base_url: ENV["MASTODON_URL"])
  app = client.create_app(app_name, "urn:ietf:wg:oauth:2.0:oob", scopes)
  ENV["MASTODON_CLIENT_ID"] = app.client_id
  ENV["MASTODON_CLIENT_SECRET"] = app.client_secret
  File.open(".env", "a+") do |f|
    f.write "MASTODON_CLIENT_ID = '#{ENV["MASTODON_CLIENT_ID"]}'\n"
    f.write "MASTODON_CLIENT_SECRET = '#{ENV["MASTODON_CLIENT_SECRET"]}'\n"
  end
end

if !ENV["MASTODON_ACCESS_TOKEN"]
  client = OAuth2::Client.new(ENV["MASTODON_CLIENT_ID"],
                              ENV["MASTODON_CLIENT_SECRET"],
                              site: ENV["MASTODON_URL"])
  login_id = ask("Your Account: ")
  password = ask("Your Password: "){|q| q.echo = "*"}
  token = client.password.get_token(login_id, password, scope: scopes)
  ENV["MASTODON_ACCESS_TOKEN"] = token.token
  File.open(".env", "a+") do |f|
    f.write "MASTODON_ACCESS_TOKEN = '#{ENV["MASTODON_ACCESS_TOKEN"]}'\n"
  end
end

client = Mastodon::REST::Client.new(base_url: ENV["MASTODON_URL"],
                                    bearer_token: ENV["MASTODON_ACCESS_TOKEN"])

## 投稿する
message = ARGV[0] || ask("Your Message: ")
response = client.create_status(message)

## とりあえず結果を出力してみる
pp response

Gemfileは以下。

Gemfile
source "https://rubygems.org"

gem "mastodon-api"
gem "highline"
gem "oauth2"
gem "dotenv"

使い方

Dotenvを使っていて、カレントディレクトリの.envファイルに書かれている情報を環境変数として参照します。また、環境変数MASTODON_URL,MASTODON_CLIENT_ID,MASTODON_CLIENT_SECRET,MASTODON_ACCESS_TOKENが設定されていない場合、.envファイルに書き込みます。

.envファイルもなく、環境変数も設定されていない場合に実行すると、以下のようにMastodonインスタンスのURL、ID、パスワード、メッセージを聞いてきて、結果を出力します。

$ ./mastodon-cli-sample.rb 
Instance URL: |https://mstdn.jp| 
Your Account: your-email-address@example.jp
Your Password: *********************
Your Message: こんにちは
#<Mastodon::Status:0x007fef32678be8
 @attributes=
  {"id"=>11111111,
   "created_at"=>"2017-04-16T00:00:00.000Z",
   "in_reply_to_id"=>nil,
(略)
   "favourited"=>false,
   "reblogged"=>false}>

2回めに実行すると、上記の.envに保存された値を利用して、

$ ./mastodon-cli-sample.rb
Your Message: こんばんは
#<Mastodon::Status:0x007fd97abdcad0
 @attributes=
  {"id"=>2222222,
(略)
   "reblogged"=>false}>

書き込むメッセージは引数でも渡せます。

$ ./mastodon-cli-sample.rb おはようございます
#<Mastodon::Status:0x007f907ab4b858
 @attributes=
  {"id"=>333333333,
   "created_at"=>"2017-04-16T14:58:17.152Z",
(略)
   "reblogged"=>false}>

.envの中身は以下のようになります(このトークンは削除済みです)。

MASTODON_URL = 'https://mstdn.jp'
MASTODON_CLIENT_ID = 'c966c6055fcf893a58826ac69bffe8532b4a38c3aa7103c776ef98364e96c3d3'
MASTODON_CLIENT_SECRET = '8b149559aa6f322749a703460927dbd91bc634973bc992822c6b6831bc3ff164'
MASTODON_ACCESS_TOKEN = '3de7aaba44c159b150e3db3b46d50a656924714967e2d7f054010d9de51b0aa6'

その他使用している環境変数は以下です。

環境変数名 内容
MASTODON_URL MastodonインスタンスのURL
MASTODON_CLIENT_ID クライアントID
MASTODON_CLIENT_SECRET クライアントSECRET
MASTODON_ACCESS_TOKEN アクセストークン
MASTODON_SCOPES スコープ(read, write, followのうち必要なものをスペース区切りで)
MASTODON_APP_NAME クライアントアプリ名(設定画面の「認証済みアプリ」で表示される)

補足説明

Mastodon::REST::Client#create_appでclient_idとclient_secretを取得してからOAuth2::Clientのパスワード認証(? RFC6749でいうところのResource Owner Password Credentials Grant)でアクセストークンを取得しています。最初それがよく分からなくて、Mastodon::REST::Clientでどうやってやればいいのか悩んでいましたが、そこはOAuth2を使うのが正解なのではという結論に達しました。

アクセストークンを取得したあとは改めてMastodon::REST::Client.newすると、今度は普通にAPIを叩けるようになります。それぞれのAPIの使い方は http://www.rubydoc.info/github/tootsuite/mastodon-api/master をどうぞ。

参考