官方API文檔: https://developers.facebook.com/docs/chat/php
下面是根據文檔修改的類:api
<?php class Invite_Chat{ protected static $_instance = array(); private $server = 'chat.facebook.com'; // fb xmpp 服務器
private $access_token = ''; // FB chat XMPP 標準
private $STREAM_XML = '<stream:stream xmlns:stream="http://etherx.jabber.org/streams" version="1.0" xmlns="jabber:client" to="chat.facebook.com" xml:lang="en" xmlns:xml="http://www.w3.org/XML/1998/namespace">'; private $AUTH_XML = '<auth xmlns="urn:ietf:params:xml:ns:xmpp-sasl" mechanism="X-FACEBOOK-PLATFORM"></auth>'; private $CLOSE_XML = '</stream:stream>'; private $RESOURCE_XML = '<iq type="set" id="3"> <bind xmlns="urn:ietf:params:xml:ns:xmpp-bind"> <resource>fb_xmpp_script</resource></bind></iq>'; private $SESSION_XML = '<iq type="set" id="4" to="chat.facebook.com"> <session xmlns="urn:ietf:params:xml:ns:xmpp-session"/></iq>'; private $START_TLS = '<starttls xmlns="urn:ietf:params:xml:ns:xmpp-tls"/>'; /** * * @return Invite_Chat */
public static function factory(){ if( !is_object( self::$_instance['invite_chat'])){ self::$_instance['invite_chat'] = new Invite_Chat(); } return self::$_instance['invite_chat']; } /** * * 獲取用戶access_token * @param unknown_type $from */
public function getAccessToken($from){ // 根據FB API 獲取access token 這裏須要本身處理
return $this->access_token; } /** * * 鏈接xmpp server * @param unknown_type $server */
public function open_connection($server){ $fp = fsockopen($server, 5222, $errno, $errstr); if(!$fp){ // print "$errstr ($errno)<br>";
}else{ // print "connnection open<br>";
} return $fp; } /** * * 發送xmpp文件流 * @param unknown_type $fp * @param unknown_type $xml */
public function send_xml($fp, $xml){ fwrite($fp, $xml); } /** * * 接收xmpp文件流 * @param unknown_type $fp * @param unknown_type $size */
public function recv_xml($fp, $size=4096) { $xml = fread($fp, $size); if (!preg_match('/^</', $xml)) { $xml = '<' . $xml; } if ($xml === "") { return null; } // parses xml
$xml_parser = xml_parser_create(); xml_parse_into_struct($xml_parser, $xml, $val, $index); xml_parser_free($xml_parser); return array($val, $index); } /** * * 解析xmpp文件流 * @param unknown_type $fp * @param unknown_type $tag * @param unknown_type $value * @param unknown_type $ret */
public function find_xmpp($fp, $tag, $value=null, &$ret=null) { static $val = null, $index = null; do { if ($val === null && $index === null) { list($val, $index) = $this->recv_xml($fp); if ($val === null || $index === null) { return false; } } foreach ($index as $tag_key => $tag_array) { if ($tag_key === $tag) { if ($value === null) { if (isset($val[$tag_array[0]]['value'])) { $ret = $val[$tag_array[0]]['value']; } return true; } foreach ($tag_array as $i => $pos) { if ($val[$pos]['tag'] === $tag && isset($val[$pos]['value']) && $val[$pos]['value'] === $value) { $ret = $val[$pos]['value']; return true; } } } } $val = $index = null; }while (!feof($fp)); return false; } /** * * xmpp 通訊 * @param unknown_type $options * @param unknown_type $access_token * @param unknown_type $message */
public function xmpp_connect($options, $access_token, $message){ $fp = $this->open_connection($options['server']); if(!$fp){ return -1; } // initiates auth process (using X-FACEBOOK_PLATFORM)
$this->send_xml($fp, $this->STREAM_XML); if(!$this->find_xmpp($fp, 'STREAM:STREAM')){ return -2; } if(!$this->find_xmpp($fp, 'MECHANISM', 'X-FACEBOOK-PLATFORM')){ return -3; } // starting tls - MANDATORY TO USE OAUTH TOKEN!!!!
$this->send_xml($fp, $this->START_TLS); if(!$this->find_xmpp($fp, 'PROCEED', null, $proceed)){ return -4; } stream_socket_enable_crypto($fp, true, STREAM_CRYPTO_METHOD_TLS_CLIENT); $this->send_xml($fp, $this->STREAM_XML); if(!$this->find_xmpp($fp, 'STREAM:STREAM')){ return -5; } if(!$this->find_xmpp($fp, 'MECHANISM', 'X-FACEBOOK-PLATFORM')){ return -6; } // gets challenge from server and decode it
$this->send_xml($fp, $this->AUTH_XML); if(!$this->find_xmpp($fp, 'CHALLENGE', null, $challenge)){ return -7; } $challenge = base64_decode($challenge); $challenge = urldecode($challenge); parse_str($challenge, $challenge_array); // creates the response array
$resp_array = array( 'method' => $challenge_array['method'],
'nonce' => $challenge_array['nonce'],
'access_token' => $access_token,
'api_key' => $options['app_id'],
'call_id' => 0,
'v' => '1.0', ); // creates signature
$response = http_build_query($resp_array); // sends the response and waits for success
$xml = '<response xmlns="urn:ietf:params:xml:ns:xmpp-sasl">'.
base64_encode($response).'</response>'; $this->send_xml($fp, $xml); if (!$this->find_xmpp($fp, 'SUCCESS')) { return -8; } // finishes auth process
$this->send_xml($fp, $this->STREAM_XML); if(!$this->find_xmpp($fp,'STREAM:STREAM')) { return -9; } if(!$this->find_xmpp($fp, 'STREAM:FEATURES')){ return -10; } $this->send_xml($fp, $this->RESOURCE_XML); if(!$this->find_xmpp($fp, 'JID')){ return -11; } $this->send_xml($fp, $this->SESSION_XML); if(!$this->find_xmpp($fp, 'SESSION')){ return -12; } // send messages
$this->send_xml($fp, $message); // we made it!
$this->send_xml($fp, $this->CLOSE_XML); // print ("Authentication complete<br>");
fclose($fp); return true; } /** * * 發送chat 信息 * @param $from 發送者id * @param $to_puid 接收者id * @param $message 消息。 例: http://www.google.com 直接輸入鏈接便可 */
function chat($from, $to_puid, $message){ $app_id= '應用appid'; $app_secret= '應用secret'; $my_url = '應用app_url'; $message_xml = '<message to="-'.$to_puid.'@chat.facebook.com" from="-'.$from.'@chat.facebook.com" >'.
'<body>'.$message.'</body>'.
'</message>'; $options = array( 'uid' => $from,
'app_id' => $app_id,
'server' => $this->server ); $access_token = $this->getAccessToken($from); if(empty($access_token)){ return false; } if($this->xmpp_connect($options, $access_token, $message_xml) > 0){ return true; }else{ return false; } } } // end class
須要注意的地方: 服務器
1. 官方文檔沒有寫明在哪裏添加消息發送。若是想了解詳情,最好去看看XMPP協議。session
2. 使用Chat API 接口,須要先獲取Chat 權限。app
3. access_token 和官方的獲取方式不一樣,這個能夠根據本身的應用的結構進行調整。socket
獲取chat 權限:ui
js 方法:this
function getXmpplogin(){ FB.ui({ method : 'permissions.request',perms : 'xmpp_login'}, function(r){ console.log(r); }); } getXmpplogin();
url 方法:google
<?php $appid = ''; $secret = ''; $appurl = ''; $url = 'https://www.facebook.com/dialog/oauth?scope=PERMISSIONS_NAME&client_id=APPID&redirect_uri=APPURL';