Bidirezionale

I messaggi tornano indietro. Quindi gestiscili.

Configurazione in:
Cursor

Ogni messaggio che qualcuno invia al tuo numero provisionato arriva come webhook firmato con HMAC. Leggi il testo, rispondi dallo stesso numero e lascia che sia Bird a gestire STOP e HELP per te. Costruisci flussi conversazionali e risposte automatiche sull'API con cui già invii.

send-notification.ts
202 · 0.4s
import { BirdClient } from "@messagebird/sdk";

const bird = new BirdClient({ apiKey: process.env.BIRD_API_KEY! });

const { data, error } = await bird.sms.send({
  from:     "Bird",
  to:       "+15005550006",
  text:     "Your order #4821 has shipped. Track it: bird.ly/t/4821x",
  category: "transactional",
}).safe();

if (error) throw error;
console.log(data.id);
// → "sms_4kT01Lq2m..."
Hi Ada, reminder of your appointment tomorrow at 14:30 with Dr. Kowalski.
Your order #4821 has shipped. Track it: bird.ly/t/4821x
Your subscription renews on 3 Sep for €12/mo. Manage it here: bird.ly/account

L'inbound è solo un altro webhook.

Il two-way fa parte della Bird SMS API. Quando qualcuno invia un messaggio al vostro numero, ricevete un evento sms.received sullo stesso endpoint firmato e protetto da replay che già trasporta le vostre ricevute di consegna. Nessuna seconda integrazione, nessun polling: verificate la firma una volta e gestite in base al tipo.

Resta in ascolto di ciò che torna indietro.

Un messaggio in entrata e un opt-out sono eventi, come una ricevuta di consegna. Verifica un'unica firma, fai lo switch sul type e gestisci ciascuno nell'handler che hai già scritto.

app/api/webhooks/bird/route.ts
signed
import { bird } from "@/lib/bird";

export async function POST(req: Request) {
  const event = bird.webhooks.unwrap(
    await req.text(),
    Object.fromEntries(req.headers),
  );

  switch (event.type) {
    case "sms.received":
      await handleInbound(event.data.from, event.data.text);
      break;
    case "sms.opted_out":
      await removeFromCampaigns(event.data.from);
      break;
  }

  return new Response(null, { status: 204 });
}

Il payload è lo stesso envelope su ogni canale di Bird: un id evt_, una firma HMAC e un timestamp protetto da replay.

  • sms.receivedUn messaggio in entrata è arrivato sul vostro numero: contiene il mittente, il vostro numero e il testo.
  • sms.deliveredUna risposta che hai inviato ha raggiunto il dispositivo (DLR del carrier).
  • sms.opted_outIl mittente ha inviato STOP: Bird lo ha soppresso e blocca gli invii futuri.

Un messaggio in entrata firmato, per intero.

Ecco com'è un evento sms.received sul filo. Il from è chiunque ti abbia scritto, il to è il tuo numero provisionato, e segmenti e codifica vengono riportati nello stesso modo di un invio, così una lunga risposta in entrata non è mai una sorpresa.

sms.received
evt_
{
  "id": "evt_7nQ9xLp2aR...",
  "type": "sms.received",
  "created_at": "2026-06-26T14:03:11Z",
  "data": {
    "id": "sms_5hV02Mr3n...",
    "from": "+15005550006",
    "to": "+14155550172",
    "text": "YES book me in for Thursday",
    "encoding": "GSM-7",
    "segments": 1
  }
}

Rispondi dallo stesso numero.

Una risposta è un invio con from e to invertiti. Imposta from sul tuo numero e to sul mittente originale, e la conversazione resta su un unico numero, così il destinatario vede un thread invece di un nuovo mittente ogni volta. Costruisci sopra risposte automatiche, conferme o un intero flusso conversazionale.

reply.ts
200 · reply
async function handleInbound(from: string, text: string) {
  if (/^yes\b/i.test(text)) {
    const { error } = await bird.sms.send({
      from:     "+14155550172", // your two-way number
      to:       from,           // reply to the sender
      text:     "Booked. See you Thursday at 10am.",
      category: "transactional",
    }).safe();

    if (error) throw error;
  }
}

STOP, HELP e START li gestiamo noi per te.

Bird riconosce le parole chiave riservate prima che raggiungano il tuo handler: STOP aggiunge il mittente alla tua lista di soppressione e attiva sms.opted_out, HELP restituisce una risposta di aiuto automatica e START lo iscrive di nuovo. Gli invii successivi a un numero soppresso vengono bloccati automaticamente. Puoi comunque mantenere le tue parole chiave per YES, BOOK o qualsiasi cosa serva al tuo flusso. Le regole complete su parole chiave e opt-out sono in gestione dell'opt-out.

Due cose che vorrai dopo.

Per i messaggi in entrata serve un numero abilitato al two-way: long code, short code e numeri toll-free possono ricevere, gli ID mittente alfanumerici no. Per interazioni più ricche sullo stesso dispositivo (indicatori di digitazione, conferme di lettura, caroselli), RCS potenzia la conversazione dove il dispositivo lo supporta.

Approfondisci nella documentazione.

Configura i webhook per gli eventi in entrata, leggi il riferimento agli errori per i fallimenti che gestirai e consulta abuso e conformità per le regole su keyword e consenso.

Invia e ricevi su un unico numero, un'unica API.

L'inbound bidirezionale è una delle funzionalità dell'API SMS di Bird: invio, numeri, conformità, routing e analisi arrivano insieme a esso, su un'infrastruttura che gestiamo da un decennio.

Inizia con un canale.
Aggiungi gli altri quando sei pronto.

Una chiave API di test è subito tua. La produzione si sblocca quando aggiungi un metodo di pagamento e verifichi un mittente.

Usi Claude Code, Cursor o Codex? Copia un prompt di configurazione e il tuo agente installerà la CLI e le skill di Bird per te. Scegli il tuo:

Cursor