In this tutorial we will learn by full coldfusion Graph API code example how to publish on your wall and your friends walls. This application uses new oauth authentication method.
The code is divided into four files: we will first start with a file called index.cfm:
The login.cfm file which is used to contact Facebook Graph API for Authentication:
Now login1.cfm will get the access token:
<!--- Your FB application IDS --->
<cfset api_key = ""/>
<cfset secret_key = ""/>
<cfset appID = ""/>
<cfif isdefined("url.code")>
<!--- Get the access token from FB --->
<cfhttp url="https://graph.facebook.com/oauth/access_token" result="login1">
<cfhttpparam name="client_id" value="#appID#" encoded="no" type="url">
<cfhttpparam name="redirect_uri" value="http://www.sms4all.info/fb/release1/login1.cfm" encoded="no" type="url">
<cfhttpparam name="client_secret" value="#secret_key#" encoded="no" type="url">
<cfhttpparam name="code" value="#url.code#" encoded="no" type="url">
</cfhttp>
<!--- now back to the application with the access token --->
<cflocation url="index.cfm?#login1.filecontent#" addtoken="no">
</cfif>
Finally the Graph.cfc Class where the main ColdFusion Graph APIs:
<cfcomponent output="false">
<cffunction name="init">
<cfargument name="appID" required="true" type="string">
<cfargument name="api_key" required="true" type="string">
<cfargument name="secret_key" required="true" type="string">
<!--- init global variables --->
<cfset variables.appID = arguments.appID />
<cfset variables.api_key = arguments.api_key />
<cfset variables.secret_key = arguments.secret_key />
<cfreturn this />
</cffunction>
<!--- Publish to Wall Method --->
<cffunction name="publishToWall">
<cfargument name="uid" required="true" type="string">
<cfargument name="access_token" required="true" type="string">
<cfargument name="message" required="true" type="string">
<cfargument name="picture" required="true" type="string">
<cfargument name="link" required="true" type="string">
<cfargument name="name" required="true" type="string">
<cfargument name="caption" required="true" type="string">
<cfargument name="description" required="true" type="string">
<cfhttp url="https://graph.facebook.com/#uid#/feed" result="publish" method="post">
<cfhttpparam name="access_token" value="#access_token#" encoded="no" type="url">
<cfhttpparam name="message" value="#message#" encoded="no" type="url">
<cfhttpparam name="picture" value="#picture#" encoded="no" type="url">
<cfhttpparam name="link" value="#link#" encoded="no" type="url">
<cfhttpparam name="name" value="#name#" encoded="no" type="url">
<cfhttpparam name="caption" value="#caption#" encoded="no" type="url">
<cfhttpparam name="description" value="#description#" encoded="no" type="url">
</cfhttp>
</cffunction>
<!--- Method returns a struct of Friends --->
<cffunction name="getFriends" access="public" output="true" returntype="any" hint="gets all of a user's friends">
<cfargument name="uid" required="true" type="string">
<cfargument name="access_token" required="true" type="string">
<cfset friends = "" />
<!--- Get FB User Friends. Friends Information allowed by the user are stored in a struct after deserialized from JSON--->
<cfhttp url="https://graph.facebook.com/#uid#/friends?access_token=#access_token#" result="friends" />
<cfif IsJSON(friends.filecontent)>
<cfreturn DeserializeJSON(friends.filecontent) />
<cfelse>
<cfreturn 0/>
</cfif>
</cffunction>
</cfcomponent>
A full working example can be found here (Ramadan Greetings)
The code is divided into four files: we will first start with a file called index.cfm:
<cfoutput>
<!--- Your FB application IDS --->
<cfset api_key = ""/>
<cfset secret_key = ""/>
<cfset appID = ""/>
<!--- create a connection to the fb graph cfc --->
<cfset graphCFC = createObject("component", "graph").init(#appID#, #api_key#, #secret_key#) />
<!--- If user is authenticated or his access token is set create a cookie --->
<!--- Your FB application IDS --->
<cfset api_key = ""/>
<cfset secret_key = ""/>
<cfset appID = ""/>
<!--- create a connection to the fb graph cfc --->
<cfset graphCFC = createObject("component", "graph").init(#appID#, #api_key#, #secret_key#) />
<!--- If user is authenticated or his access token is set create a cookie --->
<cfif not isdefined("cookie.access_token") and isdefined("url.access_token")>
<cfset cookie.access_token=url.access_token>
</cfif>
<cfset cookie.access_token=url.access_token>
</cfif>
<!--- If the user is authenticated and access token is set, then make the action of the form the same page else go and authenticate the user and get the access token from Facebook API --->
<cfif isdefined("cookie.access_token")>
<cfset action="index.cfm">
<cfelse>
<cfset action="login.cfm"> <!--- login page will be discussed after this code --->
</cfif>
<h3> Write to Wall on FaceBook </h3>
<form action="#action#" method="post">
<textarea cols="55" rows="3" name="msg"></textarea>
<input type="submit" value="Update Status" />
</form>
<cfif isdefined("form.msg")>
<cfset session.msg=form.msg>
</cfif>
<cfif isdefined("session.msg") and isdefined("cookie.access_token")>
<cftry>
<!--- Publish to Your Wall (me) The logged in user wall. A call to publish to wall method which is defined in Graph.cfc component--->
<cfset publish=graphCFC.publishToWall("me",#cookie.access_token#,#session.msg#,"img.jpg","http://blog.abusalah.info","Testing,Graph API","New Interface with Coldfusion","desc")>
<!--- Publish to A friend Wall here I want to publish to certain friend --->
<cfset friends=graphCFC.getFriends('me',#cookie.access_token#)>
<cfset aFriends=friends.data>
<cfloop from="1" to="#arraylen(aFriends)#" index="i">
<cfif aFriends[i].name is "">
<cfset uid=#aFriends[i].id#>
<cfbreak>
</cfif>
</cfloop>
<cfif isdefined("uid")>
<cfset publish=graphCFC.publishToWall(#uid#,#cookie.access_token#,#session.msg#,"img.jpg","http://blog.abusalah.info","Testing,Graph API","New Interface with Coldfusion","desc")>
</cfif>
<cfset StructDelete(session, "msg")>
Status Updated successfuly.
<cfcatch type="any">
Sorry something wrong happend #cfcatch.Message#
</cfcatch>
</cftry>
</cfif>
</cfoutput>
<cfif isdefined("cookie.access_token")>
<cfset action="index.cfm">
<cfelse>
<cfset action="login.cfm"> <!--- login page will be discussed after this code --->
</cfif>
<h3> Write to Wall on FaceBook </h3>
<form action="#action#" method="post">
<textarea cols="55" rows="3" name="msg"></textarea>
<input type="submit" value="Update Status" />
</form>
<cfif isdefined("form.msg")>
<cfset session.msg=form.msg>
</cfif>
<cfif isdefined("session.msg") and isdefined("cookie.access_token")>
<cftry>
<!--- Publish to Your Wall (me) The logged in user wall. A call to publish to wall method which is defined in Graph.cfc component--->
<cfset publish=graphCFC.publishToWall("me",#cookie.access_token#,#session.msg#,"img.jpg","http://blog.abusalah.info","Testing,Graph API","New Interface with Coldfusion","desc")>
<!--- Publish to A friend Wall here I want to publish to certain friend --->
<cfset friends=graphCFC.getFriends('me',#cookie.access_token#)>
<cfset aFriends=friends.data>
<cfloop from="1" to="#arraylen(aFriends)#" index="i">
<cfif aFriends[i].name is "">
<cfset uid=#aFriends[i].id#>
<cfbreak>
</cfif>
</cfloop>
<cfif isdefined("uid")>
<cfset publish=graphCFC.publishToWall(#uid#,#cookie.access_token#,#session.msg#,"img.jpg","http://blog.abusalah.info","Testing,Graph API","New Interface with Coldfusion","desc")>
</cfif>
<cfset StructDelete(session, "msg")>
Status Updated successfuly.
<cfcatch type="any">
Sorry something wrong happend #cfcatch.Message#
</cfcatch>
</cftry>
</cfif>
</cfoutput>
The login.cfm file which is used to contact Facebook Graph API for Authentication:
<cfoutput>
<!--- Your FB application IDS --->
<cfset api_key = ""/>
<cfset secret_key = ""/>
<cfset appID = ""/>
<!--- Create a session variable to store the status, this is the form variable from index.cfm from --->
<cfif isdefined("form.msg")>
<cfset session.msg=form.msg>
</cfif>
<!--- Check if the user is Authenticated with Facebook, if not authenticate him, ask for permissions and create a variable called code that fetches the access token --->
<cflocation url="https://graph.facebook.com/oauth/authorize?client_id=#appID#&redirect_uri=http://blog.abusalah.info/fb/release1/login1.cfm&scope=offline_access,read_stream,publish_stream" addtoken="no">
</cfoutput>
<!--- Your FB application IDS --->
<cfset api_key = ""/>
<cfset secret_key = ""/>
<cfset appID = ""/>
<!--- Create a session variable to store the status, this is the form variable from index.cfm from --->
<cfif isdefined("form.msg")>
<cfset session.msg=form.msg>
</cfif>
<!--- Check if the user is Authenticated with Facebook, if not authenticate him, ask for permissions and create a variable called code that fetches the access token --->
<cflocation url="https://graph.facebook.com/oauth/authorize?client_id=#appID#&redirect_uri=http://blog.abusalah.info/fb/release1/login1.cfm&scope=offline_access,read_stream,publish_stream" addtoken="no">
</cfoutput>
Now login1.cfm will get the access token:
<!--- Your FB application IDS --->
<cfset api_key = ""/>
<cfset secret_key = ""/>
<cfset appID = ""/>
<cfif isdefined("url.code")>
<!--- Get the access token from FB --->
<cfhttp url="https://graph.facebook.com/oauth/access_token" result="login1">
<cfhttpparam name="client_id" value="#appID#" encoded="no" type="url">
<cfhttpparam name="redirect_uri" value="http://www.sms4all.info/fb/release1/login1.cfm" encoded="no" type="url">
<cfhttpparam name="client_secret" value="#secret_key#" encoded="no" type="url">
<cfhttpparam name="code" value="#url.code#" encoded="no" type="url">
</cfhttp>
<!--- now back to the application with the access token --->
<cflocation url="index.cfm?#login1.filecontent#" addtoken="no">
</cfif>
Finally the Graph.cfc Class where the main ColdFusion Graph APIs:
<cfcomponent output="false">
<cffunction name="init">
<cfargument name="appID" required="true" type="string">
<cfargument name="api_key" required="true" type="string">
<cfargument name="secret_key" required="true" type="string">
<!--- init global variables --->
<cfset variables.appID = arguments.appID />
<cfset variables.api_key = arguments.api_key />
<cfset variables.secret_key = arguments.secret_key />
<cfreturn this />
</cffunction>
<!--- Publish to Wall Method --->
<cffunction name="publishToWall">
<cfargument name="uid" required="true" type="string">
<cfargument name="access_token" required="true" type="string">
<cfargument name="message" required="true" type="string">
<cfargument name="picture" required="true" type="string">
<cfargument name="link" required="true" type="string">
<cfargument name="name" required="true" type="string">
<cfargument name="caption" required="true" type="string">
<cfargument name="description" required="true" type="string">
<cfhttp url="https://graph.facebook.com/#uid#/feed" result="publish" method="post">
<cfhttpparam name="access_token" value="#access_token#" encoded="no" type="url">
<cfhttpparam name="message" value="#message#" encoded="no" type="url">
<cfhttpparam name="picture" value="#picture#" encoded="no" type="url">
<cfhttpparam name="link" value="#link#" encoded="no" type="url">
<cfhttpparam name="name" value="#name#" encoded="no" type="url">
<cfhttpparam name="caption" value="#caption#" encoded="no" type="url">
<cfhttpparam name="description" value="#description#" encoded="no" type="url">
</cfhttp>
</cffunction>
<!--- Method returns a struct of Friends --->
<cffunction name="getFriends" access="public" output="true" returntype="any" hint="gets all of a user's friends">
<cfargument name="uid" required="true" type="string">
<cfargument name="access_token" required="true" type="string">
<cfset friends = "" />
<!--- Get FB User Friends. Friends Information allowed by the user are stored in a struct after deserialized from JSON--->
<cfhttp url="https://graph.facebook.com/#uid#/friends?access_token=#access_token#" result="friends" />
<cfif IsJSON(friends.filecontent)>
<cfreturn DeserializeJSON(friends.filecontent) />
<cfelse>
<cfreturn 0/>
</cfif>
</cffunction>
</cfcomponent>
A full working example can be found here (Ramadan Greetings)
thanks for the headstart!
ReplyDeleteYour welcomed
ReplyDeletemy cf fb app is 2 years old and not doing what i want it to. I'm going to start over with your code up top as a starter. thanks!
ReplyDeleteAviva if ur code is two years old that means you need to rewrite it, this is a good place to start, in case you need further help drop me a line.
ReplyDeleteI can post to FB, but the CF interface is giving me this error:
ReplyDelete"Sorry something wrong happend Variable IsJSON is undefined."
Can you please send me the full error message on my email mustafa at abusalah dot info
ReplyDeleteTry the link on the end of this post it demonstrates an example of the above code.
Figured it out - my host was running CF7 which does not support isJSON.
ReplyDeleteThanks for this example, I can hack my way into accessing the other Graph API elements from this.
Hi,
ReplyDeleteI am getting error 'Application Temporarily Unavailable
The URL http://xyz.com/test/ caused too many redirections.'
Plz help me to solve this..
Thanks
Deepak, this url is not valid it shows ads only.
ReplyDeleteThanks for the great tutorial Abu and can you please let me know the similar behaviour to integrate with twitter and Linkedin.
ReplyDeleteDear Mohammad,
ReplyDeleteI did not work on Twitter nor linkedin integration yet.
Hi Mustafa,
ReplyDeleteI'm encountering this error
The column name "{error:{type:OAuthException" is invalid.
Column names must be valid variable names. They must start with a letter and can only include letters, numbers, and underscores.
The error occurred in login1.cfm: line 10
8 :
9 :
10 :
11 :
Any advice?
it's essentially pointing to this "URL.code" which FB returned starting with a number instead.
ReplyDeletecfhttpparam name="code" value="#url.code#" encoded="no" type="url"
Hi Jason, sorry for the later response! did u get this working? if not kindly contact me on mustafa at abusalah dot info
ReplyDeleteHello Mustafa,
ReplyDeleteThank you very much for your example! You've pointed me to the right direction.
Thanks!
Tim
Its my pleasure Tim.
ReplyDeleteawesome!!! saved hours for me... 1 down two more to go. Next is Twitter and LinkedIn.
ReplyDeleteMoustafa, you sent me here when I had trouble with the Facebook login tutorial, but when I tried implementing this tutorial I notice there's no way to login to FB from the index page.
ReplyDeleteIt just has a post to wall. When a user isn't logged you just get an error...
"Sorry something wrong happend Element DATA is undefined in FRIENDS."
I got it to work seamlessly on another browser.
ReplyDeleteIt doesn't work in Chrome.
Also, I don't know if you noticed but it posts the status update twice.
Is there a way to grab the users name and email on the way back from login?
ReplyDeleteI don't remember testing it on Chrome, but I tested it on Firefox and Explorer. Yes you may grab usenames and emails but you need to ask for authorization when you redirect users to the login page.
ReplyDeleteMoustafa:
ReplyDeleteThanks for this tutorial! Really helped me get started with Facebook integration on my site. I had a question though. While I can post statuses to my personal wall just fine, what I'm looking to do is to build a way to post a status to a business page that I'm an admin for.
So, I'd need to be able to detect what I'm an admin for and, once that's done be able (via a form that I'd build of the various pages I can post to as a user) to post a new status to that page's wall.
Any thoughts/guidance? Should the page show up as a "friend" via a getFriends method call?
Hi Euroranger,
ReplyDeleteI was asked to do the same exercise before, I believe this is a doable thing. Let me investigate this over the weekend and I will let u know.
Mustafa:
ReplyDeleteActually, I found it this evening.
This URL (http://developers.facebook.com/docs/reference/api/) and down to the Page Login section. You have to modify the authorization and add "manage_pages" to the scope attribute. Do that and the app will be able to do an accounts call and get back all the pages and apps that that user is an administrator for along with a unique access_token for each...which would be used to make a feed call (your publishToWall method).
Kind of a roundabout way to get to it but once there, it makes sense. That said, there's no way I'd be doing the "happy developers dance" this evening without your CFC work. Thank you very much!
Thanks for posting this Mustafa. FYI - I had some issues in IE with this approach
ReplyDeleteso I changed it to do this
and it worked like a charm in IE
Relevant code from my comment...
ReplyDeleteDidn't work in IE:
cfif not isdefined("cookie.access_token") and isdefined("url.access_token")
cfset cookie.access_token=url.access_token
cfif
Did work
cfset cookie.access_token=listGetAt(login1.fileContent,2,"=")
Thanks for the tip at the time this blog post was published the code was tested on Firefox and explorer. But maybe something has been changed!
ReplyDeleteHow do you simply return the user names using this. Basically I want the "John Smith" to show up on the "Write to Wall on FaceBook" page
ReplyDeleteYour request is not clear! what exactly you want to do? please check this page and let me know which method you want to use:
ReplyDeletehttp://developers.facebook.com/docs/reference/api/