Come costruire un bot di WhatsApp per liste di cose da fare utilizzando l'API delle Conversazioni Programmabili di Bird.

Uccello

5 feb 2020

WhatsApp

1 min read

Come costruire un bot di WhatsApp per liste di cose da fare utilizzando l'API delle Conversazioni Programmabili di Bird.

Punti Chiave

    • API delle conversazioni programmabili di Bird unifica WhatsApp, Messenger e SMS in un'unica rete di comunicazione, semplificando lo sviluppo di bot multicanale.

    • Puoi rapidamente prototipare un bot di lista delle cose da fare per WhatsApp utilizzando webhook e richieste POST semplici.

    • Strumenti come ngrok ti consentono di esporre il tuo server locale per il testing dei webhook senza una configurazione complessa di hosting.

    • L'API gestisce conversazioni attraverso più canali, permettendo una base logica unica per WhatsApp, WeChat e altre app.

    • Usa l'endpoint archiveConversation per chiudere conversazioni o “argomenti,” ideale per supporto o monitoraggio del flusso di lavoro.

    • La logica del bot può gestire conversazioni concorrenti in modo sicuro in memoria con una semplice struttura dati.

    • Lo stesso gestore di webhook funziona attraverso i canali—Bird instrada automaticamente le risposte in base all'ID della conversazione di origine.

Punti salienti del Q&A

  • Quanto è difficile costruire un bot di WhatsApp utilizzando l'API di Bird?

    È sorprendentemente facile. Con un webhook e alcune chiamate API, puoi creare un bot funzionale che legge e risponde ai messaggi in pochi minuti.

  • Ho bisogno di una configurazione speciale per ricevere messaggi?

    Sì — il bot deve essere raggiungibile da Internet. Strumenti come ngrok aiutano a creare un tunnel sicuro dal tuo computer locale.

  • Posso usare lo stesso codice sorgente per diverse app di messaggistica?

    Assolutamente. L'API Conversations astrae i canali, quindi il tuo bot può funzionare su WhatsApp, WeChat o Messenger utilizzando la stessa logica.

  • Come posso chiudere o ripristinare una conversazione?

    Invia una richiesta PATCH all'endpoint della conversazione con il corretto stato per archiviarla. Qualsiasi nuovo messaggio apre automaticamente una nuova conversazione.

  • Dove posso trovare codice di esempio?

    A: La demo completamente funzionante — Wabot su GitHub — mostra l'implementazione della gestione dei messaggi, della concorrenza e dell'archiviazione.

Bird ha recentemente lanciato le Conversazioni Programmabili. Questo permette alle aziende di integrare piattaforme di comunicazione come WhatsApp, Messenger e SMS nei loro sistemi, utilizzando una singola API.

Volevo provarlo, così ho creato un bot di WhatsApp per la lista delle cose da fare, perché chi non ha bisogno di una lista delle cose da fare automatizzata per organizzare la propria giornata? Potrebbe sembrare complicato, ma in realtà è stato facile, e mi piacerebbe raccontarvi tutto al riguardo.

Ora, lavoro in MessageBird, quindi potevo semplicemente tuffarmi e iniziare a costruire. Se provi a farlo, dovrai richiedere l'accesso anticipato. Ma una volta che sei configurato con un canale WhatsApp, puoi accedere al Dashboard sul sito web di MessageBird e iniziare.

Bird ha recentemente lanciato le Conversazioni Programmabili. Questo permette alle aziende di integrare piattaforme di comunicazione come WhatsApp, Messenger e SMS nei loro sistemi, utilizzando una singola API.

Volevo provarlo, così ho creato un bot di WhatsApp per la lista delle cose da fare, perché chi non ha bisogno di una lista delle cose da fare automatizzata per organizzare la propria giornata? Potrebbe sembrare complicato, ma in realtà è stato facile, e mi piacerebbe raccontarvi tutto al riguardo.

Ora, lavoro in MessageBird, quindi potevo semplicemente tuffarmi e iniziare a costruire. Se provi a farlo, dovrai richiedere l'accesso anticipato. Ma una volta che sei configurato con un canale WhatsApp, puoi accedere al Dashboard sul sito web di MessageBird e iniziare.

Bird ha recentemente lanciato le Conversazioni Programmabili. Questo permette alle aziende di integrare piattaforme di comunicazione come WhatsApp, Messenger e SMS nei loro sistemi, utilizzando una singola API.

Volevo provarlo, così ho creato un bot di WhatsApp per la lista delle cose da fare, perché chi non ha bisogno di una lista delle cose da fare automatizzata per organizzare la propria giornata? Potrebbe sembrare complicato, ma in realtà è stato facile, e mi piacerebbe raccontarvi tutto al riguardo.

