كيفية بناء روبوت WhatsApp لقوائم المهام باستخدام واجهة برمجة التطبيقات للمحادثات القابلة للبرمجة من Bird

طائر

05‏/02‏/2020

واتساب

1 min read

كيفية بناء روبوت WhatsApp لقوائم المهام باستخدام واجهة برمجة التطبيقات للمحادثات القابلة للبرمجة من Bird

النقاط الرئيسية

    • واجهة برمجة المحادثات القابلة للبرمجة من Bird توحد WhatsApp وMessenger وSMS في طبقة اتصالات واحدة، مما يبسط تطوير الروبوتات متعددة القنوات.

    • يمكنك بسرعة إنشاء نموذج أولي لروبوت قائمة المهام على WhatsApp باستخدام webhooks وطلبات POST بسيطة.

    • تسمح لك أدوات مثل ngrok بكشف خادمك المحلي لاختبار الويب هوك دون إعداد استضافة معقد.

    • تتعامل واجهة برمجة التطبيقات مع المحادثات عبر قنوات متعددة، مما يسمح بقاعدة منطق واحدة لـ WhatsApp وWeChat وغيرها من التطبيقات.

    • استخدم نقطة نهاية archiveConversation لـ إغلاق المحادثات أو "المواضيع"، وهي مثالية للدعم أو تتبع سير العمل.

    • يمكن أن تدير منطق الروبوت المحادثات المتزامنة بأمان في الذاكرة مع هيكل بيانات بسيط.

    • يعمل نفس معالج الويب هوك عبر القنوات - يقوم Bird تلقائياً بتوجيه الردود استنادًا إلى معرف المحادثة المصدر.

أهم النقاط في الأسئلة والأجوبة

  • ما مدى صعوبة بناء بوت على واتساب باستخدام واجهة برمجة تطبيقات بيرد؟

    من المدهش أن الأمر سهل للغاية. باستخدام واجهة ويب وعدد قليل من استدعاءات واجهة برمجة التطبيقات، يمكنك بناء روبوت وظيفي يقرا ويرد على الرسائل في غضون دقائق.

  • هل أحتاج إلى إعداد خاص لاستقبال الرسائل؟

    نعم — يجب أن يكون الروبوت متاحًا من الإنترنت. تساعد أدوات مثل ngrok في إنشاء نفق آمن من جهازك المحلي.

  • هل يمكنني استخدام نفس قاعدة التعليمات البرمجية لتطبيقات المراسلة المختلفة؟

    بالتأكيد. تقوم واجهة برمجة التطبيقات للمحادثات بتجريد القنوات، لذا يمكن لروبوت الدردشة الخاص بك العمل على واتساب، ووي تشات، أو ماسنجر باستخدام منطق متطابق.

  • كيف أغلق أو أعيد تعيين سلسلة محادثة؟

    أرسل طلب PATCH إلى نقطة نهاية المحادثة مع الحالة المناسبة لأرشفتها. أي رسالة جديدة تفتح تلقائيًا محادثة جديدة.

  • أين يمكنني العثور على أمثلة من الشيفرة؟

    أ: العرض الكامل للعمل - Wabot على GitHub - يظهر تنفيذ التعامل مع الرسائل، التزامن، والأرشفة.

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

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

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

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

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

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

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

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

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

إعداد بيئة بوت الواتساب الخاصة بك

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

ngrok http 5007 -region eu -subdomain todobot

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

ngrok http 5007 -region eu -subdomain todobot

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

ngrok http 5007 -region eu -subdomain todobot

إنشاء webhook الخاص بك وربط Bird

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

ها هو. هذا كل ما تحتاجه لإنشاء بوت يتصرف مثل إنسان في الخامسة من عمره.


إليك سبب جعل استخدام واجهة برمجة تطبيقات محادثات Bird تطوير روبوتات WhatsApp سريعًا وقابلًا للتوسع:

الميزة

ما تحلّه

معرف محادثة موحد

الحفاظ على خيط واحد عبر التطبيقات مثل WhatsApp وWeChat وMessenger

API واحدة لكل القنوات

إعادة استخدام منطق الروبوت دون الحاجة لإعادة كتابته لكل منصة

أتمتة مدفوعة بالويب هوك

معالجة استجابات سريعة دون الحاجة للاستطلاع

أرشفة + إعادة فتح المواضيع

تنظيم تاريخ الدعم وسير العمل

هيكل آمن من حيث التزامن

