https://サーバー名/api/v1/statuses/投稿ID
var xmlHttpRequest=new XMLHttpRequest(); xmlHttpRequest.addEventListener("load",function(event) { // xmlHttpRequest.responseにレスポンスが入っています },false); xmlHttpRequest.responseType="json"; xmlHttpRequest.open("GET","https://サーバー名/api/v1/timelines/home"); xmlHttpRequest.setRequestHeader("Authorization","Bearer アクセストークン"); xmlHttpRequest.send();
var xmlHttpRequest=new XMLHttpRequest(); xmlHttpRequest.addEventListener("load",function(event) { // xmlHttpRequest.responseにレスポンスが入っています },false); xmlHttpRequest.responseType="json"; xmlHttpRequest.open("POST","https://mstdn.jp/api/v1/statuses?access_token=アクセストークン"); xmlHttpRequest.setRequestHeader("Content-Type","application/x-www-form-urlencoded; charset=UTF-8"); xmlHttpRequest.send("status="+encodeURIComponent("テスト")+"&visibility=unlisted"); // file:///以下から試すと422エラーになるので注意
xmlHttpRequest.addEventListener("load",function(event) { // xmlHttpRequest.responseにレスポンスが入っています // xmlHttpRequest.getResponseHeader("Link")にページング情報 var links=xmlHttpRequest.getResponseHeader("Link").split(/, /); var pagination={}; for (var i=0;i<=links.length-1;i++) { var parsed=links[i].match(/<([^>]+)>; rel="([^"]+)"/); pagination[parsed[2]]=parsed[1]; } // 次ページを開くなら pagination.next // 前ページを開くなら pagination.prev },false);
var xmlHttpRequest=new XMLHttpRequest(); var lastResponse=""; var data=""; xmlHttpRequest.addEventListener("progress",function(event) { // chunk=今回受信した断片 var chunk=xmlHttpRequest.response.substring(lastResponse.length); lastResponse=xmlHttpRequest.response; // data=まだ処理してない断片 (改行まで受信してるとは限らない) data=data+chunk; // 空行をスキップ data=data.replace(/^\n/gm,""); // タイムアウトで切断されないようにするためのダミーデータをスキップ data=data.replace(/^:(.*)\n/gm,""); var content; do { content=data.match(/^event: (.*)\ndata: (.*)\n([\s\S]*)$/); if (content!=null) { var event=content[1]; var payload=(content[2]!="undefined" ? JSON.parse(content[2]) : null); // event(イベント名), payload(データ内容)で処理をする data=content[3]; } } while (content!=null); },false); xmlHttpRequest.open("GET","https://mstdn.jp/api/v1/streaming/public/local"); xmlHttpRequest.send(null);
イベント名 | イベント内容 | データ内容 |
---|---|---|
update | 新しい投稿 | Status |
status.update | 投稿の更新 (Mastodon3.5.0〜) | Status |
delete | 投稿の削除 | 削除された投稿のID |
notification | 新しい通知 | Notification |
filters_changed | 設定のフィルターの更新 (Mastodon2.4.3〜) | なし (undefinedの文字) |
announcement | 新しいお知らせ (Mastodon3.1〜) | Announcement |
announcement.reaction | お知らせへの新しいリアクション (Mastodon3.1〜) | AnnouncementReaction ? |
announcement.delete | お知らせの削除 (Mastodon3.1〜) | 削除されたお知らせのID |
encrypted_message | E2E暗号化されたダイレクトメッセージ (Mastodon3.2〜) ※使われていません | ? |
WebSocket版 | Long polling版 | 内容 |
---|---|---|
/api/v1/streaming/?stream=user | GET /api/v1/streaming/user | 自分のホームタイムライン+通知 |
/api/v1/streaming/?stream=user:notification | GET /api/v1/streaming/user/notification | 自分へ通知 (Mastodon1.4.2〜) |
/api/v1/streaming/?stream=public | GET /api/v1/streaming/public | 連合タイムライン (認証不要) |
/api/v1/streaming/?stream=public:local | GET /api/v1/streaming/public/local | ローカルタイムライン (認証不要) (Mastodon1.1〜) |
/api/v1/streaming/?stream=public:remote | GET /api/v1/streaming/public/remote | 連合タイムラインの別サーバーのみ (認証不要) (Mastodon3.1.4〜) |
/api/v1/streaming/?stream=public:media | GET /api/v1/streaming/public?only_media=true | 連合タイムラインのメディアのみ (認証不要) (Mastodon2.4〜) |
/api/v1/streaming/?stream=public:local:media | GET /api/v1/streaming/public/local?only_media=true | ローカルタイムラインのメディアのみ (認証不要) (Mastodon2.4〜) |
/api/v1/streaming/?stream=public:remote:media | GET /api/v1/streaming/public/remote?only_media=true | 連合タイムラインの別サーバーのメディアのみ (認証不要) (Mastodon3.1.4〜) |
/api/v1/streaming/?stream=direct | GET /api/v1/streaming/direct | 自分のダイレクトメッセージ (Mastodon2.4〜) |
/api/v1/streaming/?stream=hashtag | GET /api/v1/streaming/hashtag | 連合タイムラインのクエリーtag(#は含めない)で指定したハッシュタグの投稿 (認証不要) |
/api/v1/streaming/?stream=hashtag:local | GET /api/v1/streaming/hashtag/local | ローカルタイムラインのクエリーtag(#は含めない)で指定したハッシュタグの投稿 (認証不要) (Mastodon1.1〜) |
/api/v1/streaming/?stream=list | GET /api/v1/streaming/list | クエリーlistで指定した自分のリストの投稿 (Mastodon2.1〜) |
// instanceInfoには /api/v1/instance のレスポンスを入れておく var socket=new WebSocket(instanceInfo.urls.streaming_api+"/api/v1/streaming/?stream=public:local"); socket.addEventListener("message",function(event) { var data=JSON.parse(event.data); var event=data.event; var payload=data.payload; if (event=="update" || event=="notification") { payload=JSON.parse(data.payload); } // event, payloadで処理をする },false);
var socket=new WebSocket(instanceInfo.urls.streaming_api+"/api/v1/streaming"); socket.addEventListener("message",function(event) { var data=JSON.parse(event.data); var stream=data.stream; // event, payloadの扱いは変更なし if (stream[0]=="public") { // 連合タイムラインの場合 } },false); // 受け取るStreamingに連合タイムラインを追加 socket.send(JSON.stringify({ "type": "subscribe", "stream": "public" }));
// Service Workerを登録しておく navigator.serviceWorker.register("serviceWorker.js"); // Notification APIの利用許可を得ておく Notification.requestPermission(function(permission) { ... }); function encodeBase64(buffer) { return window.btoa( String.fromCharCode.apply(null,new Uint8Array(buffer))) .replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,""); } function decodeBase64(string) { return new Uint8Array([].map.call( window.atob((string+"=".repeat((4-string.length%4)%4)) .replace(/\-/g,"+").replace(/_/g,"/")), function(c) { return c.charCodeAt(0) })); } navigator.serviceWorker.ready.then(function(registration) { registration.pushManager.subscribe({ userVisibleOnly: true, applicationServerKey: decodeBase64("VAPID公開鍵"), }).then(function(subscription) { var endpoint=subscription.endpoint; var publicKey=encodeBase64(subscription.getKey("p256dh")); var authSecret=encodeBase64(subscription.getKey("auth")); var xmlHttpRequest=new XMLHttpRequest(); xmlHttpRequest.open("POST","https://サーバー名/api/v1/push/subscription?access_token=アクセストークン"); xmlHttpRequest.setRequestHeader("Content-Type","application/x-www-form-urlencoded; charset=UTF-8"); xmlHttpRequest.send( "subscription[endpoint]="+endpoint+ "&subscription[keys][p256dh]="+publicKey+ "&subscription[keys][auth]="+authSecret+ "&data[alerts][follow]=true&data[alerts][favourite]=true"+ "&data[alerts][reblog]=true&data[alerts][mention]=true"); }); });
// serviceWorker.jsの中身 self.addEventListener("push",function(event) { var data=event.data.json(); // data.notification_typeには"favourite"など通知の種類 return event.waitUntil( self.registration.showNotification( data.title, // 通知内容の文章 { icon: data.icon, body: data.body, // 対象の投稿など } ) ); });
var clientId,clientSecret; var xmlHttpRequest=new XMLHttpRequest(); xmlHttpRequest.addEventListener("load",function(event) { clientId =xmlHttpRequest.response.client_id; // クライアントキー clientSecret=xmlHttpRequest.response.client_secret; // クライアントシークレット // 次のステップへ },false); xmlHttpRequest.responseType="json"; xmlHttpRequest.open("POST","https://サーバー名/api/v1/apps"); xmlHttpRequest.setRequestHeader("Content-Type","application/x-www-form-urlencoded; charset=UTF-8"); xmlHttpRequest.send("client_name="+encodeURIComponent("アプリ名")+ "&redirect_uris=リダイレクト先"+ "&scopes="+encodeURIComponent(["read","write"].join(" "))); // file:///以下から試すと422エラーになるので注意
scope | 許可される操作 |
---|---|
read | 読み取り系 |
write | 書き込み系 (投稿) |
follow | フォロー、ブロック (Mastodon3.5.0〜はread/writeを使うように変更) |
push | Web Push (Mastodon2.4.0〜) |
https://サーバー名/oauth/authorize?client_id=クライアントキー&scope=許可される操作&response_type=code&redirect_uri=リダイレクト先
リダイレクト先?code=code&scope=許可される操作
var accessToken; var xmlHttpRequest=new XMLHttpRequest(); xmlHttpRequest.addEventListener("load",function(event) { accessToken=xmlHttpRequest.response.access_token; // アクセストークン },false); xmlHttpRequest.responseType="json"; xmlHttpRequest.open("POST","https://サーバー名/oauth/token"); xmlHttpRequest.setRequestHeader("Content-Type","application/x-www-form-urlencoded; charset=UTF-8"); xmlHttpRequest.send("client_id="+clientId+"&client_secret="+clientSecret+ "&redirect_uri=リダイレクト先"+ "&grant_type=authorization_code"+ "&code="+code);
https://mstdn.jp/api/v2/search?q=https%3A%2F%2Fサーバー名%2F%40ユーザー名%2F投稿ID&resolve=true (投稿IDを探す) https://mstdn.jp/api/v1/accounts/search?q=ユーザー名%40サーバー名&resolve=true (アカウントIDを探す) https://mstdn.jp/api/v1/accounts/lookup?acct=ユーザー名%40サーバー名 (サーバー上に既にIDがあるアカウントIDを探す) (Mastodon3.4〜)
x-ratelimit-limit: 300 x-ratelimit-remaining: 299 x-ratelimit-reset: 2018-08-30T02:40:00.363679Z
Endpoint | Bucket | 制限数 | 期間 | 制限単位 |
---|---|---|---|---|
* /api/* | アカウントでのアクセス | 300 (Mastodon4.2〜?は1500) | 5分 | アカウント |
* /api/* | アプリケーションのアクセス (Mastodon4.2〜?) | 300 | 5分 | アプリケーション |
* /api/* | 認証不要のアクセス | 300 | 5分 | IPアドレス |
POST /api/v1/statuses | 新規投稿 (Mastodon3.1.3〜) | 300 | 3時間 | アカウント |
POST /api/v1/media | メディアのアップロード | 30 | 30分 | アカウント |
DELETE /api/v1/statuses/:id POST /api/v1/statuses/:id/unreblog |
投稿の削除 | 30 | 30分 | アカウント |
POST /api/v1/accounts/:id/follow | フォロー (Mastodon3.1.3〜) | 400 | 24時間 | アカウント |
POST /api/v1/reports | 通報 (Mastodon3.1.3〜) | 400 | 24時間 | アカウント |
POST /api/v1/accounts | アカウント作成 | 5 | 30分 | IPアドレス |
https://サーバー名/users/ユーザー名.json (アカウント情報) https://サーバー名/users/ユーザー名/following.json?page=1 (フォロー情報) https://サーバー名/users/ユーザー名/followers.json?page=1 (フォロワー情報) https://サーバー名/users/ユーザー名/outbox?page=true (タイムライン情報) https://サーバー名/users/ユーザー名/collections/featured (固定された投稿) https://サーバー名/users/ユーザー名/collections/tags (注目のハッシュタグ) https://サーバー名/users/ユーザー名/statuses/投稿ID.json (投稿情報) https://サーバー名/tags/ハッシュタグ(#は含まない).json (ハッシュタグ検索結果情報)
https://サーバー名/.well-known/host-meta https://サーバー名/.well-known/webfinger?resource=https://サーバー名/@ユーザー名 (現行のMastodonの指定先) https://サーバー名/.well-known/webfinger?resource=acct:ユーザー名@サーバー名 (現行のMastodonの指定先)
https://サーバー名/.well-known/nodeinfo https://サーバー名/nodeinfo/2.0 (現行のMastodonの指定先)
サービス名 | サービスの概要 | APIの互換性 | "version"の値の例 |
---|---|---|---|
Mastodon Glitch Edition (glitch-soc, Glitch) | MastodonのFork。Mastodonに実験的な追加機能を加えている | ◎APIに関する変更点は基本はないので、互換性あり(追加はある) | 4.3.0-alpha.0+glitch |
hometown | MastodonのFork。Mastodonに最小限の変更のみを加えている | ◎APIに関する変更点はないので、完全互換性あり ※NodeInfoのsoftware.nameは"hometown" |
4.0.2+hometown-1.1.1 |
Pleroma | Twitterライク。バックエンドとフロントエンドを分離するコンセプトでMastodonクライアントを使うことも想定されている | ◎互換性は高めで、 独自拡張も多い | 2.7.2 (compatible; Pleroma 2.4.0-516-gdc63aaf8) |
Akkoma | PleromaのFork | ◎互換性は高め ※Pleromaを引き継いでいる |
2.7.2 (compatible; Akkoma 3.5.0-develop) |
Misskey | Twitterライク | ×独自APIで互換性なし ※Mastodon互換APIは一時期あったが廃止 |
|
Firefish (Calckey) | MisskeyのFork。 ※以前の名称はCalckey |
△開発は継続中のようです | 3.0.0 (compatible; Firefish 1.0.5-dev12) |
Iceshrimp | Misskeyの(厳密にはFirefishの)Fork | △開発は継続中のようですが、 Misskey Forkの中では最もMastodon API対応に積極的で進んでいるようです | 3.0.0 (compatible; Iceshrimp 1.0.2) |
Catodon | Misskeyの(厳密にはFirefishの)Fork ※Iceshrimpにrebase予定 |
△Firefish→Iceshrimpの実装そのままのようです | 3.0.0 (compatible; Firefish 23.12-alpha.3) |
Threads | Meta社のTwitterライク | ×ActivityPub互換対応のみが言及されており、 クライアントAPIはありません | |
GoToSocial | Twitterライク。バックエンドのみを提供するコンセプトでMastodonクライアントを使うことも想定されている | △互換性は高いはずですが、GoToSocial自体がまだα版である点に注意 | 3.5.3+0.13.0 |
Wildebeest | Cloudflare社のTwitterライク。Mastodon互換のサーバーサービスとしている | ○互換性は高いはずですが、不完全なまま ※Wildebeest自体が開発終了となってしまいました |
4.0.2 (compatible; Wildebeest 0.0.1) |
GNU social | Twitterライク | ×Twitter API互換 | |
Friendica | Facebookライク | △まだ対応途中のようです | 2.8.0 (compatible; Friendica 2023.01) |
Pixelfed | Instagramライク | ○基本的には互換性があるものの、アクセストークンなしのアクセスができなかったり、一部独自のAPIもある模様 | 2.7.2 (compatible; Pixelfed 0.11.4) |
PeerTube | YouTubeライク | ×独自APIで互換性なし | |
Lemmy | Redditライク | ×独自APIで互換性なし |
GET /api/v1/pleroma/statuses/:id/reactions (投稿に付いた絵文字リアクション一覧) GET /api/v1/pleroma/statuses/:id/reactions/:emoji (投稿に付いた指定の絵文字リアクションの一覧) PUT /api/v1/pleroma/statuses/:id/reactions/:emoji (追加) DELETE /api/v1/pleroma/statuses/:id/reactions/:emoji (削除)
GET /api/v1/statuses/:id/emoji_reactioned_by (投稿に付いた絵文字リアクションの一覧) PUT /api/v1/statuses/:id/emoji_reactions/:emoji (追加) DELETE /api/v1/statuses/:id/emoji_reactions/:emoji (削除) POST /api/v1/statuses/:id/emoji_unreaction (一括削除) GET /api/v1/emoji_reactions (自分が絵文字リアクションを付けた投稿一覧)
POST /api/v1/statuses/:id/react/:emoji (追加) POST /api/v1/statuses/:id/unreact/:emoji (削除)
サービス系統 | Statusの 追加属性 |
Notificationの type属性の値 |
エンドポイント |
---|---|---|---|
Pleroma系 (Pleroma, Akkoma) |
pleroma.emoji_reactions | pleroma:emoji_reaction | GET /api/v1/pleroma/statuses/:id/reactions (一覧) GET /api/v1/pleroma/statuses/:id/reactions/:emoji (一覧) PUT /api/v1/pleroma/statuses/:id/reactions/:emoji (追加) DELETE /api/v1/pleroma/statuses/:id/reactions/:emoji (削除) |
Fedibird系 (Fedibird, kmyblueフォーク) |
emoji_reactions emoji_reactions_count emoji_reactioned |
emoji_reaction | GET /api/v1/statuses/:id/emoji_reactioned_by (一覧) PUT /api/v1/statuses/:id/emoji_reactions/:emoji (追加) DELETE /api/v1/statuses/:id/emoji_reactions/:emoji (削除) POST /api/v1/statuses/:id/emoji_reactions (一括追加) ※kmyblueフォークのみ POST /api/v1/statuses/:id/emoji_unreaction (一括削除) GET /api/v1/emoji_reactions (自分が付けた投稿一覧) |
glitch-soc系 (glitch-soc, Firefish) |
reactions | reaction | POST /api/v1/statuses/:id/react/:emoji (追加) POST /api/v1/statuses/:id/unreact/:emoji (削除) |
PUT /api/v1/statuses/:id/emoji_reactions/:emoji (追加)
POST /api/v1/statuses/:id/emoji_reactions (一括追加)
GET /api/v1/pleroma/statuses/:id/quotes
GET /api/v1/statuses/:id/referred_by
サービス系統 | Statusの 追加属性 |
引用した投稿を得るエンドポイント |
---|---|---|
小規模サーバー系 (itabashi.0j0.jp, mstdn.y-zu.org, odakyu.appなど) |
quote | なし |
Pleroma系 (Pleroma2.6〜) |
pleroma.quote pleroma.quote_id pleroma.quote_url pleroma.quote_visible pleroma.quotes_count (Pleroma2.6.51〜) |
GET /api/v1/statuses/:id/context ※descendants内、返信も含まれる GET /api/v1/pleroma/statuses/:id/quotes (Pleroma2.6.51〜) |
Akkoma系 (Akkoma) |
quote quote_id |
GET /api/v1/statuses/:id/context ※descendants内、返信も含まれる |
Fedibird系 (Fedibird, kmyblueフォーク7.0〜) |
quote quote_id ※Fedibirdは値があるときだけ出現 status_referred_by_count ※引用数は参照数に含まれる |
GET /api/v1/statuses/:id/referred_by ※参照も含まれる GET /api/v1/statuses/:id/context?with_reference=1 ※references内、参照も含まれる |
https://サーバー名/users/ユーザー名.rss (投稿) https://サーバー名/users/ユーザー名/with_replies.rss (投稿と返信) https://サーバー名/users/ユーザー名/media.rss (メディア付き投稿のみ) https://サーバー名/users/ユーザー名/tagged/ハッシュタグ(#は含まない).rss (注目のハッシュタグ) https://サーバー名/tags/ハッシュタグ(#は含まない).rss (ハッシュタグタイムライン)
https://サーバー名/api/oembed.json?url=埋め込みたいページのURL
web+mastodon://share?text=投稿本文 (シェア) web+mastodon://follow?uri=ユーザー名@サーバー名 (フォロー)
https://サーバー名/share?text=投稿本文 (シェア) https://サーバー名/authorize_interaction?uri=ユーザー名@サーバー名 (フォロー) https://サーバー名/interact/投稿ID?type=reply (返信) (〜Mastodon3.5) https://サーバー名/interact/投稿ID?type=reblog (ブースト) (〜Mastodon3.5) https://サーバー名/interact/投稿ID?type=favourite (いいね) (〜Mastodon3.5) https://サーバー名/@ユーザー名@ユーザーのサーバー名/投稿ID (投稿への各操作) (Mastodon4.0〜)
navigator.share({ url: 共有したいURL });
戻る