كيفية إنشاء روبوت WhatsApp لقوائم المهام باستخدام Bird’s Programmable Conversations API

Bird

05‏/02‏/2020

واتساب

1 min read

كيفية إنشاء روبوت WhatsApp لقوائم المهام باستخدام Bird’s Programmable Conversations API

Bird

05‏/02‏/2020

واتساب

1 min read

كيفية إنشاء روبوت WhatsApp لقوائم المهام باستخدام Bird’s Programmable Conversations API

أطلقت Bird مؤخرًا محادثات قابلة للبرمجة. إنها تتيح للشركات دمج منصات الاتصالات مثل WhatsApp وMessenger وSMS في أنظمتها باستخدام واجهة برمجة تطبيقات واحدة.

Business in a box.

اكتشف حلولنا.

أطلقت Bird مؤخرًا المحادثات البرمجية. تتيح للشركات دمج منصات الاتصالات مثل WhatsApp وMessenger وSMS في أنظمتها - باستخدام واجهة برمجة تطبيقات واحدة.

أردت تجربتها، لذا قمت ببناء بوت قائمة مهام على WhatsApp، لأن من لا يحتاج إلى قائمة مهام آلية للمساعدة في تنظيم يومه؟ قد تبدو معقدة، لكنها كانت في الواقع سهلة، وأود أن أخبرك كل شيء عن ذلك.

الآن، أعمل في MessageBird، لذا تمكنت من الغوص مباشرة والبدء في البناء. إذا حاولت ذلك، ستحتاج إلى طلب الوصول المبكر. ولكن بمجرد إعداد قناة WhatsApp، يمكنك تسجيل الدخول إلى لوحة التحكم على موقع MessageBird والبدء.

أول شيء قمت به كان قراءة المستندات. علمت أنه من أجل الحصول على الرسائل من البوت، سأحتاج إلى استخدام ويب هوك. وهذا يعني أن البوت الخاص بي يحتاج إلى أن يكون متاحًا من الإنترنت. عند بناء واجهات برمجة التطبيقات مثل هذه، من المهم اتباع أفضل الممارسات في تقسيم إصدارات API لتحسين الصيانة. بما أنني كنت أبدأ في كتابة الكود، قررت استخدام ngrok. حيث أنه يخلق نفقًا من الإنترنت العام إلى منفذ localhost 5007 الخاص بك. ابدأ بالعمل!

ngrok http 5007 -region eu -subdomain todobot

بعد ذلك، احتجت إلى إجراء اتصال ببرمجة واجهات محادثات API لإنشاء الويب هوك. إنه POST إلى https://conversations.messagebird.com/v1/webhooks، ويبدو شيء مثل هذا:


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

رائع. الآن سوف تقوم واجهة برمجة محادثات API بإرسال طلب POST إلى:

https://todobot.eu.ngrok.io/create-hook كلما تم إنشاء رسالة جديدة على قناة WhatsApp التي قمت بإعدادها سابقًا.

هذا هو شكل حمولة الويب هوك:


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

نود الرد على هذه الرسائل. لنبدأ بإعادة إرسالها، ما رأيك؟


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

الآن، للجزء المثير. قم بعمل طلب POST إلى:

https://conversations.messagebird.com/v1/conversations/<conversationID>/messages للرد على الطلب.


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
}

هناك. هذا هو كل ما تحتاجه لإنشاء بوت يعمل مثل طفل يبلغ من العمر 5 سنوات.

الآن، لنقوم بدفع لبناء قائمة المهام بالكامل. أولًا، عدل قليلاً وظيفة createHookHandler بحيث تستدعي وظيفة handleMessage الجديدة بدلاً من الرد.

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

وظيفة handle ستقوم بفك الرسائل ببساطة، عمل بعض العمليات، واختيار الرد. دعونا نلقي نظرة على الأمر “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)
}

