Integrações: SMS e Telegram¶
Mais canais sob o mesmo contrato MessagingProvider — troque de canal sem mudar
o código de negócio.
Telegram¶
Cliente da Bot API (sem SDK). Envia por REST e recebe por long-polling.
import { TelegramProvider } from "tempest-express-sdk";
const tg = new TelegramProvider({ token: process.env.TELEGRAM_BOT_TOKEN! });
await tg.sendText("<chat_id>", "Olá do bot 🤖");
await tg.sendMedia("<chat_id>", { kind: "image", media: "https://.../foto.jpg", caption: "oi" });
// Receber (long-polling getUpdates):
const stop = await tg.onMessage((msg) => {
console.log("recebida:", msg.from, msg.text);
});
// depois: await stop();
SMS (Twilio)¶
Cliente REST do Twilio. Enviar não tem dependência; receber é por webhook (SMS
não tem assinatura persistente, então onMessage não existe neste provider).
import { TwilioSmsProvider } from "tempest-express-sdk";
const sms = new TwilioSmsProvider({
accountSid: process.env.TWILIO_SID!,
authToken: process.env.TWILIO_TOKEN!,
from: "+15550000000",
});
await sms.sendText("+15551112222", "Seu código é 1234");
Webhook de entrada (validado)¶
O makeTwilioWebhookRouter valida a assinatura X-Twilio-Signature (HMAC-SHA1)
e entrega um InboundMessage tipado.
import { createApp, makeTwilioWebhookRouter } from "tempest-express-sdk";
const app = await createApp({
configure: (a) => {
a.use(
makeTwilioWebhookRouter({
authToken: process.env.TWILIO_TOKEN!,
publicUrl: "https://api.suaempresa.com/sms/inbound", // atrás de proxy
onMessage: async (msg) => {
await handleSms(msg); // { from, messageId, text, ... }
},
}),
);
},
});
Assinatura inválida → 401. Responde <Response></Response> (TwiML vazio).
Email como canal¶
EmailProvider também implementa MessagingProvider (sobre EmailUtils), então
notificação por email usa a mesma interface.
import { EmailProvider, EmailUtils } from "tempest-express-sdk";
const email = new EmailUtils({ host: "smtp.exemplo.com", from: "no-reply@exemplo.com" });
const provider = new EmailProvider({ email, subject: "Aviso" });
await provider.sendText("ana@example.com", "Seu pedido saiu para entrega");
onMessage/checkNumber não existem no email (só envio).
Programe contra o contrato¶
import type { MessagingProvider } from "tempest-express-sdk";
// Funciona com WhatsApp, Telegram ou SMS — injete o provider.
async function notify(provider: MessagingProvider, to: string, text: string) {
await provider.sendText(to, text);
}
Broadcast e multi-canal¶
broadcastText envia uma mensagem a vários destinatários por um provider, com
concorrência limitada e resultado por destinatário (uma falha não aborta o lote).
MessagingHub registra providers por nome.
import { MessagingHub, broadcastText } from "tempest-express-sdk";
const results = await broadcastText(wa, ["5511...", "5521..."], "Promo!", { concurrency: 20 });
const falhas = results.filter((r) => !r.ok);
const hub = new MessagingHub()
.register("whatsapp", wa)
.register("sms", sms)
.register("email", emailProvider);
await hub.send("sms", "+15551112222", "Código 1234");
await hub.broadcast("whatsapp", numeros, "Aviso");
Capacidades por canal
sendText/sendMedia/status existem em todos. onMessage existe onde há
assinatura viva (WhatsApp /ws, Telegram polling); checkNumber só no
WhatsApp. Cheque a presença do método antes de chamar em código genérico.
Recapitulando¶
WhatsApp, Telegram e SMS compartilham o MessagingProvider. Telegram recebe por
polling; SMS por webhook assinado; todos enviam com a mesma interface.