Open Graph for iframe app (game) - facebook

We've created a simple game as an iframe application for facebook and we now want to use OG to make it more interesting.
The game: A user can challenge a friend and they both have to choose a card - in the end the user with the "stronger" card wins.
We don't have a website for this game - it's just the facebook app. We've read that an OG Object has to be represented by an actual object-page:
'you will now need to create a publicly accessible web page that
represents this object using Open Graph metatags.'
https://developers.facebook.com/docs/opengraph/tutorial/
Is this really necessary? And if not, is there any good tutorial or documentation about that?
We found this post: http://facebook.stackoverflow.com/questions/7771321/open-graph-beta-can-it-be-used-with-facebook-iframe-canvas-application -> is this the solution we're looking for?

It is possible to build an Open Graph app which exists inside Facebook's Canvas.
You still need to create URLs which represent each of your object instances, but they can be of the form:
https://apps.facebook.com/yourapp/foo/bar
https://apps.facebook.com/yourapp/foo
https://apps.facebook.com/yourapp?foo=bar
These map to URLs on your server like:
https://example.com/foo/bar
https://example.com/foo
https://example.com?foo=bar
You can publish actions against the apps.facebook.com urls - these will become your canonical object URLs. But the metadata which describes those objects must be present on your server URLs.
When you publish an action against an object with an apps.facebook.com URL, Facebook will make a request to your underlying server URL to read the metadata. But all links that users see will point to a URL with the domain apps.facebook.com.

Related

Facebook opengraph. Meta tags, localhost, custom actions, and testing

