feat: unify poll support
Co-authored-by: DBH <5251425+dbhurley@users.noreply.github.com>
This commit is contained in:
@@ -1,13 +1,9 @@
|
||||
import type { PollInput } from "../polls.js";
|
||||
|
||||
export type ActiveWebSendOptions = {
|
||||
gifPlayback?: boolean;
|
||||
};
|
||||
|
||||
export type PollOptions = {
|
||||
question: string;
|
||||
options: string[];
|
||||
selectableCount?: number;
|
||||
};
|
||||
|
||||
export type ActiveWebListener = {
|
||||
sendMessage: (
|
||||
to: string,
|
||||
@@ -16,7 +12,7 @@ export type ActiveWebListener = {
|
||||
mediaType?: string,
|
||||
options?: ActiveWebSendOptions,
|
||||
) => Promise<{ messageId: string }>;
|
||||
sendPoll: (to: string, poll: PollOptions) => Promise<{ messageId: string }>;
|
||||
sendPoll: (to: string, poll: PollInput) => Promise<{ messageId: string }>;
|
||||
sendComposingTo: (to: string) => Promise<void>;
|
||||
close?: () => Promise<void>;
|
||||
};
|
||||
|
||||
@@ -456,6 +456,20 @@ export async function monitorWebInbox(options: {
|
||||
const result = await sock.sendMessage(jid, payload);
|
||||
return { messageId: result?.key?.id ?? "unknown" };
|
||||
},
|
||||
sendPoll: async (
|
||||
to: string,
|
||||
poll: { question: string; options: string[]; maxSelections?: number },
|
||||
): Promise<{ messageId: string }> => {
|
||||
const jid = toWhatsappJid(to);
|
||||
const result = await sock.sendMessage(jid, {
|
||||
poll: {
|
||||
name: poll.question,
|
||||
values: poll.options,
|
||||
selectableCount: poll.maxSelections ?? 1,
|
||||
},
|
||||
});
|
||||
return { messageId: result?.key?.id ?? "unknown" };
|
||||
},
|
||||
/**
|
||||
* Send typing indicator ("composing") to a chat.
|
||||
* Used after IPC send to show more messages are coming.
|
||||
|
||||
@@ -8,15 +8,16 @@ vi.mock("./media.js", () => ({
|
||||
loadWebMedia: (...args: unknown[]) => loadWebMediaMock(...args),
|
||||
}));
|
||||
|
||||
import { sendMessageWhatsApp } from "./outbound.js";
|
||||
import { sendMessageWhatsApp, sendPollWhatsApp } 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" }));
|
||||
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
setActiveWebListener({ sendComposingTo, sendMessage });
|
||||
setActiveWebListener({ sendComposingTo, sendMessage, sendPoll });
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
@@ -137,4 +138,22 @@ describe("web outbound", () => {
|
||||
"application/pdf",
|
||||
);
|
||||
});
|
||||
|
||||
it("sends polls via active listener", async () => {
|
||||
const result = await sendPollWhatsApp(
|
||||
"+1555",
|
||||
{ question: "Lunch?", options: ["Pizza", "Sushi"], maxSelections: 2 },
|
||||
{ verbose: false },
|
||||
);
|
||||
expect(result).toEqual({
|
||||
messageId: "poll123",
|
||||
toJid: "1555@s.whatsapp.net",
|
||||
});
|
||||
expect(sendPoll).toHaveBeenCalledWith("+1555", {
|
||||
question: "Lunch?",
|
||||
options: ["Pizza", "Sushi"],
|
||||
maxSelections: 2,
|
||||
durationHours: undefined,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { randomUUID } from "node:crypto";
|
||||
|
||||
import { createSubsystemLogger, getChildLogger } from "../logging.js";
|
||||
import { normalizePollInput, type PollInput } from "../polls.js";
|
||||
import { toWhatsappJid } from "../utils.js";
|
||||
import {
|
||||
type ActiveWebSendOptions,
|
||||
type PollOptions,
|
||||
getActiveWebListener,
|
||||
} from "./active-listener.js";
|
||||
import { loadWebMedia } from "./media.js";
|
||||
@@ -86,11 +86,10 @@ export async function sendMessageWhatsApp(
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
export async function sendPollWhatsApp(
|
||||
to: string,
|
||||
poll: PollOptions,
|
||||
options: { verbose: boolean },
|
||||
poll: PollInput,
|
||||
_options: { verbose: boolean },
|
||||
): Promise<{ messageId: string; toJid: string }> {
|
||||
const correlationId = randomUUID();
|
||||
const startedAt = Date.now();
|
||||
@@ -107,12 +106,18 @@ export async function sendPollWhatsApp(
|
||||
});
|
||||
try {
|
||||
const jid = toWhatsappJid(to);
|
||||
outboundLog.info(`Sending poll -> ${jid}: "${poll.question}"`);
|
||||
const normalized = normalizePollInput(poll, { maxOptions: 12 });
|
||||
outboundLog.info(`Sending poll -> ${jid}: "${normalized.question}"`);
|
||||
logger.info(
|
||||
{ jid, question: poll.question, optionCount: poll.options.length },
|
||||
{
|
||||
jid,
|
||||
question: normalized.question,
|
||||
optionCount: normalized.options.length,
|
||||
maxSelections: normalized.maxSelections,
|
||||
},
|
||||
"sending poll",
|
||||
);
|
||||
const result = await active.sendPoll(to, poll);
|
||||
const result = await active.sendPoll(to, normalized);
|
||||
const messageId =
|
||||
(result as { messageId?: string })?.messageId ?? "unknown";
|
||||
const durationMs = Date.now() - startedAt;
|
||||
|
||||
Reference in New Issue
Block a user