Ora, lavoro in MessageBird, quindi potevo semplicemente tuffarmi e iniziare a costruire. Se provi a farlo, dovrai richiedere l'accesso anticipato. Ma una volta che sei configurato con un canale WhatsApp, puoi accedere al Dashboard sul sito web di MessageBird e iniziare.

Impostare l'ambiente del tuo bot WhatsApp

La prima cosa che ho fatto è stata leggere i documenti. Ho appreso che, per ricevere messaggi dal bot, avrei dovuto utilizzare un webhook. Questo significava che il mio bot avrebbe dovuto essere accessibile da Internet. Quando si costruiscono API come questa, è importante seguire le migliori pratiche per la versioning delle API per la manutenibilità. Poiché stavo appena iniziando a codificarlo, ho deciso di usare ngrok. Crea un tunnel da Internet pubblico al tuo caro localhost sulla porta 5007. Attivati!

ngrok http 5007 -region eu -subdomain todobot

La prima cosa che ho fatto è stata leggere i documenti. Ho appreso che, per ricevere messaggi dal bot, avrei dovuto utilizzare un webhook. Questo significava che il mio bot avrebbe dovuto essere accessibile da Internet. Quando si costruiscono API come questa, è importante seguire le migliori pratiche per la versioning delle API per la manutenibilità. Poiché stavo appena iniziando a codificarlo, ho deciso di usare ngrok. Crea un tunnel da Internet pubblico al tuo caro localhost sulla porta 5007. Attivati!

ngrok http 5007 -region eu -subdomain todobot

La prima cosa che ho fatto è stata leggere i documenti. Ho appreso che, per ricevere messaggi dal bot, avrei dovuto utilizzare un webhook. Questo significava che il mio bot avrebbe dovuto essere accessibile da Internet. Quando si costruiscono API come questa, è importante seguire le migliori pratiche per la versioning delle API per la manutenibilità. Poiché stavo appena iniziando a codificarlo, ho deciso di usare ngrok. Crea un tunnel da Internet pubblico al tuo caro localhost sulla porta 5007. Attivati!

ngrok http 5007 -region eu -subdomain todobot

Creare il tuo webhook e connettere Bird

Successivamente, dovevo effettuare una chiamata all'API Programmable Conversations per creare il webhook. Si tratta di un POST a https://conversations.messagebird.com/v1/webhooks e appare qualcosa del genere:

func main() {// define the webhook json payload
  wh := struct {
         Events    []string `json:"events"`
         ChannelID string   `json:"channelId"`
         URL       string   `json:"url"`
  } {
    // we would like to be notified on the URL
    URL:       "https://todobot.eu.ngrok.io/create-hook",
    // whenever a message gets created
    Events:    []string{"message.created"},
    // on the WhatsApp channel with ID
    ChannelID: "23a780701b8849f7b974d8620a89a279",
  }
  
  // encode the payload to json
  var b bytes.Buffer
  err := json.NewEncoder(&b).Encode(&wh)
  if err != nil {
    panic(err)
  }
  
  // create the http request and set authorization header
  req, err := http.NewRequest("POST", "https://conversations.messagebird.com/v1/webhooks", &b)
  req.Header.Set("Authorization", "AccessKey todo-your-access-key")
  req.Header.Set("Content-Type", "application/json") // fire the http request
  client := &http.Client{}
  resp, err := client.Do(req)
  if err != nil {
         panic(err)
  }
  defer resp.Body.Close()// is everything ok?
  body, _ := ioutil.ReadAll(resp.Body)
  if resp.StatusCode >= http.StatusBadRequest {
    panic(fmt.Errorf("Bad response code from api when trying to create webhook: %s. Body: %s", resp.Status, string(body)))
  } else {
    log.Println("All good. response body: ", string(body))
  }
}


Ottimo. Ora l'API Conversations effettuerà una richiesta POST a:

https://todobot.eu.ngrok.io/create-hook ogni volta che viene creato un nuovo messaggio sul canale WhatsApp che hai impostato in precedenza.

Questo è l'aspetto di un payload webhook:

{
  "conversation":{
    "id":"55c66895c22a40e39a8e6bd321ec192e",
    "contactId":"db4dd5087fb343738e968a323f640576",
    "status":"active",
    "createdDatetime":"2018-08-17T10:14:14Z",
    "updatedDatetime":"2018-08-17T14:30:31.915292912Z",
    "lastReceivedDatetime":"2018-08-17T14:30:31.898389294Z"
  },
  "message":{
    "id":"ddb150149e2c4036a48f581544e22cfe",
    "conversationId":"55c66895c22a40e39a8e6bd321ec192e",
    "channelId":"23a780701b8849f7b974d8620a89a279",
    "status":"received",
    "type":"text",
    "direction":"received",
    "content":{
      "text":"add buy milk"
    },
    "createdDatetime":"2018-08-17T14:30:31.898389294Z",
    "updatedDatetime":"2018-08-17T14:30:31.915292912Z"
  },
  "type":"message.created"
}


