This question already has an answer here:
Facebook ignoring OG image on first share
(1 answer)
Closed 6 years ago.
First of all hi and thanks in advance to anyone who can help with this because I've been going crazy over this for weeks now.
So I've got a website which lists gif taken from my mobile application (which are then stored on AWS and my visitors ( I haven't found a use for me to have users) can share these gifs on facebook using the facebook sdk.
The problem appears when I try sharing an image for the first time
This is what the share dialog shows the first time I click on my sharing button:
http://i.stack.imgur.com/lNVNF.png
and then I close and reclick the same button and now it works:
http://i.stack.imgur.com/YsDUm.png
Now I've been trying to find a way to make this work on the first sharing attempt but to no avail.
I am using meteor in combination with biasport:facebook-sdk and Amazon S3 for the hosting of my files.
Edit here is the code used:
FRONT SIDE
HTML
<div class="facebook share">
<img src="/gallery/fb.png">
</div>
Javascript
Template.*templateName*.events({
'click .facebook': function(e){
e.preventDefault();
e.stopPropagation();
// this is in a modal so I store the data I need
// (events have photos which in turn contain a url to the gif
var url = Session.get('event').photos[Session.get("id")].url;
FB.ui({
method: 'share',
href: url
});
}
SERVER SIDE
JAVASCRIPT
if(Meteor.isClient) {
window.fbAsyncInit = function() {
FB.init({
appId : 'APP_ID',
status : true,
xfbml : true,
version : 'v2.5'
});
};
}
Edit: I found a manual solution using exec future and curl
so first I added a call to a meteor method on the share that updates the facebook crawler
JAVASCRIPT
Template.*templateName*.events({
'click .facebook': function(e){
e.preventDefault();
e.stopPropagation();
// this is in a modal so I store the data I need
// (events have photos which in turn contain a url to the gif
var url = Session.get('event').photos[Session.get("id")].url;
Meteor.call('updateCrawler', url, function(){
FB.ui({
method: 'share',
href: url
});
});
}
Then I defined my meteor method as such
JAVASCRIPT
Meteor.methods({
updateCrawler: function(url){
var future = new Future();
cmd = 'curl -X POST -F "id=' + url + '" -F "scrape=true" -F "access_token={my_access_token}" "https://graph.facebook.com"';
exec(cmd, function(error){
if (error){
console.log(error);
}
future.return();
});
future.wait();
}
});
it's ugly but since I'd have to wait for the crawler to update and it works I'll leave this here for future use for someone maybe
Edit2:
I did not use og tags at all since I was simply sharing a url to aws directly and not a url to my website
I worked around this problem by calling the Facebook API direct from the server to make it scrape the og data by requesting info on the page. First time round it doesn't have the image cached but second time it does so this workaround does the initial call before sharing.
Use an access token for your facebook app and call the below in an ajax call and await the response before opening share dialog. Replace Google address with your own uri encoded address https://graph.facebook.com/v2.5/?id=http%3A%2F%2Fwww.google.co.uk&access_token=xxxxx
EDIT:
As per comments, here is my server side method for calling this which I use when posts etc are inserted to make the initial call and prompt a scrape from fb:
var getTheOGInfo = function (link)
{
if (!link || link.slice(0, 4).toLowerCase() != "http"){
throw new Meteor.Error("og-info-bad-url", "Function requires an unencoded fully qualified url");
return false;
}
var url = "https://graph.facebook.com/v2.5/{{{{id}}}}?access_token={{{{token}}}}&fields=og_object{id,description,title,type,updated_time,url,image},id,share";
var token = Meteor.settings.private.fb.token;
if (!token){
throw new Meteor.Error("og-info-no-token", "Function requires a facebook token in Meteor.settings.private.fb.token");
return false;
}
var link_id = encodeURIComponent(link);
url = url.replace('{{{{token}}}}', token).replace('{{{{id}}}}', link_id);
var result = HTTP.get(url, {timeout:1000});
return result;
}
Or for your purposes you may not want anything that might be blocking so you could change the last two lines to be aynchronous:
var result = HTTP.get(url, {timeout:1000});
return result;
//Replace with non blocking
HTTP.get(url, {timeout:1000}, function(err, result){console.log('something asynchronous', err, result);});
return true;
Related
I'm trying to allow my client's website to share a URL on Facebook that differs from the website's. For example: http://www.example.com has a share link on it for http://www.instagram.com
Whenever I try, I get the following error:
Given URL is not permitted by the Application configuration: One or
more of the given URLs is not permitted by the App's settings. It must
match the Website URL or Canvas URL, or the domain must be a subdomain
of one of the App's domains.
I can't see how I can change my App's settings to allow a different URL to be shared, although I'm guessing it must be possible.
Here's a snippet of my code, to see if that helps:
// Facebook Share
$('#facebook-share').on('click', function(e){
e.preventDefault();
var url = $(this).attr('data-href');
FB.ui({
method: 'share',
href: url
}, function(response){
if (response) {
console.log('Facebook post published.');
} else {
console.log('Facebook post was not published.');
}
});
});
Further research seems to indicate that Facebook Apps can only be used with one URL, no matter what. I changed things to use sharer.php instead:
// Facebook Share
$('.facebook-share').on('click', function(e){
e.preventDefault();
var url = encodeURIComponent($(this).attr('data-href'));
var shareURL = "https://www.facebook.com/sharer/sharer.php?app_id=XXXXXXXX&sdk=joey&u="+url+"%2F&display=popup&ref=plugin&src=share_button";
var width = 655;
var height = 250;
var left = (screen.width/2)-(width/2);
var top = (screen.height/2)-(height/2);
window.open(shareURL, 'facebookShare', 'scrollbars=1,resizable=1,width='+width+',height='+height+',left='+left+',top='+top);
});
Documentation for Parse.FacebookUtils.init() states:
The status flag will be coerced to 'false' because it interferes with Parse Facebook integration. Call FB.getLoginStatus() explicitly if this behavior is required by your application.
Unfortunately, when I try to call FB.getLoginStatus(), I get TypeError: Cannot read property 'getLoginStatus' of undefined. Is there either a callback that I can use to know when FB is loaded, or some other way to check the login status of a user on page load?
It would help to see some code, it sounds like the SDK hasn't loaded when you call getLoginStatus().
Anyway this may help, I took Facebook's basic Login flow and added Parse around it. It checks when the DOM is loaded so you could use some of this logic also.
Simple Facebook Login test with Parse - view source
Hope this helps.
I ended up using promises to resolve FB after it's loaded.
var fbDeferred = $q.defer();
$window.fbAsyncInit = function() {
Parse.FacebookUtils.init({
appId : 'xxxxxx',
xfbml : true,
version : 'v2.2'
});
fbDeferred.resolve(FB);
};
var getFB = function(){
return fbDeferred.promise;
}
var getFBLoginStatus = function(){
return getFB().then(function(FB){
//**FB is now available**
FB.getLoginStatus(function(response) {
if (response.status !== 'connected'){
...
}else{
...
}
});
});
});
Im trying to get all the feed from my facebook page whit the javascript api.
Does anybody have a working example?
I have tryed but I cant get it right, I can get photos from albums, but I cant get the feeds and I dont know what Im doing wrong.
Any input really appreciated. Thanks!
I have this code:
Edit
OK, I have the code inside the init code like below and it doesnt work, it is not executing the code and I get no errors:
<script>
window.fbAsyncInit = function() {
FB.init({
appId : '<%=facebookAppId%>', // App ID
channelUrl : 'www.mypage.se/channel.html', // Channel File
status : true, // check login status
cookie : true, // enable cookies to allow the server to access the session
xfbml : true, // parse XFBML
oauth : true
});
// get the wall - feed
var page_id = '<%=facebookPageId%>';
FB.api('/' + page_id, {fields: 'access_token'}, function(resp2) {
if(resp2.access_token) {
alert(resp2.access_token);
FB.api('/page id/feed?access_token='+resp2.access_token, function(response) {
var ul = document.getElementById('feed');
for (var i=0, l=response.data.length; i<l; i++) {
var
feed = response.data[i],
li = document.createElement('li'),
a = document.createElement('a');
a.innerHTML = feed.message;
a.href = feed.link;
li.appendChild(a);
ul.appendChild(li);
}
});
}
});
};//end window.fbAsyncInit
// Load the SDK Asynchronously
(function(d){
var js, id = 'facebook-jssdk', ref = d.getElementsByTagName('script')[0];
if (d.getElementById(id)) {return;}
js = d.createElement('script'); js.id = id; js.async = true;
js.src = "//connect.facebook.net/en_US/all.js";
ref.parentNode.insertBefore(js, ref);
}(document));
</script>
So why can I have for example:
FB.api('/facebook id', function(response) {
alert('Your name is ' + response.name);
});
inside the init code and not the other code?
I would still need some structure help writing the callbacks out on the page so it looks good as it does on facebook.
I like to write out "message, picture, link, name" and maybe something else?
As I test to get the messages in this example and some of the callback is displayed as "undefined" on the page? Does that mean that the message doesnt have a value when I get it?
If so how can I not write out emty values - undefined ones?
Thanks!
UPDATE:
If I use this code then it reads the feed, but only if Im logged in to Facebook?
Im starting to get confused, since I think that the above code should work:
I first ask for the access token in the first call, and when I get the access token, then using it in the second call, what Im I doing wrong?
FB.api('/my userid or pageid/feed?access_token=the acces token that I get from the Graph API Explorer', {limit:5} , function(response){
if (response && response.data && response.data.length){
alert(response.message);
var ul = document.getElementById('feed');
for (var j=0; j<response.data.length; j++){
var feed = response.data[j],
li = document.createElement('li'),
a = document.createElement('a');
a.innerHTML = feed.message;
a.href = feed.link;
li.appendChild(a);
ul.appendChild(li);
}
}
});
I get a couple of undefined responses, how can I not write them out on the page?
How can I get the above code to work even if the user that visit the webpage is not logged in to facebook?
I make other calls that gets the photos of an album with no problem displaying them on the webpage, I dont understand why this is different?
If I want to set this up for a customer(when its finished) what are the steps I need to take? Getting a bit confused... :-)
I would like to get the message, picture, likes etc with the call
and display it like it is on the feed-wall, any suggestions here?
Ok, finally I got it working :-)
I got the right acces token and now I can display the feeds.
I got the right token here:
https://graph.facebook.com/oauth/access_token?client_id=myapp_id&client_secret=myapp_secret&grant_type=client_credentials
And now I can use the below code both for getting user feeds and page feeds, just changing the page_id!
var page_id = '<%=facebookPageId%>';
var pageaccessToken='xxxxxxxxxxxxxxxxxxxxxxxxxx';
FB.api('/' + page_id + '/feed?access_token='+ pageaccessToken, {limit:5} , function(response){
if (response && response.data && response.data.length){
var ul = document.getElementById('pagefeed');
for (var j=0; j<response.data.length; j++){
var feed = response.data[j],
li = document.createElement('li'),
a = document.createElement('a');
a.innerHTML = feed.message;
a.href = feed.link;
li.appendChild(a);
ul.appendChild(li);
}
}
});
Ok, now it works, but I get the undefined in the response?
What is causing this, is it because it is a empty value that I get in the response?
What can I do so it is not displayed on the page?
I don't understand what it is you're trying to do, I have the feeling though that you took the wrong path..
Let's start with the fact that you don't need any special permission or a page access token to query for the page feed, it's public and so all you need (quoted from the docs) is: "any valid access_token or user access_token".
Which means that if a user authorized your application, you then acquired an access token for him and can get any page feed.
For example try the southpark page feed in the Graph API Explorer.
Another issue is that asking the user for the "manage_pages" permission and then asking the graph api for the access token of your own app would not work. When a user grants your app to manage his pages that's exactly what you get, the permissions to his pages, and so this request for example: /southpark?feilds=access_token won't get you the token since you are not the admin of this page (even if you grant the app with the "manage_pages" permission).
Last thing is the use of window.onload, which in your situation just does not address the problem.
You don't want to execute that code when the window is loaded but when the facebook sdk is loaded and intialized. That's why facebook tells you to use the fbAsyncInit event.
The code you had before the window.onload is the correct form, what exactly do you mean when you say "it didn't work"? Did you get any errors? It did not get executed?
Edit
From what I understand you want to display the content of a facebook Page feed in your website.
As I already told you, all you need in order to get the feed of a page is an active access token ("any valid access_token or user access_token").
If you follow the Authentication doc, the App Login section you'll see that you can issue an access token for your facebook app. With that token you can then get the feed of ANY PAGE you want on the server side.
I have a facebook application. The users are logged in and authorized. I am calling fb.api to post the user's name to my textfile. The alert shows the name. The post doesn't seem to post to my aspx file..
FB.Event.subscribe('edge.remove', function (href, widget) {
alert("outside");
FB.api('/me', function (response) {
alert(response.name);
var paramsObj = { 'name': response.name };
$.post("ajax/delete.aspx", paramsObj);
});
window.location.replace("Default.aspx");
});
I've updated my code to include showing the encapsulating facebook calls to give a broader picture as well as to include #Lix changes [thank you!].
Few things you might want to try :
Define your post parameters object before and only place the objects name in the jQuery $.post method.
Wrap your json keynames with quotes.
var paramsObj = { 'name':response.name};
$.post("ajax/write.aspx", paramsObj );
Use firebug/chrome developers tools to debug the AJAX request and see if any value is being passed and/or use breakpoints in your code to help you understand where the value is missing.
The page was being redirected prior to the api call/ajax post. This is what worked:
FB.Event.subscribe('edge.remove', function (href, widget) {
FB.api('/me', function (response) {
var paramsObj = { 'name': response.name };
$.post("ajax/delete.aspx", paramsObj);
window.location.replace("Default.aspx");
});
});
I'm working in a mini-app, which will have 3 pages, and i want all the interaction to happen inside a profile-tab.So, using javascript, i want to show/hide a few divs, which i'll populate using the FBJS ajax object.
My problem is, i'm not getting the user session in the ajax calls.As documentation is extremely confusing, i've ended up not knowing if this is possible at all.Any ideas?
You can get the user's id if you require login from your ajax request on a profile tab. For instance:
var ajax = new Ajax();
ajax.responseType = Ajax.RAW;
ajax.ondone = function(data) {
console.log('done');
console.log(data);
}
ajax.onerror = function(data) {
console.log('error');
console.log(data);
}
ajax.requireLogin = true;
ajax.post('http://DOMAIN/add_story', {story: story});
The requireLogin = true part will cause an authorization window to popup. If they agree, you can get the user ID in your AJAX handler using the PHP SDK, like:
$facebook->getUser();