feat(kook): P2 KOOK 专属页+后端 admin 端点(design/17 §2/§4)
后端(KOOK REST, 复用 httpclient WithAuthScheme(Bot), token不打印): - kook/admin.go(新): ListFriends/HandleFriendRequest/DeleteFriend/BlockFriend/ ListUserChats/CreateUserChat/ListDirectMessages - kook/admin_guild.go(新): ListGuilds/ListGuildChannels/ListGuildUsers/ListChannelMsgs/SendTestMessage - gateway/admin_channels_platform.go(新): kookAdmin(反射解包namedAdapter命中内嵌PlatformAdapter) + 4 handler + adminKookView聚合(子项失败记errors不伪造) - server.go 注册 4 条 ownerAuth 路由: /view /friends /friend/handle /message/test - admin.go/admin_write_channel_config.go: AdminChannelAccount 加 Capabilities 前端(KOOK 专属页): - KookPanel.tsx(新): 好友&申请/服务器/频道/成员/私信会话/发消息测试卡片 - AdapterDetailPage.tsx: platform==='kook' 渲染 KookPanel, 否则通用 - types.ts/api.ts: KOOK 类型 + adminChannelPlatformView/Friends/FriendHandle/MessageTest 文档: Docs/api-client.md 新增4端点契约(owner-only)+capabilities+v0.17 验收: go build/vet/test ./... 全绿 + npm run build 97模块全绿; 零新依赖 注: api.ts/types.ts 集中契约文件>500行属既有结构(未新增违规); KOOK其余REST方法留能力面待用
This commit is contained in:
1 parent
8eaf81bd0d
commit
5ec4c9814d
13 files changed
+1714
-2
No files matched your search
@@ -31,6 +31,9 @@ import type {
|
||||
Mode,
|
||||
PersonaRecord,
|
||||
PersonaUpsertRequest,
|
||||
KookFriendList,
|
||||
KookMessageTestResult,
|
||||
KookViewResponse,
|
||||
RagIndexRequest,
|
||||
Role,
|
||||
SessionMeta,
|
||||
@@ -592,6 +595,50 @@ export function adminDeleteChannelAccount(platform: string, id: string): Promise
|
||||
method: "DELETE",
|
||||
});
|
||||
}
|
||||
/** GET /api/v1/admin/channels/{platform}/view — one platform account's aggregated
|
||||
* panel data (friends / servers / channels / members / private chats), owner only. */
|
||||
export function adminChannelPlatformView(platform: string, accountId?: string): Promise<KookViewResponse> {
|
||||
const q = accountId ? `?accountId=${encodeURIComponent(accountId)}` : "";
|
||||
return request<KookViewResponse>(`/admin/channels/${encodeURIComponent(platform)}/view${q}`);
|
||||
}
|
||||
/** GET /api/v1/admin/channels/{platform}/friends?type= — friend/request/blocked list. */
|
||||
export function adminChannelPlatformFriends(
|
||||
platform: string,
|
||||
type: string,
|
||||
accountId?: string,
|
||||
): Promise<KookFriendList> {
|
||||
const q = new URLSearchParams();
|
||||
if (type) q.set("type", type);
|
||||
if (accountId) q.set("accountId", accountId);
|
||||
const qs = q.toString();
|
||||
return request<KookFriendList>(`/admin/channels/${encodeURIComponent(platform)}/friends${qs ? `?${qs}` : ""}`);
|
||||
}
|
||||
/** POST /api/v1/admin/channels/{platform}/friend/handle — accept/reject a friend request. */
|
||||
export function adminChannelFriendHandle(
|
||||
platform: string,
|
||||
id: number,
|
||||
accept: boolean,
|
||||
accountId?: string,
|
||||
): Promise<{ handled: boolean; id: number; accept: boolean }> {
|
||||
const q = accountId ? `?accountId=${encodeURIComponent(accountId)}` : "";
|
||||
return request<{ handled: boolean; id: number; accept: boolean }>(
|
||||
`/admin/channels/${encodeURIComponent(platform)}/friend/handle${q}`,
|
||||
{ method: "POST", body: JSON.stringify({ id, accept }) },
|
||||
);
|
||||
}
|
||||
/** POST /api/v1/admin/channels/{platform}/message/test — send one test message. */
|
||||
export function adminChannelMessageTest(
|
||||
platform: string,
|
||||
targetId: string,
|
||||
content: string,
|
||||
accountId?: string,
|
||||
): Promise<KookMessageTestResult> {
|
||||
const q = accountId ? `?accountId=${encodeURIComponent(accountId)}` : "";
|
||||
return request<KookMessageTestResult>(`/admin/channels/${encodeURIComponent(platform)}/message/test${q}`, {
|
||||
method: "POST",
|
||||
body: JSON.stringify({ targetId, content }),
|
||||
});
|
||||
}
|
||||
/** POST /api/v1/admin/plugins/install — honest 501 (needs a plugin source). */
|
||||
export function adminPluginInstall(req: { name: string; kind: string; description: string }): Promise<AdminPluginRecord> {
|
||||
return request<AdminPluginRecord>("/admin/plugins/install", { method: "POST", body: JSON.stringify(req) });
|
||||
|
||||
@@ -273,6 +273,9 @@ export interface AdminChannelAccount {
|
||||
botId?: string;
|
||||
botUsername?: string;
|
||||
botNickname?: string;
|
||||
/** Account-level admin operations the platform adapter exposes (e.g. kook's
|
||||
* ["friends","user_chats","channels","guilds","message_test"]). */
|
||||
capabilities?: string[];
|
||||
}
|
||||
|
||||
/** One message in the platform (IM channel) send/receive log. Mirrors the
|
||||
@@ -562,3 +565,98 @@ export interface RagIndexRequest {
|
||||
desc?: string;
|
||||
content: string;
|
||||
}
|
||||
|
||||
/* --- KOOK per-adapter panel data (design/17 §2; GET /admin/channels/kook/view). --- */
|
||||
|
||||
/** One friend / blocked user in GET /admin/channels/{platform}/friends. */
|
||||
export interface KookFriendEntry {
|
||||
user_id: string;
|
||||
username?: string;
|
||||
nickname?: string;
|
||||
avatar?: string;
|
||||
online?: boolean;
|
||||
}
|
||||
|
||||
/** One pending friend request (has a top-level request id). */
|
||||
export interface KookFriendRequestEntry {
|
||||
id: number;
|
||||
friend: KookFriendEntry;
|
||||
}
|
||||
|
||||
/** GET /admin/channels/{platform}/friends parsed data. */
|
||||
export interface KookFriendList {
|
||||
friends?: KookFriendEntry[];
|
||||
requests?: KookFriendRequestEntry[];
|
||||
blocked?: KookFriendEntry[];
|
||||
}
|
||||
|
||||
/** One private-chat session (GET /admin/channels/kook/view userChats). */
|
||||
export interface KookUserChat {
|
||||
code: string;
|
||||
last_read_time: number;
|
||||
latest_msg_time: number;
|
||||
unread_count: number;
|
||||
target_id: string;
|
||||
target_name?: string;
|
||||
is_friend?: boolean;
|
||||
is_blocked?: boolean;
|
||||
}
|
||||
|
||||
/** One server in the guild list. */
|
||||
export interface KookGuild {
|
||||
id: string;
|
||||
name: string;
|
||||
icon?: string;
|
||||
topic?: string;
|
||||
}
|
||||
|
||||
/** One channel in a guild. */
|
||||
export interface KookChannel {
|
||||
id: string;
|
||||
user_id?: string;
|
||||
guild_id: string;
|
||||
parent_id?: string;
|
||||
name: string;
|
||||
type: number;
|
||||
level?: number;
|
||||
is_category?: boolean;
|
||||
}
|
||||
|
||||
/** One guild member for the aggregate view. */
|
||||
export interface KookGuildUser {
|
||||
user_id: string;
|
||||
username?: string;
|
||||
nickname?: string;
|
||||
avatar?: string;
|
||||
online?: boolean;
|
||||
bot?: boolean;
|
||||
}
|
||||
|
||||
/** One channel message (GET /admin/channels/kook/view, not currently fetched). */
|
||||
export interface KookChannelMessage {
|
||||
id: string;
|
||||
type: number;
|
||||
content: string;
|
||||
author_id: string;
|
||||
author_name?: string;
|
||||
create_at: number;
|
||||
}
|
||||
|
||||
/** POST /admin/channels/{platform}/message/test result. */
|
||||
export interface KookMessageTestResult {
|
||||
msg_id: string;
|
||||
msg_timestamp: number;
|
||||
}
|
||||
|
||||
/** GET /api/v1/admin/channels/{platform}/view — the KOOK aggregate panel payload.
|
||||
* Sub-fetches that fail are recorded in errors rather than aborting the view. */
|
||||
export interface KookViewResponse {
|
||||
platform: string;
|
||||
accountId?: string;
|
||||
friends?: KookFriendList;
|
||||
userChats?: KookUserChat[];
|
||||
guilds?: KookGuild[];
|
||||
channels?: KookChannel[];
|
||||
members?: KookGuildUser[];
|
||||
errors?: Record<string, string>;
|
||||
}
|
||||
Reference in new issue
Block a user