feat: unify provider reaction tools

This commit is contained in:
Peter Steinberger
2026-01-07 04:10:13 +01:00
parent 551a8d5683
commit 3afef2d504
41 changed files with 1169 additions and 82 deletions

View File

@@ -14,6 +14,8 @@ import {
pinMessageDiscord,
reactMessageDiscord,
readMessagesDiscord,
removeOwnReactionsDiscord,
removeReactionDiscord,
removeRoleDiscord,
searchMessagesDiscord,
sendMessageDiscord,
@@ -224,6 +226,47 @@ describe("reactMessageDiscord", () => {
});
});
describe("removeReactionDiscord", () => {
beforeEach(() => {
vi.clearAllMocks();
});
it("removes a unicode emoji reaction", async () => {
const { rest, deleteMock } = makeRest();
await removeReactionDiscord("chan1", "msg1", "✅", { rest, token: "t" });
expect(deleteMock).toHaveBeenCalledWith(
Routes.channelMessageOwnReaction("chan1", "msg1", "%E2%9C%85"),
);
});
});
describe("removeOwnReactionsDiscord", () => {
beforeEach(() => {
vi.clearAllMocks();
});
it("removes all own reactions on a message", async () => {
const { rest, getMock, deleteMock } = makeRest();
getMock.mockResolvedValue({
reactions: [
{ emoji: { name: "✅", id: null } },
{ emoji: { name: "party_blob", id: "123" } },
],
});
const res = await removeOwnReactionsDiscord("chan1", "msg1", {
rest,
token: "t",
});
expect(res).toEqual({ ok: true, removed: ["✅", "party_blob:123"] });
expect(deleteMock).toHaveBeenCalledWith(
Routes.channelMessageOwnReaction("chan1", "msg1", "%E2%9C%85"),
);
expect(deleteMock).toHaveBeenCalledWith(
Routes.channelMessageOwnReaction("chan1", "msg1", "party_blob%3A123"),
);
});
});
describe("fetchReactionsDiscord", () => {
beforeEach(() => {
vi.clearAllMocks();

View File

@@ -566,6 +566,55 @@ export async function reactMessageDiscord(
return { ok: true };
}
export async function removeReactionDiscord(
channelId: string,
messageId: string,
emoji: string,
opts: DiscordReactOpts = {},
) {
const token = resolveToken(opts.token);
const rest = resolveRest(token, opts.rest);
const encoded = normalizeReactionEmoji(emoji);
await rest.delete(
Routes.channelMessageOwnReaction(channelId, messageId, encoded),
);
return { ok: true };
}
export async function removeOwnReactionsDiscord(
channelId: string,
messageId: string,
opts: DiscordReactOpts = {},
): Promise<{ ok: true; removed: string[] }> {
const token = resolveToken(opts.token);
const rest = resolveRest(token, opts.rest);
const message = (await rest.get(
Routes.channelMessage(channelId, messageId),
)) as {
reactions?: Array<{ emoji: { id?: string | null; name?: string | null } }>;
};
const identifiers = new Set<string>();
for (const reaction of message.reactions ?? []) {
const identifier = buildReactionIdentifier(reaction.emoji);
if (identifier) identifiers.add(identifier);
}
if (identifiers.size === 0) return { ok: true, removed: [] };
const removed: string[] = [];
await Promise.allSettled(
Array.from(identifiers, (identifier) => {
removed.push(identifier);
return rest.delete(
Routes.channelMessageOwnReaction(
channelId,
messageId,
normalizeReactionEmoji(identifier),
),
);
}),
);
return { ok: true, removed };
}
export async function fetchReactionsDiscord(
channelId: string,
messageId: string,