Polls¶
Las encuestas en WhatsApp están cifradas end-to-end: cada voto se cifra en el dispositivo del votante y solo el creador de la encuesta (y @arcaelas/whatsapp corriendo en su sesión) puede descifrar el conteo. La librería maneja la derivación de claves y el descifrado de forma transparente — solo tratas con content, options y count.
El cifrado es automático
La librería deriva la clave HMAC por encuesta, descifra los payloads entrantes de pollUpdateMessage y los fusiona en la instancia original de Poll. Nunca necesitas tocar bytes crudos ni firmas de votos.
Configuración¶
import { WhatsApp } from '@arcaelas/whatsapp';
import { FileSystemEngine } from '@arcaelas/whatsapp/engines';
export const wa = new WhatsApp({
engine: new FileSystemEngine(__dirname),
phone: 14155551234,
});
await wa.connect((auth) => {
if (typeof auth === 'string') {
console.log('Pair code:', auth);
}
});
Crear una encuesta¶
wa.Message.poll(cid, { content, options }) publica una encuesta de elección única. content es la pregunta; cada entrada en options es un objeto con un string content.
import { wa } from './client';
const GROUP_CID = '120363025912345678@g.us';
await wa.Message.poll(GROUP_CID, {
content: 'What should we order for lunch?',
options: [
{ content: 'Pizza' },
{ content: 'Sushi' },
{ content: 'Tacos' },
],
});
Recibir votos¶
Los conteos de votos llegan como eventos message:updated sobre la encuesta original. Detéctalos con instanceof wa.Message.Poll, luego lee options (cada entrada es { content, count }) y la bandera multiple.
import { wa } from './client';
wa.on('message:updated', (msg, chat) => {
if (!(msg instanceof wa.Message.Poll)) {
return;
}
console.log(`[${chat.name}] ${msg.caption}`);
console.log(`Mode: ${msg.multiple ? 'multi-select' : 'single-select'}`);
for (const option of msg.options) {
console.log(` ${option.content}: ${option.count}`);
}
});
Suscripción por mensaje
Si solo te importa una encuesta específica, usa poll.watch(handler) después de crearla — la librería devuelve una función de desuscripción y solo se dispara para ese mensaje exacto.
Votar programáticamente¶
Llama a poll.select(index) para emitir un voto de elección única, o poll.select([i, j]) para encuestas multi-select. Los índices mapean al orden de options en el PollOptions original.
import { wa } from './client';
const POLL_CID = '120363025912345678@g.us';
const POLL_MID = '3EB0C7689C2E0F5A4F4E';
const poll = await wa.Message.get(POLL_CID, POLL_MID);
if (poll instanceof wa.Message.Poll) {
if (poll.multiple) {
await poll.select([0, 2]); // primera y tercera opción
} else {
await poll.select(1); // segunda opción
}
}
Bot de auto-voto (helper de tests)¶
Útil para tests de integración: cada vez que llega una encuesta en un chat observado, el bot elige una opción válida al azar y vota. Demuestra crear + recibir + votar en un solo ejemplo.
import { wa } from './client';
const TEST_GROUP = '120363025912345678@g.us';
wa.on('message:created', async (msg) => {
if (!(msg instanceof wa.Message.Poll)) {
return;
}
if (msg.cid !== TEST_GROUP || msg.me) {
return;
}
const total_options = msg.options.length;
if (total_options === 0) {
return;
}
if (msg.multiple) {
// Elegir un subconjunto no vacío aleatorio.
const picks: number[] = [];
for (let i = 0; i < total_options; i++) {
if (Math.random() < 0.5) {
picks.push(i);
}
}
if (picks.length === 0) {
picks.push(Math.floor(Math.random() * total_options));
}
await msg.select(picks);
} else {
const choice = Math.floor(Math.random() * total_options);
await msg.select(choice);
}
console.log(`Auto-voted on "${msg.caption}"`);
});
Citar una encuesta en una respuesta¶
Como cada subclase de Message, Poll hereda text(), image(), etc. — responder a una encuesta la cita automáticamente.