Vogliamo rispondere a quei messaggi. Iniziamo con l'eco, che ne dici?

// define the structs where we'll parse the webhook payload into
type whPayload struct {
  Conversation conversation `json:"conversation"`
  Message      message      `json:"message"`
  Type         string       `json:"type"`
}

type message struct {
  ID        string  `json:"id"`
  Direction string  `json:"direction"`
  Type      string  `json:"type"`
  Content   content `json:"content"`
}

type content struct {
  Text string `json:"text"`
}

type conversation struct {
  ID string `json:"id"`
}

func main() {
  http.HandleFunc("/create-hook", createHookHandler)
  log.Fatal(http.ListenAndServe(*httpListenAddress, nil))
}
// createHookHandler is an http handler that will handle webhook requests
func createHookHandler(w http.ResponseWriter, r *http.Request) {
  // parse the incoming json payload
  whp := &whPayload{}
  err := json.NewDecoder(r.Body).Decode(whp)
  if err != nil {
    log.Println("Err: got weird body on the webhook")
    w.WriteHeader(http.StatusInternalServerError)
    fmt.Fprintf(w, "Internal Server Error")
    return
  } 
  if whp.Message.Direction != "received" {
    // you will get *all* messages on the webhook. Even the ones this bot sends to the channel. We don't want to answer those.
    fmt.Fprintf(w, "ok")
    return
  } // echo: respond what we get
  err = respond(whp.Conversation.ID, whp.Message.Content.Text)
  
  if err != nil {
    log.Println("Err: ", err)
    w.WriteHeader(http.StatusInternalServerError)
    fmt.Fprintf(w, "Internal Server Error")return
  }
  w.WriteHeader(http.StatusOK)
  fmt.Fprintf(w, "ok")
}

Successivamente, dovevo effettuare una chiamata all'API Programmable Conversations per creare il webhook. Si tratta di un POST a https://conversations.messagebird.com/v1/webhooks e appare qualcosa del genere:

func main() {// define the webhook json payload
  wh := struct {
         Events    []string `json:"events"`
         ChannelID string   `json:"channelId"`
         URL       string   `json:"url"`
  } {
    // we would like to be notified on the URL
    URL:       "https://todobot.eu.ngrok.io/create-hook",
    // whenever a message gets created
    Events:    []string{"message.created"},
    // on the WhatsApp channel with ID
    ChannelID: "23a780701b8849f7b974d8620a89a279",
  }
  
  // encode the payload to json
  var b bytes.Buffer
  err := json.NewEncoder(&b).Encode(&wh)
  if err != nil {
    panic(err)
  }
  
  // create the http request and set authorization header
  req, err := http.NewRequest("POST", "https://conversations.messagebird.com/v1/webhooks", &b)
  req.Header.Set("Authorization", "AccessKey todo-your-access-key")
  req.Header.Set("Content-Type", "application/json") // fire the http request
  client := &http.Client{}
  resp, err := client.Do(req)
  if err != nil {
         panic(err)
  }
  defer resp.Body.Close()// is everything ok?
  body, _ := ioutil.ReadAll(resp.Body)
  if resp.StatusCode >= http.StatusBadRequest {
    panic(fmt.Errorf("Bad response code from api when trying to create webhook: %s. Body: %s", resp.Status, string(body)))
  } else {
    log.Println("All good. response body: ", string(body))
  }
}


Ottimo. Ora l'API Conversations effettuerà una richiesta POST a:

https://todobot.eu.ngrok.io/create-hook ogni volta che viene creato un nuovo messaggio sul canale WhatsApp che hai impostato in precedenza.

Questo è l'aspetto di un payload webhook:

{
  "conversation":{
    "id":"55c66895c22a40e39a8e6bd321ec192e",
    "contactId":"db4dd5087fb343738e968a323f640576",
    "status":"active",
    "createdDatetime":"2018-08-17T10:14:14Z",
    "updatedDatetime":"2018-08-17T14:30:31.915292912Z",
    "lastReceivedDatetime":"2018-08-17T14:30:31.898389294Z"
  },
  "message":{
    "id":"ddb150149e2c4036a48f581544e22cfe",
    "conversationId":"55c66895c22a40e39a8e6bd321ec192e",
    "channelId":"23a780701b8849f7b974d8620a89a279",
    "status":"received",
    "type":"text",
    "direction":"received",
    "content":{
      "text":"add buy milk"
    },
    "createdDatetime":"2018-08-17T14:30:31.898389294Z",
    "updatedDatetime":"2018-08-17T14:30:31.915292912Z"
  },
  "type":"message.created"
}


