Introduction
Pulsate Specification は Pulsate プロジェクトに関するAPIエンドポイントや設計などの仕様を記述したドキュメントです.
プロジェクトの概要については こちら をご覧ください.
note
この仕様書は現在開発中の Pulsate v0.1 となります. 今後のバージョンアップにより仕様が変更される可能性があります.
プロジェクト概要
プロジェクトの目標
高速で安全な ActivityPub 実装
-
パフォーマンス重視
-
セキュリティ重視
-
ActivityPub 仕様の重視
実装方針
パフォーマンス・セキュリティの強化
- Misskey や Mastodon よりも高速に動作する次世代の ActivityPub 実装.
- 各APIリクエストに対するレスポンスを始めとするパフォーマンスの向上(タイムラインの読み込み, メディアのレスポンスなど).
- TypeScript での開発を行い, パフォーマンスの向上を図る.
- TypeScript は JavaScript に比べて型安全性が高く, パフォーマンスが向上する.
- SQL Injection や XSS などセキュリティに関わる脆弱性が少ない.
見つかったとしてもすぐに修正できる仕組みづくり.
- パスワードレスログイン, 2FA など.
ActivityPub 実装の重視
- 無駄な機能は実装せずあくまで ActivityPub の実装として忠実に従う.
- MFM など特定の分散型ソフトウェアのみの実装に従わない. ただし Mastodon や Misskey などの主要実装が互いに実装している機能は実装する. (引用など)
クライアント, App 周りのサポートの強化
- PWA は対応状況が酷い.
- Chromium系ブラウザは概ね対応しているが, Firefox や Safari は対応していない.
- ターゲットはモバイルユーザーが大半だと考え, Pulsate ではネイティブアプリとして iOS App, Android App をリリースする(構想段階).
- ネイティブアプリと同様コミュニティが開発するサードパーティクライアントも尊重し, API リファレンスなどリソースを多く用意しコミュニティの開発を支援する.
開発手法の厳格化 / 改善
- semver (セマンティックバージョニング) に従い, 破壊的変更をなるべく少なくする. 破壊的変更が行われる場合は予めコミュニティに通告する.
- Rust のエディション方式を採用し,
同じエディション内では基本的に後方互換性を保つ.
- エディションが切り替わる = リリース の切り替わり (メジャーバージョンアップ)
- またエディションをまたぐときには,
そのエディションの変更点をまとめたガイドを提供したりスクリプトを提供することで,
既存のインスタンスを新しいエディションに対応させる手助けをする.
- これは Rust の思想を受けたもの.
Rust 1.0 のリリースでは、Rust のコア機能として「よどみない安定性」が提供されるようになりました。 Rust は、1.0 のリリース以来、いちど安定版にリリースされた機能は、将来の全リリースに渡ってサポートし続ける、というルールの下で開発されてきました。
一方で、後方互換でないような小さい変更を言語に加えることも、ときには便利です。 最もわかりやすいのは新しいキーワードの導入で、これは同名の変数を使えなくします。 例えば、Rust の最初のバージョンには
async
やawait
といったキーワードはありませんでした。 後のバージョンになってこれらを突然キーワードに変えてしまうと、例えばlet async = 1;
のようなコードが壊れてしまいます。我々は、クレートを新しいエディションにアップグレードするのが簡単になるよう目指しています。 新しいエディションがリリースされるとき、我々は移行を自動化するツールも提供します。 このツールは、新しいエディションに適合させるために必要な小さな変更をコードに施します。 例えば、Rust 2018 への移行の際は、
async
と名のつく全てのものを、等価な生識別子構文であるr#async
へと書き換える、といった具合です。
コミュニティの声を聞く
- 簡単に言えば Discord や GitHub Discussions の採用.
- バグ報告は基本的に インスタンス管理者 , ユーザー から受けるのが多いと考えるため, Discord での報告も受け付ける. (GitHub Issues には Discord Bot を使ってうまく Import する)
プロジェクトコードネーム
Pulsate
- 意味: 脈打つ, 鼓動する; 〈光・音などが〉振動する; ドキドキする; など.
- 由来: indigo la End のアルバム "PULSATE" から.
バージョンコードネーム
v0, v1 - Antenna
v0 (開発途上バージョン), v1 (最初の安定版) のコードネーム.
由来は Mrs. GREEN APPLE の ANTENNA から.
ER図 (WIP)
Mermaid code
erDiagram
account {
string id PK
string name
string nickname
string mail
string passphrase_hash
string bio
int role "権限"
int status "アカウントの状態"
datetime created_at
datetime updated_at
datetime deleted_at
}
account ||--o{ note : "has"
account ||--o{ list : "has"
account ||--o{ bookmark : "has"
account ||--o{ following : "has"
account ||--o{ medium : "hosts"
account ||--o{ reaction : "has"
following {
string from FK
string to FK
int state "FOLLOWING/REQUESTING_FOLLOW/BLOCKINGの3値を取る"
datetime created_at
datetime updated_at
datetime deleted_at
}
note {
string id PK
string text "投稿本文"
string author_id FK "投稿者のID"
int visibility "公開範囲"
datetime created_at
datetime deleted_at
}
note ||--o{ bookmark : "has"
note ||--o{ reaction : "has"
reaction {
string reacted_by FK "リアクションしたユーザーID"
string reacted_to FK "リアクションしたノートID"
string body "内容(絵文字)"
datetime created_at
datetime deleted_at
}
bookmark {
string note_id FK
string author_id FK "ブックマークをしたユーザーID"
datetime created_at
datetime deleted_at
}
list {
string id PK
string title "リスト名"
int visibility "公開するかどうか"
datetime created_at
datetime updated_at
datetime deleted_at
}
list ||--o{ list_member : "has"
list_member {
string list_id FK
string member_id FK "メンバのアカウントID"
datetime created_at
datetime deleted_at
}
list_member }o--|| account : ""
medium {
string id PK
string name "ファイル名"
string mime "mime type"
string author_id FK
datetime created_at
datetime deleted_at
}
note_attachment {
string medium_id FK
string note_id FK
string alt "altテキスト"
datetime created_at
datetime deleted_at
}
note_attachment }o--|| note: ""
note_attachment }o--|| medium: "references"
- 未定義リスト
- リノートの扱い
- notesがrenoteに対してリレーションを持つようにする
- notesにrenote先のIDを持たせる
- 登録中アカウント用のテーブルを作るか否か
- アカウント(同士の)関係
- リノートの扱い
note
ドライブが階層構造などを持たないという仕様になった上, 一旦これ以上は複雑化させない方針になっているのでメディアが直接アカウントに紐づく形になっています.
important
CONSIDERATIONS:
-
note_attachements
との関連は多対多になるかも? - accounts に bookmarks が直接関連しているのは正しいのか?
モデルリファレンス
ID
Twitter の Snowflake をベースに, 次のようなビットフィールド (図はビッグエンディアン) からなる 64 ビット整数です.
先頭に時刻を含んでいるため, そのまま時刻順にソートが可能です.
111111111111111111111111111111111111111111 1111111111 111111111111
64 22 12 0
timestamp worker id incremental
各ビットフィールドの意味は以下のとおりです.
フィールド | ビット範囲 | 意味 |
---|---|---|
timestamp | [64, 22) | Pulsate エポックからのミリ秒数. エポックは 2022 年 1 月 1 日 0 時 0 分 0.000 秒. UNIX 時間のミリ秒に 1640995200000 を足すことでこれに変換可能. |
worker id | [22, 12) | この ID を生成したワーカーの識別子 |
incremental | [12, 0) | ワーカーにて同一時刻で ID を生成する度に増える値 |
TypeScript 上ではこのような型として表現します. 型引数によりエンティティ間で ID を取り違えるようなミスを防ぎます.
declare const snowflakeNominal: unique symbol;
export type ID<T> = string & { [snowflakeNominal]: T };
認証トークン
JSON Web Token の一種で, ペイロードには 更新トークン など以下の情報を含みます.
更新トークンも JWT なので, JWT がネストしています.
sub
: 発行対象のアカウント名iat
: 発行時刻 (UNIX エポックの秒数)
{
"sub": "hogehoge-user",
"iat": 1640995201
}
このトークンの有効期限は発行時刻から 15 分 (900 秒) です.
生成や検証の自作は実装ミスによる脆弱性を誘発しますのでライブラリを利用します.
更新トークン
JSON Web Token の一種で, ペイロードには以下の情報を含みます.
{
"sub": "3e1644833000002",
"iat": 1640995201
}
このトークンの有効期限は発行時刻から 30 日 (2,592,000 秒) です. 特に再発行はされず, 手動でのログイン時にのみ発行されます.
なおこのトークンは長命なので, 利用後に無効化しておかないと奪取されて再利用されるリスクがあります. 危険度は高いですがネットワーク上に流れることがほとんどないため, このリスクには対処せず保有することにします.
連合
このシステムが実際に稼働しているプロセスを表すものです. この連合 (つまり Pulsate サーバーのインスタンス) は次の属性を持ちます.
id
: すべての連合において一意な IDorigin
: オリジンname
: 名称description
: 説明version
: (ソフトウェア)バージョンsoftware_name
: ソフトウェア名extensions
: 拡張対応リストmaintainer_name
: 管理者名
アカウント
自然人, 団体, ボットなど, このシステム上でオブジェクトを発行する主体となるものです. これは次の制約を持つ属性を備えます.
name
: アカウント名- 1 文字以上の URL 安全な ASCII 文字からなる
nickname
: 表示名, アカウントの表示に用いる自然言語の名称- 初期値は空文字列
- 空文字列の場合はアカウント名にフォールバックする
- RTL 制御文字を除く任意の
UTF-8
シーケンス
created_at
: このアカウントが作成された時刻mail
: メールアドレス- 有効なメールアドレスであることが検証済み
passphrase_hash
: パスフレーズのハッシュ- 元となったパスフレーズは以下の性質を満たします
- 文字種は正規化された
UTF-8
シーケンス - 連続する空白タイプの文字 (スペース, タブ, 全角スペース, 改行文字など) は 1 つの半角スペースへと置き換えられる
- 長さは Unicode スカラー値で 8 つぶん以上
- 文字種は正規化された
- 元となったパスフレーズは以下の性質を満たします
salt
: パスフレーズのハッシュに使ったソルト- パスフレーズの平文にこれを連結したもののハッシュは,
passphrase_hash
に等しい
- パスフレーズの平文にこれを連結したもののハッシュは,
なお, 基本情報はアカウント ID に関連付けられるようにし, このモデル自体は基本情報を保持しません.
アカウント状態
Mermaid code
stateDiagram-v2
NOT_ACTIVATED --> ACTIVE
ACTIVE --> FROZEN
ACTIVE --> SILENCED
SILENCED --> FROZEN
FROZEN --> SILENCED
SILENCED --> ACTIVE
FROZEN --> ACTIVE
登録中アカウント
まだ実際にアカウントが発行されておらず, メールアドレスを検証するスキームに入れられているアカウントです. アカウントに加えて次の属性を持っており, このアカウントは通常のアカウントとは別の領域に永続化されます.
state
: メールアドレスの検証のためにmail
へと送信した暗号学的乱数
なお, 登録中アカウントが追加されてから 168 時間(7days) が経過したものは無効とみなします.
アカウント関係
アカウントが他のアカウントに対してどのような関係性を持っているかを表すステートマシンです. あるアカウントから他のアカウントに対しては次のような関係が存在します.
NONE
: なしREQUESTING_FOLLOW
: フォローリクエスト中FOLLOWING
: フォロー中BLOCKING
: ブロック中
そしてこれらの関係は次の遷移図のように遷移できます.
Mermaid code
stateDiagram-v2
NONE --> REQUESTING_FOLLOW
REQUESTING_FOLLOW --> NONE
REQUESTING_FOLLOW --> FOLLOWING
FOLLOWING --> NONE
FOLLOWING --> BLOCKING
NONE --> BLOCKING
BLOCKING --> NONE
検索述語
タイムラインの設定や検索クエリに用いられる組み合わせ可能な述語です. これは後述の検索命題を用いて帰納的に構成されます.
Atom
: 原子式で, ある検索命題をそのまま述語とします.Not
: 論理否定です. ある検索述語によって選択されなかったもののみを選択する述語です.And
: 論理積です. 2 つの検索述語の両方によって選択されたものを選択する述語です.Or
: 論理和です. 2 つの検索述語のいずれか一方または両方によって選択されたものを選択する述語です.Xor
: 排他的論理和です. 2 つの検索述語のどちらか一方のみによって選択されたものを選択する述語です.
検索命題
命題は 所属, 特定のワード, ユーザー ID などを表す次の属性のあつまりとして定義されます. いずれの属性の条件も未設定にでき, その場合は選択されずそのまま次の条件へと渡ります.
id_mask
: そのユーザー ID が完全に一致するのもだけを選択します.belonging
: その投稿が所属する連合が完全一致するのもだけを選択します.match_word
: 任意の自然言語エントリに対してそのテキストが部分一致するものだけを選択します.
メディアソース
文章, 画像, 動画などのコンテンツを効率的かつ高速に配信するオリジンおよびその URL, その配信を提供するサービスを指します.
内部メディアソース
(wip)
外部メディアソース
(wip)
投稿
Pulsate に対して送信されたユーザー生成コンテンツのエンティティです.
すべての投稿は ID を保持しています. これに加えて, 以下の属性が関連付けられます.
(wip)
タイムライン
main
ブランチの最新 API リファレンスは
api.pulsate.dev/reference で閲覧可能.
APIのバージョニング
APIの規定パス(Base Path)は /api/v0
である.
APIのバージョンは以下の通り.
バージョン | ステータス |
---|---|
v0 | 策定途中 |
資格情報が必要なエンドポイントの実行方法
Pulsate v0 APIでは殆どのエンドポイントで資格情報が必要である.
資格情報が必要なエンドポイントへアクセスするためには, 以下の方法でエンドポイントにアクセスする必要がある.
エンドポイントへアクセスするときのAuthorization
HTTPヘッダーに
Bearer <token>
の形式で 認証トークン をつけて送信する必要がある.
例:
Bearer
“文字数”の扱い
特に明記しない限り、文字数は 以下のコードを実行して計算できる文字数 とする.
const count = (s: string) => {
const segmenter = new Intl.Segmenter({ granularity: "word" });
return [...segmenter.segment(s)].length;
};
このAPIを実装する実行環境のリストはMDNを参照せよ.
Intl.Segmenter - JavaScript | MDN
“時刻/時間”の扱い
特に明記しない限り、システム上の時刻の扱いは以下の通りである.
- 日時は例外なくタイムゾーンをUTCとして扱う
- 時刻のフォーマットは ISO 8601 とする.
"yyyy-MM-DDTHH:mm:ss.SSSZ"
形式- タイムゾーン指定されていた場合は指定したタイムゾーンの日時をUTCに変換する.
- 例:
2023-11-21T09:00:00.000+09:00
: 日本時間(JST, UTC+9) 2023年11月21日09:00:00.000 →2023-11-21T00:00:00.000Z
: 世界協定時(UTC) 2023年11月21日00:00:00.000
- 例:
- 以上の形式に合致しない形で日時の表現がされた場合はエラー終了するものとする.
絵文字の扱い
絵文字とは, Unicodeによって定義される絵文字とカスタム絵文字のことである.
その他の記号や環境依存文字は絵文字ではないとする.
Unicode絵文字
Unicode絵文字とは,Unicodeによって定義される絵文字である.
APIとやり取りするテキストデータでは特殊な記法を用いずUnicodeで表現する.
例:
{
"content": "🎉"
}
カスタム絵文字
カスタム絵文字を文字列内に埋め込むための形式は以下の通りである.
以下の形式に沿わない場合は単なる文字列であると解釈する.
- 全体を
<>
で囲む- カスタム絵文字のエイリアスは
::
で囲む - カスタム絵文字に関する詳細な定義はここでは行わない. (ToDo)
- カスタム絵文字のエイリアスは
- エイリアスのあとに(絵文字があるインスタンスではなく,APIを提供するインスタンスでの)カスタム絵文字のIDを表記する.
例:
<:alias:2949583895994> <:ii_hanashi:284745363>
特殊なテキスト埋め込みオブジェクト
投稿本文, CW注釈, アカウントbio のテキスト内にカスタム絵文字やメンションなど, Unicodeで規定された文字以外のデータを表現するときの記法
カスタム絵文字は カスタム絵文字 を参照せよ.
メンション
表記法は以下の通り
- メンションは
<>
で囲む - 囲んだ中にアカウント名を入れる
- RFC 7565で規定される形式
のスキームである
acct:
を取り除き,@
に置き換えたもの - 例: アカウント名が
@[email protected]
である場合
- RFC 7565で規定される形式
のスキームである
<@[email protected]>
- 宛先のホスト名(FQDN)は 省略不可
<@[email protected]> <@[email protected]> <@[email protected]>
基本エラーオブジェクト
APIにおいて何らかのエラーが発生した際には以下のようなエラーオブジェクトを返却する.
{
"error": "TEST_ERROR_CODE"
}
errorの中にはエラーコード
が入る.
エラーコードはエラーを返却するAPIのエンドポイントでどのようなコードを返すか指定するものとする.
エラーオブジェクトはエラーコードのみをメンバーとして含むオブジェクトである.
エラーコード以外の情報をエラーオブジェクトとして返却することは許容されない.
NSFWフラグ
言葉の意味:
NSFWとは、英語圏で用いられるインターネットスラングで、「職場では見ない方がいい」(職場での閲覧は危険)という意味の略語である。日本語の「閲覧注意」におおむね相当する。
NSFWは画像がメインの掲示板や、掲示板中の画像へのリンクなどに付けて用いられやすい。たいていは卑猥(エロ画像)・残酷(グロ画像)といった要素の強い、不用意な閲覧ははばかられる類のコンテンツが掲載されている。
- NSFWフラグとは,画像/音声/動画の内容がNSFWであることを示すためのフラグである.
- 大抵の場合画像/音声/動画にぼかし(ブラー)がかけられたり,閲覧注意の文言が(システムのUI上で)表示される.
ContentsWarning/CWフラグ
- CWフラグとは,投稿本文に何らかのコンテンツ警告があることを示すフラグである.
- 大抵の場合,投稿の注釈(投稿本文より短い,本文の内容を端的に表した文)のみが表示され,本文は[続きを読む]といったボタンを押さないと見ることができない
- リファレンスへの追加状況 (See:
pulsate-dev/specification#3
)
-
アカウント
- アカウント情報(プロフィール)を管理する
- アカウント情報の取得
- アカウントの削除
- アカウントの検索
- アカウントのサイレンス
- アカウトのサイレンス解除
- アカウントの凍結
- アカウトの解凍
- ログイン
- アカウント登録
-
フォロー
- アカウントをフォロー
- アカウントをフォロー解除
-
ノート
- ノートの作成
- (自分の)ノートの削除
- リノートの作成
- リノートの解除(削除)
- ノートへのリアクションの作成
- ノートへのリアクションの解除
- ノートのブックマーク
- ノートの検索
- ノートの取得
-
リスト
- リストの作成
- リストの削除
- リストへのアカウントの追加
- リストへのアカウントの除外/削除
- リストのノート取得
-
ドライブ
- ファイルのアップロード
- ファイルの取得
- ノートへの紐付け
- NSFWフラグの設定
-
アカウント
アカウントAPI
POST /accounts
✓
新規アカウントを作成する 正確には登録中の状態のアカウントを作成し,アカウント登録スキームを開始するものである.
入力
body: application/json
項目名 | 型 | 制約/説明 | 文字数制約 | 例 |
---|---|---|---|---|
name | string | 文字は A-Z a-z 0-9 - . _ である必要がある. 先頭,及び最後の文字は A-Z a-z 0-9 のみとする. | 1 ≤ N ≤ 64 [文字] | john ※登録される情報は@[email protected] |
string | メールアドレスとして正しい形式 (メールアドレスを受信可能であるかは問わない) | 7≤N≤319[文字] | [email protected] | |
passphrase | string | スペース,タブ,全角スペース,改行,ヌルを除くUTF-8文字列 | 8≤N≤512[文字] | じゃすた・いぐざんぽぅ , just~@_examp1e! |
captcha_token | string | Cloudflare Turnstile などの手動操作検証のトークン |
入力例
{
"name": "example",
"email": "[email protected]",
"passphrase": "じゃすた・いぐざんぽぅ",
"captcha_token": "hogehogehgoe"
}
出力
200 OK
{
"id": "38477395",
"name": "example",
"email": "[email protected]"
}
body: application/json
項目名 | 型 | 説明 | 文字数 | 例 |
---|---|---|---|---|
id | snowflake | アカウントのID | - | 30848577730000 |
name | string | ユーザー名 | 8≤N≤512[文字] | @[email protected] |
string | メールアドレスとして正しい形式 (メールアドレスを受信可能であるかは問わない) | 7≤N≤319[文字] | [email protected] |
400 Bad Request
{
"error": "TEST_ERROR_CODE"
}
INVALID_ACCOUNT_NAME
: 使用できない文字が含まれている,文字の使用制限に違反しているTOO_LONG_ACCOUNT_NAME
: アカウント名が長すぎるEMAIL_IN_USE
: メールアドレスが既に使用されているYOU_ARE_BOT
: captcha_token の検証に失敗した
409 Conflict
{
"error": "TEST_ERROR_CODE"
}
ACCOUNT_NAME_IN_USE
: アカウント名が既に使用されているEMAIL_IN_USE
: メールアドレスが既に使用されている
PATCH /accounts/{account_name}
✓
アカウント情報を指定のパラメータで編集するエンドポイント.
入力の body から次の情報のいずれか 1 つ以上を受け付け、それらを同時に適用できるかを検証し,反映する.
競合を防ぐために「更新前のニックネームと更新前のメールアドレスを結合した文字列」のハッシュを ETag (Entity Tag) として用いる.
これをMD5でハッシュするものとする.
メールアドレスを更新した場合はそのメールアドレスの確認スキームが開始される.
そしてそのメールアドレスが確認されるまで,メールアドレスの更新処理は遅延される.
ニックネームも同時に更新した場合,ニックネームの更新は先に反映される.
warning
ETag が一致しないときは 412 Precondition Failed のエラーとなる. 結合方法は
更新前のニックネーム:更新前のメールアドレス
である
入力
- body:
application/json
項目名 | 型 | 制約/説明 | 文字数制約 | 例 |
---|---|---|---|---|
name | string | 文字は A-Z a-z 0-9 - . _ である必要がある. 先頭,及び最後の文字は A-Z a-z 0-9 のみとする. | 1 ≤ N ≤ 64 [文字] | john ※登録される情報は@[email protected] |
string | メールアドレスとして正しい形式 (メールアドレスを受信可能であるかは問わない) | 7≤N≤319[文字] | [email protected] | |
passphrase | string | スペース,タブ,全角スペース,改行,ヌルを除くUTF-8文字列 | 8≤N≤512[文字] | じゃすた・いぐざんぽぅ , just~@_examp1e! |
captcha_token | string | Cloudflare Turnstile などの手動操作検証のトークン | ||
bio | string | 自己紹介文. 0文字である場合はnull やundefined ではなく空の文字列"" である必要がある. | 0≤N≤1024 | "" (空文字列), いい感じの自己紹介🆓 , This is bio hello^~ <:javascript:358409384> |
入力例
{
"nickname": "example",
"email": "[email protected]",
"passphrase": "じゃすた・いぐざんぽぅ",
"bio": "テストユーザーなのぜ"
}
出力
200 OK
編集に成功しました.
{
"id": "38477395",
"name": "@[email protected]",
"nickname": "John Doe",
"bio": "テストユーザーなのぜ",
"email": "[email protected]"
}
項目名 | 型 | 説明 | 文字数 | 例 |
---|---|---|---|---|
id | snowflake | アカウントのID | - | 30848577730000 |
name | string | ユーザー名 | 8≤N≤512[文字] | @[email protected] |
string | メールアドレスとして正しい形式 (メールアドレスを受信可能であるかは問わない) | 7≤N≤319[文字] | [email protected] | |
nickname | string | 表示名,アカウントの表示に用いる短い文字列 | 1≤N≤256 | JohnDoe<:json:299384730049> |
ジョン・ドゥ🚉 |
202 Accepted
メールアドレスが更新された場合
{
"id": "38477395",
"name": "@[email protected]",
"nickname": "John Doe",
"bio": "テストユーザーなのぜ",
"email": "[email protected]"
}
400 Bad Request
{
"error": "TEST_ERROR_CODE"
}
INVALID_SEQUENCE
: パラメータ内に使用不可能な文字種を含んでいるVULNERABLE_PASSPHRASE
: 新しいパスフレーズがパスフレーズとしての要件を満たしていない
404 Not Found
{
"error": "TEST_ERROR_CODE"
}
ACCOUNT_NOT_FOUND
: 名前がaccount_name
のアカウントが見つからない
412 Precondition Failed
{
"error": "TEST_ERROR_CODE"
}
INVALID_ETAG
: ETagが不正である
PUT /accounts/{account_name}/freeze
✓
アカウントを凍結するエンドポイント.
モデレータ以上の権限を持つアカウント認証情報が必要である.
凍結されると以下のような挙動になる.
- ログインできなくなる.
- ログインしようとするとエラー終了する.
- 投稿できなくなる.
- (公開APIを除く)いかなるAPIへの操作も受け付けなくなる.
入力
- パスパラメータ
account_name
:string
- アカウント名
- body:
application/json
- 空のオブジェクトを送信せよ.
- 空でない場合のメンバーは無視される.
- 空のオブジェクトを送信せよ.
入力例
{}
出力
204 No Content
凍結が完了した.
※レスポンスボディは空になる.
400 Bad Request
{
"error": "TEST_ERROR_CODE"
}
ALREADY_FROZEN
: すでに凍結済みである.
403 Forbidden
{
"error": "TEST_ERROR_CODE"
}
NO_PERMISSION
: アカウントを凍結できる権限がない.
404 Not Found
{
"error": "TEST_ERROR_CODE"
}
ACCOUNT_NOT_FOUND
: アカウントが見つからない.
DELETE /accounts/{account_name}/freeze
✓
アカウントを凍結解除する(解凍と表記することもある).
モデレータ以上の権限の持つアカウント認証情報が必要.
入力
- パスパラメータ
account_name
:string
- アカウント名
- body:
application/json
- 空のオブジェクトを送信せよ.
- 空でない場合のメンバは無視される.
- 空のオブジェクトを送信せよ.
入力例
{}
出力
204 No Content
凍結解除した.
※レスポンスボディは空になる.
403 Forbidden
{
"error": "TEST_ERROR_CODE"
}
NO_PERMISSION
: アカウントを凍結解除できる権限がない.
404 Not Found
{
"error": "TEST_ERROR_CODE"
}
ACCOUNT_NOT_FOUND
: アカウントが見つからない.
POST /accounts/{account_name}/resend_verify_email
✓
メールアドレスの検証コードを再送
入力
- パスパラメータ
account_name
:string
- アカウント名
body: application/json
項目名 | 型 | 制約/説明 | 文字数 | 例 |
---|---|---|---|---|
captcha_token | string | Cloudflare Trunstileなどの検証トークン |
入力例
{
"captcha_token": "hogehogehgoe"
}
出力
204 No Content
再送した
※レスポンスボディは空になる.
400 Bad Request
{
"error": "TEST_ERROR_CODE"
}
ACCOUNT_ALREADY_VERIFIED
: アカウントのメールアドレスはすでに検証されている.
404 Not Found
{
"error": "TEST_ERROR_CODE"
}
ACCOUNT_NOT_FOUND
: アカウントが見つからない
POST /accounts/{account_name}/verify_email
✓
メールアドレス認証が終了していないアカウントに対して,
メールアドレスに送信された認証トークンを検証することでメールアドレス認証を行う.
処理が完了すると,検証済みアカウントになりログインなどの各種操作が行えるようになる(ToDo 行うことのできる操作の一覧へのリンク
入力
- パスパラメータ
account_name
:string
- アカウント名
- body:
application/json
項目名 | 型 | 制約/説明 | 文字数 | 例 |
---|---|---|---|---|
token | string | 認証トークン: モデル を参照 |
入力例
{
"token": "vq34rvyanho10q9hbc98ydbvaervna43r0varhj"
}
出力
204 No Content
検証に成功
※ レスポンスボディは空になります
400 Bad Request
{
"error": "TEST_ERROR_CODE"
}
INVALID_TOKEN
: トークンの検証に失敗.
404 Not Found
{
"error": "TEST_ERROR_CODE"
}
ACCOUNT_NOT_FOUND
: 指定した名前のアカウントは存在しない.
POST /login
✓
ログインして認証/更新トークンを作成します.
warning
認証トークンの有効期限は15分(900秒), 更新トークンの有効期限は30日(2,592,000秒)である. どちらのトークンも,APIサーバーが再起動されると無効になり,その場合は再度ログインする必要がある.
入力
- body:
application/json
項目名 | 型 | 制約/説明 | 文字数 | 例 |
---|---|---|---|---|
name | string | アカウント名 | 8≤N≤512[文字] | @[email protected] |
passphrase | string | パスフレーズ | 8≤N≤512 | じゃすた・いぐざんぽぅ , just~@_examp1e! |
captcha_token | string | Cloudflare Trunstileなどの検証トークン |
入力例
{
"name": "@[email protected]",
"passphrase": "じゃすた・いぐざんぽぅ",
"captcha_token": "hogehogehoge"
}
出力
200 OK
ログインしました
{
"authorization_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9. eyJzdWIiOiIzZTE2NDQ4MzMwMDAwMDIiLCJpYXQiOjE2NDA5OTUyMDEsInJlZnJlc2hfdG9rZW4iOiJleUpoYkdjaU9pSklVekkxTmlJc0luUjVjQ0k2SWtwWFZDSjkuZXlKemRXSWlPaUl6WlRFMk5EUTR Nek13TURBd01ESWlMQ0pwWVhRaU9qRTJOREE1T1RVeU1ERjkud2Q4cWJVcWowWGtCU1hud0FxM0lRYU1nQS1RTFd2MHVKU1NLX3BIVTZCYyJ9.mRUfLIYOGlLuC9D72zBriVvrHYrQgVHW7ntQ-bp5SHs",
"refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9. eyJzdWIiOiIzZTE2NDQ4MzMwMDAwMDIiLCJpYXQiOjE2NDA5OTUyMDEsInJlZnJlc2hfdG9rZW4iOiJleUpoYkdjaU9pSklVekkxTmlJc0luUjVjQ0k2SWtwWFZDSjkuZXlKemRXSWlPaUl6WlRFMk5EUTR Nek13TURBd01ESWlMQ0pwWVhRaU9qRTJOREE1T1RVeU1ERjkud2Q4cWJVcWowWGtCU1hud0FxM0lRYU1nQS1RTFd2MHVKU1NLX3BIVTZCYyJ9.mRUfLIYOGlLuC9D72zBriVvrHYrQgVHW7ntQ-bp5SHs",
"expires_in": 1672498800
}
項目名 | 型 | 制約/説明 | 文字数 | 例 |
---|---|---|---|---|
authorization_token | string | 認証トークン | ||
refresh_token | string | 更新トークン | ||
expires_in | number | 有効期限. Pulsate Epochからの秒数: モデル を参照. |
400 Bad Request
{
"error": "TEST_ERROR_CODE"
}
FAILED_TO_LOGIN
: パスフレーズかアカウント名が間違っているYOU_ARE_BOT
: captchaトークンの検証に失敗
403 Forbidden
{
"error": "TEST_ERROR_CODE"
}
YOU_ARE_FROZEN
: ログインしようとしたアカウントは凍結されている
POST /refresh
✓
更新トークンで認証トークンを再発行
入力
- body:
application/json
refresh_token
:string
- 更新トークン
項目名 | 型 | 制約/説明 | 文字数 | 例 |
---|---|---|---|---|
refresh_token | string | 更新トークン 参照 |
入力例
{
"refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIzZTE2NDQ4MzMwMDAwMDIiLCJpYXQiOjE2NDA5OTUyMDEsInJlZnJlc2hfdG9rZW4iOiJleUpoYkdjaU9pSklVekkxTmlJc0luUjVjQ0k2SWtwWFZDSjkuZXlKemRXSWlPaUl6WlRFMk5EUTRNek13TURBd01ESWlMQ0pwWVhRaU9qRTJOREE1T1RVeU1ERjkud2Q4cWJVcWowWGtCU1hud0FxM0lRYU1nQS1RTFd2MHVKU1NLX3BIVTZCYyJ9.mRUfLIYOGlLuC9D72zBriVvrHYrQgVHW7ntQ-bp5SHs"
}
出力
200 OK
ログインに成功した
{
"authorization_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIzZTE2NDQ4MzMwMDAwMDIiLCJpYXQiOjE2NDA5OTUyMDEsInJlZnJlc2hfdG9rZW4iOiJleUpoYkdjaU9pSklVekkxTmlJc0luUjVjQ0k2SWtwWFZDSjkuZXlKemRXSWlPaUl6WlRFMk5EUTRNek13TURBd01ESWlMQ0pwWVhRaU9qRTJOREE1T1RVeU1ERjkud2Q4cWJVcWowWGtCU1hud0FxM0lRYU1nQS1RTFd2MHVKU1NLX3BIVTZCYyJ9.mRUfLIYOGlLuC9D72zBriVvrHYrQgVHW7ntQ-bp5SHs"
}
項目名 | 型 | 制約/説明 | 文字数 | 例 |
---|---|---|---|---|
autorization_token | string | 認証トークン | ||
共通 を参照 |
400 Bad Request
{
"error": "TEST_ERROR_CODE"
}
INVALID_TOKEN
: 更新トークンが不正EXPIRED_TOKEN
: トークンの有効期限切れ
GET /accounts/{account_name}
✓
アカウント情報を取得
入力
- パスパラメータ
account_name
:string
- アカウント名
出力
200 OK
取得に成功
{
"id": "2874987398",
"name": "@[email protected]",
"nickname": "John Doe",
"bio": "I am Test User.",
"avatar": "https://example.com/images/avatar.png",
"header": "https://example.com/images/header.png",
"followed_count": 200,
"following_count": 10,
"note_count": 20000
}
項目名 | 型 | 制約/説明 | 文字数 | 例 |
---|---|---|---|---|
id | snowflake | アカウントID | 2934002842 | |
name | string | アカウント名 | 8≤N≤512[文字] | @[email protected] |
nickname | string | 表示名,アカウントの表示に用いる短い文字列 | 1≤N≤256 | JohnDoe<:json:299384730049> , ジョン・ドゥ🚉 |
bio | string | 自己紹介文. 0文字である場合はnullやundefinedではなくからの文字列である必要がある. | 0≤N≤1024 | "" (空文字列), いい感じの自己紹介🆓 ,This is bio hello^~ <:javascript:358409384> |
avatar | string | アカウントのアイコン画像のURL | ||
header | string | アカウントのヘッダー画像のURL | ||
followed_count | number | そのアカウントをフォローしている人数 | ||
following_count | number | そのアカウントがフォローしている人数 | ||
note_count | number | そのアカウントの投稿数 |
404 Not Found
{
"error": "TEST_ERROR_CODE"
}
ACCOUNT_NOT_FOUND
: 指定した名前のアカウントは存在しない
PUT /accounts/{account_name}/silence
✓
アカウントをサイレンスする.モデレータ以上の権限を持つアカウント認証情報が必要.
サイレンスされると以下のような挙動になる.
- 公開投稿(投稿範囲が
public
になる投稿)ができなくなる
入力
- パスパラメータ
account_name
:string
- アカウント名
- body:
application/json
- ボディは空オブジェクトである必要がある.
- 空でない場合,メンバは無視される.
入力例
{}
出力
204 No Content
凍結に成功
※レスポンスボディは空になる.
403 Forbidden
{
"error": "TEST_ERROR_CODE"
}
NO_PERMISSION
: アカウントをサイレンスできる権限がない.
404 Not Found
{
"error": "TEST_ERROR_CODE"
}
ACCOUNT_NOT_FOUND
: 指定した名前のアカウントは存在しない.
DELETE /accounts/{account_name}/silence
✓
アカウントをサイレンス解除
モデレータ以上の権限の持つアカウント認証情報が必要.
入力
- パスパラメータ
account_name
:string
- アカウント名
- body:
application/json
- オブジェクトは空である必要がある.
- 空でない場合,メンバは無視される.
入力例
{}
出力
204 No Content
サイレンスを解除
※レスポンスボディは空になる.
403 Forbidden
{
"error": "TEST_ERROR_CODE"
}
NO_PERMISSION
: アカウントをサイレンス解除できる権限がない
404 Not Found
{
"error": "TEST_ERROR_CODE"
}
ACCOUNT_NOT_FOUND
: 指定した名前のアカウントは存在しない
POST /accounts/{account_name}/follow
✓
指定したアカウントをフォロー
入力
- パスパラメータ
account_name
:string
- フォローしたいアカウント名
- body:
application/json
- 空オブジェクトを送信せよ
- 空でない場合のメンバは無視される
- 空オブジェクトを送信せよ
入力例
{}
出力
201 Accepted
フォローを受け付けた
{
"pending": true
}
- フォローする相手がフォローを手動承認制にしている場合はpendingがtrueになる.
- フォローする相手がフォローを手動承認制にしていない場合もある.
- この場合はpendingは必ず
false
になる.
- この場合はpendingは必ず
- フォローする相手がフォローを手動承認制にしていない場合もある.
- v2以降の予定: フォローする相手が同じインスタンスに所属していない場合はすべての場合でpendingがtrueになる.
400 Bad Request
{
"error": "TEST_ERROR_CODE"
}
ALREADY_FOLLOWING
: アカウントをすでにフォローしているYOU_ARE_BLOCKED
: 相手にブロックされている
404 Not Found
{
"error": "TEST_ERROR_CODE"
}
ACCOUNT_NOT_FOUND
: 指定した名前のアカウントは存在しない.
DELETE /accounts/{account_name}/follow
✓
フォローを解除します
入力
- パスパラメータ
account_name
:string
- フォロー解除したいアカウント名
- body:
application/json
- リクエストボディは空オブジェクトを送信せよ.
- 空でない場合のメンバは無視される.
- リクエストボディは空オブジェクトを送信せよ.
入力例
{}
出力
204 No Content
フォローを解除した.
※レスポンスボディは空になる.
400 Bad Request
{
"error": "TEST_ERROR_CODE"
}
YOU_
ARE_NOT_FOLLOW_ACCOUNT
: 指定したアカウントをフォローしていない
404 Not Found
{
"error": "TEST_ERROR_CODE"
}
ACCOUNT_NOT_FOUND
: 指定した名前のアカウントは存在しない
ドライブAPI
GET /drive
自分がアップロードした画像のリストを取得します
入力
なし
出力
200 OK
[
{
"id": "2938492384",
"name": "image.jpeg",
"author_id": "384880009940302",
"hash": "nf9:e;g711*c@drgj55",
"mime": "image/jpeg",
"nsfw": false,
"url": "https://images.example.com/image.jpeg",
"thumbnail": "https://images.example.com/thumb-image.jpeg"
}
]
項目名 | 型 | 説明 | 制約 | 例 |
---|---|---|---|---|
id | snowflake | ファイルのID | ||
name | string | ファイル名 | 1≤N≤256[文字] | |
author_id | snowflake | アップロードしたアカウントのID | ||
hash | string | 画像のblurhash | ||
mime | string | mimeタイプ | ||
nsfw | boolean | NSFWフラグ | ||
url | string | 画像へのリンク | ||
thumbnail | string , undefined | (利用可能な場合のみ) 縮小版のサムネイル画像 |
404 Not Found
{
"error": "TEST_ERROR_CODE"
}
FILE_NOT_FOUND
: ファイルが存在しません
POST /drive/
添付ファイルをアップロードします
入力
- body:
multipart/form-data
項目名 | 型 | 説明 | 制約 | 例 |
---|---|---|---|---|
name | string | ファイル名拡張子が必須 | 1≤N≤256[文字] | neko.png , 箱根駅伝.mp3 |
file | (ファイルの実体) | アップロードするファイル. アップロード可能なファイル種類は後述 | 1≤100 [MB] | |
nsfw | string ( "true", "false" ) | NSFWフラグ |
アップロード可能なファイル種類(mimeタイプ) mimeタイプについて詳しくは [https://www.iana.org/assignments/media-types/media-types.xhtml](https://www.iana.org/assignments/media-types/media-types.xhtml) を参照
画像:
image/apng
image/avif
image/gif
image/jpeg
image/png
image/webp
音声、動画:
audio/wave
,audio/wav
audio/webm
audio/mpeg
video/mpeg
video/webm
audio/ogg
出力
200 OK
アップロードが完了しました.
{
"id": "2938492384",
"name": "image.jpeg",
"author_id": "493094050",
"hash": "nf9:e;g711*c@drgj55",
"mime": "image/jpeg",
"nsfw": false,
"url": "https://images.example.com/image.jpeg",
"thumbnail": "https://images.example.com/thumb-image.jpeg"
}
項目名 | 型 | 説明 | 制約 | 例 |
---|---|---|---|---|
id | snowflake | ファイルのID | ||
name | string | ファイル名 | 1≤N≤256[文字] | |
author_id | snowflake | アップロードしたアカウントのID | ||
hash | string | 画像のblurhash | ||
mime | string | mimeタイプ | ||
nsfw | boolean | NSFWフラグ | ||
url | string | 画像へのリンク | ||
thumbnail | string , undefined | (利用可能な場合のみ) 縮小版のサムネイル画像 |
400 Bad Request
{
"error": "TEST_ERROR_CODE"
}
FILE_SIZE_TOO_BIG
: ファイルサイズが大きすぎますFILE_NAME_TOO_LONG
: ファイル名が長すぎます
DELETE /drive/{file_id}
指定したファイルを削除します
warning
ファイルを削除すると,紐付けられているすべてのノートに影響します.
入力
- パスパラメータ
file_id
:snowflake
- ファイルのID
出力
204 No Content
削除しました.
※レスポンスボディは空になります.
404 Not Found
{
"error": "TEST_ERROR_CODE"
}
FILE_NOT_FOUND
: ファイルが存在しません
GET /drive/{file_id}
ファイルのメタ情報を取得します
入力
- パスパラメータ
file_id
:snowflake
- ファイルのID
出力
200 OK
{
"id": "2938492384",
"name": "image.jpeg",
"author_id": "384880009940302",
"hash": "nf9:e;g711*c@drgj55",
"mime": "image/jpeg",
"nsfw": false,
"url": "https://images.example.com/image.jpeg",
"thumbnail": "https://images.example.com/thumb-image.jpeg"
}
項目名 | 型 | 説明 | 制約 | 例 |
---|---|---|---|---|
id | snowflake | ファイルのID | ||
name | string | ファイル名 | 1≤N≤256[文字] | |
author_id | snowflake | アップロードしたアカウントのID | ||
hash | string | 画像のblurhash | ||
mime | string | mimeタイプ | ||
nsfw | boolean | NSFWフラグ | ||
url | string | 画像へのリンク | ||
thumbnail | string , undefined | (利用可能な場合のみ) 縮小版のサムネイル画像 |
404 Not Found
{
"error": "TEST_ERROR_CODE"
}
FILE_NOT_FOUND
: ファイルが存在しません
PUT /drive/{file_id}
ファイルの情報を変更します
warning
情報を変更すると、そのファイルが紐付けられているすべてのノートに影響します
入力
-
パスパラメータ
file_id
:snowflake
- ファイルのID
-
body:
application/json
項目名 | 型 | 説明 | 制約 | 例 |
---|---|---|---|---|
nsfw | boolean | NSFWフラグ |
入力例
{
"nsfw": false
}
出力
200 OK
{
"id": "2938492384",
"name": "image.jpeg",
"author_id": "384880009940302",
"hash": "nf9:e;g711*c@drgj55",
"mime": "image/jpeg",
"nsfw": false,
"url": "https://images.example.com/image.jpeg",
"thumbnail": "https://images.example.com/thumb-image.jpeg"
}
項目名 | 型 | 説明 | 制約 | 例 |
---|---|---|---|---|
id | snowflake | ファイルのID | ||
name | string | ファイル名 | 1≤N≤256[文字] | |
author_id | snowflake | アップロードしたアカウントのID | ||
hash | string | 画像のblurhash | ||
mime | string | mimeタイプ | ||
nsfw | boolean | NSFWフラグ | ||
url | string | 画像へのリンク | ||
thumbnail | string , undefined | (利用可能な場合のみ) 縮小版のサムネイル画像 |
404 Not Found
{
"error": "TEST_ERROR_CODE"
}
FILE_NOT_FOUND
: ファイルが存在しません
項目名 | 型 | 説明 | 制約 | 例 |
---|---|---|---|---|
id | snowflake | ファイルのID | ||
name | string | ファイル名 | 1≤N≤256[文字] | |
author_id | snowflake | アップロードしたアカウントのID | ||
hash | string | 画像のblurhash | ||
mime | string | mimeタイプ | ||
nsfw | boolean | NSFWフラグ | ||
url | string | 画像へのリンク | ||
thumbnail | string , undefined | (利用可能な場合のみ) 縮小版のサムネイル画像 |
リストAPI
POST /lists/
リストを作成します
入力
- body:
application/json
項目名 | 型 | 説明 | 制約 | 例 |
---|---|---|---|---|
title | string | リストのタイトル | 1≤N≤100[文字] | |
public | boolean | デフォルト: false (非公開) 公開: リストにアサインされたアカウントには通知が飛びます. 非公開: 通知は飛ばず、自分以外のアカウントからは見えません |
入力例
{
"title": "Pulsate Developers",
"public": false
}
出力
200 OK
{
"id": "18342938400393",
"title": "Pulsate Developers",
"public": false
}
400 Bad Request
{
"error": "TEST_ERROR_CODE"
}
TITLE_TOO_LONG
: タイトルが長すぎます
PATCH /lists/{list_id}
リスト情報を編集します
入力
-
パスパラメータ
list_id
:string
- 編集したいリストのID
-
body:
application/json
項目名 | 型 | 説明 | 制約 |
---|---|---|---|
title | string | リストのタイトル | 1≤N≤100[文字] |
public | boolean | 公開・非公開のフラグ |
入力例
{
"title": "Edited Title",
"public": true
}
出力
200 OK
{
"id": "18342938400393",
"title": "Edited Title",
"public": true,
"assignees": [
{
"id": "1838933554",
"name": "@[email protected]"
}
]
}
404 Not Found
{
"error": "TEST_ERROR_CODE"
}
LIST_NOTFOUND
: リストが見つかりません
400 Bad Request
{
"error": "TEST_ERROR_CODE"
}
TITLE_TOO_LONG
: タイトルが長すぎます
GET /lists/{list_id}
リスト情報を取得します
入力
- パスパラメータ
list_id
:string
- 取得したいリストのID
出力
200 OK
{
"id": "18342938400393",
"title": "Pulsate Developers",
"public": false,
"assignees": [
{
"id": "1838933554",
"name": "@[email protected]"
}
]
}
404 Not Found
{
"error": "TEST_ERROR_CODE"
}
LIST_NOTFOUND
: リストが見つかりません
GET /lists/accounts/{account_id}
アカウントが持つリストを取得します
入力
- パスパラメータ
account_id
:snowflake
- アカウントのID
出力
200 OK
[
{
"id": "18342938400393",
"title": "Pulsate Developers",
"public": false,
"assignees": [
{
"id": "1838933554",
"name": "@[email protected]"
}
]
}
]
404 Not Found
{
"error": "TEST_ERROR_CODE"
}
ACCOUNT_NOT_FOUND
: ユーザーが存在しませんLIST_NOTFOUND
: リストが見つかりません
POST /lists/{list_id}
リストにアカウントをアサインします
入力
- パスパラメータ
list_id
:string
- リストのID
- body:
application/json
- account_id:
Array<
snowflake>
- アカウントID
- 一度にアサインできる最大アカウント数: 30
- account_id:
出力
200 OK
{
"account_id": [
"389384553329569",
"586039500493885",
"4847377595"
]
}
400 Bad Request
{
"error": "TEST_ERROR_CODE"
}
TOO_MANY_TARGETS
: アサインするアカウント数が多すぎます
404 Not Found
{
"error": "TEST_ERROR_CODE"
}
ACCOUNT_NOT_FOUND
: アカウントが存在しませんLIST_NOTFOUND
: リストが見つかりません
DELETE /lists/{list_id}
リストからアカウントを削除します
入力
- パスパラメータ
list_id
:string
- リストのID
- body:
application/json
- account_id:
Array<
snowflake>
- 削除するアカウントのID
- 一度に削除できるアカウント数: 30
- account_id:
入力例
{
"account_id": [
"389384553329569",
"586039500493885",
"4847377595"
]
}
出力
204 No Content
削除しました.
※レスポンスボディは空になります.
400 Bad Request
{
"error": "TEST_ERROR_CODE"
}
TOO_MANY_TARGETS
: 削除するアカウント数が多すぎます
404 Not Found
{
"error": "TEST_ERROR_CODE"
}
ACCOUNT_NOT_FOUND
: アカウントが存在しませんLIST_NOTFOUND
: リストが見つかりません
DELETE /lists/{list_id}
リストを削除します.
入力
- パスパラメータ
list_id
:string
- リストのID
出力
204 No Content
削除しました.
※レスポンスボディは空になります.
404 Not Found
{
"error": "TEST_ERROR_CODE"
}
LIST_NOTFOUND
: リストが見つかりません
GET /lists/{list_id}/notes
リストのノートを取得します.
入力
- パスパラメータ
list_id
:snowflake
- リストのID
- クエリパラメータ
has_attachment
:bool | undefined
- デフォルト:
false
- ファイルを含む投稿のみを返します
- デフォルト:
no_nsfw
:bool | undefined
- デフォルト:
false
- NSFWフラグの立っているファイルを含む投稿を返さなくなります
- デフォルト:
before_id
: ``snowflake| undefined
- デフォルト:
undefined
- デフォルトでは現在取得できる最新の投稿から20件取得します.
- 指定したIDより古い投稿を返します.指定したIDの投稿は含まれません
- デフォルト:
出力
200 OK
取得に成功しました
[
{
"id": "3893974892",
"content": "hello world!",
"cw_comment": "",
"visibility": "public",
"created_at": "2023-09-27T14:17:29.169Z",
"attachment_files": [
{
"id": "204980348583",
"filename": "hello.png",
"content_type": "image/png",
"url": "https://example.com/images/hello.png",
"blur": "eoig:woi!our@nj/d",
"nsfw": false
}
],
"reactions": [
{
"emoji": "<:alias:11938437>",
"reacted_by": "3085763644"
},
{
"emoji": "🎉",
"reacted_by": "494984128"
}
],
"author": {
"id": "2874987398",
"name": "@[email protected]",
"display_name": "John Doe",
"bio": "I am Test User.",
"avatar": "https://example.com/images/avatar.png",
"header": "https://example.com/images/header.png",
"followed_count": 200,
"following_count": 10
}
}
]
404 Not Found
{
"error": "TEST_ERROR_CODE"
}
LIST_NOTFOUND
: リストが見つかりませんNOTHING_LEFT
: これ以上古い投稿はありません- 1つでも古い投稿がある場合は投稿を返します
投稿API
note
投稿は”ノート”, 再投稿は”リノート”と言い換えられている場合があります.
ダイレクト投稿: ノートのうち,公開範囲がダイレクトに指定されているもの
POST /notes
ノートを作成
入力
- body:
application/json
項目名 | 型 | 制約/説明 | 数制約 | 例 |
---|---|---|---|---|
content | string | 投稿本文添付ファイルが存在する場合は0文字を許容 | 1≤3000[文字] | |
visibility | string , undefined | 投稿の公開範囲 デフォルト: public とり得る値: public home followers , direct | - | |
attachment_file_ids | Array<snowflake>, undefined | 投稿の添付ファイルID 1つでもファイルが存在しない場合はエラー終了する | 0≤N≤16[個] | |
cw_comment | string | CW時の注釈. CW/CWフラグ 参照デフォルトは空文字列 | 0≤N≤256[文字] | |
send_to | snowflake , undefined | ダイレクト投稿の宛先公開範囲がdirect のときのみ指定可能 |
入力例
{
"content": "hello world!",
"visibility": "public",
"attachment_file_ids": [
"11938472"
],
"cw_comment": ""
}
{
"content": "hello world!",
"visibility": "direct",
"attachment_file_ids": [
"11938472"
],
"cw_comment": "",
"send_to": "8585030584"
}
出力
201 Created
投稿を作成しました.
{
"id": "3893974892",
"content": "hello world!",
"cw_comment": "",
"visibility": "public",
"created_at": "2023-09-27T14:17:29.169Z",
"attachment_files": [
{
"id": "11938472",
"filename": "hello.png",
"content_type": "image/png",
"url": "https://example.com/images/hello.png",
"blur": "eoig:woi!our@nj/d",
"nsfw": false
}
]
}
項目名 | 型 | 説明 | 数制約 | 例 |
---|---|---|---|---|
id | snowflake | 投稿のID | ||
content | string | 投稿本文. 添付ファイルが存在する場合は0文字を許容 | 1≤3000[文字] | |
visibility | string | 投稿の公開範囲. デフォルト: public . とり得る値: public home followers direct | - | |
attachment_files | Array<object> | 投稿の添付ファイルのオブジェクト (後述) | 0≤N≤16[個] | |
cw_comment | string | CW時の注釈, 参照 デフォルトは空文字列 | 0≤N≤256[文字] | |
send_to | Snowflake, undefined | ダイレクト投稿の宛先. 公開範囲がdirectのときのみ指定可能 | ||
created_at | string | 投稿の送信日時 |
- 添付ファイル (
attchment_files
)
項目名 | 型 | 説明 | 数制約 | 例 |
---|---|---|---|---|
id | snowflake | 投稿のID | ||
filename | string | ファイル名 | 3≤N≤256[文字] | |
content_type | string | mimeタイプ | ||
url | string | 添付ファイルのURL | ||
blurhash | string , undefined | 添付ファイルが画像であるときのサムネイルの blurhash | ||
nsfw | boolean | ToDo |
400 Bad Request
{
"error": "TEST_ERROR_CODE"
}
TOO_MANY_ATTACHMENTS
: 添付ファイルが制限を超過TOO_MANY_C
ONTENT`` : CW注釈/投稿本文の文字数制限を超過NO_DESTINATION
: 公開範囲がdirectのノートでsend_toが指定されていないINVALID_VISIBILITY
: 公開範囲が正しい形式でない
403 Forbidden
{
"error": "TEST_ERROR_CODE"
}
YOU_ARE_SILENCED
: サイレンスされている際に公開範囲をpublic
に指定した場合
404 Not Found
{
"error": "TEST_ERROR_CODE"
}
ATTACHMENT_NOT_FOUND
: 添付したファイルが存在しないACCOUNT_NOT_FOUND
: 宛先(send_to)に指定したアカウントが存在しない
GET /notes/{note_id}
特定の投稿を取得します.
入力
- パスパラメータ
note_id
:string
- 取得したい投稿のID
出力例
200 OK
投稿を取得しました.
{
"id": "3893974892",
"content": "hello world!",
"cw_comment": "",
"visibility": "public",
"created_at": "2023-09-27T14:17:29.169Z",
"attachment_files": [
{
"id": "204980348583",
"filename": "hello.png",
"content_type": "image/png",
"url": "https://example.com/images/hello.png",
"blur": "eoig:woi!our@nj/d",
"nsfw": false
}
],
"reactions": [
{
"emoji": "<:alias:11938437>",
"reacted_by": "3085763644"
},
{
"emoji": "🎉",
"reacted_by": "494984128"
}
],
"author": {
"id": "2874987398",
"name": "@[email protected]",
"display_name": "John Doe",
"bio": "I am Test User.",
"avatar": "https://example.com/images/avatar.png",
"header": "https://example.com/images/header.png",
"followed_count": 200,
"following_count": 10
}
}
項目名 | 型 | 説明 | 数制約 | 例 |
---|---|---|---|---|
id | snowflake | 投稿のID |
404 Not Found
{
"error": "TEST_ERROR_CODE"
}
NOTE_NOT_FOUND
: 指定したIDのノートが存在しない- 指定したIDのノートを(アクセスしたユーザーが)取得できない場合もこのエラーを返す.
POST /notes/{note_id}/renote
指定したIDのノートをリノートします.
入力
- パスパラメータ
note_id
:string
- 取得したい投稿のID
- body:
application/json
項目名 | 型 | 説明 | 数制約 | 例 |
---|---|---|---|---|
id | snowflake | 投稿のID | ||
content | string | 投稿本文. 添付ファイルが存在する場合は0文字を許容 | 1≤3000[文字] | |
visibility | string | 投稿の公開範囲. デフォルト: public . とり得る値: public home followers direct | - | |
attachment_files | Array<object> | 投稿の添付ファイルのオブジェクト (後述) | 0≤N≤16[個] | |
cw_comment | string | CW時の注釈, 参照 デフォルトは空文字列 | 0≤N≤256[文字] | |
send_to | Snowflake, undefined | ダイレクト投稿の宛先. 公開範囲がdirectのときのみ指定可能 | ||
created_at | string | 投稿の送信日時 |
attachment_files
:
項目名 | 型 | 説明 | 数制約 | 例 |
---|---|---|---|---|
id | snowflake | 投稿のID | ||
filename | string | ファイル名 | ToDo | |
content_type | string | mimeタイプ | ||
ToDo | ||||
url | string | 添付ファイルのURL | ||
blur | string | 添付ファイルが画像であるときのサムネイルの blurhash | ||
nsfw | boolean | ToDo |
入力例
{
"content": "hello world!",
"visibility": "public",
"attachment_file_ids": [
"11938472"
],
"cw_comment": ""
}
出力
200 OK
リノートしました
{
"id": "3893974892",
"content": "hello world!",
"cw_comment": "",
"visibility": "public",
"renote_id": "4973874850",
"created_at": "2023-09-27T14:17:29.169Z",
"attachment_files": [
{
"id": "11938472",
"filename": "hello.png",
"content_type": "image/png",
"url": "https://example.com/images/hello.png",
"blur": "eoig:woi!our@nj/d",
"nsfw": false
}
]
}
項目名 | 型 | 説明 | 数制約 | 例 |
---|---|---|---|---|
id | snowflake | 投稿のID | ||
content | string | 投稿本文. 添付ファイルが存在する場合は0文字を許容 | 1≤3000[文字] | |
visibility | string | 投稿の公開範囲. デフォルト: public . とり得る値: public home followers direct | - | |
attachment_files | Array<object> | 投稿の添付ファイルのオブジェクト (後述) | 0≤N≤16[個] | |
cw_comment | string | CW時の注釈, 参照 デフォルトは空文字列 | 0≤N≤256[文字] | |
send_to | Snowflake, undefined | ダイレクト投稿の宛先. 公開範囲がdirectのときのみ指定可能 | ||
created_at | string | 投稿の送信日時 |
項目名 | 型 | 説明 | 数制約 | 例 |
---|---|---|---|---|
id | snowflake | 投稿のID | ||
filename | string | ファイル名 | ToDo | |
content_type | string | mimeタイプ | ||
ToDo | ||||
url | string | 添付ファイルのURL | ||
blur | string | 添付ファイルが画像であるときのサムネイルの blurhash | ||
nsfw | boolean | ToDo |
400 Bad Request
{
"error": "TEST_ERROR_CODE"
}
TOO_MANY_CHAR_LENGTH
: CW注釈/投稿本文の文字数制限を超過INVALID_VISIBILITY
: 公開範囲が正しい形式でないNO_DESTINATION
: 公開範囲がdirectのノートでsend_toが指定されていない
403 Forbidden
{
"error": "TEST_ERROR_CODE"
}
YOU_ARE_SILENCED
: サイレンスされている際に公開範囲をpublic
に指定した
404 Not Found
{
"error": "TEST_ERROR_CODE"
}
ATTACHMENT_NOT_FOUND
: 添付したファイルが存在しないNOTE_NOT_FOUND
: ノートが存在しない
POST /notes/{note_id}/reply
指定したIDのノートに返信します.
入力
- パスパラメータ
note_id
:string
- 取得したい投稿のID
- body:
application/json
項目名 | 型 | 説明 | 数制約 | 例 |
---|---|---|---|---|
id | snowflake | 投稿のID | ||
content | string | 投稿本文. 添付ファイルが存在する場合は0文字を許容 | 1≤3000[文字] | |
visibility | string | 投稿の公開範囲. デフォルト: public . とり得る値: public home followers direct | - | |
attachment_files | Array<object> | 投稿の添付ファイルのオブジェクト (後述) | 0≤N≤16[個] | |
cw_comment | string | CW時の注釈, 参照 デフォルトは空文字列 | 0≤N≤256[文字] | |
created_at | string | 投稿の送信日時 |
attachment_files
:
項目名 | 型 | 説明 | 数制約 | 例 |
---|---|---|---|---|
id | snowflake | 投稿のID | ||
filename | string | ファイル名 | ToDo | |
content_type | string | mimeタイプ | ||
ToDo | ||||
url | string | 添付ファイルのURL | ||
blur | string | 添付ファイルが画像であるときのサムネイルの blurhash | ||
nsfw | boolean | ToDo |
入力例
{
"content": "hello world!",
"visibility": "public",
"attachment_file_ids": [
"11938472"
],
"cw_comment": ""
}
出力
200 OK
投稿を作成しました.
{
"id": "3893974892",
"content": "hello world!",
"cw_comment": "",
"reply_to": "2948933000",
"visibility": "public",
"created_at": "2023-09-27T14:17:29.169Z",
"attachment_files": [
{
"id": "11938472",
"filename": "hello.png",
"content_type": "image/png",
"url": "https://example.com/images/hello.png",
"blur": "eoig:woi!our@nj/d",
"nsfw": false
}
]
}
項目名 | 型 | 説明 | 数制約 | 例 |
---|---|---|---|---|
id | snowflake | 投稿のID | ||
content | string | 投稿本文. 添付ファイルが存在する場合は0文字を許容 | 1≤3000[文字] | |
visibility | string | 投稿の公開範囲. デフォルト: public . とり得る値: public home followers direct | - | |
attachment_files | Array<object> | 投稿の添付ファイルのオブジェクト (後述) | 0≤N≤16[個] | |
cw_comment | string | CW時の注釈, 参照 デフォルトは空文字列 | 0≤N≤256[文字] | |
send_to | Snowflake, undefined | ダイレクト投稿の宛先. 公開範囲がdirectのときのみ指定可能 | ||
created_at | string | 投稿の送信日時 |
項目名 | 型 | 説明 | 数制約 | 例 |
---|---|---|---|---|
id | snowflake | 投稿のID | ||
filename | string | ファイル名 | ToDo | |
content_type | string | mimeタイプ | ||
ToDo | ||||
url | string | 添付ファイルのURL | ||
blur | string | 添付ファイルが画像であるときのサムネイルの blurhash | ||
nsfw | boolean | ToDo |
400 Bad Request
{
"error": "TEST_ERROR_CODE"
}
TOO_MANY_CHAR_LENGTH
: CW注釈/投稿本文の文字数制限を超過INVALID_VISIBILITY
: 公開範囲が正しい形式でない
403 Forbidden
{
"error": "TEST_ERROR_CODE"
}
YOU_ARE_SILENCED
: サイレンスされている際に公開範囲をpublic
に指定したYOU_ARE_BLOCKED
: 返信先ユーザーにブロックされている
404 Not Found
{
"error": "TEST_ERROR_CODE"
}
ATTACHMENT_NOT_FOUND
: 添付したファイルが存在しないNOTE_NOT_FOUND
: ノートが存在しない
DELETE /notes/{note_id}
投稿を削除します.
NOTICE: 自分以外のノートを削除する場合はモデレータ以上の資格情報が必要です.
入力
- パスパラメータ
note_id
:string
- 削除するノートのID
出力
204 No Content
削除しました.
※ レスポンスボディは空になります
403 Forbidden
{
"error": "TEST_ERROR_CODE"
}
NO_PERMISSION
: ノートの投稿者でないため削除できない
404 Not Found
{
"error": "TEST_ERROR_CODE"
}
NOTE_NOT_FOUND
: 削除するノートが存在しない
POST /notes/{note_id}/reaction
指定したノートにリアクションします.
入力
- パスパラメータ
note_id
:string
- リアクションしたい投稿のID
body: application/json
項目名 | 型 | 説明 | 例 |
---|---|---|---|
emoji | string | 絵文字 | |
表記法は カスタム絵文字 を参照 | <:alias:11938437> | ||
🎉 |
入力例
{
"emoji": "🎉"
}
{
"emoji": "<:awesome:489395643749>"
}
出力
200 OK
リアクションしました.
{
"id": "3893974892",
"content": "hello world!",
"cw_comment": "",
"visibility": "public",
"created_at": "2023-09-27T14:17:29.169Z",
"attachment_files": [
{
"id": "204980348583",
"filename": "hello.png",
"content_type": "image/png",
"url": "https://example.com/images/hello.png",
"blur": "eoig:woi!our@nj/d",
"nsfw": false
}
],
"reactions": [
{
"emoji": "<:alias:11938437>",
"reacted_by": "3085763644"
},
{
"emoji": "🎉",
"reacted_by": "494984128"
}
],
"author": {
"id": "2874987398",
"name": "@[email protected]",
"display_name": "John Doe",
"bio": "I am Test User.",
"avatar": "https://example.com/images/avatar.png",
"header": "https://example.com/images/header.png",
"followed_count": 200,
"following_count": 10
}
}
項目名 | 型 | 説明 | 数制約 | 例 |
---|---|---|---|---|
id | snowflake | 投稿のID | ||
content | string | 投稿本文. 添付ファイルが存在する場合は0文字を許容 | 1≤3000[文字] | |
visibility | string | 投稿の公開範囲. デフォルト: public . とり得る値: public home followers direct | - | |
attachment_files | Array<object> | 投稿の添付ファイルのオブジェクト (後述) | 0≤N≤16[個] | |
cw_comment | string | CW時の注釈, 参照 デフォルトは空文字列 | 0≤N≤256[文字] | |
send_to | Snowflake, undefined | ダイレクト投稿の宛先. 公開範囲がdirectのときのみ指定可能 | ||
created_at | string | 投稿の送信日時 |
attachment_files
:
項目名 | 型 | 説明 | 数制約 | 例 |
---|---|---|---|---|
id | snowflake | 投稿のID | ||
filename | string | ファイル名 | ToDo | |
content_type | string | mimeタイプ | ||
ToDo | ||||
url | string | 添付ファイルのURL | ||
blur | string | 添付ファイルが画像であるときのサムネイルの blurhash | ||
nsfw | boolean | ToDo |
reactions
:
項目名 | 型 | 説明 | 例 |
---|---|---|---|
emoji | string | 絵文字. 表記法は 絵文字の扱い を参照 | 🎉 , <:alias:11938437> |
reacted_by | snowflake | リアクションしたアカウントID | 48499372 |
400
Bad Request
{
"error": "TEST_ERROR_CODE"
}
ALREADY_REACTED
: すでにリアクション済みEMOJI_NOT_FOUND
: 指定した絵文字が存在しない(カスタム絵文字のみ)/複数指定している(Unicode絵文字
404 Not Found
{
"error": "TEST_ERROR_CODE"
}
NOTE_NOT_FOUND
: リアクションするノートが存在しない
DELETE /notes/{note_id}/reaction
指定したノートにつけたリアクションを解除します
入力
- パスパラメータ
note_id
:string
- リアクションしたい投稿のID
出力
204 No Content
削除しました.
※ レスポンスボディは空になります.
400 Forbidden
{
"error": "TEST_ERROR_CODE"
}
NOT_REACTED
: リアクションしていない
404 Not Found
{
"error": "TEST_ERROR_CODE"
}
NOTE_NOT_FOUND
: ノートが存在しない
POST /notes/{note_id}/bookmark
指定した投稿をブックマークします
入力
- パスパラメータ
note_id
:string
- リアクションしたい投稿のID
出力
200 OK
ブックマークしました
{
"id": "3893974892",
"content": "hello world!",
"cw_comment": "",
"visibility": "public",
"created_at": "2023-09-27T14:17:29.169Z",
"attachment_files": [
{
"id": "204980348583",
"filename": "hello.png",
"content_type": "image/png",
"url": "https://example.com/images/hello.png",
"blur": "eoig:woi!our@nj/d",
"nsfw": false
}
],
"reactions": [
{
"emoji": "<:alias:11938437>",
"reacted_by": "3085763644"
},
{
"emoji": "🎉",
"reacted_by": "494984128"
}
],
"author": {
"id": "2874987398",
"name": "@[email protected]",
"display_name": "John Doe",
"bio": "I am Test User.",
"avatar": "https://example.com/images/avatar.png",
"header": "https://example.com/images/header.png",
"followed_count": 200,
"following_count": 10
}
}
項目名 | 型 | 説明 | 数制約 | 例 |
---|---|---|---|---|
id | snowflake | 投稿のID | ||
content | string | 投稿本文. 添付ファイルが存在する場合は0文字を許容 | 1≤3000[文字] | |
visibility | string | 投稿の公開範囲. デフォルト: public . とり得る値: public home followers direct | - | |
attachment_files | Array<object> | 投稿の添付ファイルのオブジェクト (後述) | 0≤N≤16[個] | |
cw_comment | string | CW時の注釈, 参照 デフォルトは空文字列 | 0≤N≤256[文字] | |
send_to | Snowflake, undefined | ダイレクト投稿の宛先. 公開範囲がdirectのときのみ指定可能 | ||
created_at | string | 投稿の送信日時 |
attachment_files
:
項目名 | 型 | 説明 | 数制約 | 例 |
---|---|---|---|---|
id | snowflake | 投稿のID | ||
filename | string | ファイル名 | ToDo | |
content_type | string | mimeタイプ | ||
ToDo | ||||
url | string | 添付ファイルのURL | ||
blur | string | 添付ファイルが画像であるときのサムネイルの blurhash | ||
nsfw | boolean | ToDo |
reactions
:
項目名 | 型 | 説明 | 例 |
---|---|---|---|
emoji | string | 絵文字 | |
表記法は 絵文字の扱い を参照 | <:alias:11938437 | ||
🎉 | |||
reacted_by | snowflake | リアクションしたアカウントID | 48499372 |
404 Not Found
{
"error": "TEST_ERROR_CODE"
}
NOTE_NOT_FOUND
: ノートが存在しない
DELETE /notes/{note_id}/bookmark
指定した投稿をブックマーク解除します
入力
- パスパラメータ
note_id
:string
- ブックマーク解除したい投稿のID
出力
204 No Content
ブックマーク解除しました
※レスポンスボディは空になります.
404 Not Found
{
"error": "TEST_ERROR_CODE"
}
NOTE_NOT_FOUND
: ノートが存在しない
項目名 | 型 | 説明 | 数制約 | 例 |
---|---|---|---|---|
id | snowflake | 投稿のID | ||
content | string | 投稿本文. 添付ファイルが存在する場合は0文字を許容 | 1≤3000[文字] | |
visibility | string | 投稿の公開範囲. デフォルト: public . とり得る値: public home followers direct | - | |
attachment_files | Array<object> | 投稿の添付ファイルのオブジェクト (後述) | 0≤N≤16[個] | |
cw_comment | string | CW時の注釈, 参照 デフォルトは空文字列 | 0≤N≤256[文字] | |
send_to | Snowflake, undefined | ダイレクト投稿の宛先. 公開範囲がdirectのときのみ指定可能 | ||
created_at | string | 投稿の送信日時 |
項目名 | 型 | 説明 | 数制約 | 例 |
---|---|---|---|---|
id | snowflake | 投稿のID | ||
filename | string | ファイル名 | ToDo | |
content_type | string | mimeタイプ | ||
ToDo | ||||
url | string | 添付ファイルのURL | ||
blur | string | 添付ファイルが画像であるときのサムネイルの blurhash | ||
nsfw | boolean | ToDo |
項目名 | 型 | 説明 | 例 |
---|---|---|---|
emoji | string | 絵文字 | |
表記法は 絵文字の扱い を参照 | <:alias:11938437 | ||
🎉 | |||
reacted_by | snowflake | リアクションしたアカウントID | 48499372 |
検索API
クエリ
ベースは Twitter v2 のクエリ.
オペレータ
Operator | 意味 | 例 | 単独使用可能 |
---|---|---|---|
keyword | 特定のキーワードを含む | 松江 AND どこ | yes |
"" | 文字列の完全一致 | "造幣局 桜" | yes |
from: | 特定ユーザーによるノート | from:@[email protected] or from:@[email protected] | yes |
is:renote | リノート | hello world -is:renote | no |
is:quote | 引用リノート | #筑後川花火大会 is:quote | no |
has:link | 本文にリンクを含むノート | nowplaying has:link | no |
has:media | 添付ファイルを含むノート | #徳川家康 has:media | no |
演算子
演算子 | 説明 |
---|---|
AND | スペースを挟んで連続する演算子はAND 論理演算となり、両方の条件を満たしたノートが返されます |
OR | OR を挟んで連続する演算子はOR論理演算となり、どちらかの条件を満たしたノートが返されます. |
- | キーワードの前にハイフンをつけると、そのキーワードを論理否定することができます. |
() | カッコでくくると演算子をグループ化できます. AND>ORの順で適用されます. |
GET /search/notes
投稿を検索します. 返す最大件数は100件です
入力
- クエリパラメータ
query
:string
- 検索クエリ
- 上記の内容を受け取ります
出力
200 OK
検索に成功
出力の内容はタイムラインと同一である.
[
{
"id": "3893974892",
"content": "hello world!",
"cw_comment": "",
"visibility": "public",
"created_at": "2023-09-27T14:17:29.169Z",
"attachment_files": [
{
"id": "204980348583",
"filename": "hello.png",
"content_type": "image/png",
"url": "https://example.com/images/hello.png",
"blur": "eoig:woi!our@nj/d",
"nsfw": false
}
],
"reactions": [
{
"emoji": "<:alias:11938437>",
"reacted_by": "3085763644"
},
{
"emoji": "🎉",
"reacted_by": "494984128"
}
],
"author": {
"id": "2874987398",
"name": "@[email protected]",
"display_name": "John Doe",
"bio": "I am Test User.",
"avatar": "https://example.com/images/avatar.png",
"header": "https://example.com/images/header.png",
"followed_count": 200,
"following_count": 10
}
}
]
400 Bad Request
{
"error": "TEST_ERROR_CODE"
}
INVALID_QUERY
: クエリが正しくありません
タイムラインAPI
warning
取得した投稿は時系列順にソートされた状態で返されます.
一度に取得できる件数は最大20件です.
GET /timeline/{timeline_type}
タイムラインを取得します.
入力
- パスパラメータ
timeline_type
:string
,undefined
- とり得る値:
home
/global
- デフォルト:
home
- とり得る値:
- クエリパラメータ
has_attachment
:bool | undefined
- デフォルト:
false
- ファイルを含む投稿のみを返します
- デフォルト:
no_nsfw
:bool | undefined
- デフォルト:
false
- NSFWフラグの立っているファイルを含む投稿を返さなくなります
- デフォルト:
before_id
:snowflake| undefined
- デフォルト:
undefined
デフォルトでは現在取得できる最新の投稿から20件取得します.
- 指定したIDより古い投稿を返します.指定したIDの投稿は含まれません
- デフォルト:
出力
200 OK
タイムラインを取得します.
[
{
"id": "3893974892",
"content": "hello world!",
"cw_comment": "",
"visibility": "public",
"created_at": "2023-09-27T14:17:29.169Z",
"attachment_files": [
{
"id": "204980348583",
"filename": "hello.png",
"content_type": "image/png",
"url": "https://example.com/images/hello.png",
"blur": "eoig:woi!our@nj/d",
"nsfw": false
}
],
"reactions": [
{
"emoji": "<:alias:11938437>",
"reacted_by": "3085763644"
},
{
"emoji": "🎉",
"reacted_by": "494984128"
}
],
"author": {
"id": "2874987398",
"name": "@[email protected]",
"display_name": "John Doe",
"bio": "I am Test User.",
"avatar": "https://example.com/images/avatar.png",
"header": "https://example.com/images/header.png",
"followed_count": 200,
"following_count": 10
}
}
]
400 Bad Request
{
"error": "TEST_ERROR_CODE"
}
INVALID_TIMELINE_TYPE
: 指定したタイムラインタイプは存在しません
404 Not Found
{
"error": "TEST_ERROR_CODE"
}
NOTHING_LEFT
: これ以上古い投稿はありません- 1つでも古い投稿がある場合は投稿を返します
GET /timeline/accounts/{account_id|account_name}
特定のユーザーの投稿を取得します.
入力
- パスパラメータ
account_id,account_name
:snowflake
|string
- アカウント名かアカウントのIDを指定できます.
- クエリパラメータ
has_attachment
:bool | undefined
- デフォルト:
false
- ファイルを含む投稿のみを返します
- デフォルト:
no_nsfw
:bool | undefined
- デフォルト:
false
- NSFWフラグの立っているファイルを1つでも含む投稿を返さなくなります
- デフォルト:
before_id
:snowflake
| undefined`- デフォルト:
undefined
- デフォルトでは現在取得できる最新の投稿から20件取得します.
- 指定したIDより古い投稿を返します.指定したIDの投稿は含まれません
- デフォルト:
出力
200 OK
タイムラインを取得します.
[
{
"id": "3893974892",
"content": "hello world!",
"cw_comment": "",
"visibility": "public",
"created_at": "2023-09-27T14:17:29.169Z",
"attachment_files": [
{
"id": "204980348583",
"filename": "hello.png",
"content_type": "image/png",
"url": "https://example.com/images/hello.png",
"blur": "eoig:woi!our@nj/d",
"nsfw": false
}
],
"reactions": [
{
"emoji": "<:alias:11938437>",
"reacted_by": "3085763644"
},
{
"emoji": "🎉",
"reacted_by": "494984128"
}
],
"author": {
"id": "2874987398",
"name": "@[email protected]",
"display_name": "John Doe",
"bio": "I am Test User.",
"avatar": "https://example.com/images/avatar.png",
"header": "https://example.com/images/header.png",
"followed_count": 200,
"following_count": 10
}
}
]
400 Bad Request
{
"error": "TEST_ERROR_CODE"
}
INVALID_TIMELINE_TYPE
: 指定したタイムラインタイプは存在しません
403 Forbidden
{
"error": "TEST_ERROR_CODE"
}
YOU_ARE_BLOCKED
: 指定したアカウントにブロックされています.
404 Not Found
{
"error": "TEST_ERROR_CODE"
}
NOTHING_LEFT
: これ以上古い投稿はありません- 1つでも古い投稿がある場合は投稿を返します
ACCOUNT_NOT_FOUND
: 指定したアカウントが見つかりませんでした
GET /timeline/conversations
ダイレクト投稿を受け取った、もしくは送った相手を取得します.
入力
なし
出力
200 OK
[
{
"account": {
"accountId": "20983985",
"accountName": "@[email protected]",
"nickname": "John Doe",
"avatar": "https://example.com/images/avatar.png"
},
"updatedAt": "2023-09-10T00:00:00.000Z"
}
]
GET /timeline/conversations/{account_id}
指定したアカウントとのダイレクト投稿を取得します.
入力
- パスパラメータ
account_id
:snowflake
- ダイレクト投稿を取得したいアカウントID.
- クエリパラメータ
before_id
:snowflake
|undefined
- デフォルト:
undefined
- 指定したIDより古い投稿を返します.指定したIDの投稿は含まれません
- デフォルト:
出力
200 OK
タイムラインを取得します.
[
{
"id": "3893974892",
"content": "hello world!",
"cw_comment": "",
"visibility": "public",
"created_at": "2023-09-27T14:17:29.169Z",
"attachment_files": [
{
"id": "204980348583",
"filename": "hello.png",
"content_type": "image/png",
"url": "https://example.com/images/hello.png",
"blur": "eoig:woi!our@nj/d",
"nsfw": false
}
],
"reactions": [
{
"emoji": "<:alias:11938437>",
"reacted_by": "3085763644"
},
{
"emoji": "🎉",
"reacted_by": "494984128"
}
],
"author": {
"id": "2874987398",
"name": "@[email protected]",
"display_name": "John Doe",
"bio": "I am Test User.",
"avatar": "https://example.com/images/avatar.png",
"header": "https://example.com/images/header.png",
"followed_count": 200,
"following_count": 10
}
}
]
404 Not Found
{
"error": "TEST_ERROR_CODE"
}
NOTHING_LEFT
: これ以上古い投稿はありません- 1つでも古い投稿がある場合は投稿を返します
ACCOUNT_NOT_FOUND
: 指定したアカウントが見つかりませんでした
内部フロー・モジュール間通信
Mermaid code
sequenceDiagram
autonumber
actor ユーザー
ユーザー ->> NoteModule: 投稿
opt ダイレクト投稿の場合
NoteModule ->> AccountModule: 送信先アカウントの存在チェック
end
NoteModule ->> AccountModule: 投稿者情報取得
opt リノートの場合
NoteModule ->> NoteModule: 引用 or リノート先情報取得
end
NoteModule ->> ユーザー: 投稿完了
NoteModule ->> SearchModule: 検索インデックス投入
NoteModule ->> TimelineModule: 投稿作成イベント発火
TimelineModule ->> AccountModule: フォロー関係情報取得
TimelineModule ->> NotificationModule:通知イベント発火
TimelineModule ->> ActivityPubModule: 投稿作成イベント発火
モジュールの概要
Note Module
- ノート(投稿)の作成を行う.
- ノートの削除を行う.
- ノート情報を返す.
Account Module
- アカウント情報の管理を行う.
- アカウントを凍結/解除する.
- アカウントをサイレンスする.
Timeline Module
- タイムラインを構築する.
- 特定のアカウントが見ることのできる投稿をフォロー関係と公開範囲から決定する.
- (ActivityPub 外部配送 / Push通知)の送信先アカウントを決定する.
Notification Module
- クライアントに対してPush通知・メール通知を送信する.
ActivityPub Module
- ActivityPubを経由した外部サーバーへのノート配送を行う.
- ActivityPubを経由したノートの受信を行う.
ユースケース図
全体
- アクター
- アカウント
- 別インスタンスのアカウント
- 管理者
- ユースケース
- アカウント
- アカウント
- アカウント情報(プロフィール)を管理する
- アカウント情報の取得
- アカウントの削除
- アカウントの検索
- アカウントのサイレンス
- アカウントの凍結
- フォロー
- アカウントをフォロー
- アカウントをフォロー解除
- ノート
- ノートの作成
- (自分の)ノートの削除
- リノートの作成
- リノートの解除(削除)
- ノートへのリアクションの作成
- ノートへのリアクションの解除
- ノートのブックマーク
- ノートの検索
- ノートの取得
- リスト
- リストの作成
- リストの削除
- リストへのアカウントの追加
- リストへのアカウントの除外(削除)
- リストのノート取得
- ドライブ
- ファイルのアップロード
- ファイルの取得
- ノートへの紐付け
- ノートへの紐付け解除
- NSFWフラグの設定
- アカウント
- アカウント