2013-04-04 212 views
8

我目前正在搞Facebook聊天API。我想通過應用程序發送聊天消息給我的Facebook聯繫人。Facebook XMPP聊天API發送消息PHP

使用facebook提供的示例,我能夠連接到facebook聊天服務器。 但是這裏有更多的嘗試和錯誤的東西。我只能模糊地理解請求和響應是如何發送和接收的。如果有人能提供進一步的解釋或進一步閱讀,那將是很棒的。

我的實際問題是:如何在連接到聊天服務器後發送消息?

<?php 

// Copyright 2004-present Facebook. All Rights Reserved. 

$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">'; 

$AUTH_XML = '<auth xmlns="urn:ietf:params:xml:ns:xmpp-sasl" '. 
    'mechanism="X-FACEBOOK-PLATFORM"></auth>'; 

$CLOSE_XML = '</stream:stream>'; 

$RESOURCE_XML = '<iq type="set" id="3">'. 
    '<bind xmlns="urn:ietf:params:xml:ns:xmpp-bind">'. 
    '<resource>fb_xmpp_script</resource></bind></iq>'; 

$SESSION_XML = '<iq type="set" id="4" to="chat.facebook.com">'. 
    '<session xmlns="urn:ietf:params:xml:ns:xmpp-session"/></iq>'; 

$START_TLS = '<starttls xmlns="urn:ietf:params:xml:ns:xmpp-tls"/>'; 


function open_connection($server) { 
    print "[INFO] Opening connection... "; 

    $fp = fsockopen($server, 5222, $errno, $errstr); 
    if (!$fp) { 
    print "$errstr ($errno)<br>"; 
    } else { 
    print "connnection open<br>"; 
    } 

    return $fp; 
} 

function send_xml($fp, $xml) { 
    fwrite($fp, $xml); 
} 

function recv_xml($fp, $size=4096) { 
    $xml = fread($fp, $size); 
    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); 
} 

function find_xmpp($fp, $tag, $value=null, &$ret=null) { 
    static $val = null, $index = null; 

    do { 
    if ($val === null && $index === null) { 
     list($val, $index) = 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; 
} 



function xmpp_connect($options, $access_token) { 
    global $STREAM_XML, $AUTH_XML, $RESOURCE_XML, $SESSION_XML, $CLOSE_XML, $START_TLS; 

    $fp = open_connection($options['server']); 
    if (!$fp) { 
    return false; 
    } 
    print("Connection Opened <br />"); 


    // initiates auth process (using X-FACEBOOK_PLATFORM) 
    send_xml($fp, $STREAM_XML); 
    if (!find_xmpp($fp, 'STREAM:STREAM')) { 
    return false; 
    } 
    print_r("XMPP Stream Found <br />"); 
    if (!find_xmpp($fp, 'MECHANISM', 'X-FACEBOOK-PLATFORM')) { 
    return false; 
    } 

    print_r("XMPP Mechanism Found <br />"); 
    // starting tls - MANDATORY TO USE OAUTH TOKEN!!!! 
    send_xml($fp, $START_TLS); 
    if (!find_xmpp($fp, 'PROCEED', null, $proceed)) { 
    return false; 
    } 
    print_r("XMPP Proceed Found <br />"); 
    stream_socket_enable_crypto($fp, true, STREAM_CRYPTO_METHOD_TLS_CLIENT); 

    send_xml($fp, $STREAM_XML); 
    if (!find_xmpp($fp, 'STREAM:STREAM')) { 
    return false; 
    } 
    if (!find_xmpp($fp, 'MECHANISM', 'X-FACEBOOK-PLATFORM')) { 
    return false; 
    } 

    // gets challenge from server and decode it 
    send_xml($fp, $AUTH_XML); 
    if (!find_xmpp($fp, 'CHALLENGE', null, $challenge)) { 
    return false; 
    } 
    $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>'; 
    send_xml($fp, $xml); 
    if (!find_xmpp($fp, 'SUCCESS')) { 
    return false; 
    } 

    // finishes auth process 
    send_xml($fp, $STREAM_XML); 
    if (!find_xmpp($fp,'STREAM:STREAM')) { 
    return false; 
    } 
    if (!find_xmpp($fp, 'STREAM:FEATURES')) { 
    return false; 
    } 
send_xml($fp, $RESOURCE_XML); 
    if (!find_xmpp($fp, 'JID')) { 
    return false; 
    } 
    send_xml($fp, $SESSION_XML); 
    if (!find_xmpp($fp, 'SESSION')) { 
    return false; 
    } 

    // we made it! 
    send_xml($fp, $CLOSE_XML); 
    print ("Authentication complete<br>"); 
    fclose($fp); 

    return true; 
} 



//Gets access_token with xmpp_login permission 
function get_access_token($app_id, $app_secret, $my_url){ 

    $code = $_REQUEST["code"]; 

    if(empty($code)) { 
    $dialog_url = "https://www.facebook.com/dialog/oauth?scope=xmpp_login". 
    "&client_id=" . $app_id . "&redirect_uri=" . urlencode($my_url) ; 
    echo("<script>top.location.href='" . $dialog_url . "'</script>"); 
    } 
    $token_url = "https://graph.facebook.com/oauth/access_token?client_id=" 
    . $app_id . "&redirect_uri=" . urlencode($my_url) 
    . "&client_secret=" . $app_secret 
    . "&code=" . $code; 
    $access_token = file_get_contents($token_url); 
    parse_str($access_token, $output); 

    return($output['access_token']); 
} 

function _main() { 
    print "Test platform connect for XMPP<br>"; 
    $app_id=''; 
    $app_secret=''; 
    $my_url = ""; 
    $uid = ''; 
    $access_token = get_access_token($app_id,$app_secret,$my_url); 
    print "access_token: ".$access_token."<br>"; 

    $options = array(
    'uid' => $uid, 
    'app_id' => $app_id, 
    'server' => 'chat.facebook.com', 
    ); 

    // prints options used 
    print "server: ".$options['server']."<br>"; 
    print "uid: ".$options['uid']."<br>"; 
    print "app id: ".$options['app_id']."<br>"; 

    if (xmpp_connect($options, $access_token)) { 
    print "Done<br>"; 

    } else { 
    print "An error ocurred<br>"; 
    } 

} 

_main(); 

?> 

我知道這裏已經有一個這樣的問題(facebook chat api - php)。但這是一個非常古老的話題,也許Facebook在聊天API中改變了一些東西。

回答

12

您應該將消息發送到socket命令。常見的信息格式是

<message from="[email protected]" to="[email protected]"> 
    <body>message body</body> 
</message> 

所以在評論「我們做到了!插入函數調用send_xml您的郵件模板

send_xml($fp, $MESSAGE); 
if (!find_xmpp($fp, 'BODY')) { 
    return false; 
} 
+0

這個答案的伎倆我。我必須解決的下一個問題是性能...我的腳本需要約。 1分15秒執行(建立連接,發送消息,關閉連接)。我已經開始使用FB示例代碼,就像OP包含在他們的問題中一樣。我能做些什麼來加快速度?有任何想法嗎? – 2013-05-24 15:25:44

+0

您是如何知道您發佈的郵件格式的?它是否在本SO文章以外的其他地方進行了記錄? – 2013-05-24 15:27:33

+0

您是否找到長時間執行時間的解決方案?我也有同樣的問題... – user1711384 2014-03-28 11:58:05