/** * QQ Channel API proxy tool core logic. * QQ 频道 API 代理工具核心逻辑。 * * Provides an authenticated HTTP proxy for the QQ Open Platform channel * APIs. The caller (old tools/channel.ts shell) resolves the access * token and passes it in; this module handles URL building, path * validation, fetch, and structured response formatting.
*/
import { formatErrorMessage } from "../utils/format.js"; import { debugLog, debugError } from "../utils/log.js";
/** * JSON Schema for AI tool parameters (used by framework registration). * AI Tool 参数的 JSON Schema 定义(供框架注册使用)。
*/
export const ChannelApiSchema = {
type: "object",
properties: {
method: {
type: "string",
description: "HTTP method. Allowed values: GET, POST, PUT, PATCH, DELETE.", enum: ["GET", "POST", "PUT", "PATCH", "DELETE"],
},
path: {
type: "string",
description: "API path without the host. Replace placeholders with concrete values. " + "Examples: /users/@me/guilds, /guilds/{guild_id}/channels, /channels/{channel_id}.",
},
body: {
type: "object",
description: "JSON request body for POST/PUT/PATCH requests. GET/DELETE usually do not need it.",
},
query: {
type: "object",
description: "URL query parameters as key/value pairs appended to the path. " + 'For example, { "limit": "100", "after": "0" } becomes ?limit=100&after=0.',
additionalProperties: { type: "string" },
},
},
required: ["method", "path"],
} as const;
/** * Build the full API URL from base + path + query params. * 拼接 API 基地址 + 路径 + 查询参数。
*/
export function buildUrl(path: string, query?: Record<string, string>): string {
let url = `${API_BASE}${path}`; if (query && Object.keys(query).length > 0) { const params = new URLSearchParams(); for (const [key, value] of Object.entries(query)) { if (value !== undefined && value !== null && value !== "") {
params.set(key, value);
}
} const qs = params.toString(); if (qs) {
url += `?${qs}`;
}
} return url;
}
/** * Validate API path format; returns an error string or null if valid. * 校验 API 路径格式,返回错误描述或 null(合法)。
*/
export function validatePath(path: string): string | null { if (!path.startsWith("/")) { return"path must start with /";
} if (path.includes("..") || path.includes("//")) { return"path must not contain .. or //";
} if (!/^\/[a-zA-Z0-9\-._~:@!$&'()*+,;=/%]+$/.test(path) && path !== "/") { return"path contains unsupported characters";
} returnnull;
}
/** * Options provided by the caller when executing a channel API request. * 执行频道 API 请求时由调用方提供的选项。
*/
export interface ChannelApiExecuteOptions {
accessToken: string;
}
/** * Execute a channel API proxy request. * 执行频道 API 代理请求。 * * The caller provides the access token; this function handles * URL building, path validation, HTTP fetch, and structured * response formatting suitable for AI tool output.
*/
export async function executeChannelApi(
params: ChannelApiParams,
options: ChannelApiExecuteOptions,
) { if (!params.method) { return json({ error: "method is required" });
} if (!params.path) { return json({ error: "path is required" });
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.