التعامل مع محادثات متعددة في وقت واحد بشكل موثوق


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

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

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

قائمة المهام هي شريحة سلسلية آمنة من حيث التزامن. كل ذلك في الذاكرة!

الآن، للجزء المثير. أرسل طلب 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
}

ها هو. هذا كل ما تحتاجه لإنشاء بوت يتصرف مثل إنسان في الخامسة من عمره.


إليك سبب جعل استخدام واجهة برمجة تطبيقات محادثات Bird تطوير روبوتات WhatsApp سريعًا وقابلًا للتوسع:

الميزة

ما تحلّه

معرف محادثة موحد

الحفاظ على خيط واحد عبر التطبيقات مثل WhatsApp وWeChat وMessenger

API واحدة لكل القنوات

إعادة استخدام منطق الروبوت دون الحاجة لإعادة كتابته لكل منصة

أتمتة مدفوعة بالويب هوك

معالجة استجابات سريعة دون الحاجة للاستطلاع

أرشفة + إعادة فتح المواضيع

تنظيم تاريخ الدعم وسير العمل

هيكل آمن من حيث التزامن

التعامل مع محادثات متعددة في وقت واحد بشكل موثوق


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

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

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

قائمة المهام هي شريحة سلسلية آمنة من حيث التزامن. كل ذلك في الذاكرة!

الآن، للجزء المثير. أرسل طلب 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
}

ها هو. هذا كل ما تحتاجه لإنشاء بوت يتصرف مثل إنسان في الخامسة من عمره.


إليك سبب جعل استخدام واجهة برمجة تطبيقات محادثات Bird تطوير روبوتات WhatsApp سريعًا وقابلًا للتوسع:

الميزة

ما تحلّه

معرف محادثة موحد

الحفاظ على خيط واحد عبر التطبيقات مثل WhatsApp وWeChat وMessenger

API واحدة لكل القنوات

إعادة استخدام منطق الروبوت دون الحاجة لإعادة كتابته لكل منصة

أتمتة مدفوعة بالويب هوك

معالجة استجابات سريعة دون الحاجة للاستطلاع

أرشفة + إعادة فتح المواضيع

تنظيم تاريخ الدعم وسير العمل

هيكل آمن من حيث التزامن

التعامل مع محادثات متعددة في وقت واحد بشكل موثوق


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

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

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

قائمة المهام هي شريحة سلسلية آمنة من حيث التزامن. كل ذلك في الذاكرة!

أرشفة المحادثات وتوسيع نطاق الروبوت الخاص بك

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

إدارة دورة حياة المحادثة

أيضاً. القيام بإرسال طلب 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 عنوان URL الذي استخدمناه لـ WhatsApp!

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

هل تريد بناء روبوتك الخاص؟ ألقِ نظرة على الكود الكامل على Github: Wabot على Github، واطلب وصولاً مبكراً إلى WhatsApp من خلال زيارة صفحة WhatsApp والنقر على زر الاتصال بالمبيعات لملء النموذج. حظاً سعيداً في البرمجة!

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

إدارة دورة حياة المحادثة

أيضاً. القيام بإرسال طلب 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 عنوان URL الذي استخدمناه لـ WhatsApp!

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

هل تريد بناء روبوتك الخاص؟ ألقِ نظرة على الكود الكامل على Github: Wabot على Github، واطلب وصولاً مبكراً إلى WhatsApp من خلال زيارة صفحة WhatsApp والنقر على زر الاتصال بالمبيعات لملء النموذج. حظاً سعيداً في البرمجة!

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

إدارة دورة حياة المحادثة

أيضاً. القيام بإرسال طلب 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 عنوان URL الذي استخدمناه لـ WhatsApp!

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

هل تريد بناء روبوتك الخاص؟ ألقِ نظرة على الكود الكامل على Github: Wabot على Github، واطلب وصولاً مبكراً إلى WhatsApp من خلال زيارة صفحة WhatsApp والنقر على زر الاتصال بالمبيعات لملء النموذج. حظاً سعيداً في البرمجة!

أخبار أخرى

اقرأ المزيد من هذه الفئة

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

المنصة الكاملة المدعومة بالذكاء الاصطناعي التي تتوسع مع أعمالك.

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

المنصة الكاملة المدعومة بالذكاء الاصطناعي التي تتوسع مع أعمالك.

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

المنصة الكاملة المدعومة بالذكاء الاصطناعي التي تتوسع مع أعمالك.