This is a series of questions about implementation with the Facebook open graph.
So, I make a query to the api as such: $this->facebook->api('me/namespace:action', 'post', $args );
My first query is where do posts appear? For example if I make a call with the parameters as follows:
$args = array(
//'message' => 'I just posted a pub review at PubJudge.com',
'website'=>'www.pubjudge.com',
'user'=>current_url(),
'link' => 'http://www.pubjudge.com/',
'caption' => 'Independent, social, pub reviews.'
);
The post appears on my timeline under 'Activity'
As far as I understand, if a user explicitly shares an action it will appear on the timeline. Is this correct?
Is "fb:explicitly_shared" a parameter that should be passed in the $args array?
Next comes Facebooks custom meta data. In this case my obect is a user, and I pass their URL through the $args array. Facebook then scrapes this array to get data from the custom meta tags on this link. Is this correct?
Does this url have to be the url from which the action is initiated? Can I not have a page on my website which simply generates custom meta tags based on a $_GET variable - this way I can keep all this complicated Facebook stuff independent of the main site.
Does anyone know why Facebook gets data for open graph actions like this anyway?
Finally because Facebook scrapes data like this I cannot test this functionality on my localhost. (I could do but it'd be very complex) What I have opted for instead is a testing.domain.com address to test my website and this functionality whilst having domain.com as my main live stable site.
I have also created two apps.. my main app, and a testing app because if I use my main app I have to change the site url to testing.domain.com which then breaks my stable site. Is this a suitable approach?
As far as I understand, if a user explicitly shares an action it will
appear on the timeline. Is this correct?
Yes, that's correct. You can find more information at the Facebook docs for explicit sharing. To be noted from the docs, you'll have to mark your action as able to explicitly share on your app dashboard and Facebook will have to approve it.
Is "fb:explicitly_shared" a parameter that should be passed in the
$args array?
Yes.
Next comes Facebooks custom meta data. In this case my obect is a
user, and I pass their URL through the $args array. Facebook then
scrapes this array to get data from the custom meta tags on this link.
Is this correct?
Yes, Facebook scrapes the URL you pass so they can get data from the OG tags at that link.
Does this url have to be the url from which the action is initiated?
Can I not have a page on my website which simply generates custom meta
tags based on a $_GET variable - this way I can keep all this
complicated Facebook stuff independent of the main site.
No, it does not have to be the url from which the action is generated. You can have a separate page on your website, and in fact you can even use javascript to redirect users who land on that page to a more appropriate page.
Does anyone know why Facebook gets data for open graph actions like
this anyway?
That's probably a deeper question than you realize. In short, they are trying to create a semantic web. The long answer would be an essay.
Finally because Facebook scrapes data like this I cannot test this
functionality on my localhost.
You can use reverse proxy which works in most cases (I've seen problems with photos if you are using a port for the reverse proxy). Not very complicated. Something like the following works well:
ssh -nN -f -R externalhost.com:49080:localhost:80 your#credentials.biz
I have also created two apps.. my main app, and a testing app because
if I use my main app I have to change the site url to
testing.domain.com which then breaks my stable site. Is this a
suitable approach?
Yes, that's normal. We typically have a development app (localhost), a staging app (external host for testing), and a production app.

Can an in-app object only be posted through an opengraph action?

I have a page inside a facebook application that is an opengraph object, when I post a custom action on this object to facebook from my app it is posted right, but when I use a facebook social plugin such as like and like that object it is not posted as that object but instead the object of my facebook application is posted on the timeline... so my question here is Can an in-app object only be posted through an opengraph action?
Nope, new OpenGraph object will be created or data will be updated for existing one once Facebook linter crawl your page to get data this will happen in several cases:
OpenGraph action referencing object published
Like button clicked for specific URL
Link to your page shared on Facebook (in direct way or via any dialogs using link, etc).
Your Like button is probably linked not to your real application URL but to URL within Facebook resulting in different Pages parsed by Facebook on Like Button click and OpenGraph action publishing.
I assume that your like button pointing to Application Tab Canvas or Application Page since links to regular application's canvas parsed correctly by Facebook.
Update:
Seems like the issue with OpenGraph tags is related to the fact that your application returning 404 (Not Found status code) for URL you provided and only returns data for HTTP (but not HTTPS) requests. If error code is returned the cached data is preserved and will not be updated until correct status code returned.
Update 2:
As you've provided real URL it's became clear that you get details for your application instead of actual page because of redirect for all unauthorized users, which lead to inability to rich the real OpenGraph data by Facebook linter.
BTW, You should be aware that every OpenGraph object MUST have publicly accessible URL.

Facebook like and share create a fanpage

We are using the facebook like plugin with the share button. The URL points to a resource of our app. For example
http://apps.facebook.com/appname/resources/id
The first time this resource/url is shared or liked, everything works fine. The share for example holds the URL given above.
But if the same resource/url is shared again, an error occurs. Facebook did create a fanpage for that resource like
http://www.facebook.com/pages/appname
So from now on, share/likes refer to that page instead of the resource/url of our app.
The URL we use for the like plugin is correct and always points to the app resource URL. The fbappid in there is correct, too. Furthermore the page of the resource holds open graph meta tags like og:url, also pointing to the correct URL.
The facebook linter/debugger returns URLs to the correct app resource URLs, when checking the liked/shared resource.
Why is a fanpage created instead and the URL exchanged in shares/likes? How to fix it? We want the share to include the URL of the app resource and to increase the like count for that open graph object.
We want the share to include the URL of the app resource and to increase the like count for that open graph object.
If you just want to increase like count fo your OG object, why don’t you link your actual URL, and not a Facebook URL? I mean, your app should be accessible via yourdomain.example.com/something/resources/id, right? So why not like that, since it is the real Open Graph object …?
There is a related facebook bug for this:
http://developers.facebook.com/bugs/240986412684045?browse=search_4fe13eff357e29b43787690
So, apparently there is nothing we could do about it, but wait for facebook to fix it. The alternative would be what CBroe suggested and point to the ressource without using the canvas URL. But this would put the non-canvas URL in the shared message, which is not what we want.

Does an open graph object have to correspond to a user visible page?

I have defined "book" to be an open graph object in my Facebook app. A book is a logical unit, and the user can view a book in a number of different ways in the app. However, there is no single URL in my app which corresponds to any single book.
I thought I would be able to have a URL which spits out open graph meta data to Facebook behind the scenes. For example http://www.example.com/opengrpah/object_book.php?id=3265 would return the title, author, and other info for a book, but not actually be user visible.
However it appears that Facebook uses the object URL for actions involving the object. If I create an action related to the book (e.g. add a book), then if somebody clicks on the link in the ticker they will go to the object_book.php URL, instead of an actual app page. Thus they will see the meta data but nothing useful.
Is this by design? Certainly an object shouldn't have to correspond to a single user-visible page. Can we not have object data drawn from one URL, but have that object displayed to the user within the context of an app?
How about just redirecting from your Open Graph Object URL to the actual app page? Or how about designing your app pages to provide Open Graph metadata?
I think this could be a tricky solution.
In the app I'm working on we had a similar problem because it is an FB Canvas App, so if the og:url for our objects is something like http://apps.facebook.com/our_namespace/?my_first_obj=0 then FB sees the app itself instead of the object loaded in the app. That is where we ultimately want people to land, but we had to provide a direct URL to our app that provided the proper meta tags, much like your situation. I simply put this in the head of those pages:
<script>
try {
if (top.location.href === window.location.href) {
window.location.replace("http://apps.facebook.com/our_namespace/"+window.location.search);
}
} catch(e) {}
</script>
So if somebody is sent directly to that page, they are immediately redirected to our Canvas App, but Facebook's scraper can still get the correct meta data about the object.
I had a similar problem and I ended up with 2 layers for my objects. One is the "master" object, which is actually the object (book in your case, goal in mine).
Then, I have another "user" object, which is actually an association between the master object and a user. This user object has the url like mysite/user/object and it's what I publish to the fb graph with the "add" action.

How can I get a link to a Facebook or Twitter avatar by username?

How can I get a link to a Facebook or Twitter avatar by username?
For Facebook the image is publically availible and can be seen at: http://graph.facebook.com/username/picture
For example, here is mine: http://graph.facebook.com/totten/picture
You will notice that the url above actually gets forwarded to another caching url. Don't save the long url (http://profile.ak.fbcdn.net/....) save the short http://graph.facebook.com/ one. The other, longer url, could change and break.
If you want to display that url in a web page you just need to do the following:
<img src="//graph.facebook.com/totten/picture" />
Which gets you: http://graph.facebook.com/totten/picture
Thats it, no complicated API or authentication is needed.
For twitter you need to use the api: http://apiwiki.twitter.com/w/page/22554755/Twitter-REST-API-Method:-users%C2%A0show
you have to use facebook's graph API to get profile pictures. You'll have to register your app with facebook to get an API key, and then you can access most of the information on a given user's profile.check out their developer page to see some examples
Twitter just changed the way they handle API call. Looks like you'll have to register your app with them as well to get access to the avatars. I haven't used the twitter API since they changed it, so i'm not a sure about what goes on, but check out the docs page to read up on what you'd have to do.
hope this helps!
Some programming paradigms (Razor in ASP.NET or ASP.NET MVC 3, for example) have their own helpers to work with social media. If the paradigm you are programming in does not have helpers, you will have to access the FaceBook and/or Twitter APIs and use them to get the "avatar".
I have not played with Facebook, but the Twitter avatar link is provided on the user's profile, when you get it.
With regards twitter, I was able to get mine by visiting my profile page:
https://twitter.com/<USERNAME>
From there, you locate the <a> tag with the class ProfileAvatar-image and extract the href attribute. I was able to use that link on a separate site to import my avatar from Twitter.
I did all this manually, but it would be relatively easy to set up a script that used the username to request the profile page and isolate that link.