Skip to content

feat(calls): YouTubeを同期視聴するWatch Togetherを追加 - #77

Open
mattyatea wants to merge 11 commits into
codex/calls-activitiesfrom
codex/calls-watch-together
Open

mattyatea wants to merge 11 commits into
codex/calls-activitiesfrom
codex/calls-watch-together

Conversation

@mattyatea

@mattyatea mattyatea commented Oct 6, 2026 •

Copy link
Copy Markdown

What

Calls の Activity に、YouTube の動画を一緒に見る Watch Together を追加します。動画 URL を入力して再生またはキューに追加できます。キューにはサムネイル・タイトル・説明文を表示します。PCなど幅のあるアクティビティ領域では「次に再生」を動画の右側に配置し、狭いウィンドウ・スマホ幅では下に並べます。タイトルと説明文はそれぞれ1行で省略し、スマホ幅でも横に収まります。「今すぐ再生」と削除は、キューの動画を右クリック・長押ししたコンテキストメニューから操作します。既存のリンクプレビューを使うため API キーは不要です。キューはルーム全員で共有し、ホスト・モデレーターが削除・途中の動画への切り替えを行えます。再生終了を受け取った操作権限者が次の動画へ進め、変更は全員に同期します。

ホスト・有効なルームモデレーターが YouTube 標準のボタンやタイムラインで再生・停止・シークすると、他の視聴者も同じ動画と再生位置に追従します。既存のインスタンスモデレーター権限も維持します。

独自の再生ボタン・秒数入力・音量スライダーをなくし、YouTube の操作 UI に統一しました。URL 入力は動画の選択・変更・キューへの追加時だけ表示します。YouTube検索は追加していません。

各自が「視聴を開始」を押してから YouTube プレーヤーに接続します。キューのサムネイルはYouTubeの画像配信先から表示します。音量と自動再生の許可は本人だけに作用します。途中参加・再表示時は現在の状態を取得し、ルーム終了時は再生を止めます。音声なしで視聴するホストも30秒ごとの状態取得で在席期限を更新します。

Why

YouTube を見る Activity を実装する依頼に対応します。操作権限は「ホスト・モデレーターが操作し、他の人は同期して視聴」の指定に従っています。

ベースは Activity の土台 #76(codex/calls-activities、a5ef420731)。最新develop 62d7367944を含む土台を取り込み、Callsの接続完了判定・設定・接続情報とWatch Togetherを維持して競合を解消しています。土台のPR #76のlocale競合も解消済みです。#76 → この PR の順で取り込めます。絵チャ #34 への依存はありません。関連: #17。

Additional info (optional)

flowchart LR
  Controller["ホスト・モデレーターのYouTube操作"] --> API["動画変更・再生・停止・シークAPI"]
  API --> Auth["Calls権限・操作権限・revision確認"]
  Auth --> Redis["ルーム単位の視聴状態"]
  Redis --> Stream["既存Calls streaming"]
  Stream --> Players["各自のYouTubeプレーヤー"]
  Snapshot["途中参加・再表示時の取得"] --> Redis
Loading
erDiagram
  CALLS_ROOM ||--o| WATCH_TOGETHER_STATE : "RedisキーのroomId"
  CALLS_ROOM {
    string id PK
  }
  WATCH_TOGETHER_STATE {
    string roomId PK "Redisキーから決定"
    string videoId "nullなら未選択"
    boolean playing
    number position "秒"
    string_array queue "次に再生する動画ID(最大50本)"
    number updatedAt "基準時刻ms"
    integer revision
  }
Loading

