Created
July 13, 2013 23:43
-
-
Save MaxHorstmann/5992611 to your computer and use it in GitHub Desktop.
Connect to Facebook chat API using their sample code (https://developers.facebook.com/docs/chat/), then send presence information and an actual message.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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); | |
print $xml; | |
print "\n"; | |
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 "1"; | |
// initiates auth process (using X-FACEBOOK_PLATFORM) | |
send_xml($fp, $STREAM_XML); | |
if (!find_xmpp($fp, 'STREAM:STREAM')) { | |
return false; | |
} | |
if (!find_xmpp($fp, 'MECHANISM', 'X-FACEBOOK-PLATFORM')) { | |
return false; | |
} | |
print "2"; | |
// starting tls - MANDATORY TO USE OAUTH TOKEN!!!! | |
send_xml($fp, $START_TLS); | |
print "3"; | |
if (!find_xmpp($fp, 'PROCEED', null, $proceed)) { | |
return false; | |
} | |
stream_socket_enable_crypto($fp, true, STREAM_CRYPTO_METHOD_TLS_CLIENT); | |
print "4"; | |
send_xml($fp, $STREAM_XML); | |
print "5"; | |
if (!find_xmpp($fp, 'STREAM:STREAM')) { | |
return false; | |
} | |
if (!find_xmpp($fp, 'MECHANISM', 'X-FACEBOOK-PLATFORM')) { | |
return false; | |
} | |
print "6"; | |
// 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); | |
print "7"; | |
// 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); | |
print "8"; | |
// 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); | |
print "9"; | |
if (!find_xmpp($fp, 'SUCCESS')) { | |
return false; | |
} | |
print "10"; | |
// finishes auth process | |
send_xml($fp, $STREAM_XML); | |
if (!find_xmpp($fp,'STREAM:STREAM')) { | |
return false; | |
} | |
if (!find_xmpp($fp, 'STREAM:FEATURES')) { | |
return false; | |
} | |
print "11"; | |
send_xml($fp, $RESOURCE_XML); | |
if (!find_xmpp($fp, 'JID')) { | |
return false; | |
} | |
print "12"; | |
send_xml($fp, $SESSION_XML); | |
if (!find_xmpp($fp, 'SESSION')) { | |
return false; | |
} | |
// send presence | |
$xml = "<presence />"; | |
send_Xml($fp, $xml); | |
// send a message! | |
$xml = "<message xmlns='urn:ietf:params:xml:ns:xmpp-stanzas' xml:lang='en' to='-someUserId@chat.facebook.com' from='-myUserId@chat.facebook.com' type='chat'><body>Another test 12345</body></message>"; | |
send_xml($fp, $xml); | |
// 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='<your app id>'; | |
$app_secret='<your app secret>'; | |
$uid = '<your user id here>'; | |
$access_token = '<your access token>'; | |
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(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment