المنتج

حلول

الموارد

شركة

المنتج

حلول

الموارد

شركة

كيفية إنشاء روبوت 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 مؤخرًا المحادثات القابلة للبرمجة. تسمح للشركات بدمج منصات الاتصالات مثل واتساب، ماسنجر وSMS في أنظمتها — باستخدام واجهة برمجة تطبيقات واحدة.

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

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

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

ngrok http 5007 -region eu -subdomain todobot

التالي، احتجت إلى القيام باستدعاء واجهة برمجة المحادثات القابلة للبرمجة لإنشاء الويب هوك. إنه طلب 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))
  }
}

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

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

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


{
  "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 ستحلل الرسائل ببساطة، تقوم ببعض العمل، وتختار الرد. دعونا نلقي نظرة على أمر "الإضافة":

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

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

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

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

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

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

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

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

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

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

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

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

منصة AI-native الكاملة التي تتماشى مع نمو عملك.

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

منصة AI-native الكاملة التي تتماشى مع نمو عملك.

المنتج

حلول

الموارد

شركة

إعدادات الخصوصية

اجتماعي

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

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

اشتراك

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

منصة AI-native الكاملة التي تتماشى مع نمو عملك.

المنتج

حلول

الموارد

شركة

إعدادات الخصوصية

اجتماعي

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

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

اشتراك