視聴状態とキューは Redis に7日間保持します。既存 Calls のロック・配信・閲覧権限を使い、処分された参加者への配信も拒否します。API と SDK の型を追加し、RDB entity・migration は変更していません。roomId は Redis キーに含み、値には重複して保存しません。

  • PASS: 最終のfrontend Calls unit 246件(21ファイル)、frontend型チェック・build、i18n再生成・build、変更ファイルlint・SPDX・locale safety。
  • PASS: 接続完了判定との競合解消時にbackend Calls unit 110件、Calls API E2E 6件、backend型チェック・build、SDK再生成。以降のベース更新はfrontend・localeのみです。
  • PASS: 実YouTubeと2ブラウザーで、標準UIの再生・停止・シーク同期、視聴者の操作拒否、モデレーター操作、URLからのキュー追加・共有、実動画終了後の自動送りを確認。
  • PASS: 最終UIを実ブラウザーで確認。1360px幅でキューが右側、900px・390px幅で下側に配置されます。タイトル・説明文の1行省略、右クリックからの即時再生、タッチ長押しからの削除、通常タップのリンク遷移を確認し、JavaScriptエラー0件。スクリーンショットを更新しました。

最新コミット 022c5bed3a のGitHub Checksは42件成功・条件付きStorybook 1件スキップ。土台のPR #76 (a5ef420731) も26件成功・1件スキップで、両PRとも競合なしです。

動作確認記録

Calls内のYouTube視聴とキュー

スマホ幅

長押しのキュー操作メニュー

リンクプレビューが無効・取得失敗の場合は、キューに動画URLと取得失敗の表示を出します。YouTubeの埋め込み・地域制限・広告とブラウザーの自動再生制限の影響を受けます。自動再生が止められた場合は「再生を許可」を表示します。広告ブロックは含みません(公式パラメーター)。Cloudflareの実音声接続は試験用認証情報のため未検証です。

追加の参加確認fixtureテストは46件通過。テストファイルを単独でlintすると、develop由来のResizeObserverコンストラクターモック2か所がprefer-arrow-callbackに抵触します(既存の指摘)。変更ソースのlint・SPDX・locale safetyは通過しています。

Storybook登録の生成は完了しましたが、事前処理には既存の.storybook/main.tsの型エラーがあり、本体は未検証です。CI用のテスト設定には、外部音声接続を行わないCallsのダミー設定を追加しました。

CHANGELOG 候補: Enhance: Calls の Activity に YouTube を同期視聴する Watch Together を追加。

Checklist

  • Read the contribution guide
  • Test working in a local environment
  • (If needed) Add story of storybook
  • (If needed) Update CHANGELOG.md
  • (If possible) Add tests

Copilot AI balanced review requested due to automatic review settings October 6, 2026 14:39

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@coderabbitai

coderabbitai Bot commented Oct 6, 2026 •

Copy link
Copy Markdown

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 40 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

Learn how review limits work.

Review configuration:

⚙️ Run configuration
  • Configuration used: Repository: Type4ny-Project/Misskey/.coderabbit.yaml
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 09bfc662-6082-4d1f-a9bc-0299738a75b9
📥 Commits

Reviewing files that changed from the base of the PR and between a5ef420 and 022c5be.

