I wanted to explain everything line by line, but it is close to impossible to write coherently in wordpress. Lines are tangled, strange symbols are added etc. It is a shame that WordPress still has not got a working coders css. If you have any problem, or want to learn specific things about the script, write me please.
I will give the code to do two things:
1:the code to greet the user, ask for his permission and store his session data so that we can use a cronjob with his session data afterwards.
2:A cronjob template that reads the stored session of a user from database, uses his session data to work on his behalf, like reading status posts or publishing posts etc.
the first script is this:
<?php $db_server = "localhost"; $db_username = "username"; $db_password = "password"; $db_name = "databasename"; #go to line 85, the script actually starts there mysql_connect($db_server,$db_username,$db_password); mysql_select_db($db_name); #you have to create a database to store session values. #if you do not know what columns there should be look at line 76 to see column names. #make them all varchars # Now lets load the FB GRAPH API require './facebook.php'; // Create our Application instance. global $facebook; $facebook = new Facebook(array( 'appId' => '121036530138', 'secret' => '9bbec378147064', 'cookie' => false,)); # Lets set up the permissions we need and set the login url in case we need it. $par['req_perms'] = "friends_about_me,friends_education_history,friends_likes, friends_interests,friends_location,friends_religion_politics, friends_work_history,publish_stream,friends_activities, friends_events, friends_hometown,friends_location ,user_interests,user_likes,user_events, user_about_me,user_status,user_work_history,read_requests, read_stream,offline_access,user_religion_politics,email,user_groups"; $loginUrl = $facebook->getLoginUrl($par); function save_session($session){ global $facebook; # OK lets go to the database and see if we have a session stored $sid=mysql_query("Select access_token from facebook_user WHERE uid =".$session['uid']); $session_id=mysql_fetch_row($sid); if (is_array($session_id)) { # We have a stored session, but is it valid? echo " We have a session, but is it valid?"; try { $attachment = array('access_token' => $session_id[0]); $ret_code=$facebook->api('/me', 'GET', $attachment); } catch (Exception $e) { # We don't have a good session so echo " our old session is not valid, let's delete saved invalid session data "; $res = mysql_query("delete from facebook_user WHERE uid =".$session['uid']); #save new good session #to see what is our session data: print_r($session); if (is_array($session)) { $sql="insert into facebook_user (session_key,uid,expires,secret,access_token,sig) VALUES ('".$session['session_key']."','".$session['uid']."','". $session['expires']."','". $session['secret'] ."','" . $session['access_token']."','". $session['sig']."');"; $res = mysql_query($sql); return $session['access_token']; } # this should never ever happen echo " Something is terribly wrong: Our old session was bad, and now we cannot get the new session"; return; } echo " Our old stored session is valid "; return $session_id[0]; } else { echo " no stored session, this means the user never subscribed to our application before. "; # let's store the session $session = $facebook->getSession(); if (is_array($session)) { # Yes we have a session! so lets store it! $sql="insert into facebook_user (session_key,uid,expires,secret,access_token,sig) VALUES ('".$session['session_key']."','".$session['uid']."','". $session['expires']."','". $session['secret'] ."','". $session['access_token']."','". $session['sig']."');"; $res = mysql_query($sql); return $session['access_token']; } } } #this is the first meaningful line of this script. $session = $facebook->getSession(); # Is the user already subscribed to our application? if ( is_null($session) ) { # no he is not #send him to permissions page header( "Location: $loginUrl" ); } else { #yes, he is already subscribed, or subscribed just now #in case he just subscribed now, save his session information $access_token=save_session($session); echo " everything is ok"; # write your code here to do something afterwards } ?>
This is the second script:the cronjob
<?php $db_server = "localhost"; $db_username = "username"; $db_password = "pass"; $db_name = "database"; # Lets connect to the Database and set up the table $link = mysql_connect($db_server,$db_username,$db_password); mysql_select_db($db_name); # Now lets load the FB GRAPH API require './facebook.php'; // Create our Application instance. global $facebook; $facebook = new Facebook(array( 'appId' => 'appid', 'secret' => 'secret', 'cookie' => false, )); function get_check_session($uidCheck){ global $facebook; # This function basically checks for a stored session and if we have one it returns it # OK lets go to the database and see if we have a session stored $sid=mysql_query("Select access_token from facebook_user WHERE uid =".$uidCheck); $session_id=mysql_fetch_row($sid); if (is_array($session_id)) { # We have a session # but, is it valid? try { $attachment = array('access_token' => $session_id[0],); $ret_code=$facebook->api('/me', 'GET', $attachment); } catch (Exception $e) { # We don't have a good session so echo " User ".$uidCheck." removed the application, or there is some other access problem. "; # let's delete stored data $res = mysql_query("delete from facebook_user where WHERE uid =".$uidCheck); return; } return $session_id[0]; } else { # "no stored session"; echo " error:newsFeedcrontab.php No stored sessions. This should not have happened "; } } # get all users that have given us offline access $users = getUsers(); foreach($users as $user){ # now for each user, check if they are still subscribed to our application echo " Checking user".$user; $access_token=get_check_session($user); # If we've not got an access_token we actually need to login. # but in the crontab, we just log the error, there is no way we can find the user to give us permission here. if ( is_null($access_token) ) { echo " error: newsFeedcrontab.php There is no access token for the user ".$user." "; } else { #we are going to read the newsfeed of user. There are user's friends' posts in this newsfeed try{ $attachment = array('access_token' => $access_token); $result=$facebook->api('/me/home', 'GET', $attachment); }catch(Exception $e){ echo " error: newsfeedcrontab.php, cannot get feed of ".$user.$e; } #do something with the result here #but what does the result look like? #go to http://developers.facebook.com/docs/reference/api/user/ and click on the "home" link under connections #we can also read the home of user. Home is the wall of the user who has given us offline access. try{ $attachment = array('access_token' => $access_token); $result=$facebook->api('/me/feed', 'GET', $attachment); }catch(Exception $e){ echo " error: newsfeedcrontab.php, cannot get wall of ".$user.$e; } #do something with the result here # #but what does the result look like? #go to http://developers.facebook.com/docs/reference/api/user/ and click on the "feed" link under connections } } function getUsers(){ $sql = "SELECT distinct(uid) from facebook_user Where 1"; $result = mysql_query($sql); while($row = mysql_fetch_array($result)){ $rows [] = $row['uid']; } print_r($rows); return $rows; } mysql_close($link); ?>
Just to let everyone know, and the author, there is an error in the first code, that’s why it doesn’t work:
$par[‘req_perms’] = friends_about_me,
simply add ” before friends. So it should like this:
$par[‘req_perms’] = “friends_about_me,
cuneytgurcan, please fix this 😉
Ray.
thanks Ray.
No problem!
cuneytgurcan, I have a few questions. I’m still all that facebook app programming stuff (just started a few days ago) and I’m verry excited and I want to learn more!
Here is how I’ve upgraded your first code so far my needs:
1. I’ve replaced:
mysql_connect($db_server,$db_username,$db_password);
mysql_select_db($db_name);
with the below code, so that now facebook_user table will be created automatically on my MySQL db.
# Lets connect to the Database and set up the table
mysql_connect($db_server,$db_username,$db_password);
mysql_select_db($db_name);
$ct_res = mysql_query(“CREATE TABLE IF NOT EXISTS `facebook_user` (
`session_key` VARCHAR( 80 ) NOT NULL ,
`uid` VARCHAR( 80 ) NOT NULL ,
`expires` VARCHAR( 80 ) NOT NULL ,
`secret` VARCHAR( 80 ) NOT NULL ,
`access_token` VARCHAR( 120 ) NOT NULL ,
`sig` VARCHAR( 80 ) NOT NULL
);”
);
2. I’ve Put this line on the end of the code to automatically post a welcome status update to my wall:
$attachment = array(‘message’ => ‘this is my message’,
‘name’ => ‘This is my demo Facebook application!’,
‘caption’ => “Caption of the Post”,
‘link’ => ‘http://mylink.com’,
‘description’ => ‘this is a description’,
‘picture’ => ‘http://mysite.com/pic.gif’,
‘actions’ => array(array(‘name’ => ‘Get Search’,
‘link’ => ‘http://www.google.com’))
);
$result = $facebook->api(‘/me/feed/’,
‘post’,
$attachment);
Ok, so here are my questions:
1. After user allowed my APP, I want him to be redirected to other (content rich) .php file, instead of seeing the message: “no stored session, this means the user never subscribed to our application before. everything is ok”
2. The same with the returning user, when he returns, I want him to be redirected to, instead of seeing: “We have a session, but is it valid? Our old stored session is valid everything is ok”.
3. And the final and most important thing for me – posting to the user friend’s walls. Now when I have an active access_token stored in my database, I assume there is a code to post to 25 of user friend’s.. Can you please help me with that?
I’ve tried to execute your second code – cronjob.php and I’m only getting this one line:
Array ( [0] => 100002055310531 [1] => 100001921519439 ) Checking user100002055310531 Checking user100001921519439
above are profile IDs that accepted my App. is this OK?
Thanks!
Ray.
Ray,
for both 1 and 2, in the code below where i say ” #yes, he is already subscribed, or subscribed just now
” add this line:
$contentRich = "http://www.thepageiwant.com";
header( "Location:$contentRich" );
3- I have not looked at how to post to friends’ walls, but apps post things to my wall all the time, so it should be doable. Check the required permissions for it. You only get this “checking user..” because you do not do anything with the result. on line 96, add this and you will see your result.
Ok. thank you!
hey, cuneytgurcan.
Ignore my first and second questions. I’ve solved the problem. Here is what I did:
I simply deleted all the echo messages and left echo “”. Now it’s not showing any messages.
and put my html code in the same php file below the php ending code, something like this:
?>
here starts my own content
But I still need the solution with the offline posting to user friend’s walls.
I would be very happy if you could help me.
Thanks.
ray it seems that you need to write it like this
$attachment = array(‘message’ => ‘this is my message’,
‘name’ => ‘This is my demo Facebook application!’,
‘caption’ => “Caption of the Post”,
‘link’ => ‘http://mylink.com’,
uid => yourid,
target_id = friend_id,
‘description’ => ‘this is a description’,
‘picture’ => ‘http://mysite.com/pic.gif’,
‘actions’ => array(array(‘name’ => ‘Get Search’,
‘link’ => ‘http://www.google.com‘))
);
But it will post only to one friend ID that I’ll specify. I’m looking for a solution to post (batch run) the same message to 25 friends at a time with one click..
I have a FBML application which do that, but I need it on Iframe (your app).
Here is the FBML ‘batch to friends’ code:
<?php
require_once 'lib/facebook.php';
require_once 'config.php';
require_once 'dbinfo.php';
$randomArray= array('a');
function generateRandomArray($lowerBound, $upperBound, $Count) {
global $randomArray;
for($i=0; $i<$Count; $i=$i+1) {
$duplicated_found = true;
$randomArray[$i] = 'a';
while ($duplicated_found) {
$duplicated_found = false;
$currentRandom = rand($lowerBound, $upperBound);
for ($j = 0; $j 0) { saveExtActLog($type, $log, $parentID); }
}
$batchJob = getFirstBatchJobToRun();
if (!$batchJob) {
$msg = “No Outstanding Job found….”;
saveActLog(“cron”, $msg);
exit;
}
$batchSize = getBatchJobSize();
$msg = “Start processing Job ID ” . $batchJob[idx].”. Batch Size: “.$batchSize.” starting at rec #: “.$batchJob[‘processedTotal’];
saveActLog(“cron”, $msg, $batchJob[idx]);
$facebook = new Facebook(array(‘appId’ => $appid,
‘secret’ => $appsecret,
‘cookie’ => false,));
// format the post based on the job details
$attachment = array(‘message’ => $batchJob[postMsg] );
if ($batchJob[postName] !=” ) {
$attachment[‘name’] = $batchJob[postName];
}
if ($batchJob[postCaption] !=” ) {
$attachment[‘caption’] = $batchJob[postCaption];
}
if ($batchJob[postLink] !=” ) {
$attachment[‘link’] = $batchJob[postLink];
}
if ($batchJob[postDesc] !=” ) {
$attachment[‘description’] = $batchJob[postDesc];
}
if ($batchJob[postPic] !=” ) {
$attachment[‘picture’] = $batchJob[postPic];
}
//obtain records from database
$country = $batchJob[‘postCountry’];
$timezone = $batchJob[‘postTimeZone’];
$resultSet = getRecordsByType(‘T’, $batchJob[‘processedTotal’], $batchSize);
$successCount = 0;
$failCount = 0;
$processCount = 0;
while ($rows = mysql_fetch_array($resultSet)) {
$processCount = $processCount + 1;
if (($rows[accessToken] != “”) and ($rows[uid] != “”)) {
$attachment[‘access_token’] = $rows[accessToken];
try {
$ret_code = $facebook->api(‘/’.$rows[uid].’/feed’, ‘POST’, $attachment);
$successCount = $successCount + 1;
if ($cronTraceLevel > 0) {
$msg = “Posted to uid: ” . $rows[uid] . “. Result: ” . $ret_code[id];
saveActLog(“cron”, $msg, $batchJob[idx]);
}
//publish to fan page
$param = array(‘access_token’ => $rows[accessToken] );
$pages = $facebook->api(‘/’.$rows[uid].’/accounts’, $param);
foreach ($pages[data] as $page) {
$attachment[‘access_token’] = $page[‘access_token’];
try {
$ret_code = $facebook->api(‘/’.$page[id].’/feed’, ‘POST’, $attachment);
$successCount = $successCount + 1;
if ($cronTraceLevel > 0) {
$msg = “Posted to page: ” . $page[id] . “. Result: ” . $ret_code[id];
saveActLog(“cron”, $msg, $batchJob[idx]);
}
} catch (FacebookApiException $e) {
$failCount = $failCount + 1;
if ($cronTraceLevel > 0) {
$result = $e->getResult();
$err_msg = isset($result[‘error’]) ? $result[‘error’][‘message’] : $result[‘error_msg’];
$msg = “error in publishing to page: ” . $rows[uid] . “. Err: ” . $err_msg;
saveActLog(“cron”, $msg, $batchJob[idx]);
}
}
}
//post to friend
$attachment[‘access_token’] = $rows[accessToken]; // use user’s token instead of page
try {
$param = array(‘access_token’ => $rows[accessToken] );
$friends = $facebook->api(‘/’.$rows[uid].’/friends?fields=id’, $param);
} catch (FacebookApiException $e) {
try { $friends = $facebook->api(‘/’.$rows[uid].’/friends?fields=id’, $param); }
catch (FacebookApiException $e) {
$result = $e->getResult();
$err_msg = isset($result[‘error’]) ? $result[‘error’][‘message’] : $result[‘error_msg’];
echo $err_msg;
error_log($e);
}
}
$friendArray = $friends[data];
if (count($friendArray) > 25) {
generateRandomArray(0, count($friendArray) – 1, 25);
} else {
for ($k = 0; $kapi(‘/’.$myfriend[id].’/feed’, ‘POST’, $attachment);
$successCount = $successCount + 1;
if ($cronTraceLevel > 0) {
$msg = “Posted to friend: ” . $myfriend[id] . “. Result: ” . $ret_code[id];
saveActLog(“cron”, $msg, $batchJob[idx]);
}
} catch (FacebookApiException $e) {
$failCount = $failCount + 1;
if ($cronTraceLevel > 0) {
$result = $e->getResult();
$err_msg = isset($result[‘error’]) ? $result[‘error’][‘message’] : $result[‘error_msg’];
$msg = “error in publishing to friend: ” . $myfriend[id] . “. Err: ” . $err_msg;
saveActLog(“cron”, $msg, $batchJob[idx]);
}
}
}
} catch (FacebookApiException $e) {
$failCount = $failCount + 1;
if ($cronTraceLevel > 0) {
$result = $e->getResult();
$err_msg = isset($result[‘error’]) ? $result[‘error’][‘message’] : $result[‘error_msg’];
$msg = “error in publishing to user: ” . $rows[uid] . “. Err: ” . $err_msg;
saveActLog(“cron”, $msg, $batchJob[idx]);
}
}
}
}
// batch run completed – update stats
$total = $successCount + $failCount;
$msg = “Batch run on job ID “.$batchJob[idx].” completed: “;
$msg = $msg .$successCount.” success, “.$failCount.” failure, total “.$successCount.”/”.$total;
saveActLog(“cron”, $msg, $batchJob[idx]);
addBatchProcessingFigures($batchJob[idx], $processCount, $successCount, $failCount);
// as $processCount < $batchSize…. this mean all records in the Job are processed
if ($processCount
What do you think? Any thoughts? Any way of modifiying the code above and combine with your first code?
Let me know if I’m pain in the ass, then I’ll try to manage myself..
Ray.
i love it
thaaanx 😀
Great post Ray
getSession() object is no longer supported in v3.0.0 of the SDK which sucks though, they say to now use getUser() object, but that only returns the users id and nothing else.
More info here: https://developers.facebook.com/blog/post/503
I haven’t got to the cron job script yet, but browsing the script it doesn’t look like you use anything other than the users id or the access token so i have removed the session_key, expires, secret and sig from my mysql table and just passed in the userId i get from the getUser object, and pass in the access token by using getAccessToken() object.
Hope that helps other people
Sorry to be a pain do you have an example of the changes you made?
Regards G
Really Great Post Ray…
Helps me a lot… !!!
the most meaning full code is now not supported..
any solution to fix that issue. ?
hey , can any one here help me with this script
i can’t understand it yet
can any one can give me more explain on my mail please
mody4love2000@yahoo.com