سيتناول هذا العرض التوضيحي كل ما تحتاج إلى معرفته لإنشاء تجربة Messenger الأولى. قبل البدء، اختر أحد الخيارات المتوفرة ضمن المشاريع المبدئية للحصول على الرمز الذي ستحتاج إليه للبدء، ثم اتبع الخطوات ضمن بدء الاستخدام لبدء الإعداد.
هل تريد عرض الرمز النهائي فحسب؟ لا توجد مشكلة! يمكنك نسخه من GitHub.قبل التعمق في دليل البدء السريع هذا، احرص على إكمال أحد الإجراءات التالية للتأكد من حصولك على الرمز المبدئي الذي ستحتاج إليه. يوفر الرمز المبدئي حدث webhook أساسيًا سنستخدمه كأساس لتجربة Messenger.
سيتناول دليل إعداد حدث webhook الذي نوفره كيفية إنشاء حدث webhook الأول الذي يمكنك استخدامه إلى جانب دليل البدء السريع هذا من البداية للنهاية.
إنشاء حدث Webhookيمكنك تنزيل الرمز المبدئي لحدث webhook من GitHub، ونشره على خادم من اختيارك.
تنزيل الرمزإذا لم يتوفر لديك خادم لنشر حدث webhook عليه، فيمكنك إعادة دمج مشروع حدث webhook المبدئي على Glitch، والذي سيوفر عنوان URL عامًا يتم عرضه عبر HTTPS المرتبط بحدث webhook.
لإنشاء حدث webhook خاص على Glitch، قم بإجراء ما يلي:
/webhook
:
https://
قبل إنشاء تجربتك الأولى على Messenger، ابدأ من خلال إعداد بيانات الاعتماد في تطبيقك.
إذا لم تكن قد أعددت التطبيق بالفعل، فاتبع دليل إعداد التطبيق لإعداد تطبيق فيسبوك واستخدامه مع منصة Messenger.
إلى أن يتم إرسال تطبيقك والموافقة عليه للاستخدام العام على Messenger، لن تتيح رموز الصفحة لصفحتك سوى إمكانية التفاعل مع حسابات فيسبوك التي تم منحها دور المسؤول أو المطوّر أو المختبِر في تطبيقك.
لمنح هذه الأدوار إلى حسابات فيسبوك أخرى، انتقل إلى علامة التبويب "الأدوار" في إعدادات التطبيق.
تتم مصادقة كل الطلبات التي يتم إرسالها إلى واجهات API منصة Messenger عن طريق تضمين رمز وصول على مستوى الصفحة في المعلمة access_token
لسلسلة الاستعلام.
إذا لم تكن قد أنشأت رمز وصول بالفعل عند إعداد تطبيق فيسبوك، فقم بإنشاء رمز وصول الصفحة، عن طريق إجراء ما يلي:
يوصى بالحفاظ على آمان المعلومات الحساسة مثل رمز وصول صفحتك من خلال عدم تضمينها برمجيًا في حدث webhook.
لإجراء ذلك، أضف ما يلي إلى متغيرات البيئة لديك، حيث يكون <PAGE_ACCESS_TOKEN>
هو رمز الوصول الذي أنشأته للتو و<VERIFY_TOKEN>
هي سلسلة عشوائية قمت بتعيينها للتحقق من حدث webhook:
PAGE_ACCESS_TOKEN="
إذا كنت تستخدم Glitch، فقم بتعيين متغيرات البيئة في ملف .env
المتوفر لضمان عدم ظهورها لمستخدمي Glitch الآخرين.
والآن كل ما عليك فعله هو إضافة رمز وصول الصفحة ورمز التحقق في أعلى ملف app.js
، لاستخدامه في منطق حدث webhook:
const PAGE_ACCESS_TOKEN = process.env.PAGE_ACCESS_TOKEN;
const VERIFY_TOKEN = process.env.VERIFY_TOKEN;
في هذا العرض التوضيحي، سننشئ تجربة Messenger بسيطة تعمل على ما يلي:
تحليل الرسالة ومعرف المُرسِل على مستوى الصفحة من حدث webhook الوارد.
معالجة حدثي webhook messages
وmessaging_postbacks
.
إرسال الرسائل عبر API الإرسال.
الرد على الرسائل النصية برسالة نصية.
الرد على مرفق صورة بقالب عام يستخدم الصورة التي تم تلقيها.
الرد بشكل مشروط على حمولة بيانات الرد الجاهز.
للبدء، يجب إنشاء ثلاث وظائف من شأنها معالجة أنواع أحداث webhook الواردة التي نريد دعمها، بالإضافة إلى الاستجابة عبر API الإرسال. لإجراء ذلك، يجب إلحاق ما يلي في ملف app.js
:
// Handles messages events
function handleMessage(sender_psid, received_message) {
}
// Handles messaging_postbacks events
function handlePostback(sender_psid, received_postback) {
}
// Sends response messages via the Send API
function callSendAPI(sender_psid, response) {
}
للرد على الأشخاص في Messenger، نحتاج أولاً إلى معرفة هويتهم. ويحدث ذلك في Messenger عن طريق الحصول على معرف المُرسِل على مستوى الصفحة (PSID) من حدث webhook الوارد.
يتم تعيين معرف على مستوى الصفحة (PSID) للشخص مقابل كل صفحة فيسبوك يبدأ محادثة معها. ويتم استخدام المعرف على مستوى الصفحة (PSID) لتحديد هوية الشخص عند إرسال الرسائل.
إذا أكملت أحد الخيارات في القسم المشروع المبدئي أعلاه، فيجب أن تتوفر لديك نقطة نهاية /webhook
أساسية تقبل طلبات POST
وتسجل نص أحداث webhook المستلمة التي تبدو كالتالي:
app.post('/webhook', (req, res) => {
// Parse the request body from the POST
let body = req.body;
// Check the webhook event is from a Page subscription
if (body.object === 'page') {
// Iterate over each entry - there may be multiple if batched
body.entry.forEach(function(entry) {
// Get the webhook event. entry.messaging is an array, but
// will only ever contain one event, so we get index 0
let webhook_event = entry.messaging[0];
console.log(webhook_event);
});
// Return a '200 OK' response to all events
res.status(200).send('EVENT_RECEIVED');
} else {
// Return a '404 Not Found' if event is not from a page subscription
res.sendStatus(404);
}
});
للحصول على معرف المُرسِل على مستوى الصفحة (PSID)، يمكنك تحديث قالب body.entry.forEach
باستخدام الرمز التالي لاستخراج المعرف على مستوى الصفحة (PSID) من الخاصية sender.id
للحدث:
body.entry.forEach(function(entry) {
// Gets the body of the webhook event
let webhook_event = entry.messaging[0];
console.log(webhook_event);
// Get the sender PSID
let sender_psid = webhook_event.sender.id;
console.log('Sender PSID: ' + sender_psid);
});
Sender PSID: 1254938275682919
نريد أن تكون التجربة قادرة على معالجة نوعين من أحداث webhook: messages
وmessaging_postback
. ولا يتم تضمين اسم نوع الحدث في نص الحدث، ولكن يمكننا تحديده عن طريق التحقق من وجود خصائص معينة للكائن.
ترسل منصة Messenger أحداث webhook لإبلاغك بالإجراءات التي تحدث في Messenger. ويتم إرسال الأحداث بتنسيق JSON كطلبات POST
التي يتم إرسالها إلى حدث webhook. لمزيد من المعلومات، راجع أحداث Webhook.
لإجراء ذلك، قم بتحديث قالب body.entry.forEach
المرتبط بحدث webhook على شرط أن يتحقق مما إذا كان الحدث المستلم يحتوي على الخاصية message
أو postback
. سنضيف أيضًا الاستدعاءات إلى الوظائف handleMessage()
وhandlePostback()
التي أنشأناها سابقًا:
body.entry.forEach(function(entry) {
// Gets the body of the webhook event
let webhook_event = entry.messaging[0];
console.log(webhook_event);
// Get the sender PSID
let sender_psid = webhook_event.sender.id;
console.log('Sender PSID: ' + sender_psid);
// Check if the event is a message or postback and
// pass the event to the appropriate handler function
if (webhook_event.message) {
handleMessage(sender_psid, webhook_event.message);
} else if (webhook_event.postback) {
handlePostback(sender_psid, webhook_event.postback);
}
});
والآن بما أنه أصبح يتم توجيه الرسائل الواردة إلى وظيفة المعالج المناسبة، سنعمل على تحديث handleMessage()
لمعالجة الرسائل النصية الأساسية والرد عليها. ولإجراء ذلك، قم بتحديث الرمز لتحديد حمولة بيانات الرسالة المرتبطة بالرد، ثم أدخل حمولة البيانات هذه في callSendAPI()
. نريد الرد برسالة نصية أساسية، لذلك سنحدد كائن JSON بالخاصية "text"
:
function handleMessage(sender_psid, received_message) {
let response;
// Check if the message contains text
if (received_message.text) {
// Create the payload for a basic text message
response = {
"text": `You sent the message: "${received_message.text}". Now send me an image!`
}
}
// Sends the response message
callSendAPI(sender_psid, response);
}
حان وقت إرسال رسالتك الأولى من خلال API الإرسال في منصة Messenger!
في handleMessage()
، سنستدعي callSendAPI()
بحيث لا يتعين علينا سوى تحديثه لإنشاء نص الطلب الكامل وإرساله إلى منصة Messenger. ويتضمن الطلب الذي يتم إرساله إلى API الإرسال خاصيتين:
recipient
: تعمل على تعيين مستلم الرسالة المقصود. وفي هذه الحالة، نحدد الشخص بواسطة المعرف على مستوى الصفحة.message
: تعمل على تعيين تفاصيل الرسالة المطلوب إرسالها. وهنا، سنقوم بتعيينها إلى كائن الرسالة الذي أدخلناه مسبقًا من الوظيفة handleMessage()
.لبناء نص الطلب، قم بتحديث الرمز البرمجي في callSendAPI()
إلى ما يلي:
function callSendAPI(sender_psid, response) {
// Construct the message body
let request_body = {
"recipient": {
"id": sender_psid
},
"message": response
}
}
الآن كل ما علينا فعله هو إرسال الرسالة من خلال إرسال طلب POST
إلى API الإرسال في https://graph.facebook.com/v2.6/me/messages
.
لاحظ أنه يجب إلحاق PAGE_ACCESS_TOKEN
في المعلمة access_token
لعنوان URL سلسلة الاستعلام.
في دليل البدء السريع هذا، نستخدم وحدة طلب Node.js لإرسال طلبات HTTP مرة أخرى إلى منصة Messenger، ولكن يمكنك استخدام أي عميل HTTP تريده.
لتثبيت وحدة الطلب، قم بتشغيل npm install request --save
من سطر الأوامر، ثم قم استيرادها عن طريق إضافة ما يلي في مقدمة ملف app.js
:
const request = require('request');
function callSendAPI(sender_psid, response) {
// Construct the message body
let request_body = {
"recipient": {
"id": sender_psid
},
"message": response
}
// Send the HTTP request to the Messenger Platform
request({
"uri": "https://graph.facebook.com/v2.6/me/messages",
"qs": { "access_token": process.env.PAGE_ACCESS_TOKEN },
"method": "POST",
"json": request_body
}, (err, res, body) => {
if (!err) {
console.log('message sent!')
} else {
console.error("Unable to send message:" + err);
}
});
}
نظرًا لأن الرد التلقائي يطالب مستلم الرسالة بإرسال صورة، فإن الخطوة التالية ستتمثل في تحديث الرمز لمعالجة المرفقات. ويتم حفظ المرفقات المرسلة تلقائيًا بواسطة منصة Messenger وتصبح متوفرة عبر عنوان URL في الخاصية payload.url
لكل فهرس في المصفوفة attachments
، لذلك سنستخرج هذا أيضًا من الحدث.
لتحديد ما إذا كانت الرسالة عبارة عن مرفق، قم بتحديث الشرط في الوظيفة handleMessage()
للتحقق من received_message
لخاصية attachments
، ثم استخرج عنوان URL لها. بالنسبة لأي برنامج تلقائي متوفر فعليًا، سنكرر المصفوفة للتحقق من وجود مرفقات متعددة، ولكن لخدمة الغرض من دليل البدء السريع هذا، سنحصل فقط على المرفق الأول.
function handleMessage(sender_psid, received_message) {
let response;
// Checks if the message contains text
if (received_message.text) {
// Creates the payload for a basic text message, which
// will be added to the body of our request to the Send API
response = {
"text": `You sent the message: "${received_message.text}". Now send me an attachment!`
}
} else if (received_message.attachments) {
// Gets the URL of the message attachment
let attachment_url = received_message.attachments[0].payload.url;
}
// Sends the response message
callSendAPI(sender_psid, response);
}
بعد ذلك، سنرد على الصورة برسالة قالب عام. ويُعد القالب العام أكثر أنواع الرسائل ذات البنية المحددة استخدامًا، ويتيح لك إرسال صورة ونص وأزرار في رسالة واحدة.
نعم! توفر منصة Messenger مجموعة من قوالب الرسائل المفيدة، كل منها مصمم لدعم بنية رسائل شائعة مختلفة، بما في ذلك القوائم ومؤشرات الحالة والأزرار والمزيد. للحصول على التفاصيل الكاملة، راجع القوالب.
يتم تحديد قوالب الرسائل في الخاصية attachment
للرسالة، والتي تحتوي على الخاصيتين type
وpayload
. وتمثل الخاصية payload
المكان الذي يتم فيه تعيين تفاصيل القالب العام في الخصائص التالية:
template_type
: تعمل على تعيين نوع القالب المستخدم في الرسالة. ولأننا نستخدم القالب العام، ستكون القيمة "عام".elements
: تعمل على تعيين الخصائص المخصصة للقالب. وبالنسبة للقالب العام، سنحدد عنوانًا أساسيًا وعنوانًا فرعيًا وصورة وزرين للرد الجاهز.بالنسبة للرسالة ذات البنية المحددة، سنستخدم attachment_url
الذي تم إرساله إلينا كعنوان image_url
لعرضه في القالب، وسنقوم بتضمين زرين للرد الجاهز للسماح لمستلم الرسالة بالرد. لإنشاء حمولة بيانات الرسالة وإرسال القالب العام، قم بتحديث handleMessage()
إلى ما يلي:
function handleMessage(sender_psid, received_message) {
let response;
// Checks if the message contains text
if (received_message.text) {
// Create the payload for a basic text message, which
// will be added to the body of our request to the Send API
response = {
"text": `You sent the message: "${received_message.text}". Now send me an attachment!`
}
} else if (received_message.attachments) {
// Get the URL of the message attachment
let attachment_url = received_message.attachments[0].payload.url;
response = {
"attachment": {
"type": "template",
"payload": {
"template_type": "generic",
"elements": [{
"title": "Is this the right picture?",
"subtitle": "Tap a button to answer.",
"image_url": attachment_url,
"buttons": [
{
"type": "postback",
"title": "Yes!",
"payload": "yes",
},
{
"type": "postback",
"title": "No!",
"payload": "no",
}
],
}]
}
}
}
}
// Send the response message
callSendAPI(sender_psid, response);
}
تتمثل خطوتنا الأخيرة في معالجة حدث webhook messaging_postbacks
الذي سيتم إرساله عندما يضغط مستلم الرسالة على أحد أزرار الرد الجاهز المتوفرة في القالب العام.
يرسل زر الرد الجاهز حدث webhook messaging_postbacks
إلى حدث webhook المتوفر لديك والذي يتضمن سلسلة مخصصة تضم ما يصل إلى 1,000 حرف في الخاصية payload
. ويتيح لك ذلك تنفيذ حمولات بيانات الرد الجاهز المختلفة بسهولة والتي يمكنك تحليلها والرد عليها بطرق محددة.
بما أن القالب العام الذي نوفره يتيح لمستلم الرسالة الاختيار من بين زرين للرد الجاهز، فسيكون الرد من جانبنا استنادًا إلى قيمة الخاصية payload
المرتبطة بحدث الرد الجاهز. لإجراء ذلك، قم بتحديث الرمز البرمجي في handlePostback()
إلى ما يلي:
function handlePostback(sender_psid, received_postback) {
let response;
// Get the payload for the postback
let payload = received_postback.payload;
// Set the response based on the postback payload
if (payload === 'yes') {
response = { "text": "Thanks!" }
} else if (payload === 'no') {
response = { "text": "Oops, try sending another image." }
}
// Send the message to acknowledge the postback
callSendAPI(sender_psid, response);
}