2013-04-04 16 views
8

Attualmente sto scherzando con l'API di Facebook Chat. Voglio inviare messaggi di chat ai miei contatti di Facebook tramite un'app.Facebook XMPP Chat API invia Messaggio PHP

Utilizzando l'esempio fornito da Facebook, sono riuscito a collegarmi al server di chat di Facebook. Ma quello ha avuto più di una cosa di prova ed errore qui. Ho potuto solo vagamente capire come vengono inviate e ricevute le richieste e le risposte. Sarebbe bello se qualcuno potesse fornire ulteriori spiegazioni o ulteriori letture.

La mia domanda effettiva è: come posso inviare messaggi dopo la connessione al server di chat?

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

?> 

So che c'è già una domanda come questa qui (facebook chat api - php). Ma è un argomento piuttosto vecchio e forse Facebook ha cambiato qualcosa nella loro chat api.

risposta

12

È necessario inviare al comando socket il messaggio. Formato di messaggio comune è

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

Quindi prima del commento "ce l'abbiamo fatta!" inserire la funzione di chiamata send_xml con il vostro modello di messaggio

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

Questa risposta ha fatto il trucco per me. Il prossimo numero che devo affrontare è la performance ... La mia sceneggiatura dura all'incirca. 1 minuto e 15 secondi per eseguire (effettuare la connessione, inviare un messaggio, chiudere la connessione). Ho iniziato con il codice di esempio FB proprio come l'OP ha incluso nella domanda. Cosa posso fare per velocizzare le cose? Qualche idea? –

+0

come hai conosciuto il formato del messaggio che hai postato? È documentato online ovunque tranne che in questo post SO? –

+0

Hai trovato una soluzione per il lungo tempo di esecuzione? Ho lo stesso problema... – user1711384

Problemi correlati