feat: Add WhatsApp poll support (#248)

Implements issue #123 - WhatsApp Poll Support

## Gateway Protocol
- Add `poll` RPC method with params: to, question, options (2-12), selectableCount

## ActiveWebListener
- Add `sendPoll(to, poll)` method to interface
- Implementation uses Baileys poll message type

## CLI Command
- `clawdbot poll --to <jid> -q <question> -o <opt1> -o <opt2> [-s count]`
- Supports --dry-run, --json, --verbose flags
- Validates 2-12 options

## Changes
- src/gateway/protocol/schema.ts: Add PollParamsSchema
- src/gateway/protocol/index.ts: Export validator and types
- src/web/active-listener.ts: Add sendPoll to interface
- src/web/inbound.ts: Implement sendPoll using Baileys
- src/web/outbound.ts: Add sendPollWhatsApp function
- src/gateway/server-methods/send.ts: Add poll handler
- src/commands/poll.ts: New CLI command
- src/cli/program.ts: Register poll command

Closes #123
This commit is contained in:
DBH
2026-01-05 23:44:15 -05:00
committed by GitHub
parent ea6ee16461
commit 2737e17c67
8 changed files with 278 additions and 1 deletions

73
src/commands/poll.ts Normal file
View File

@@ -0,0 +1,73 @@
import type { CliDeps } from "../cli/deps.js";
import { callGateway, randomIdempotencyKey } from "../gateway/call.js";
import { success } from "../globals.js";
import type { RuntimeEnv } from "../runtime.js";
export async function pollCommand(
opts: {
to: string;
question: string;
options: string[];
selectableCount?: number;
json?: boolean;
dryRun?: boolean;
},
_deps: CliDeps,
runtime: RuntimeEnv,
) {
if (opts.options.length < 2) {
throw new Error("Poll requires at least 2 options");
}
if (opts.options.length > 12) {
throw new Error("Poll supports at most 12 options");
}
if (opts.dryRun) {
runtime.log(
`[dry-run] would send poll to ${opts.to}:\n Question: ${opts.question}\n Options: ${opts.options.join(", ")}\n Selectable: ${opts.selectableCount ?? 1}`,
);
return;
}
const result = await callGateway<{
messageId: string;
toJid?: string;
}>({
url: "ws://127.0.0.1:18789",
method: "poll",
params: {
to: opts.to,
question: opts.question,
options: opts.options,
selectableCount: opts.selectableCount ?? 1,
idempotencyKey: randomIdempotencyKey(),
},
timeoutMs: 10_000,
clientName: "cli",
mode: "cli",
});
runtime.log(
success(
`✅ Poll sent via gateway. Message ID: ${result.messageId ?? "unknown"}`,
),
);
if (opts.json) {
runtime.log(
JSON.stringify(
{
provider: "whatsapp",
via: "gateway",
to: opts.to,
toJid: result.toJid,
messageId: result.messageId,
question: opts.question,
options: opts.options,
selectableCount: opts.selectableCount ?? 1,
},
null,
2,
),
);
}
}