php中引入facebook的messenger消息接口

来源:互联网 发布:centos 安装 分区 编辑:程序博客网 时间:2024/06/06 14:00

前一段时间需要开发一个messenger的消息接口,但是facebook的官方文档似是而非,而且由于在国内比较小众,之前也没有另外的人写过中文的开发教程,只好自己进行了一番研究并完成了一个demo,希望给后来的人能带来一点方便。

一.创建Facebook应用和主页

https://developers.facebook.com/docs/messenger-platform/guides/quick-start

直接按照官方文档的第一步去完成即可

二.设置webhook

这里的webhook实际上就是你的第三方服务器,这里facebook的主页类似于微信的公众号。其中webhook的callback url就是回调函数的地址。类似于微信的服务器验证方式,这里的webhook也需要返回给facebook服务器指定的信息。

在 webhook 网址中,添加身份验证代码。此代码应对应上述验证口令,并以验证请求中发送的 challenge 为响应。点击“新建主页订阅”窗口中的“验证并保存”,以便通过 GET 请求调用 Webhook

然后给了一个官方案例,返回信息

app.get('/webhook', function(req, res) {  if (req.query['hub.mode'] === 'subscribe' &&      req.query['hub.verify_token'] === <VERIFY_TOKEN>) {    console.log("Validating webhook");    res.status(200).send(req.query['hub.challenge']);  } else {    console.error("Failed validation. Make sure the validation tokens match.");    res.sendStatus(403);            }  });

我不是很熟悉node.js,发现get[‘hub.verify_token’]并不能拿到并返回验证的信息,这里贴出我的php的验证方式

private function setupWebhook()    {        if(isset($_REQUEST['hub_challenge']) && isset($_REQUEST['hub_verify_token']) && $this->getValidationToken()==$_REQUEST['hub_verify_token'])        {            echo $_REQUEST['hub_challenge'];            exit;        }    }

hub_verify_token就是你自己设定的token,需要验证每次get的token,然后echo出hub_challenge

三.获取主页访问口令并订阅主页

建议把所有配置信息放在单独的文件里面,方便调用和修改。生成的口令不会在此界面保存。每次选择此主页都会生成一个新的口令。但之前生成的任何口令仍然有效。

四.接收消息
完成订阅后,系统需要在 webhook 中侦听 POST 调用。所有回调都将向此 webhook 发出。

Messenger Platform 的所有回调都使用相同的结构。

{  "object":"page",  "entry":[    {      "id":"PAGE_ID",      "time":1458692752478,      "messaging":[        {          "sender":{            "id":"USER_ID"          },          "recipient":{            "id":"PAGE_ID"          },          ...        }      ]    }  ]} 

纯文字信息的详细结构

{  "object":"page",  "entry":[    {      "id":"PAGE_ID",      "time":1458692752478,      "messaging":[        {          "sender":{            "id":"USER_ID"          },          "recipient":{            "id":"PAGE_ID"          },          "timestamp":1458692752478,          "message":{            "mid":"mid.1457764197618:41d102a3e1ae206a38",            "seq":73,            "text":"hello, world!",            "quick_reply": {              "payload": "DEVELOPER_DEFINED_PAYLOAD"            }          }        }      ]    }  ]} 

附上webhook的参考文档的地址

https://developers.facebook.com/docs/messenger-platform/webhook-reference

关于具体处理消息的过程,我贴上我的代码
入口文件

require_once 'config.php';require_once 'FacebookBot.php';$bot = new FacebookBot(FACEBOOK_VALIDATION_TOKEN, FACEBOOK_PAGE_ACCESS_TOKEN);$bot->run();$messages = $bot->getReceivedMessages(); foreach ($messages as $message) {    $recipientId = $message->senderId;    $text=$message->text;    if($text)    {        $bot->sendTextMessage($recipientId, $text);    }    elseif($message->attachments)    {        $bot->sendTextMessage($recipientId, "Attachment received");    }}

定义类的文件