Vogliamo rispondere a quei messaggi. Iniziamo con l'eco, che ne dici?

// define the structs where we'll parse the webhook payload into
type whPayload struct {
  Conversation conversation `json:"conversation"`
  Message      message      `json:"message"`
  Type         string       `json:"type"`
}

type message struct {
  ID        string  `json:"id"`
  Direction string  `json:"direction"`
  Type      string  `json:"type"`
  Content   content `json:"content"`
}

type content struct {
  Text string `json:"text"`
}

type conversation struct {
  ID string `json:"id"`
}

func main() {
  http.HandleFunc("/create-hook", createHookHandler)
  log.Fatal(http.ListenAndServe(*httpListenAddress, nil))
}
// createHookHandler is an http handler that will handle webhook requests
func createHookHandler(w http.ResponseWriter, r *http.Request) {
  // parse the incoming json payload
  whp := &whPayload{}
  err := json.NewDecoder(r.Body).Decode(whp)
  if err != nil {
    log.Println("Err: got weird body on the webhook")
    w.WriteHeader(http.StatusInternalServerError)
    fmt.Fprintf(w, "Internal Server Error")
    return
  } 
  if whp.Message.Direction != "received" {
    // you will get *all* messages on the webhook. Even the ones this bot sends to the channel. We don't want to answer those.
    fmt.Fprintf(w, "ok")
    return
  } // echo: respond what we get
  err = respond(whp.Conversation.ID, whp.Message.Content.Text)
  
  if err != nil {
    log.Println("Err: ", err)
    w.WriteHeader(http.StatusInternalServerError)
    fmt.Fprintf(w, "Internal Server Error")return
  }
  w.WriteHeader(http.StatusOK)
  fmt.Fprintf(w, "ok")
}

Successivamente, dovevo effettuare una chiamata all'API Programmable Conversations per creare il webhook. Si tratta di un POST a https://conversations.messagebird.com/v1/webhooks e appare qualcosa del genere:

func main() {// define the webhook json payload
  wh := struct {
         Events    []string `json:"events"`
         ChannelID string   `json:"channelId"`
         URL       string   `json:"url"`
  } {
    // we would like to be notified on the URL
    URL:       "https://todobot.eu.ngrok.io/create-hook",
    // whenever a message gets created
    Events:    []string{"message.created"},
    // on the WhatsApp channel with ID
    ChannelID: "23a780701b8849f7b974d8620a89a279",
  }
  
  // encode the payload to json
  var b bytes.Buffer
  err := json.NewEncoder(&b).Encode(&wh)
  if err != nil {
    panic(err)
  }
  
  // create the http request and set authorization header
  req, err := http.NewRequest("POST", "https://conversations.messagebird.com/v1/webhooks", &b)
  req.Header.Set("Authorization", "AccessKey todo-your-access-key")
  req.Header.Set("Content-Type", "application/json") // fire the http request
  client := &http.Client{}
  resp, err := client.Do(req)
  if err != nil {
         panic(err)
  }
  defer resp.Body.Close()// is everything ok?
  body, _ := ioutil.ReadAll(resp.Body)
  if resp.StatusCode >= http.StatusBadRequest {
    panic(fmt.Errorf("Bad response code from api when trying to create webhook: %s. Body: %s", resp.Status, string(body)))
  } else {
    log.Println("All good. response body: ", string(body))
  }
}


Ottimo. Ora l'API Conversations effettuerà una richiesta POST a:

https://todobot.eu.ngrok.io/create-hook ogni volta che viene creato un nuovo messaggio sul canale WhatsApp che hai impostato in precedenza.

Questo è l'aspetto di un payload webhook:

{
  "conversation":{
    "id":"55c66895c22a40e39a8e6bd321ec192e",
    "contactId":"db4dd5087fb343738e968a323f640576",
    "status":"active",
    "createdDatetime":"2018-08-17T10:14:14Z",
    "updatedDatetime":"2018-08-17T14:30:31.915292912Z",
    "lastReceivedDatetime":"2018-08-17T14:30:31.898389294Z"
  },
  "message":{
    "id":"ddb150149e2c4036a48f581544e22cfe",
    "conversationId":"55c66895c22a40e39a8e6bd321ec192e",
    "channelId":"23a780701b8849f7b974d8620a89a279",
    "status":"received",
    "type":"text",
    "direction":"received",
    "content":{
      "text":"add buy milk"
    },
    "createdDatetime":"2018-08-17T14:30:31.898389294Z",
    "updatedDatetime":"2018-08-17T14:30:31.915292912Z"
  },
  "type":"message.created"
}


Vogliamo rispondere a quei messaggi. Iniziamo con l'eco, che ne dici?

