Add WhatsApp reactions support
Summary: Test Plan:
This commit is contained in:
committed by
Peter Steinberger
parent
aa87d6cee8
commit
551a8d5683
@@ -14,6 +14,13 @@ export type ActiveWebListener = {
|
||||
options?: ActiveWebSendOptions,
|
||||
) => Promise<{ messageId: string }>;
|
||||
sendPoll: (to: string, poll: PollInput) => Promise<{ messageId: string }>;
|
||||
sendReaction: (
|
||||
chatJid: string,
|
||||
messageId: string,
|
||||
emoji: string,
|
||||
fromMe: boolean,
|
||||
participant?: string,
|
||||
) => Promise<void>;
|
||||
sendComposingTo: (to: string) => Promise<void>;
|
||||
close?: () => Promise<void>;
|
||||
};
|
||||
|
||||
@@ -566,6 +566,30 @@ export async function monitorWebInbox(options: {
|
||||
const jid = toWhatsappJid(to);
|
||||
await sock.sendPresenceUpdate("composing", jid);
|
||||
},
|
||||
/**
|
||||
* Send a reaction (emoji) to a specific message.
|
||||
* Pass an empty string for emoji to remove the reaction.
|
||||
*/
|
||||
sendReaction: async (
|
||||
chatJid: string,
|
||||
messageId: string,
|
||||
emoji: string,
|
||||
fromMe: boolean,
|
||||
participant?: string,
|
||||
): Promise<void> => {
|
||||
const jid = toWhatsappJid(chatJid);
|
||||
await sock.sendMessage(jid, {
|
||||
react: {
|
||||
text: emoji,
|
||||
key: {
|
||||
remoteJid: jid,
|
||||
id: messageId,
|
||||
fromMe,
|
||||
participant,
|
||||
},
|
||||
},
|
||||
});
|
||||
},
|
||||
} as const;
|
||||
}
|
||||
|
||||
|
||||
@@ -8,16 +8,26 @@ vi.mock("./media.js", () => ({
|
||||
loadWebMedia: (...args: unknown[]) => loadWebMediaMock(...args),
|
||||
}));
|
||||
|
||||
import { sendMessageWhatsApp, sendPollWhatsApp } from "./outbound.js";
|
||||
import {
|
||||
sendMessageWhatsApp,
|
||||
sendPollWhatsApp,
|
||||
sendReactionWhatsApp,
|
||||
} from "./outbound.js";
|
||||
|
||||
describe("web outbound", () => {
|
||||
const sendComposingTo = vi.fn(async () => {});
|
||||
const sendMessage = vi.fn(async () => ({ messageId: "msg123" }));
|
||||
const sendPoll = vi.fn(async () => ({ messageId: "poll123" }));
|
||||
const sendReaction = vi.fn(async () => {});
|
||||
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
setActiveWebListener({ sendComposingTo, sendMessage, sendPoll });
|
||||
setActiveWebListener({
|
||||
sendComposingTo,
|
||||
sendMessage,
|
||||
sendPoll,
|
||||
sendReaction,
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
@@ -156,4 +166,18 @@ describe("web outbound", () => {
|
||||
durationHours: undefined,
|
||||
});
|
||||
});
|
||||
|
||||
it("sends reactions via active listener", async () => {
|
||||
await sendReactionWhatsApp("1555@s.whatsapp.net", "msg123", "✅", {
|
||||
verbose: false,
|
||||
fromMe: false,
|
||||
});
|
||||
expect(sendReaction).toHaveBeenCalledWith(
|
||||
"1555@s.whatsapp.net",
|
||||
"msg123",
|
||||
"✅",
|
||||
false,
|
||||
undefined,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -91,6 +91,52 @@ export async function sendMessageWhatsApp(
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
export async function sendReactionWhatsApp(
|
||||
chatJid: string,
|
||||
messageId: string,
|
||||
emoji: string,
|
||||
options: {
|
||||
verbose: boolean;
|
||||
fromMe?: boolean;
|
||||
participant?: string;
|
||||
},
|
||||
): Promise<void> {
|
||||
const correlationId = randomUUID();
|
||||
const active = getActiveWebListener();
|
||||
if (!active) {
|
||||
throw new Error(
|
||||
"No active gateway listener. Start the gateway before sending WhatsApp reactions.",
|
||||
);
|
||||
}
|
||||
const logger = getChildLogger({
|
||||
module: "web-outbound",
|
||||
correlationId,
|
||||
chatJid,
|
||||
messageId,
|
||||
});
|
||||
try {
|
||||
const jid = toWhatsappJid(chatJid);
|
||||
outboundLog.info(`Sending reaction "${emoji}" -> message ${messageId}`);
|
||||
logger.info({ chatJid: jid, messageId, emoji }, "sending reaction");
|
||||
await active.sendReaction(
|
||||
chatJid,
|
||||
messageId,
|
||||
emoji,
|
||||
options.fromMe ?? false,
|
||||
options.participant,
|
||||
);
|
||||
outboundLog.info(`Sent reaction "${emoji}" -> message ${messageId}`);
|
||||
logger.info({ chatJid: jid, messageId, emoji }, "sent reaction");
|
||||
} catch (err) {
|
||||
logger.error(
|
||||
{ err: String(err), chatJid, messageId, emoji },
|
||||
"failed to send reaction via web session",
|
||||
);
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
export async function sendPollWhatsApp(
|
||||
to: string,
|
||||
poll: PollInput,
|
||||
|
||||
Reference in New Issue
Block a user