快速入门教程

本教程将详细讲解构建您的首个 Messenger 体验所需了解的所有内容。在开始之前,请选择入门项目下的任一选项,获取开始所需的代码,然后按照新手入门下的步骤进行设置。

只是想看看已完成的代码?没问题!您可以在 GitHub 上查看

目录

入门项目

在开始此快速入门之前,请确保您已完成以下其中一项操作,以确保您拥有所需的入门代码。入门代码提供了基本的 Webhooks,我们会将其用作 Messenger 体验的基础。

选项 1:自行构建

我们的 Webhooks 设置指南将引导您构建自己的首个 Webhooks,供您在此快速入门的全程使用。

构建您的 Webhooks

选项 2:从 GitHub 下载

从 GitHub 下载我们的 Webhooks 入门代码,并将其部署到您选择的服务器上。

下载代码

选项 3:在 Glitch 上整合

如果您没有用于部署 Webhooks 的服务器,则可以在 Glitch 上整合我们的入门 Webhooks 项目,为 Webhooks 提供使用 HTTPS 的公共网址。

要在 Glitch 上创建自己的 Webhooks,请执行以下操作:

  1. 在 Glitch 上打开我们的入门 Webhooks 项目: 在 Glitch 上整合
  2. 点击“整合自己的项目”按钮。系统将为您创建项目副本。
  3. 点击左上角的下拉菜单,然后复制项目说明下方的公共网址。此网址将是您 Webhooks 的基本网址。
  4. 按照我们的应用设置指南,为您的 Webhooks 订阅您的 Facebook 应用。您的 Webhooks 网址将是附加 /webhook 的 Glitch 网址:
    https://

入门指南

在构建首个 Messenger 体验之前,请先为您的应用设置凭证。

1
设置 Facebook 应用

如果您还未设置,请按照我们的应用设置指南设置您的 Facebook 应用,以与 Messenger 开放平台配合使用。

您的应用处于开发模式

在您的应用经过提交并获准在 Messenger 上公开使用之前,公共主页口令仅允许您的公共主页与已被授予应用管理员、开发者或测试者身份的 Facebook 帐户进行互动。

要将这些身份授予其他 Facebook 帐户,请前往应用设置的“身份”选项卡。

2
生成公共主页访问口令

针对 Messenger 开放平台 API 的所有请求的验证方式为在查询字符串的 access_token 参数中添加公共主页层级访问口令。

如果您在设置 Facebook 应用时尚未完成这一步,请执行以下操作来生成公共主页访问口令:

  1. 在应用 Messenger 设置的“口令生成”部分,从“公共主页”下拉菜单中选择您要为其生成口令的 Facebook 公共主页。访问口令将显示在“公共主页访问口令”字段中。
  2. 点击“公共主页访问口令”字段,将口令复制到剪贴板。

生成的口令不会保存在此用户界面中。每次您从下拉菜单中选择一个公共主页时,都会生成一个新口令。如果生成了新口令,之前创建的口令将继续生效。
3
将您的公共主页口令保存为环境变量

建议您不要将敏感信息(例如公共主页访问口令)硬编码到 Webhooks 中,以确保其安全。

为此,请将以下内容添加到您的环境变量中,其中 <PAGE_ACCESS_TOKEN> 是您刚刚生成的访问口令,而 <VERIFY_TOKEN> 是您设置用于验证 Webhooks 的随机字符串:

PAGE_ACCESS_TOKEN="

Glitch 中的环境变量

如果您使用 Glitch,请在提供的 .env 文件中设置您的环境变量,以确保其他 Glitch 用户无法看到。

4
验证口令并将公共主页添加到您的 Webhooks

现在您所要做的就是在 app.js 文件的顶部添加并验证公共主页访问口令,以便在 Webhooks 逻辑中使用:

const PAGE_ACCESS_TOKEN = process.env.PAGE_ACCESS_TOKEN;
const VERIFY_TOKEN = process.env.VERIFY_TOKEN;

设置完成

让我们构建首个 Messenger 体验!

构建体验

在本教程中,我们将构建一个用以完成以下操作的简单 Messenger 体验:

从传入的 Webhooks 事件中解析消息和发送者的公共主页范围编号。

处理 messagesmessaging_postbacks Webhooks 事件。

通过发送 API 发送消息。

用文本消息回复文本消息。

用使用所接收图像的通用模板回复图像附件。

有条件地响应回传负载。


1
存根处理程序函数

首先,我们将存根三个函数,这些函数会处理我们想要支持的传入 Webhooks 事件类型,以及通过发送 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) {
  
}
2
获取发送者的公共主页范围编号

要在 Messenger 上回复用户,我们首先需要知道对方的身份。在 Messenger 中,这通过从传入 Webhooks 事件中获取消息发送者的公共主页范围编号 (PSID) 来实现。

什么是 PSID?


系统针对用户展开对话的每个 Facebook 公共主页,为用户分配了唯一公共主页范围编号 (PSID)。PSID 用于在发送消息时识别用户。

