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的开发文档不算友好,全文算是译文吧,有的地方感觉比较生硬,比如它说的接受消息和发送消息是以用户做主体的,和一般人的理解还有一点出入。
- php中引入facebook的messenger消息接口
- facebook messenger简介
- php中引入文件方式及引入的优先级
- Facebook Messenger的后台架构是什么样的?
- 使用facebook messenger做外贸推广的优势
- 轻松浏览MSN Messenger的消息历史
- Messenger:使用消息的跨进程通信
- Messenger:使用消息的跨进程通信
- Messenger:使用消息的跨进程通信
- Messenger:使用消息的跨进程通信
- Messenger:使用消息的跨进程通信
- Messenger:使用消息的跨进程通信
- java 接口的引入
- Android中Messenger的使用
- Android中Messenger的使用
- Facebook强制要求下载Messenger
- facebook messenger platform指南(完整)
- php开发中简单的引入编辑器的方法
- ubuntu 下su root 失败su: Authentication failure
- 细节记录
- mysql之select 查询表数据(一)
- UIActionSheet/ UIAlaterView/UIAlertController
- Linux内核之BUS驱动设备模型理解
- php中引入facebook的messenger消息接口
- Java 多线程(四) 多线程访问成员变量与局部变量
- c语言的四个标准
- maven项目少lang的包
- 二分法学习总结
- MySql创建表
- 三星遭遇2016
- 面试总结
- Gradle for Android 学习笔记(一) 下载并安装gradle(Linux 环境),小白也能看懂的gradle教程