feat(discord): eyes reaction as a read receipt on every admitted message (#1509)

QUEUE row 15, MVP iteration 1 after the Sage pilot. rest.react is best
effort (2xx true, anything else false, never throws); the connector reacts
at admission before the engine runs and records the outcome in the turn
record as receipt. Drops and refusals get no reaction. Suite 28/28, 90
node tests.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
This commit is contained in:
2026-09-13 14:20:30 -05:00
co-authored by Claude Fable 5.1
parent 788515dc69
commit 93d6b62457
10 changed files with 115 additions and 6 deletions
+17
View File
@@ -71,3 +71,20 @@ test("rest: content and nonce limits are enforced locally; typing never throws",
await rest.typing("c");
assert.equal(f.calls.length, 2);
});
test("rest: react PUTs the encoded emoji on the inbound message for @me; 2xx is true, anything else is false and never throws", async () => {
const f = fakeFetch([{ status: 204 }, { status: 403, body: { message: "Missing Permissions", code: 50013 } }, { throw: "down" }]);
const logs = [];
const rest = createRest({ token: TOKEN, fetch: f.fetch, log: (m) => logs.push(m) });
assert.equal(await rest.react("c1", "m1", "\u{1F440}"), true);
assert.equal(f.calls[0].url, "https://discord.com/api/v10/channels/c1/messages/m1/reactions/%F0%9F%91%80/@me");
assert.equal(f.calls[0].init.method, "PUT");
assert.equal(f.calls[0].init.body, undefined);
assert.equal(f.calls[0].init.headers.Authorization, `Bot ${TOKEN}`);
assert.equal(await rest.react("c1", "m2", "\u{1F440}"), false);
assert.equal(await rest.react("c1", "m3", "\u{1F440}"), false);
assert.equal(logs.length, 2);
assert.match(logs[0], /HTTP 403/);
assert.ok(logs.every((l) => !l.includes(TOKEN)));
await assert.rejects(rest.react("c1", "m4", ""), /emoji required/);
});