<?phprequire_once 'config.php';class FacebookBot{    private $_validationToken;    private $_pageAccessToken;    private $_receivedMessages;    public function __construct($validationToken, $pageAccessToken)    {        $this->_validationToken = $validationToken;        $this->_pageAccessToken = $pageAccessToken;        $this->setupWebhook();    }    public function getReceivedMessages()    {        $this->run();        return $this->_receivedMessages;    }    public function getPageAccessToken()    {        return $this->_pageAccessToken;    }    public function getValidationToken()    {        return $this->_validationToken;    }    private function setupWebhook()    {        if(isset($_REQUEST['hub_challenge']) && isset($_REQUEST['hub_verify_token']) && $this->getValidationToken()==$_REQUEST['hub_verify_token'])        {            echo $_REQUEST['hub_challenge'];            exit;        }    }    public function sendTextMessage($recipientId, $text)    {        $url = "https://graph.facebook.com/v2.6/me/messages?access_token=%s";        $url = sprintf($url, FACEBOOK_PAGE_ACCESS_TOKEN);        $recipient = new stdClass();        $recipient->id = $recipientId;        $message = new stdClass();        $message->text = $text;        $parameters = ['recipient' => $recipient, 'message' => $message];        $response = self::executePost($url, $parameters, true);        if($response)        {            $responseObject = json_decode($response);            return is_object($responseObject) && isset($responseObject->recipient_id) && isset($responseObject->message_id);        }        return false;    }    public function run()    {        $request = self::getJsonRequest();        //var_dump($request);        if(!$request) return;        $entries = isset($request->entry) ? $request->entry : null;        if(!$entries) return;        $messages = [];        foreach ($entries as $entry)        {            $messagingList = isset($entry->messaging) ? $entry->messaging : null;            if(!$messagingList) continue;            foreach ($messagingList as $messaging)            {                $message = new stdClass();                $message->entryId = isset($entry->id) ? $entry->id : null;                $message->senderId = isset($messaging->sender->id) ? $messaging->sender->id : null;                $message->recipientId = isset($messaging->recipient->id) ? $messaging->recipient->id : null;                $message->timestamp = isset($messaging->timestamp) ? $messaging->timestamp : null;                $message->messageId = isset($messaging->message->mid) ? $messaging->message->mid : null;                $message->sequenceNumber = isset($messaging->message->seq) ? $messaging->message->seq : null;                $message->text = isset($messaging->message->text) ? $messaging->message->text : null;                $message->attachments = isset($messaging->message->attachments) ? $messaging->message->attachments : null;                $messages[] = $message;            }        }        $this->_receivedMessages = $messages;    }    private static function getJsonRequest()    {        $content = file_get_contents("php://input",true);        $return=json_decode($content, false, 512, JSON_BIGINT_AS_STRING);        return $return;    }    private static function executePost($url, $parameters, $json = false)    {        $ch = curl_init();        curl_setopt($ch, CURLOPT_URL, $url);        if($json)        {            $data = json_encode($parameters);            curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");            curl_setopt($ch, CURLOPT_POSTFIELDS, $data);            curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json', 'Content-Length: ' . strlen($data)));        }        else        {            curl_setopt($ch, CURLOPT_POST, count($parameters));            curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($parameters));        }        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);        $response = curl_exec($ch);        curl_close($ch);        return $response;    }}

我这里做测试,返回的就是复述发送者的信息
这里写图片描述

六.测试
接入第三方平台和自己开发的差别还是很大的,起码报错消息你是看不见的,所以光从messenger那里发消息给主页是不方便调试的。
我这次用了shell下的curl来进行测试,用主页访问口令向 https://graph.facebook.com/v2.6/me/messages?access_token= 发出 POST 请求。负载必须以如下所述的 JSON 格式提供:

curl -X POST -H "Content-Type: application/json" -d '{  "recipient":{    "id":"USER_ID"  },  "message":{    "text":"hello, world!"  }}' "https://graph.facebook.com/v2.6/me/messages?access_token=PAGE_ACCESS_TOKEN"

windows和linux略有区别。windows下建议用git bash等基于linux的环境而不要用cmd,例如上面的post请求,在cmd下其引号会失效,必须手动进行转义

七.关于一些坑
首先是facebook会偶尔向你的绑定的回调地址get消息,如果8个小时之内没有正确的返回的话,它就会自动解绑,我前一天晚上绑定的url第二天早上自动失效了,发现没有消息返回之后调了半天,才发现了这个问题。
其次是post回messenger的时候用了curl,需要开启php的curl,linux下的安装和windows不太一样,装的时候不要装错了php的版本,否则是不能生效的。
最后是messenger的应用没有提交审核之前是只能开发者发消息才有作用~

messenger的开发文档不算友好,全文算是译文吧,有的地方感觉比较生硬,比如它说的接受消息和发送消息是以用户做主体的,和一般人的理解还有一点出入。

0 0
原创粉丝点击