هنا، نقوم بإعداد: قائمة: = manager.fetch(whp.Conversation.ID). في الأساس، “manager” هو خريطة آمنة للتوازي تُخزن معرفات المحادثة لقوائم المهام.

قائمة المهام هي عبارة عن شريط نصي آمن للتوازي. كل ذلك في الذاكرة!

شيء آخر مهم! يمكنك أرشفة المحادثات. في بعض التطبيقات، مثل نظم إدارة علاقات العملاء، من المهم تتبع بعض التفاعلات - لتتبع فعالية موظفي دعم العملاء، على سبيل المثال. تسمح لك واجهة برمجة محادثات API بأرشفة المحادثة لـ “إغلاق” الموضوع. إذا أرسل المستخدم/العميل رسالة أخرى، ستفتح المحادثات API موضوعًا جديدًا تلقائيًا.

أيضًا. القيام بطلب PATCH إلى https://conversations.messagebird.com/v1/conversations/{id} مع الحالة الصحيحة في الجسم يتيح لك أرشفة المحادثة مع هذا المعرف. نفعل ذلك باستخدام الأمر “bye”:

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

وظيفة archiveConversation ستقوم بطلب PATCH و manager.close(whp.Conversation.ID) ستزيل محادثة قائمة المهام.

ولكن مهلاً، المحادثات البرمجية هي حل متعدد القنوات. ماذا لو كنت تريد إعادة استخدام كود البوت لمنصة مختلفة، مثل WeChat؟ هذا النهج متعدد القنوات هو جزء من استراتيجية تحويل الاستفسارات إلى قنوات أقل تكلفة. كيف يمكنك القيام بذلك؟

فقط قم بإنشاء ويب هوك جديد لاستهداف تلك القناة! ويب هوك الذي يرسل الطلبات إلى نفس عنوان https://todobot.eu.ngrok.io/create-hook الذي استخدمناه لواتساب!

سيعمل هذا لأن كود المعالجة يستخدم دائمًا conversationID من حمولة الويب هوك للرد على الرسائل بدلاً من معرف القناة الثابت. واجهة برمجة محادثات API من MessageBird ستقوم بتحديد القناة تلقائيًا للمحادثة لإرسال رسالتك عبرها.

هل تريد بناء بوتك الخاص؟ ألق نظرة على الكود الكامل على Github: https://github.com/marcelcorso/wabot، واطلب الوصول المبكر إلى WhatsApp عبر هذا الرابط وابدأ بالبناء مباشرة. بارك الله في بناء البوتات!

دعنا نوصلك بخبير من Bird.
رؤية القوة الكاملة لـ Bird في 30 دقيقة.

بتقديمك طلبًا، فإنك توافق على أن تقوم Bird بالاتصال بك بشأن منتجاتنا وخدماتنا.

يمكنك إلغاء الاشتراك في أي وقت. انظر بيان الخصوصية الخاص بـ Bird للتفاصيل حول معالجة البيانات.

دعنا نوصلك بخبير من Bird.
رؤية القوة الكاملة لـ Bird في 30 دقيقة.

بتقديمك طلبًا، فإنك توافق على أن تقوم Bird بالاتصال بك بشأن منتجاتنا وخدماتنا.

يمكنك إلغاء الاشتراك في أي وقت. انظر بيان الخصوصية الخاص بـ Bird للتفاصيل حول معالجة البيانات.

دعنا نوصلك بخبير من Bird.
رؤية القوة الكاملة لـ Bird في 30 دقيقة.

بتقديمك طلبًا، فإنك توافق على أن تقوم Bird بالاتصال بك بشأن منتجاتنا وخدماتنا.

يمكنك إلغاء الاشتراك في أي وقت. انظر بيان الخصوصية الخاص بـ Bird للتفاصيل حول معالجة البيانات.

R

وصول

G

نمو

م

إدارة

A

أتمتة

النشرة الإخبارية

ابقَ على اطلاع مع Bird من خلال التحديثات الأسبوعية إلى بريدك الوارد.