// define the structs where we'll parse the webhook payload into
type whPayload struct {
  Conversation conversation `json:"conversation"`
  Message      message      `json:"message"`
  Type         string       `json:"type"`
}

type message struct {
  ID        string  `json:"id"`
  Direction string  `json:"direction"`
  Type      string  `json:"type"`
  Content   content `json:"content"`
}

type content struct {
  Text string `json:"text"`
}

type conversation struct {
  ID string `json:"id"`
}

func main() {
  http.HandleFunc("/create-hook", createHookHandler)
  log.Fatal(http.ListenAndServe(*httpListenAddress, nil))
}
// createHookHandler is an http handler that will handle webhook requests
func createHookHandler(w http.ResponseWriter, r *http.Request) {
  // parse the incoming json payload
  whp := &whPayload{}
  err := json.NewDecoder(r.Body).Decode(whp)
  if err != nil {
    log.Println("Err: got weird body on the webhook")
    w.WriteHeader(http.StatusInternalServerError)
    fmt.Fprintf(w, "Internal Server Error")
    return
  } 
  if whp.Message.Direction != "received" {
    // you will get *all* messages on the webhook. Even the ones this bot sends to the channel. We don't want to answer those.
    fmt.Fprintf(w, "ok")
    return
  } // echo: respond what we get
  err = respond(whp.Conversation.ID, whp.Message.Content.Text)
  
  if err != nil {
    log.Println("Err: ", err)
    w.WriteHeader(http.StatusInternalServerError)
    fmt.Fprintf(w, "Internal Server Error")return
  }
  w.WriteHeader(http.StatusOK)
  fmt.Fprintf(w, "ok")
}

Inviare risposte e gestire messaggi

Ora, per la parte interessante. Fai una richiesta POST a:

https://conversations.messagebird.com/v1/conversations/<conversationID>/messages per rispondere alla richiesta.

func respond(conversationID, responseBody string) error {
  u := fmt.Sprintf("https://conversations.messagebird.com/v1/conversations/%s/messages", conversationID)msg := message{
  Content: content{
    Text: responseBody,
  },
  Type: "text",
  }
  var b bytes.Buffer
  err := json.NewEncoder(&b).Encode(&msg)
  if err != nil {
    return fmt.Errorf("Error encoding buffer: %v", err)
  }
  req, err := http.NewRequest("POST", u.String(), &b)
  req.Header.Set("Authorization", "AccessKey todo-your-access-key")
  req.Header.Set("Content-Type", "application/json")client := &http.Client{}
  resp, err := client.Do(req)
  if err != nil {
    return err
  }
  defer resp.Body.Close()body, _ := ioutil.ReadAll(resp.Body)
  if resp.StatusCode != http.StatusCreated {
    return fmt.Errorf("Bad response code from api when trying to create message: %s. Body: %s", resp.Status, string(body))
  }
  log.Println("All good. Response body: ", string(body))
  return nil
}

Ci siamo. Questo è tutto ciò di cui hai bisogno per creare un bot che si comporta come un umano di 5 anni.


Ecco perché utilizzare l'API Conversations di Bird rende lo sviluppo di bot per WhatsApp veloce e scalabile:

Caratteristica

Cosa risolve

ID conversazione unificato

Mantieni un singolo thread attraverso app come WhatsApp, WeChat, Messenger

API singola per tutti i canali

Riutilizza la logica del bot senza riscrivere per ogni piattaforma

Automazione guidata da webhook

Gestione delle risposte rapida senza polling

Archiviazione + riapertura argomenti

Organizza la cronologia di supporto e flussi di lavoro

Struttura sicura per la concorrenza

Gestisci più chat contemporaneamente in modo affidabile


Ora, facciamo un passo verso la costruzione della lista di cose da fare. Prima, modifica un po' la funzione createHookHandler in modo che chiami la nuova funzione handleMessage invece di respond.

func createHookHandler(w http.ResponseWriter, r *http.Request) {
  ...
  err = handleMessage(whp)
  ...
}


handle parserà in modo semplice i messaggi, eseguirà alcune operazioni e sceglierà la risposta. Guardiamo il comando “add”:

func handleMessage(whp *whPayload) error {
  // every conversation has a todo list
  list := manager.fetch(whp.Conversation.ID)
  // parse the command from the message body: it's the first word
  text := whp.Message.Content.Text
  text = regexp.MustCompile(" +").ReplaceAllString(text, " ")
  parts := strings.Split(text, " ")
  command := strings.ToLower(parts[0])
  // default message
  responseBody := "I don't understand. Type 'help' to get help."
  switch command {
  ...
  case "add":
    if len(parts) < 2 {
           return respond(whp.Conversation.ID, "err... the 'add' command needs a second param: the todo item you want to save. Something like 'add buy milk'.")
    }
    // get the item from the message body
    item := strings.Join(parts[1:], " ")list.add(item)
    responseBody = "added."
  ...
  return respond(whp.Conversation.ID, responseBody)
}

Qui, impostiamo:list := manager.fetch(whp.Conversation.ID). Fondamentalmente, “manager” è una mappa sicura per la concorrenza che mappa gli ID conversazione alle liste delle cose da fare.

Una lista di cose da fare è uno slice di stringhe sicuro per la concorrenza. Tutto in memoria!

Ora, per la parte interessante. Fai una richiesta POST a:

https://conversations.messagebird.com/v1/conversations/<conversationID>/messages per rispondere alla richiesta.

func respond(conversationID, responseBody string) error {
  u := fmt.Sprintf("https://conversations.messagebird.com/v1/conversations/%s/messages", conversationID)msg := message{
  Content: content{
    Text: responseBody,
  },
  Type: "text",
  }
  var b bytes.Buffer
  err := json.NewEncoder(&b).Encode(&msg)
  if err != nil {
    return fmt.Errorf("Error encoding buffer: %v", err)
  }
  req, err := http.NewRequest("POST", u.String(), &b)
  req.Header.Set("Authorization", "AccessKey todo-your-access-key")
  req.Header.Set("Content-Type", "application/json")client := &http.Client{}
  resp, err := client.Do(req)
  if err != nil {
    return err
  }
  defer resp.Body.Close()body, _ := ioutil.ReadAll(resp.Body)
  if resp.StatusCode != http.StatusCreated {
    return fmt.Errorf("Bad response code from api when trying to create message: %s. Body: %s", resp.Status, string(body))
  }
  log.Println("All good. Response body: ", string(body))
  return nil
}

Ci siamo. Questo è tutto ciò di cui hai bisogno per creare un bot che si comporta come un umano di 5 anni.


Ecco perché utilizzare l'API Conversations di Bird rende lo sviluppo di bot per WhatsApp veloce e scalabile:

Caratteristica

Cosa risolve

ID conversazione unificato

Mantieni un singolo thread attraverso app come WhatsApp, WeChat, Messenger

API singola per tutti i canali

Riutilizza la logica del bot senza riscrivere per ogni piattaforma

Automazione guidata da webhook

Gestione delle risposte rapida senza polling

Archiviazione + riapertura argomenti

Organizza la cronologia di supporto e flussi di lavoro

Struttura sicura per la concorrenza

Gestisci più chat contemporaneamente in modo affidabile


Ora, facciamo un passo verso la costruzione della lista di cose da fare. Prima, modifica un po' la funzione createHookHandler in modo che chiami la nuova funzione handleMessage invece di respond.

func createHookHandler(w http.ResponseWriter, r *http.Request) {
  ...
  err = handleMessage(whp)
  ...
}


handle parserà in modo semplice i messaggi, eseguirà alcune operazioni e sceglierà la risposta. Guardiamo il comando “add”:

func handleMessage(whp *whPayload) error {
  // every conversation has a todo list
  list := manager.fetch(whp.Conversation.ID)
  // parse the command from the message body: it's the first word
  text := whp.Message.Content.Text
  text = regexp.MustCompile(" +").ReplaceAllString(text, " ")
  parts := strings.Split(text, " ")
  command := strings.ToLower(parts[0])
  // default message
  responseBody := "I don't understand. Type 'help' to get help."
  switch command {
  ...
  case "add":
    if len(parts) < 2 {
           return respond(whp.Conversation.ID, "err... the 'add' command needs a second param: the todo item you want to save. Something like 'add buy milk'.")
    }
    // get the item from the message body
    item := strings.Join(parts[1:], " ")list.add(item)
    responseBody = "added."
  ...
  return respond(whp.Conversation.ID, responseBody)
}

Qui, impostiamo:list := manager.fetch(whp.Conversation.ID). Fondamentalmente, “manager” è una mappa sicura per la concorrenza che mappa gli ID conversazione alle liste delle cose da fare.

Una lista di cose da fare è uno slice di stringhe sicuro per la concorrenza. Tutto in memoria!

Ora, per la parte interessante. Fai una richiesta POST a:

https://conversations.messagebird.com/v1/conversations/<conversationID>/messages per rispondere alla richiesta.

func respond(conversationID, responseBody string) error {
  u := fmt.Sprintf("https://conversations.messagebird.com/v1/conversations/%s/messages", conversationID)msg := message{
  Content: content{
    Text: responseBody,
  },
  Type: "text",
  }
  var b bytes.Buffer
  err := json.NewEncoder(&b).Encode(&msg)
  if err != nil {
    return fmt.Errorf("Error encoding buffer: %v", err)
  }
  req, err := http.NewRequest("POST", u.String(), &b)
  req.Header.Set("Authorization", "AccessKey todo-your-access-key")
  req.Header.Set("Content-Type", "application/json")client := &http.Client{}
  resp, err := client.Do(req)
  if err != nil {
    return err
  }
  defer resp.Body.Close()body, _ := ioutil.ReadAll(resp.Body)
  if resp.StatusCode != http.StatusCreated {
    return fmt.Errorf("Bad response code from api when trying to create message: %s. Body: %s", resp.Status, string(body))
  }
  log.Println("All good. Response body: ", string(body))
  return nil
}

Ci siamo. Questo è tutto ciò di cui hai bisogno per creare un bot che si comporta come un umano di 5 anni.


Ecco perché utilizzare l'API Conversations di Bird rende lo sviluppo di bot per WhatsApp veloce e scalabile:

Caratteristica

Cosa risolve

ID conversazione unificato

Mantieni un singolo thread attraverso app come WhatsApp, WeChat, Messenger

API singola per tutti i canali

Riutilizza la logica del bot senza riscrivere per ogni piattaforma

Automazione guidata da webhook

Gestione delle risposte rapida senza polling

Archiviazione + riapertura argomenti

Organizza la cronologia di supporto e flussi di lavoro

Struttura sicura per la concorrenza

Gestisci più chat contemporaneamente in modo affidabile


Ora, facciamo un passo verso la costruzione della lista di cose da fare. Prima, modifica un po' la funzione createHookHandler in modo che chiami la nuova funzione handleMessage invece di respond.

func createHookHandler(w http.ResponseWriter, r *http.Request) {
  ...
  err = handleMessage(whp)
  ...
}


handle parserà in modo semplice i messaggi, eseguirà alcune operazioni e sceglierà la risposta. Guardiamo il comando “add”:

func handleMessage(whp *whPayload) error {
  // every conversation has a todo list
  list := manager.fetch(whp.Conversation.ID)
  // parse the command from the message body: it's the first word
  text := whp.Message.Content.Text
  text = regexp.MustCompile(" +").ReplaceAllString(text, " ")
  parts := strings.Split(text, " ")
  command := strings.ToLower(parts[0])
  // default message
  responseBody := "I don't understand. Type 'help' to get help."
  switch command {
  ...
  case "add":
    if len(parts) < 2 {
           return respond(whp.Conversation.ID, "err... the 'add' command needs a second param: the todo item you want to save. Something like 'add buy milk'.")
    }
    // get the item from the message body
    item := strings.Join(parts[1:], " ")list.add(item)
    responseBody = "added."
  ...
  return respond(whp.Conversation.ID, responseBody)
}

Qui, impostiamo:list := manager.fetch(whp.Conversation.ID). Fondamentalmente, “manager” è una mappa sicura per la concorrenza che mappa gli ID conversazione alle liste delle cose da fare.

Una lista di cose da fare è uno slice di stringhe sicuro per la concorrenza. Tutto in memoria!

Archiviare le conversazioni e scalare il tuo bot

Un'altra cosa importante! Puoi archiviare le conversazioni. In alcune applicazioni, come i CRM, è importante tenere traccia di alcune interazioni — per tenere traccia dell'efficacia degli impiegati del supporto clienti, ad esempio. L'API Conversations ti consente di archiviare una conversazione per "chiudere" l'argomento. Se l'utente/client invia un altro messaggio, l'API Conversations aprirà automaticamente un nuovo argomento.

Gestione del ciclo di vita della conversazione

Inoltre. Effettuando una richiesta PATCH a https://conversations.messagebird.com/v1/conversations/{id} con lo stato corretto nel corpo, puoi archiviare la conversazione con quell'id. Facciamo questo con il comando “bye”:

case "bye":
  archiveConversation(whp.Conversation.ID)
  manager.close(whp.Conversation.ID)
  responseBody = "bye!"

archiveConversation eseguirà la richiesta PATCH e manager.close(whp.Conversation.ID) rimuoverà la conversazione dalla lista delle cose da fare.

Ma ehi, Programmable Conversations è una soluzione omnicanale. E se volessi riutilizzare il codice del bot per una piattaforma diversa, come WeChat? Questo approccio multicanale fa parte della strategia di deviare le richieste verso canali a costo inferiore. Come procederesti?

Devi solo creare un nuovo webhook per targettare quel canale! Un webhook che invia richieste allo stesso https://todobot.eu.ngrok.io/create-hook url che abbiamo usato per WhatsApp!

Questo funzionerà perché il codice del gestore utilizza sempre il conversationID dal payload del webhook per rispondere ai messaggi invece di un channelID codificato. L'API Conversations di MessageBird determinerà automaticamente il canale per la conversazione per inviare il tuo messaggio.

Vuoi costruire il tuo bot? Dai un'occhiata al codice completo su Github: Wabot su Github, richiedi l'accesso anticipato a WhatsApp visitando la pagina di WhatsApp e cliccando sul pulsante Contatta Vendite per compilare il modulo. Buon botting!

Un'altra cosa importante! Puoi archiviare le conversazioni. In alcune applicazioni, come i CRM, è importante tenere traccia di alcune interazioni — per tenere traccia dell'efficacia degli impiegati del supporto clienti, ad esempio. L'API Conversations ti consente di archiviare una conversazione per "chiudere" l'argomento. Se l'utente/client invia un altro messaggio, l'API Conversations aprirà automaticamente un nuovo argomento.

Gestione del ciclo di vita della conversazione

Inoltre. Effettuando una richiesta PATCH a https://conversations.messagebird.com/v1/conversations/{id} con lo stato corretto nel corpo, puoi archiviare la conversazione con quell'id. Facciamo questo con il comando “bye”:

case "bye":
  archiveConversation(whp.Conversation.ID)
  manager.close(whp.Conversation.ID)
  responseBody = "bye!"

archiveConversation eseguirà la richiesta PATCH e manager.close(whp.Conversation.ID) rimuoverà la conversazione dalla lista delle cose da fare.

Ma ehi, Programmable Conversations è una soluzione omnicanale. E se volessi riutilizzare il codice del bot per una piattaforma diversa, come WeChat? Questo approccio multicanale fa parte della strategia di deviare le richieste verso canali a costo inferiore. Come procederesti?

Devi solo creare un nuovo webhook per targettare quel canale! Un webhook che invia richieste allo stesso https://todobot.eu.ngrok.io/create-hook url che abbiamo usato per WhatsApp!

Questo funzionerà perché il codice del gestore utilizza sempre il conversationID dal payload del webhook per rispondere ai messaggi invece di un channelID codificato. L'API Conversations di MessageBird determinerà automaticamente il canale per la conversazione per inviare il tuo messaggio.

Vuoi costruire il tuo bot? Dai un'occhiata al codice completo su Github: Wabot su Github, richiedi l'accesso anticipato a WhatsApp visitando la pagina di WhatsApp e cliccando sul pulsante Contatta Vendite per compilare il modulo. Buon botting!

Un'altra cosa importante! Puoi archiviare le conversazioni. In alcune applicazioni, come i CRM, è importante tenere traccia di alcune interazioni — per tenere traccia dell'efficacia degli impiegati del supporto clienti, ad esempio. L'API Conversations ti consente di archiviare una conversazione per "chiudere" l'argomento. Se l'utente/client invia un altro messaggio, l'API Conversations aprirà automaticamente un nuovo argomento.

Gestione del ciclo di vita della conversazione

Inoltre. Effettuando una richiesta PATCH a https://conversations.messagebird.com/v1/conversations/{id} con lo stato corretto nel corpo, puoi archiviare la conversazione con quell'id. Facciamo questo con il comando “bye”:

case "bye":
  archiveConversation(whp.Conversation.ID)
  manager.close(whp.Conversation.ID)
  responseBody = "bye!"

archiveConversation eseguirà la richiesta PATCH e manager.close(whp.Conversation.ID) rimuoverà la conversazione dalla lista delle cose da fare.

Ma ehi, Programmable Conversations è una soluzione omnicanale. E se volessi riutilizzare il codice del bot per una piattaforma diversa, come WeChat? Questo approccio multicanale fa parte della strategia di deviare le richieste verso canali a costo inferiore. Come procederesti?

Devi solo creare un nuovo webhook per targettare quel canale! Un webhook che invia richieste allo stesso https://todobot.eu.ngrok.io/create-hook url che abbiamo usato per WhatsApp!

Questo funzionerà perché il codice del gestore utilizza sempre il conversationID dal payload del webhook per rispondere ai messaggi invece di un channelID codificato. L'API Conversations di MessageBird determinerà automaticamente il canale per la conversazione per inviare il tuo messaggio.

Vuoi costruire il tuo bot? Dai un'occhiata al codice completo su Github: Wabot su Github, richiedi l'accesso anticipato a WhatsApp visitando la pagina di WhatsApp e cliccando sul pulsante Contatta Vendite per compilare il modulo. Buon botting!

Altre notizie

Leggi di più da questa categoria

A person is standing at a desk while typing on a laptop.

La piattaforma completa nativa dell'IA che si espande con la tua azienda.

© 2025 Uccello

A person is standing at a desk while typing on a laptop.

La piattaforma completa nativa dell'IA che si espande con la tua azienda.

© 2025 Uccello