⛔ Files ignored due to path filters (3)
  • specs/watch-together/screenshots/desktop.png is excluded by !**/*.png
  • specs/watch-together/screenshots/mobile-menu.png is excluded by !**/*.png
  • specs/watch-together/screenshots/mobile.png is excluded by !**/*.png
📒 Files selected for processing (31)
  • .github/misskey/test.yml
  • locales/ja-JP.yml
  • packages/backend/src/core/CoreModule.ts
  • packages/backend/src/core/GlobalEventService.ts
  • packages/backend/src/core/calls/CallsRoomService.ts
  • packages/backend/src/core/calls/CallsWatchTogetherService.ts
  • packages/backend/src/server/api/endpoint-list.ts
  • packages/backend/src/server/api/endpoints/calls/watch-together/_shared.ts
  • packages/backend/src/server/api/endpoints/calls/watch-together/show.ts
  • packages/backend/src/server/api/endpoints/calls/watch-together/update.ts
  • packages/backend/src/server/api/stream/channels/calls-room.ts
  • packages/backend/test/e2e/calls.ts
  • packages/backend/test/unit/core/calls/CallsRoomChannel.ts
  • packages/backend/test/unit/core/calls/CallsWatchTogetherService.ts
  • packages/frontend/.storybook/generate.tsx
  • packages/frontend/src/components/MkCallsRoomWindow.vue
  • packages/frontend/src/components/calls/MkCallsWatchTogether.stories.impl.ts
  • packages/frontend/src/components/calls/MkCallsWatchTogether.vue
  • packages/frontend/src/components/calls/MkCallsWatchTogetherVideoPreview.stories.impl.ts
  • packages/frontend/src/components/calls/MkCallsWatchTogetherVideoPreview.vue
  • packages/frontend/src/components/calls/youtube-player.ts
  • packages/frontend/test/unit/calls-join-confirmation.test.ts
  • packages/frontend/test/unit/calls-watch-together.test.ts
  • packages/i18n/src/autogen/locale.ts
  • packages/misskey-js/etc/misskey-js.api.md
  • packages/misskey-js/src/autogen/apiClientJSDoc.ts
  • packages/misskey-js/src/autogen/endpoint.ts
  • packages/misskey-js/src/autogen/entities.ts
  • packages/misskey-js/src/autogen/types.ts
  • packages/misskey-js/src/streaming.types.ts
  • specs/watch-together/verification.md
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

github-actions Bot commented Oct 6, 2026 •

Copy link
Copy Markdown

🖥 Frontend Diagnostics Report

(No significant changes)

View details

Requests by resource type
Type Requests Encoded bytes
Base Head Δ Base Head Δ
Document 2 2 0 34 KB 34 KB 0 B
Script 152 152 0 2.4 MB 2.4 MB $\color{orange}{\text{+6 B}}$
Stylesheet 63 63 0 320 KB 320 KB 0 B
Fetch 28 28 0 47 KB 47 KB 0 B
Image 9 9 0 238 KB 238 KB 0 B
Font 2 2 0 130 KB 130 KB 0 B
Other 9 9 0 421 KB 421 KB $\color{green}{\text{-8 B}}$
V8 heap snapshot statistics
Metric @ Base @ Head Δ MAD
$\color{gray}{\rule{8pt}{8pt}}$ Total 12 MB
± 4.4 KB
12 MB
± 2.6 KB
$\text{-4.2 KB}$
$\text{-0\%}$
5.2 KB
$\color{orange}{\rule{8pt}{8pt}}$ Code 3 MB 3 MB $\text{+96 B}$ 3.2 KB
$\color{red}{\rule{8pt}{8pt}}$ Strings 1.3 MB 1.3 MB $\text{-40 B}$ 145 B
$\color{cyan}{\rule{8pt}{8pt}}$ JS arrays 122 KB 122 KB 0 B 0 B
$\color{green}{\rule{8pt}{8pt}}$ Typed arrays 0 B 0 B 0 B 0 B
$\color{yellow}{\rule{8pt}{8pt}}$ System objects 0 B 0 B 0 B 0 B
$\color{violet}{\rule{8pt}{8pt}}$ Other JS objs 2.2 MB 2.2 MB $\text{+68 B}$ 230 B
$\color{pink}{\rule{8pt}{8pt}}$ Other non-JS objs 5.5 MB 5.5 MB $\text{-3.1 KB}$ 4.8 KB

Download representative heap snapshot: base / head

📦 Bundle Stats

Chunk size diff (1 updated, 0 added, 0 removed)
Chunk Base Head Δ Δ (%)
(total) 6.1 MB 6.1 MB $\color{orange}{\text{+12 KB}}$ $\color{orange}{\text{+0.2\%}}$
src/components/MkCallsRoomWindow.vue ja-JP/yBBkbG7I1-mxHq9nWA.js → ja-JP/4rsInMzIG-DVzdDliU.js
27 KB 38 KB $\color{orange}{\text{+12 KB}}$ $\color{orange}{\text{+43.4\%}}$
(other generated chunks) 2.3 MB 2.3 MB $\text{+3 B}$ $\text{+0\%}$
Startup chunk size (0 updated, 0 added, 0 removed)
Chunk Base Head Δ Δ (%)
(total) 957 KB 957 KB $\text{+3 B}$ $\text{+0\%}$
(other generated chunks) 883 KB 883 KB $\text{+3 B}$ $\text{+0\%}$
(other) 74 KB 74 KB 0 B 0%

Startup chunks are the Vite entry for src/_boot_.ts and its static imports.

Bundles Modules Entries Imports Size
Static Dynamic Rendered Gzip Brotli
Base 509 3,033 22 11,279 366 11 MB 3 MB 2.6 MB
Head 509 3,040 22 11,298 366 11 MB 3 MB 2.6 MB
Δ 0 $\color{orange}{\text{+7}}$ 0 $\color{orange}{\text{+19}}$ 0 $\color{orange}{\text{+25 KB}}$ $\color{orange}{\text{+7.2 KB}}$ $\color{orange}{\text{+6.3 KB}}$
Δ (%) 0% $\color{orange}{\text{+0.2\%}}$ 0% $\color{orange}{\text{+0.2\%}}$ 0% $\color{orange}{\text{+0.2\%}}$ $\color{orange}{\text{+0.2\%}}$ $\color{orange}{\text{+0.2\%}}$

Open treemap HTML

@mattyatea
mattyatea added this pull request to stack #79 October 6, 2026 16:06
@github-actions

github-actions Bot commented Oct 6, 2026 •

Copy link
Copy Markdown

このPRによるapi.jsonの差分

差分はこちら
--- base
+++ head
@@ -36511,6 +36511,620 @@
         }
       }
     },
+    "/calls/watch-together/show": {
+      "post": {
+        "operationId": "post___calls___watch-together___show",
+        "summary": "calls/watch-together/show",
+        "description": "No description provided.\n\n**Credential required**: *Yes* / **Permission**: *read:calls*",
+        "externalDocs": {
+          "description": "Source code",
+          "url": "https://github.com/misskey-dev/misskey/blob/develop/packages/backend/src/server/api/endpoints/calls/watch-together/show.ts"
+        },
+        "tags": [
+          "calls"
+        ],
+        "security": [
+          {
+            "bearerAuth": []
+          }
+        ],
+        "requestBody": {
+          "required": true,
+          "content": {
+            "application/json": {
+              "schema": {
+                "type": "object",
+                "properties": {
+                  "roomId": {
+                    "type": "string",
+                    "format": "misskey:id"
+                  }
+                },
+                "required": [
+                  "roomId"
+                ]
+              }
+            }
+          }
+        },
+        "responses": {
+          "200": {
+            "description": "OK (with results)",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "type": "object",
+                  "properties": {
+                    "queue": {
+                      "type": "array",
+                      "items": {
+                        "type": "string"
+                      }
+                    },
+                    "videoId": {
+                      "type": [
+                        "string",
+                        "null"
+                      ]
+                    },
+                    "playing": {
+                      "type": "boolean"
+                    },
+                    "position": {
+                      "type": "number"
+                    },
+                    "updatedAt": {
+                      "type": "number"
+                    },
+                    "revision": {
+                      "type": "integer"
+                    },
+                    "serverTime": {
+                      "type": "number"
+                    }
+                  },
+                  "required": [
+                    "queue",
+                    "videoId",
+                    "playing",
+                    "position",
+                    "updatedAt",
+                    "revision",
+                    "serverTime"
+                  ]
+                }
+              }
+            }
+          },
+          "400": {
+            "description": "Client error",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/Error"
+                },
+                "examples": {
+                  "CALLS_ACCESS_DENIED": {
+                    "value": {
+                      "error": {
+                        "message": "You do not have access to this Calls room.",
+                        "code": "CALLS_ACCESS_DENIED",
+                        "id": "3a432e2d-51e8-42f4-ae52-d2b0a7b89afa"
+                      }
+                    }
+                  },
+                  "CALLS_ATTACHMENT_NOT_FOUND": {
+                    "value": {
+                      "error": {
+                        "message": "The attached room does not exist.",
+                        "code": "CALLS_ATTACHMENT_NOT_FOUND",
+                        "id": "5985f4cf-84bb-4997-9e68-46f421f29e84"
+                      }
+                    }
+                  },
+                  "CALLS_ACTIVE_ATTACHMENT": {
+                    "value": {
+                      "error": {
+                        "message": "An active Calls room already exists for this attachment.",
+                        "code": "CALLS_ACTIVE_ATTACHMENT",
+                        "id": "4a8fd21d-0d68-4b8d-884c-9970f1d5f1f4"
+                      }
+                    }
+                  },
+                  "CALLS_INVALID_STATE": {
+                    "value": {
+                      "error": {
+                        "message": "The Calls room is not in the required state.",
+                        "code": "CALLS_INVALID_STATE",
+                        "id": "27bbe09b-c516-4c8a-a9fc-4b5c8de79cbb"
+                      }
+                    }
+                  },
+                  "CALLS_INVALID_METADATA": {
+                    "value": {
+                      "error": {
+                        "message": "The Calls room metadata is invalid.",
+                        "code": "CALLS_INVALID_METADATA",
+                        "id": "7fc75953-7ec9-4e2f-aee2-af12a8101971"
+                      }
+                    }
+                  },
+                  "CALLS_PARTICIPANT_NOT_FOUND": {
+                    "value": {
+                      "error": {
+                        "message": "The Calls participant does not exist.",
+                        "code": "CALLS_PARTICIPANT_NOT_FOUND",
+                        "id": "17e679a9-0ad9-4fe0-a09f-92dae12e445a"
+                      }
+                    }
+                  },
+                  "CALLS_ROOM_FULL": {
+                    "value": {
+                      "error": {
+                        "message": "The Calls room participant limit has been reached.",
+                        "code": "CALLS_ROOM_FULL",
+                        "id": "0b5e0eea-8c21-433c-94f9-e2359c57096e"
+                      }
+                    }
+                  },
+                  "CALLS_ROOM_NOT_FOUND": {
+                    "value": {
+                      "error": {
+                        "message": "The Calls room does not exist.",
+                        "code": "CALLS_ROOM_NOT_FOUND",
+                        "id": "09fd2742-0fc7-4222-ad41-1c395427a7d1"
+                      }
+                    }
+                  },
+                  "CALLS_STALE_REVISION": {
+                    "value": {
+                      "error": {
+                        "message": "The Calls room revision is stale.",
+                        "code": "CALLS_STALE_REVISION",
+                        "id": "fde2c128-2b65-4784-a0de-59f20eb901c1"
+                      }
+                    }
+                  },
+                  "CALLS_FEATURE_DISABLED": {
+                    "value": {
+                      "error": {
+                        "message": "Misskey Calls is disabled on this instance.",
+                        "code": "CALLS_FEATURE_DISABLED",
+                        "id": "bc70cfca-3247-4cd5-a9b7-a88b381195af"
+                      }
+                    }
+                  },
+                  "INVALID_PARAM": {
+                    "value": {
+                      "error": {
+                        "message": "Invalid param.",
+                        "code": "INVALID_PARAM",
+                        "id": "3d81ceae-475f-4600-b2a8-2bc116157532"
+                      }
+                    }
+                  }
+                }
+              }
+            }
+          },
+          "401": {
+            "description": "Authentication error",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/Error"
+                },
+                "examples": {
+                  "CREDENTIAL_REQUIRED": {
+                    "value": {
+                      "error": {
+                        "message": "Credential required.",
+                        "code": "CREDENTIAL_REQUIRED",
+                        "id": "1384574d-a912-4b81-8601-c7b1c4085df1"
+                      }
+                    }
+                  }
+                }
+              }
+            }
+          },
+          "403": {
+            "description": "Forbidden error",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/Error"
+                },
+                "examples": {
+                  "AUTHENTICATION_FAILED": {
+                    "value": {
+                      "error": {
+                        "message": "Authentication failed. Please ensure your token is correct.",
+                        "code": "AUTHENTICATION_FAILED",
+                        "id": "b0a7f5f8-dc2f-4171-b91f-de88ad238e14"
+                      }
+                    }
+                  }
+                }
+              }
+            }
+          },
+          "418": {
+            "description": "I'm Ai",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/Error"
+                },
+                "examples": {
+                  "I_AM_AI": {
+                    "value": {
+                      "error": {
+                        "message": "You sent a request to Ai-chan, Misskey's showgirl, instead of the server.",
+                        "code": "I_AM_AI",
+                        "id": "60c46cd1-f23a-46b1-bebe-5d2b73951a84"
+                      }
+                    }
+                  }
+                }
+              }
+            }
+          },
+          "500": {
+            "description": "Internal server error",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/Error"
+                },
+                "examples": {
+                  "INTERNAL_ERROR": {
+                    "value": {
+                      "error": {
+                        "message": "Internal error occurred. Please contact us if the error persists.",
+                        "code": "INTERNAL_ERROR",
+                        "id": "5d37dbcb-891e-41ca-a3d6-e690c97775ac"
+                      }
+                    }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    },
+    "/calls/watch-together/update": {
+      "post": {
+        "operationId": "post___calls___watch-together___update",
+        "summary": "calls/watch-together/update",
+        "description": "No description provided.\n\n**Credential required**: *Yes* / **Permission**: *write:calls*",
+        "externalDocs": {
+          "description": "Source code",
+          "url": "https://github.com/misskey-dev/misskey/blob/develop/packages/backend/src/server/api/endpoints/calls/watch-together/update.ts"
+        },
+        "tags": [
+          "calls"
+        ],
+        "security": [
+          {
+            "bearerAuth": []
+          }
+        ],
+        "requestBody": {
+          "required": true,
+          "content": {
+            "application/json": {
+              "schema": {
+                "type": "object",
+                "properties": {
+                  "roomId": {
+                    "type": "string",
+                    "format": "misskey:id"
+                  },
+                  "queue": {
+                    "type": "array",
+                    "maxItems": 50,
+                    "items": {
+                      "type": "string",
+                      "pattern": "^[A-Za-z0-9_-]{11}$"
+                    }
+                  },
+                  "expectedRevision": {
+                    "type": "integer",
+                    "minimum": 0
+                  },
+                  "videoId": {
+                    "type": [
+                      "string",
+                      "null"
+                    ],
+                    "pattern": "^[A-Za-z0-9_-]{11}$"
+                  },
+                  "playing": {
+                    "type": "boolean"
+                  },
+                  "position": {
+                    "type": "number",
+                    "minimum": 0
+                  }
+                },
+                "required": [
+                  "roomId",
+                  "expectedRevision"
+                ]
+              }
+            }
+          }
+        },
+        "responses": {
+          "200": {
+            "description": "OK (with results)",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "type": "object",
+                  "properties": {
+                    "queue": {
+                      "type": "array",
+                      "items": {
+                        "type": "string"
+                      }
+                    },
+                    "videoId": {
+                      "type": [
+                        "string",
+                        "null"
+                      ]
+                    },
+                    "playing": {
+                      "type": "boolean"
+                    },
+                    "position": {
+                      "type": "number"
+                    },
+                    "updatedAt": {
+                      "type": "number"
+                    },
+                    "revision": {
+                      "type": "integer"
+                    },
+                    "serverTime": {
+                      "type": "number"
+                    }
+                  },
+                  "required": [
+                    "queue",
+                    "videoId",
+                    "playing",
+                    "position",
+                    "updatedAt",
+                    "revision",
+                    "serverTime"
+                  ]
+                }
+              }
+            }
+          },
+          "400": {
+            "description": "Client error",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/Error"
+                },
+                "examples": {
+                  "CALLS_ACCESS_DENIED": {
+                    "value": {
+                      "error": {
+                        "message": "You do not have access to this Calls room.",
+                        "code": "CALLS_ACCESS_DENIED",
+                        "id": "3a432e2d-51e8-42f4-ae52-d2b0a7b89afa"
+                      }
+                    }
+                  },
+                  "CALLS_ATTACHMENT_NOT_FOUND": {
+                    "value": {
+                      "error": {
+                        "message": "The attached room does not exist.",
+                        "code": "CALLS_ATTACHMENT_NOT_FOUND",
+                        "id": "5985f4cf-84bb-4997-9e68-46f421f29e84"
+                      }
+                    }
+                  },
+                  "CALLS_ACTIVE_ATTACHMENT": {
+                    "value": {
+                      "error": {
+                        "message": "An active Calls room already exists for this attachment.",
+                        "code": "CALLS_ACTIVE_ATTACHMENT",
+                        "id": "4a8fd21d-0d68-4b8d-884c-9970f1d5f1f4"
+                      }
+                    }
+                  },
+                  "CALLS_INVALID_STATE": {
+                    "value": {
+                      "error": {
+                        "message": "The Calls room is not in the required state.",
+                        "code": "CALLS_INVALID_STATE",
+                        "id": "27bbe09b-c516-4c8a-a9fc-4b5c8de79cbb"
+                      }
+                    }
+                  },
+                  "CALLS_INVALID_METADATA": {
+                    "value": {
+                      "error": {
+                        "message": "The Calls room metadata is invalid.",
+                        "code": "CALLS_INVALID_METADATA",
+                        "id": "7fc75953-7ec9-4e2f-aee2-af12a8101971"
+                      }
+                    }
+                  },
+                  "CALLS_PARTICIPANT_NOT_FOUND": {
+                    "value": {
+                      "error": {
+                        "message": "The Calls participant does not exist.",
+                        "code": "CALLS_PARTICIPANT_NOT_FOUND",
+                        "id": "17e679a9-0ad9-4fe0-a09f-92dae12e445a"
+                      }
+                    }
+                  },
+                  "CALLS_ROOM_FULL": {
+                    "value": {
+                      "error": {
+                        "message": "The Calls room participant limit has been reached.",
+                        "code": "CALLS_ROOM_FULL",
+                        "id": "0b5e0eea-8c21-433c-94f9-e2359c57096e"
+                      }
+                    }
+                  },
+                  "CALLS_ROOM_NOT_FOUND": {
+                    "value": {
+                      "error": {
+                        "message": "The Calls room does not exist.",
+                        "code": "CALLS_ROOM_NOT_FOUND",
+                        "id": "09fd2742-0fc7-4222-ad41-1c395427a7d1"
+                      }
+                    }
+                  },
+                  "CALLS_STALE_REVISION": {
+                    "value": {
+                      "error": {
+                        "message": "The Calls room revision is stale.",
+                        "code": "CALLS_STALE_REVISION",
+                        "id": "fde2c128-2b65-4784-a0de-59f20eb901c1"
+                      }
+                    }
+                  },
+                  "CALLS_FEATURE_DISABLED": {
+                    "value": {
+                      "error": {
+                        "message": "Misskey Calls is disabled on this instance.",
+                        "code": "CALLS_FEATURE_DISABLED",
+                        "id": "bc70cfca-3247-4cd5-a9b7-a88b381195af"
+                      }
+                    }
+                  },
+                  "INVALID_PARAM": {
+                    "value": {
+                      "error": {
+                        "message": "Invalid param.",
+                        "code": "INVALID_PARAM",
+                        "id": "3d81ceae-475f-4600-b2a8-2bc116157532"
+                      }
+                    }
+                  }
+                }
+              }
+            }
+          },
+          "401": {
+            "description": "Authentication error",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/Error"
+                },
+                "examples": {
+                  "CREDENTIAL_REQUIRED": {
+                    "value": {
+                      "error": {
+                        "message": "Credential required.",
+                        "code": "CREDENTIAL_REQUIRED",
+                        "id": "1384574d-a912-4b81-8601-c7b1c4085df1"
+                      }
+                    }
+                  }
+                }
+              }
+            }
+          },
+          "403": {
+            "description": "Forbidden error",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/Error"
+                },
+                "examples": {
+                  "AUTHENTICATION_FAILED": {
+                    "value": {
+                      "error": {
+                        "message": "Authentication failed. Please ensure your token is correct.",
+                        "code": "AUTHENTICATION_FAILED",
+                        "id": "b0a7f5f8-dc2f-4171-b91f-de88ad238e14"
+                      }
+                    }
+                  }
+                }
+              }
+            }
+          },
+          "418": {
+            "description": "I'm Ai",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/Error"
+                },
+                "examples": {
+                  "I_AM_AI": {
+                    "value": {
+                      "error": {
+                        "message": "You sent a request to Ai-chan, Misskey's showgirl, instead of the server.",
+                        "code": "I_AM_AI",
+                        "id": "60c46cd1-f23a-46b1-bebe-5d2b73951a84"
+                      }
+                    }
+                  }
+                }
+              }
+            }
+          },
+          "429": {
+            "description": "Too many requests",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/Error"
+                },
+                "examples": {
+                  "RATE_LIMIT_EXCEEDED": {
+                    "value": {
+                      "error": {
+                        "message": "Rate limit exceeded. Please try again later.",
+                        "code": "RATE_LIMIT_EXCEEDED",
+                        "id": "d5826d14-3982-4d2e-8011-b9e9f02499ef"
+                      }
+                    }
+                  }
+                }
+              }
+            }
+          },
+          "500": {
+            "description": "Internal server error",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/Error"
+                },
+                "examples": {
+                  "INTERNAL_ERROR": {
+                    "value": {
+                      "error": {
+                        "message": "Internal error occurred. Please contact us if the error persists.",
+                        "code": "INTERNAL_ERROR",
+                        "id": "5d37dbcb-891e-41ca-a3d6-e690c97775ac"
+                      }
+                    }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    },
     "/channels/create": {
       "post": {
         "operationId": "post___channels___create",

Get diff files from Workflow Page

@github-actions

github-actions Bot commented Oct 6, 2026 •

Copy link
Copy Markdown

⚙️ Backend Diagnostics Report

Memory: After GC

Metric @ Base @ Head Δ MAD
HeapUsed 77 MB
± 0 MB
77.2 MB
± 0 MB
$\color{orange}{\text{+0.2~MB}}$
$\color{orange}{\text{+0.2\%}}$
0 MB

Only metrics showing significant changes are displayed.

V8 Heap Snapshot Statistics

Metric @ Base @ Head Δ MAD
$\color{gray}{\rule{8pt}{8pt}}$ Total 90 MB
± 11 KB
90 MB
± 14 KB
$\color{orange}{\text{+113 KB}}$
$\color{orange}{\text{+0.1\%}}$
18 KB
$\color{orange}{\rule{8pt}{8pt}}$ Code 26 MB 26 MB $\text{+8.4 KB}$ 6.5 KB
$\color{red}{\rule{8pt}{8pt}}$ Strings 31 MB 31 MB $\text{+4.5 KB}$ 1.8 KB
$\color{cyan}{\rule{8pt}{8pt}}$ JS arrays 4.9 MB 4.9 MB $\text{+12 KB}$ 0 B
$\color{green}{\rule{8pt}{8pt}}$ Typed arrays 566 KB 566 KB 0 B 0 B
$\color{yellow}{\rule{8pt}{8pt}}$ System objects 2.3 MB 2.3 MB $\text{+3.1 KB}$ 1.6 KB
$\color{violet}{\rule{8pt}{8pt}}$ Other JS objs 25 MB 25 MB $\text{+60 KB}$ 168 B
$\color{pink}{\rule{8pt}{8pt}}$ Other non-JS objs 39 KB 39 KB 0 B 0 B

Download representative heap snapshot: base / head

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants