Hoe bouw je een WhatsApp-bot voor takenlijsten met behulp van Bird’s Programmable Conversations API

Bird

5 feb 2020

WhatsApp

1 min read

Hoe bouw je een WhatsApp-bot voor takenlijsten met behulp van Bird’s Programmable Conversations API

Belangrijkste punten

    • Bird’s Programmable Conversations API verenigt WhatsApp, Messenger en SMS in een enkele communicatielaag, wat de ontwikkeling van multi-channel bots vereenvoudigt.

    • Je kunt snel een WhatsApp to-do lijst bot prototypen met behulp van webhooks en eenvoudige POST-verzoeken.

    • Tools zoals ngrok stellen je in staat om je lokale server bloot te stellen voor het testen van webhooks zonder complexe hosting opzet.

    • De API beheert gesprekken over meerdere kanalen, zodat er één logische basis is voor WhatsApp, WeChat en andere apps.

    • Gebruik het archiveConversation endpoint om gesprekken of "onderwerpen" te sluiten, ideaal voor ondersteuning of workflow tracking.

    • De botlogica kan gelijktijdige gesprekken veilig in het geheugen beheren met een eenvoudige datastructuur.

    • Dezelfde webhook-handler werkt over kanalen heen—Bird routeert automatisch reacties op basis van de oorspronkelijke conversatie-ID.

Q&A Hoogtepunten

  • Hoe moeilijk is het om een WhatsApp-bot te bouwen met de Bird API?

    Het is verrassend eenvoudig. Met een webhook en een paar API-oproepen kun je binnen enkele minuten een functionele bot bouwen die berichten leest en erop reageert.

  • Heb ik speciale setup nodig om berichten te ontvangen?

    Ja — de bot moet bereikbaar zijn vanaf het internet. Tools zoals ngrok helpen bij het creëren van een veilige tunnel vanaf je lokale machine.

  • Kan ik dezelfde codebase gebruiken voor verschillende messaging apps?

    Absoluut. De Conversations API abstraheert kanalen, zodat je bot kan draaien op WhatsApp, WeChat, of Messenger met identieke logica.

  • Hoe sluit of reset ik een chatthread?

    Stuur een PATCH-verzoek naar het eindpunt van het gesprek met de juiste status om het te archiveren. Elk nieuw bericht opent automatisch een nieuw gesprek.

  • Waar kan ik voorbeeldcode vinden?

    A: De volledige werkende demo — Wabot on GitHub — toont de implementatie van berichtverwerking, gelijktijdigheid en archivering.

Bird heeft onlangs Programmable Conversations gelanceerd. Hiermee kunnen bedrijven communicatieplatforms zoals WhatsApp, Messenger en SMS in hun systemen integreren — met behulp van een enkele API.

Ik wilde het uitproberen, dus ik bouwde een WhatsApp-bot takenlijst, want wie heeft er geen geautomatiseerde takenlijst nodig om hun dag te organiseren? Het klinkt misschien ingewikkeld, maar het was eigenlijk eenvoudig, en ik wil je er alles over vertellen.

Nu werk ik bij MessageBird, dus ik kon gewoon beginnen met bouwen. Als je dit probeert, moet je vroege toegang aanvragen. Maar zodra je een WhatsApp-kanaal hebt ingesteld, kun je inloggen op het Dashboard op de MessageBird-website en aan de slag gaan.

Bird heeft onlangs Programmable Conversations gelanceerd. Hiermee kunnen bedrijven communicatieplatforms zoals WhatsApp, Messenger en SMS in hun systemen integreren — met behulp van een enkele API.

Ik wilde het uitproberen, dus ik bouwde een WhatsApp-bot takenlijst, want wie heeft er geen geautomatiseerde takenlijst nodig om hun dag te organiseren? Het klinkt misschien ingewikkeld, maar het was eigenlijk eenvoudig, en ik wil je er alles over vertellen.

Nu werk ik bij MessageBird, dus ik kon gewoon beginnen met bouwen. Als je dit probeert, moet je vroege toegang aanvragen. Maar zodra je een WhatsApp-kanaal hebt ingesteld, kun je inloggen op het Dashboard op de MessageBird-website en aan de slag gaan.

Bird heeft onlangs Programmable Conversations gelanceerd. Hiermee kunnen bedrijven communicatieplatforms zoals WhatsApp, Messenger en SMS in hun systemen integreren — met behulp van een enkele API.

Ik wilde het uitproberen, dus ik bouwde een WhatsApp-bot takenlijst, want wie heeft er geen geautomatiseerde takenlijst nodig om hun dag te organiseren? Het klinkt misschien ingewikkeld, maar het was eigenlijk eenvoudig, en ik wil je er alles over vertellen.

Nu werk ik bij MessageBird, dus ik kon gewoon beginnen met bouwen. Als je dit probeert, moet je vroege toegang aanvragen. Maar zodra je een WhatsApp-kanaal hebt ingesteld, kun je inloggen op het Dashboard op de MessageBird-website en aan de slag gaan.

Het instellen van je WhatsApp bot-omgeving

Het eerste wat ik deed, was de docs lezen. Ik leerde dat ik, om berichten van de bot te ontvangen, een webhook zou moeten gebruiken. Dit betekende dat mijn bot toegankelijk zou moeten zijn vanaf het internet. Bij het bouwen van API's zoals deze, is het belangrijk om API versioning best practices te volgen voor de onderhoudbaarheid. Aangezien ik net begon met het coderen daarvan, besloot ik ngrok te gebruiken. Het creëert een tunnel van het openbare internet naar je geliefde localhost poort 5007. Engage!

ngrok http 5007 -region eu -subdomain todobot

Het eerste wat ik deed, was de docs lezen. Ik leerde dat ik, om berichten van de bot te ontvangen, een webhook zou moeten gebruiken. Dit betekende dat mijn bot toegankelijk zou moeten zijn vanaf het internet. Bij het bouwen van API's zoals deze, is het belangrijk om API versioning best practices te volgen voor de onderhoudbaarheid. Aangezien ik net begon met het coderen daarvan, besloot ik ngrok te gebruiken. Het creëert een tunnel van het openbare internet naar je geliefde localhost poort 5007. Engage!

ngrok http 5007 -region eu -subdomain todobot

Het eerste wat ik deed, was de docs lezen. Ik leerde dat ik, om berichten van de bot te ontvangen, een webhook zou moeten gebruiken. Dit betekende dat mijn bot toegankelijk zou moeten zijn vanaf het internet. Bij het bouwen van API's zoals deze, is het belangrijk om API versioning best practices te volgen voor de onderhoudbaarheid. Aangezien ik net begon met het coderen daarvan, besloot ik ngrok te gebruiken. Het creëert een tunnel van het openbare internet naar je geliefde localhost poort 5007. Engage!

ngrok http 5007 -region eu -subdomain todobot

Uw webhook maken en Bird verbinden

Vervolgens moest ik een aanroep doen naar de Programmable Conversations API om de webhook te maken. Het is een POST naar https://conversations.messagebird.com/v1/webhooks en het ziet er ongeveer zo uit:

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))
  }
}


Mooi. Nu gaat de Conversations API een POST verzoek doen naar:

https://todobot.eu.ngrok.io/create-hook wanneer er een nieuw bericht wordt aangemaakt op het WhatsApp-kanaal dat je eerder hebt ingesteld.

Dit is hoe een webhook payload eruit ziet:

{
  "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"
}


We willen die berichten beantwoorden. Laten we beginnen met ze terug te sturen, wat zeg je?

// 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")
}

Vervolgens moest ik een aanroep doen naar de Programmable Conversations API om de webhook te maken. Het is een POST naar https://conversations.messagebird.com/v1/webhooks en het ziet er ongeveer zo uit:

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))
  }
}


Mooi. Nu gaat de Conversations API een POST verzoek doen naar:

https://todobot.eu.ngrok.io/create-hook wanneer er een nieuw bericht wordt aangemaakt op het WhatsApp-kanaal dat je eerder hebt ingesteld.

Dit is hoe een webhook payload eruit ziet:

{
  "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"
}


We willen die berichten beantwoorden. Laten we beginnen met ze terug te sturen, wat zeg je?

// 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")
}

Vervolgens moest ik een aanroep doen naar de Programmable Conversations API om de webhook te maken. Het is een POST naar https://conversations.messagebird.com/v1/webhooks en het ziet er ongeveer zo uit:

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))
  }
}


Mooi. Nu gaat de Conversations API een POST verzoek doen naar:

https://todobot.eu.ngrok.io/create-hook wanneer er een nieuw bericht wordt aangemaakt op het WhatsApp-kanaal dat je eerder hebt ingesteld.

Dit is hoe een webhook payload eruit ziet:

{
  "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"
}


We willen die berichten beantwoorden. Laten we beginnen met ze terug te sturen, wat zeg je?

// 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")
}

Reacties versturen en berichten verwerken

Nu, voor het interessante gedeelte. Doe een POST-verzoek naar:

https://conversations.messagebird.com/v1/conversations/<conversationID>/messages om het verzoek te beantwoorden.

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
}

Daar. Dit is alles wat je nodig hebt om een bot te maken die zich gedraagt als een 5-jarige mens.


Hier is waarom het gebruik van Bird's Conversations API de ontwikkeling van WhatsApp-bots snel en schaalbaar maakt:

Functie

Wat het oplost

Geïdentificeerde conversatie-ID

Onderhouden van een enkele thread over apps zoals WhatsApp, WeChat, Messenger

Enkele API voor alle kanalen

Herbruik botlogica zonder herschrijven voor elk platform

Webhook-gestuurde automatisering

Snelle verwerking van reacties zonder polsen

Archiveren + heropenen van onderwerpen

Organiseer ondersteuningsgeschiedenis en workflows

Concurentie-veilige structuur

Betrouwbaar meerdere chats tegelijk afhandelen


Nu, laten we een stap zetten naar het bouwen van de complete takenlijst. Pas eerst de functie createHookHandler een beetje aan zodat het de nieuwe functie handleMessage aanroept in plaats van respond.

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


handle zal op simplistische wijze de berichten analyseren, wat werk doen en een reactie uitkiezen. Laten we eens kijken naar het “add”-commando:

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)
}

Hier stellen we in: list := manager.fetch(whp.Conversation.ID). In feite is "manager" een concurrerende veilige map die conversatie-ID's koppelt aan takenlijsten.

Een takenlijst is een concurrerende veilige string-slice. Alles in het geheugen!

Nu, voor het interessante gedeelte. Doe een POST-verzoek naar:

https://conversations.messagebird.com/v1/conversations/<conversationID>/messages om het verzoek te beantwoorden.

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
}

Daar. Dit is alles wat je nodig hebt om een bot te maken die zich gedraagt als een 5-jarige mens.


Hier is waarom het gebruik van Bird's Conversations API de ontwikkeling van WhatsApp-bots snel en schaalbaar maakt:

Functie

Wat het oplost

Geïdentificeerde conversatie-ID

Onderhouden van een enkele thread over apps zoals WhatsApp, WeChat, Messenger

Enkele API voor alle kanalen

Herbruik botlogica zonder herschrijven voor elk platform

Webhook-gestuurde automatisering

Snelle verwerking van reacties zonder polsen

Archiveren + heropenen van onderwerpen

Organiseer ondersteuningsgeschiedenis en workflows

Concurentie-veilige structuur

Betrouwbaar meerdere chats tegelijk afhandelen


Nu, laten we een stap zetten naar het bouwen van de complete takenlijst. Pas eerst de functie createHookHandler een beetje aan zodat het de nieuwe functie handleMessage aanroept in plaats van respond.

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


handle zal op simplistische wijze de berichten analyseren, wat werk doen en een reactie uitkiezen. Laten we eens kijken naar het “add”-commando:

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)
}

Hier stellen we in: list := manager.fetch(whp.Conversation.ID). In feite is "manager" een concurrerende veilige map die conversatie-ID's koppelt aan takenlijsten.

Een takenlijst is een concurrerende veilige string-slice. Alles in het geheugen!

Nu, voor het interessante gedeelte. Doe een POST-verzoek naar:

https://conversations.messagebird.com/v1/conversations/<conversationID>/messages om het verzoek te beantwoorden.

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
}

Daar. Dit is alles wat je nodig hebt om een bot te maken die zich gedraagt als een 5-jarige mens.


Hier is waarom het gebruik van Bird's Conversations API de ontwikkeling van WhatsApp-bots snel en schaalbaar maakt:

Functie

Wat het oplost

Geïdentificeerde conversatie-ID

Onderhouden van een enkele thread over apps zoals WhatsApp, WeChat, Messenger

Enkele API voor alle kanalen

Herbruik botlogica zonder herschrijven voor elk platform

Webhook-gestuurde automatisering

Snelle verwerking van reacties zonder polsen

Archiveren + heropenen van onderwerpen

Organiseer ondersteuningsgeschiedenis en workflows

Concurentie-veilige structuur

Betrouwbaar meerdere chats tegelijk afhandelen


Nu, laten we een stap zetten naar het bouwen van de complete takenlijst. Pas eerst de functie createHookHandler een beetje aan zodat het de nieuwe functie handleMessage aanroept in plaats van respond.

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


handle zal op simplistische wijze de berichten analyseren, wat werk doen en een reactie uitkiezen. Laten we eens kijken naar het “add”-commando:

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)
}

Hier stellen we in: list := manager.fetch(whp.Conversation.ID). In feite is "manager" een concurrerende veilige map die conversatie-ID's koppelt aan takenlijsten.

Een takenlijst is een concurrerende veilige string-slice. Alles in het geheugen!

Archiveren van gesprekken en het opschalen van je bot

Een ander belangrijk ding! Je kunt gesprekken archiveren. In sommige applicaties, zoals CRM's, is het belangrijk om bepaalde interacties bij te houden — om bijvoorbeeld de effectiviteit van klantenservice medewerkers te volgen. De Conversations API laat je een gesprek archiveren om het onderwerp te "sluiten". Als de gebruiker/klant een ander bericht stuurt, opent de Conversations API automatisch een nieuw onderwerp.

Beheer van de gesprekslevenscyclus

Ook. Door een PATCH-verzoek te doen naar https://conversations.messagebird.com/v1/conversations/{id} met de juiste status in de body, kun je het gesprek met die id archiveren. We doen dit met het “bye” commando:

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

archiveConversation zal het PATCH-verzoek uitvoeren en manager.close(whp.Conversation.ID) zal de to-dolijst conversatie verwijderen.

Maar hé, Programmable Conversations is een omni-channel oplossing. Wat als je de code van de bot voor een ander platform, zoals WeChat, wilt hergebruiken? Deze multi-channel benadering is deel van de strategie om vragen te verwijzen naar goedkopere kanalen. Hoe zou je dit aanpakken?

Maak gewoon een nieuwe webhook om dat kanaal te targeten! Een webhook die verzoeken stuurt naar dezelfde https://todobot.eu.ngrok.io/create-hook url die we voor WhatsApp hebben gebruikt!

Dit zal werken omdat de handler code altijd de conversationID van de webhook payload gebruikt om de berichten te beantwoorden in plaats van een hardcoded channelID. MessageBird’s Conversations API zal automatisch het kanaal voor het gesprek bepalen om je bericht over te sturen.

Wil je je eigen bot bouwen? Bekijk de volledige code op Github: Wabot op Github, vraag vroegtijdige toegang aan tot WhatsApp door de WhatsApp pagina te bezoeken en op de Contact Sales knop te klikken om het formulier in te vullen. Veel plezier met botten!

