窓を作っては壊していた人のブログ

この謎のブログタイトルの由来を知るものはもういないだろう

C# で Mastodon のAPIライブラリの Mastodot を作った

最近 Twitter も見つつの Mastodon も見つつみたいな生活になってきました(どのインスタンスかは…察してください)(就活の方をちゃんとやりなさい)(研究が炎上している)

そうなると自分で適当なクライントを作ったり,API を叩いてちょっとした監視などをしたいなぁという欲求が出てくるようになってきます.

ということで実際にライブラリを作って Nuget に公開してみました.

GitHub - yamachu/Mastodot: C# Library for Mastodon. Easy Toot!

www.nuget.org

それで作ってみた監視の Bot がこちら.

qiita.com

使ってみる

とりあえず最低限使えるような流れを少し載せようと思います.

MastodonAPI を叩いてごにょごにょするためには Mastodonインスタンスに対して自分のクライアントアプリを登録して,それに紐付けられた ClientIdClientSecret を取得する必要があります.

var app = await ApplicationManager.RegistApp("mastodon.cloud", "はじめての Mastodon アプリ", Scope.Read | Scope.Write | Scope.Follow);

こんな感じで Mastodonインスタンスに今回では “はじめての Mastodon アプリ” というアプリを登録することが出来ました. ここで得られた app にさっき必要といった ClientIdClientSecret が格納されています.

このオブジェクト自体をシリアライズするなりトークンを別に保存するなりします(接続の度にアプリケーションを作り直すのはちょっと…)

  • AccessToken の取得

先程得られた ClientIdClientSecret を使って AccessToken を取得していきます. Mastodon ではユーザー認可に OAuth を使っているのですが,そこで必要になるのがその AccessToken です.

この取得方法には2種類あり,メールアドレスとパスワードのペアによる取得か,ログイン済みのブラウザなどで特定の URL に飛ぶことで行う方法があります.

様々な解説記事ではメールアドレスとパスワードのペアによるログインが多く載っているので,ここでは後者の方法を取ってみようと思います.

// さっきの app 変数が残っているのであれば,
var url = ApplicationManager.GetOAuthUrl(app);
// なければこんな感じで
// var url = ApplicationManager.GetOAuthUrl("mastodon.cloud", "ここにClientId", Scope.Read | Scope.Write | Scope.Follow);

ここで得られた url にログイン済みのブラウザなどでアクセスして認証?をクリックすると,真ん中にながーーーーーーい文字列が表示されます.これをコピーしてください.

var tokens = await ApplicaionManager.GetAccessTokenByCode(app, 長い文字列);
// もしくは
// var tokens = await ApplicaionManager.GetAccessTokenByCode("mastodon.cloud", "ここにClientId", "ClientSecret", 長い文字列);

ここで得られた tokens に お待ちかねの AccessToken が格納されています. これからはこの AccessToken を使って API を叩くのでどこかに保存しておいてください.

自分は今のところ確認していないのですが,たまに認証・認可を行う際にサブドメインを切ってそこで認証とかをする場合があります. その際は上のメソッドに名前付き引数で subdomain: "authenticate" みたいな感じに入れるといいと思います(仮に authenticate.mastodon.cloud みたいなURLで認証が行われるのであれば).

  • Toot しよう

簡単に HelloWorld 的なこともやってみましょう. 自分のクライントから Toot 出来たときは本当に嬉しいものなので(個人差があります),それをやってみます.

var client = new MastodonClient("mastodon.cloud", "ここにAccessToken");
var status = await client.PostNewStatus(status: "Hello Mastodon!");

こうすると対象の Mastodon インスタンスに自分の Toot が投稿されます.やったぜ

画像つきはちょっと面倒で,Xamarin とかだと自分で画像を byte[] に変換して〜という作業が入ってここに書くのは大変なので,コンソールアプリとかで実行していることを想定してみます.

var attachment = await client.UploadMedia("アップしたいファイルのパス");
var status = await client.PostNewStatus("矢澤にこは俺の嫁", mediaIds: new int[] { attachment.Id});

みたいにすると画像つきの投稿もできます. 他の詳しい仕様などは公式のドキュメント

documentation/API.md at master · tootsuite/documentation · GitHub

またはこのライブラリのソースなどをご覧ください(投げやり).

  • ストリームをだら見する

最後にストリームをダラダラと見ていきます. 本ライブラリでは Reactive 系のライブラリを導入しているため,ストリームに接続すると Observable 系のものが返ってくるようになっています. そのため他の Rx.* を使ったことのある人であればなんとなく使い勝手がわかると思います.

var publicStream = client.GetObservablePublicTimeline()
                    .OfType<Status>()
                    .Subscribe(x => Console.WriteLine($"{x.Account.FullUserName} Tooted: {x.Content}"));
            

ここでは流れてくる投稿のみをフィルタして表示していますが,OfType<Notification> などにすると通知が取れたりもします.

非常に簡単に使えるように,ということを心がけて作ってみたので,是非試してみてください.

まとめたコードなどは Mastodot/Program.cs at master · yamachu/Mastodot · GitHub

に置いてあるので参考にしてみてください.

バグ報告やIssue,PRお待ちしております!