如果您完成了上面入门项目部分中的任一选项,您应该已获得一个基本 /webhook 端点,这个端点可接受 POST 请求并记录所接收 Webhooks 事件的主体,如下所示:

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 包,以从事件的 sender.id 属性中提取 PSID:

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

});

测试一下!


打开 Messenger 并向与您 Messenger 体验相关联的 Facebook 公共主页发送消息。您不会在 Messenger 中收到回复,但您应该会看到一条消息,显示您的 PSID 已被记录到运行 Webhooks 的控制台中:
Sender PSID: 1254938275682919
3
解析 Webhooks 事件类型

我们希望体验能够处理两种类型的 Webhooks 事件:messagesmessaging_postback。事件类型的名称不包含在事件主体中,但我们可以通过检查特定对象属性来确定名称。

什么是 Webhooks 事件?


Messenger 开放平台发送 Webhooks 事件以通知您 Messenger 中发生的操作。系统会将事件作为 POST 请求,以 JSON 格式发送至您的 Webhooks。详情请参阅 Webhooks 事件

为此,请使用检查所接收事件是否包含 body.entry.forEachmessage 属性的条件更新 Webhooks 的 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);
  }
  
});
4
处理文本消息

在系统会将我们的传入消息转至相应的处理程序函数后,我们将更新 handleMessage() 以处理和响应基本文本消息。为此,请更新代码以定义我们响应的消息负载,然后将该负载传递至 callSendAPI()。我们想使用基本文本消息进行响应,所以定义了一个带有 "text" 属性的 JSON 对象:

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);    
}
5
使用发送 API 发送消息

是时候使用 Messenger 开放平台的发送 API 发送您的第一条消息了!

handleMessage() 中,我们正在调用 callSendAPI(),所以现在我们需要加以更新以构建完整的请求正文并将其发送到 Messenger 开放平台。对发送 API 的请求有两个属性:

  • recipient:设置预期的消息收件人。在这个案例中,我们通过 PSID 来识别这个用户。
  • message:设置要发送的消息的详细信息。此处,我们将其设置为我们从 handleMessage() 函数传入的消息对象。

要构建请求正文,请将 callSendAPI() 的存根更新为以下内容:

function callSendAPI(sender_psid, response) {
  // Construct the message body
  let request_body = {
    "recipient": {
      "id": sender_psid
    },
    "message": response
  }
}

现在我们所要做的就是在 https://graph.facebook.com/v2.6/me/messages 向发送 API 提交 POST 请求,以发送消息。

请注意,您必须在网址查询字符串的 access_token 参数中附加 PAGE_ACCESS_TOKEN

发出 HTTP 请求

在本快速入门中,我们使用 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 中,向您的 Facebook 公共主页发送另一条文本消息。您应该会收到来自 Messenger 体验的自动回复,该回复会回显您的消息并提示您发送图像。
6
处理附件

由于我们的回复提示消息接收者发送图像,所以下一步是更新代码以处理附件。发送的附件由 Messenger 开放平台自动保存,并可通过 attachments 数组每个指数 payload.url 属性中的网址获取,因此我们也可从事件中加以提取。

支持哪些附件类型?


您的 Messenger 体验可以收发大部分媒体类型,包括图像、音频、视频和文件。媒体可以显示出来,还能在对话中播放,可便于您创建媒体类型丰富的体验。

要确定消息是否为附件,请更新 handleMessage() 函数中的条件,检查 received_message 是否具有 attachments 属性,然后提取其网址。在实际的智能助手中,我们将迭代数组以检查多个附件,但在本快速入门中,我们将只获取第一个附件。

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);    
}
7
发送结构化消息

接下来,我们将使用通用模板消息回复图像。通用模板是最常用的结构化消息类型,允许您在一条消息中发送图像、文本和按钮。

是否有其他可用的消息模板?


有!Messenger 开放平台提供了一组实用的消息模板,每个模板都旨在支持不同的常见消息结构,包括清单、收据和按钮等。如需获取完整的详细信息,请参阅模板

消息模板由消息的 attachment 属性定义,其中包含 typepayload 属性。我们在以下属性的 payload 中设置通用模板的详情:

  • template_type:设置用于消息的模板类型。我们使用通用模板,因此值为“generic”。
  • 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);    
}

测试一下!

在 Messenger 中,向您的 Facebook 公共主页发送图像。您的 Messenger 体验应使用通用模板进行回复。
8
处理回传

最后一步是处理 messaging_postbacks Webhooks 事件,该事件将在消息接收者轻触我们通用模板中的其中一个回传按钮时发送。

我可以通过回传做什么?


回传按钮向您的 Webhooks 发送一个 messaging_postbacks Webhooks 事件,该事件的 payload 属性中包含最多 1,000 个字符的自定义字符串。这使您可以轻松实施不同的回传负载。您可以使用特定的行为对其进行解析和回复。

由于通用模板允许消息接收者从两个回传按钮中进行选择,我们将根据回传事件 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);
}

测试一下!

在 Messenger 中,轻触通用模板上的每个回传按钮。对于每个按钮,您应该会收到不同的文本回复。
9
如果一切顺利,那您便完成了首个 Messenger 体验的构建!

开发者支持