セルフホストサーバー
顧客は自前のハードウェアで GameVox を運用でき、あなたのボットもそこで動きます。クラウド API が Discord 形式の REST 呼び出しを顧客のコントロールチャンネル経由で転送し、セルフホスト側がローカルのデータベースに対して実行し、同じ経路で応答が戻ります。ゲートウェイイベントはその逆方向に流れます。ほとんどのエンドポイントは透過的です。違いは以下のとおりです。
仕組み
ボットが GET /guilds/{id} や POST /channels/{id}/messages を呼ぶと、クラウド API が対象サーバーのティアを確認します。セルフホストであれば、リクエスト(メソッド、パス、クエリ、ボディ、bot_user_id)をシリアライズし、顧客のサーバーが常時開いているコントロールチャンネルの WebSocket に送ります。セルフホストのプロセスは、ボットの権限を自身のロールに照らして確認し、自身の SQLite データベースに対して同等のハンドラーを実行して応答のエンベロープを返すので、それをボットへ書き戻します。
転送はクラウドで行われるため、ライブラリはそれを意識しません。トークンもゲートウェイ URL も SDK も同じです。ギルドがクラウドでもセルフホストでも、ボットは同じ gateway.gamevox.com に接続し、同じ app-api.gamevox.com を呼びます。ボットはセルフホストサーバーのメンバーである必要があり、そうでない場合、呼び出しには 403 が返ります。
レイテンシ
往復時間は顧客の WAN 回線と SQLite のクエリ時間に依存し、通常はクラウド呼び出しに 30–300 ms 上乗せされます。エンドツーエンドで 12 秒の期限を設けています(ファイルを含むメッセージは、サーバーがファイルをダウンロードするため 90 秒)。サーバーが接続されていない場合、ボットにはすぐに 503 が返ります。接続されていても時間内に応答がない場合は、ボットに 504 が返ります。
動作するもの
以下はすべて、セルフホストサーバーのローカルデータに対して実行され、クラウドと同じ応答形式になります。
- メッセージ: 一覧、取得、送信、編集、削除、一括削除。埋め込み、コンポーネント、返信(
message_reference)、添付ファイル(multipart のfiles[n]とpayload_json)、投票。ttsは受け付けますが無視されます。 - リアクション: 追加、自分の削除、他ユーザーの削除、全削除、絵文字ごとの全削除、ユーザー一覧。
- ピン留め: 追加、解除、一覧。
- 入力中表示:
POST /channels/{id}/typing。 - チャンネル: 取得、更新、削除、一覧、作成(アプリチャンネルを含む)、並べ替え。
- チャンネルの権限上書き:
PUTとDELETE .../channels/{id}/permissions/{oid}、およびすべてのチャンネルオブジェクト(とCHANNEL_UPDATE)のpermission_overwrites。permission_overwritesの読み取りは現時点ではセルフホストのみです。クラウドのチャンネルオブジェクトにはこのフィールドが含まれず、クラウド API はPUTとDELETEによる書き込みのみに対応します。セルフホストサーバーに存在するのはロールの上書きだけです。oidはロール ID で、typeは0でなければなりません。メンバーの上書き(type: 1)は拒否されます。上書きの対象は、チャンネルの閲覧、メッセージの送信、ファイルの添付、リアクションの追加、接続、発言、音声検出の使用、配信です。allow によってロール自体に許可された範囲を超える権限が付与されることはないため、ロールが持たない権限への allow は返されません。上書きのないチャンネルは空のリストを返します。 - サーバー(ギルド): 取得、更新(名前と説明)。
- メンバー: 一覧、検索、
@me、取得、更新、ニックネーム変更、キック、ロールの追加と削除。 - BAN: 一覧、取得、追加、解除。
- ロール: 一覧、取得、作成、更新(
colorを含む)、並べ替え、削除、およびロール権限。 - 絵文字: 一覧、取得(サーバー所有のもの)。
- サウンドボード: 一覧、取得(サーバー所有のもの)。
- 監査ログ:
GET /guilds/{id}/audit-logs。ボット API 経由で行われた操作のエントリ。 - バニティ URL: GET(常に空の形式)。
- ボイス状態: GET(SFU からのライブ情報)、および
mute、deaf、channel_id(移動、またはnullで切断)を自由に組み合わせた PATCH。muteとdeafはサーバー側のフラグで、self_muteとself_deafはメンバー自身のフラグです。 - Webhook: 完全な CRUD と実行。Webhook のレコードはクラウドに保存され、実行されたメッセージはセルフホストのチャンネルに書き込まれて、Webhook の名前で表示されます。
- 予定イベント: 一覧、作成、取得、更新、削除、「興味あり」のユーザー一覧、メンバーの参加表明(RSVP)の設定と解除。形式はクラウドと同じです。繰り返しの設定は保存されますが、繰り返しイベントの 2 回目以降の開催は生成されません。
- フォーラム投稿: 投稿の作成(
POST /channels/{forum}/threads)、閲覧、返信。投稿の最初のメッセージは 10,000 文字まで(クラウドでは 20,000 文字)です。 - スラッシュコマンド: 呼び出しに対応し、権限はセルフホストのサーバー自身のロールに対して確認されます。登録方法はクラウドと同じです。
- メッセージコンポーネント: ボタン、文字列セレクト、モーダル、エフェメラル返信。インタラクションのコールバック、フォローアップ、元の応答のエンドポイントを含みます。メッセージコンポーネントを参照。
501 を返すもの(受け付けるが未実装)
PATCH .../guilds/{id}/vanity-url。セルフホストサーバーにバニティ URL はありません。
セルフホスト側ではなくクラウドが応答するもの
これらのエンドポイントは特定のサーバーではなく GameVox アカウントに関するものなので、どのボットに対してもクラウドが応答します。セルフホストサーバーのメンバーも通常の GameVox アカウントです。
GET /users/{id}とGET /users/by-name/{name}。GET /users/@me/guilds。アプリがインストールされているセルフホストサーバーも含まれます。POST /users/@me/channelsは DM チャンネルを返しますが、そこへのメッセージ送信は、クラウドでもセルフホストでもまだ対応していません。
ゲートウェイイベント
セルフホストのサーバーは、クラウドと同じゲートウェイセッションでイベントを配信します。購読モデルも変わりません。チャンネルのイベントはそのチャンネルを閲覧できるボットにだけ配信され、Intent はクラウドと同様に適用されます。
セルフホストのサーバー上でのユーザーの操作と、ボット自身の REST 呼び出しで発行されるもの:
MESSAGE_CREATE,MESSAGE_UPDATE,MESSAGE_DELETEMESSAGE_DELETE_BULK(キックや BAN でメンバーのメッセージが削除された場合も)MESSAGE_REACTION_ADD,MESSAGE_REACTION_REMOVEMESSAGE_POLL_VOTE_ADD,MESSAGE_POLL_VOTE_REMOVECHANNEL_CREATE,CHANNEL_UPDATE,CHANNEL_DELETECHANNEL_PINS_UPDATEGUILD_UPDATE(名前 / 説明の変更)GUILD_MEMBER_ADDGUILD_MEMBER_REMOVE(退出、キック、BAN、非アクティブなゲストの整理)GUILD_MEMBER_UPDATE(ロールの変更、ユーザー名またはアバターの変更)GUILD_BAN_ADDGUILD_ROLE_CREATE,GUILD_ROLE_UPDATE,GUILD_ROLE_DELETE(作成、名前の変更、並べ替え、色と権限の変更)GUILD_EMOJIS_UPDATETYPING_STARTPRESENCE_UPDATE(GUILD_PRESENCESIntent が必要。変更のみで、接続した時点ですでにオンラインのメンバーのスナップショットはありません)VOICE_STATE_UPDATE(参加、退出、移動、自分/サーバーによるミュートとスピーカーミュート)INTERACTION_CREATE(スラッシュコマンド、コンポーネントのクリック、モーダルの送信。クラウドが中継します)
ボットが REST で行った変更に対してのみ発行されるもの:
GUILD_BAN_REMOVE(セルフホストのサーバーには、ユーザーが BAN を解除する操作がありません)MESSAGE_REACTION_REMOVE_ALL,MESSAGE_REACTION_REMOVE_EMOJI(セルフホストのサーバーには、ユーザーが行うこの操作がありません)
発行されないもの(クラウドでも同様):
THREAD_*、INVITE_*、GUILD_SCHEDULED_EVENT_*。
既知の差異
- ボイスチャンネルの移動で 2 つのイベントが発生します: Discord では新しい
channel_idを付けたvoice-states/{uid}への PATCH はVOICE_STATE_UPDATEを 1 回だけ発行しますが、セルフホストでは移動が退出+再参加として実装されているため、対象ユーザーのchannel_idが一度nullになってから新しいチャンネルに変わります。同じユーザーについて数百ミリ秒以内に続いた更新は、1 回の移動として扱ってください。移動と一緒に送ったmuteやdeafは、メンバーが再参加したときに適用されます。 - 添付ファイルの URL: セルフホストサーバーでの添付ファイルの
urlは顧客のサーバーを指しており、ダウンロードにはメンバーのセッションが必要です。ボットはファイルの名前、サイズ、種類を確認できますが、ファイル自体はまだ取得できません。width、height、descriptionはセルフホストでは保持されません。
セルフホストかどうかの判別
現時点では guild オブジェクトに“セルフホスト”を示すフラグはありません(Discord とバイト単位で同一を保つためです)。処理を分ける必要がある場合、手がかりは上記のエンドポイントから返る 501 で、JSON のエラーボディには次のようにセルフホストのサーバーからの理由が入ります。
{ "code": 0, "message": "vanity URL not supported on self-hosted" } 404("Unknown resource")はリソースが存在しないことを意味し、サーバーがセルフホストであることを示すものではありません。より軽い判別を必要とするボットが増えれば、ギルドのペイロードに features のエントリ(例: "SELF_HOSTED")を追加します。役立つようであれば、アプリケーションのサポートタブからご意見をお寄せください。
エラー
502 Bad Gateway。セルフホストのサーバーが不正な応答を返しました。まれで、たいていはアップグレード中のバージョン不一致です。503 Service Unavailable。コントロールチャンネルが現在接続されていません。バックオフしながら再試行してください。504 Gateway Timeout。サーバーが 12 秒以内に応答しませんでした。