Een ander belangrijk ding! Je kunt gesprekken archiveren. In sommige applicaties, zoals CRM's, is het belangrijk om bepaalde interacties bij te houden — om bijvoorbeeld de effectiviteit van klantenservice medewerkers te volgen. De Conversations API laat je een gesprek archiveren om het onderwerp te "sluiten". Als de gebruiker/klant een ander bericht stuurt, opent de Conversations API automatisch een nieuw onderwerp.

Beheer van de gesprekslevenscyclus

Ook. Door een PATCH-verzoek te doen naar https://conversations.messagebird.com/v1/conversations/{id} met de juiste status in de body, kun je het gesprek met die id archiveren. We doen dit met het “bye” commando:

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

archiveConversation zal het PATCH-verzoek uitvoeren en manager.close(whp.Conversation.ID) zal de to-dolijst conversatie verwijderen.

Maar hé, Programmable Conversations is een omni-channel oplossing. Wat als je de code van de bot voor een ander platform, zoals WeChat, wilt hergebruiken? Deze multi-channel benadering is deel van de strategie om vragen te verwijzen naar goedkopere kanalen. Hoe zou je dit aanpakken?

Maak gewoon een nieuwe webhook om dat kanaal te targeten! Een webhook die verzoeken stuurt naar dezelfde https://todobot.eu.ngrok.io/create-hook url die we voor WhatsApp hebben gebruikt!

Dit zal werken omdat de handler code altijd de conversationID van de webhook payload gebruikt om de berichten te beantwoorden in plaats van een hardcoded channelID. MessageBird’s Conversations API zal automatisch het kanaal voor het gesprek bepalen om je bericht over te sturen.

Wil je je eigen bot bouwen? Bekijk de volledige code op Github: Wabot op Github, vraag vroegtijdige toegang aan tot WhatsApp door de WhatsApp pagina te bezoeken en op de Contact Sales knop te klikken om het formulier in te vullen. Veel plezier met botten!

Een ander belangrijk ding! Je kunt gesprekken archiveren. In sommige applicaties, zoals CRM's, is het belangrijk om bepaalde interacties bij te houden — om bijvoorbeeld de effectiviteit van klantenservice medewerkers te volgen. De Conversations API laat je een gesprek archiveren om het onderwerp te "sluiten". Als de gebruiker/klant een ander bericht stuurt, opent de Conversations API automatisch een nieuw onderwerp.

Beheer van de gesprekslevenscyclus

Ook. Door een PATCH-verzoek te doen naar https://conversations.messagebird.com/v1/conversations/{id} met de juiste status in de body, kun je het gesprek met die id archiveren. We doen dit met het “bye” commando:

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

archiveConversation zal het PATCH-verzoek uitvoeren en manager.close(whp.Conversation.ID) zal de to-dolijst conversatie verwijderen.

Maar hé, Programmable Conversations is een omni-channel oplossing. Wat als je de code van de bot voor een ander platform, zoals WeChat, wilt hergebruiken? Deze multi-channel benadering is deel van de strategie om vragen te verwijzen naar goedkopere kanalen. Hoe zou je dit aanpakken?

Maak gewoon een nieuwe webhook om dat kanaal te targeten! Een webhook die verzoeken stuurt naar dezelfde https://todobot.eu.ngrok.io/create-hook url die we voor WhatsApp hebben gebruikt!

Dit zal werken omdat de handler code altijd de conversationID van de webhook payload gebruikt om de berichten te beantwoorden in plaats van een hardcoded channelID. MessageBird’s Conversations API zal automatisch het kanaal voor het gesprek bepalen om je bericht over te sturen.

Wil je je eigen bot bouwen? Bekijk de volledige code op Github: Wabot op Github, vraag vroegtijdige toegang aan tot WhatsApp door de WhatsApp pagina te bezoeken en op de Contact Sales knop te klikken om het formulier in te vullen. Veel plezier met botten!

Andere nieuws

Lees meer uit deze categorie

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

Het complete AI-native platform dat met uw bedrijf meegroeit.

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

Het complete AI-native platform dat met uw bedrijf meegroeit.