fix: use passive QQ event replies

This commit is contained in:
zenord
2026-08-18 22:20:55 +08:00
parent 4af5049605
commit ffedf616e3
9 changed files with 560 additions and 48 deletions
+37
View File
@@ -51,3 +51,40 @@ test("sendMessage uses C2C endpoint and forwards reply sequences as msg_seq", as
]);
} finally { globalThis.fetch = original; }
});
test("sendMessage without replyTo omits msg_id and msg_seq from the body", async () => {
const original = globalThis.fetch; const bodies: Array<Record<string, unknown>> = [];
globalThis.fetch = (async (input: string | URL | Request, init?: RequestInit) => {
if (String(input).includes("getAppAccessToken")) return new Response(JSON.stringify({ access_token: "token", expires_in: 7200 }), { status: 200 });
bodies.push(JSON.parse(String(init?.body)) as Record<string, unknown>);
return new Response(JSON.stringify({ id: "sent" }), { status: 200 });
}) as typeof fetch;
try {
const adapter = new QqAdapter(config, { receive: async () => ({ ok: true }) } as never);
const target = { platform: "qq", chatId: "group:g1", raw: { group_openid: "g1" } };
await adapter.sendMessage({ target, text: "proactive" });
assert.deepEqual(bodies, [{ content: "proactive" }]);
} finally { globalThis.fetch = original; }
});
test("sendMessage surfaces safe QQ error details (HTTP status and code) without the request body", async () => {
const original = globalThis.fetch;
globalThis.fetch = (async (input: string | URL | Request) => {
if (String(input).includes("getAppAccessToken")) return new Response(JSON.stringify({ access_token: "token", expires_in: 7200 }), { status: 200 });
return new Response(JSON.stringify({ code: 40034105, message: "proactive message not allowed" }), { status: 400 });
}) as typeof fetch;
try {
const adapter = new QqAdapter(config, { receive: async () => ({ ok: true }) } as never);
const target = { platform: "qq", chatId: "group:g1", raw: { group_openid: "g1" } };
await assert.rejects(
adapter.sendMessage({ target, text: "secret message content" }),
(error: Error) => {
assert.match(error.message, /HTTP 400/);
assert.match(error.message, /code=40034105/);
assert.match(error.message, /proactive message not allowed/);
assert.doesNotMatch(error.message, /secret message content/);
return true;
}
);
} finally { globalThis.fetch = original; }
});