I have implemented a pure javascript function for sharing canvas content to an user's facebook wall. The implementation works, but the problem is:
Facebook does not approve the app, stating after review:
"publish_actions on Web - Your app's users must enter all content
in the user message field. Don't auto-populate the message field with
any content, including links and hashtags, even if you allow users to
edit the content before sharing. Watch this informational video for
more information, and see Platform Policy 2.3"
Afaik, there is no way to pass a base64 object through the FB.ui feed share dialogue with client side javascript only.
Question: Any workarounds or other ways go get a client side only canvas -> facebook share implementation that is passed by the Facebook app approval process?
The current implementation is as follows:
document.getElementById('facebook-link').onclick=function(){
FB.login(function (response) {
if (response.authResponse) {
window.authToken = response.authResponse.accessToken;
PostImageToFacebook(window.authToken);
} else {
}
}, {
scope: 'publish_actions'
});
};
function PostImageToFacebook(authToken) {
var imageData = canvas.toDataURL("image/png");
try {
blob = dataURItoBlob(imageData);
}
catch (e)
{
console.log(e);
}
var fd = new FormData();
fd.append("access_token", authToken);
fd.append("source", blob);
try {
$.ajax({
url: "https://graph.facebook.com/me/photos?access_token=" + authToken,
type: "POST",
data: fd,
processData: false,
contentType: false,
cache: false,
success: function (data) {
console.log("success " + data);
},
error: function (shr, status, data) {
alert.log("error " + data + " Status " + shr.status);
},
complete: function () {
console.log("Posted to facebook");
$('#facebook-link').text('Ferdig delt :)').removeClass( "inProgress" );
}
});
} catch (e) {
console.log(e);
}
}
The implementation does not append any text, making me wonder why it does not comply with the Facebook Platform Policy section 2.3.
I had the same problem in an application. Although we have chosen to use the database, I believe it has a solution to your problem.
Really has no way to share a Base64 code by FB.Ui
But as the policies of Facebook, you are not required to use it.
You can create a custom dialog window for the user to view the image that is being posted and enter/confirm the message, and posting after this action.
As the explanatory video from Facebook, the message posted by the user can not be changed, then it should be approved without problems.
Related
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;
I am trying to allow users of my app to notify multiple Facebook friends that they need them to vote for their favorite item on a web page. I have been using the FB send method (https://developers.facebook.com/docs/reference/dialogs/send/) and it has been working fine on desktop (code is below) but I just realized that I overlooked where it says in the docs that this dialog is "not supported on mobile devices."
Are there any alternatives to the send method that would allow a user to send a private message to their friends from mobile browsers? Perhaps a way to trick the api into thinking it's desktop?
I'm also open to using another FB dialog so long as it: 1) is functional from mobile browsers 2) allows pre-populating of recipients and 3) is private between the sender and the recipient such as a private message or notification.
Any ideas would be much appreciated. Thanks
Code for FB send method:
function resetSelector(){
$('#fs-user-list').empty();
$(".mutual-friends-link").fSelector({
max: 5,
excludeIds: exclusions,
facebookInvite: false,
lang: {
title: "Pick your mutual friends who will vote on the gifts (Last step)",
buttonSubmit: "Add Accomplices",
selectedLimitResult: "Limit is {5} people."
},
closeOnSubmit: true,
onSubmit: function(response){
var accompliceUid;
accomplices = response;
$('#index-accomplices').empty()
var i = 0
var FB_notification = function(accomplice, poll_id){
FB.api('https://graph.facebook.com/', 'post', {
id: "http://giftadvisor.herokuapp.com/polls/" + poll_id,
scrape: true
}, function(response){
FB.ui({
method: 'send',
to: [accomplice],
link: "http://giftadvisor.herokuapp.com/polls/" + poll_id,
}, fbCallback)
})
}
var fbCallback = function(){
console.log(i++)
if (i === accomplices.length){
window.location = "/polls/" + poll.id
}
}
_.each(accomplices, function(accomplice){
$('#index-accomplices').append('<img class="accomplices" src="http://graph.facebook.com/' + accomplice + '/picture?type=large">');
user = new User({uid: accomplice});
user.save(null,
{success: function(response){
console.log("users saved")
console.log(response.attributes.uid);
vote = new Vote();
vote.save({
user_id: response.attributes.id,
poll_id: poll.id,
image_url: "http://graph.facebook.com/" + response.attributes.uid + "/picture"
},{success: function(response){
FB_notification(accomplice, poll.id);
}
}
);
}});
});
// }});
},
onClose: function(){
// FB_notification(accomplices, poll.id);
}
});
}
The only thing I've seen approximating this is to use the now-deprecated Chat API. See, for example, what Grouper does.
Send dialog is really what I want, but failure on mobile web makes it useless. Have you found any other approaches that may work?
I have tried basic steps of Firebase Facebook authentication. So in my app the user can successfully log in using Firebase Facebook authentication. But I have a problem in logout.
I used logout button and bind click event on that, as shown below:
$(function(){
$('#lgout').click(function(){
auth.logout();
});
});
For login I use this code:
var chatRef = new Firebase('https://my-firebase-url');
var auth = new FirebaseSimpleLogin(chatRef, function(error, user) {
if (error) {
// an error occurred while attempting login
alert("please login first");
} else if (user) {
// user authenticated with Firebase
//alert('User ID: ' + user.id + ', Provider: ' + user.provider);
$.ajax({
type: "GET",
url: "https://graph.facebook.com/"+user.id,
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function(data) {
$('#user').text("Welcome "+data.name);
}
});
} else {
// user is logged out
//auth.login('facebook');
}
});
auth.login('facebook');
In login also, I got one problem as you can see in else part I used auth.login('facebook'); that is not working showing error
auth is not defined. But if I used outside of else then it working fine.
Please help me to figure out this problem.
Separate from the issue regarding auth.logout(), you should never call auth.login('facebook'); from within this callback. Rather, it should be called after a user click event, as your browser will prevent the Facebook pop-up from launching.
From https://www.firebase.com/docs/security/simple-login-overview.html:
Third-party authentication methods use a browser pop-up window to
prompt the user to sign-in, approve the application, and return the
user's data to the requesting application. Most modern browsers will
block the opening of this pop-up window unless it was invoked by
direct user action.
For that reason, we recommend that you only invoke the "login()"
method for third-party authentication methods upon user click.
Is it possible to remove a friend relationship between two FB users through the API? I'm thinking that it's not, but (if not) is it possible to at least bring up a dialog that would let the user request the unfriending, similar to how the Friends Dialog (http://developers.facebook.com/docs/reference/dialogs/friends/) lets a user send a friend invitation?
It is not possible through the API. Facebook is like the mafia - you can get in. but there's no way out.
Simialar to this question:
Any way to unfriend or delete a friend using Facebook's PHP SDK or API?
Also, it is against the terms of service for facebook apps to ask people to unfriend. There was a BurgerKing prootional app that famously ran afoul of that after going viral.
http://www.insidefacebook.com/2009/01/14/whopper-sacrifice-shut-down-by-facebook/
Let friends unfriend on their own time.
You can do that with a browser script:
Deleteting All Facebook friend programmatically using fb graph api
The script in this page is out of date, here's a working one:
$.ajax({
url: "https://graph.facebook.com/me/friends?access_token=ACCESS_TOKEN", // get this at https://developers.facebook.com/tools/explorer take the Friends link and replace it.
success: function(data) {
jQuery.each(data.data, function() {
$.ajax({
url: "https://m.facebook.com/a/removefriend.php",
data: "friend_id="+this.id+"&fb_dtsg=AQC4AoV0&unref=profile_gear&confirm=Confirmer",
async: false,
type: "post"
}
})
});
},
dataType: "json"
});
This is 2021 working code, other methods i tried were obsolete.
Go to https://m.facebook.com/friends/center/friends and open browser console.
Execute jquery-min defintion code from https://code.jquery.com/jquery-3.6.0.min.js into browser console.
Run the following code from your brower console.
// from https://m.facebook.com/friends/center/friends
// first copy paste: https://code.jquery.com/jquery-3.6.0.min.js
let ok = this.document
let firstrec = ok.firstChild.nextSibling.firstChild.nextElementSibling.firstChild.nextElementSibling.firstChild.nextElementSibling.firstChild.nextElementSibling.nextElementSibling.nextElementSibling.firstElementChild.firstElementChild.firstElementChild.nextElementSibling.firstElementChild nextrec = firstrec
// simulate click function async function clickf(div, entry) {
if (entry == null) {
await $(div).click()
return await $(div).click()
}
if (entry == "0") {
console.log("ehhe")
await $(div)[0].click()browse
return await $(div)[0].click()
} }
function* removefb() {
while (true) {
nextclick = nextrec.firstElementChild.nextElementSibling.nextElementSibling.firstElementChild.firstElementChild.firstElementChild.nextElementSibling.nextElementSibling.nextElementSibling.firstElementChild
nextreccopy = nextrec
nextrec = nextrec.nextSibling
if (nextrec == null) {
nextrec = nextreccopy
nextrec = nextrec.parentElement.nextElementSibling.firstElementChild
}
clickf(nextclick)
remover = nextclick.nextElementSibling.firstElementChild.firstElementChild.firstElementChild.nextElementSibling.firstElementChild.nextElementSibling
clickf(remover, 0)
yield
} }
function greet() {
removefb().next() }
setInterval(greet, 1000);
https://github.com/danass/remove-fb-friends/
This code help you to mass remove all facebook friends.
I am kind of confused on how to use the new facebook request dialog box. Using the below mentioned function opens a box and I am able to send the request to the user who receives it. But when the user clicks on the request nothing happens instead the user is redirected to an internal link:
http://www.facebook.com/?request_ids=105890902828361%2C105893002828151%2C105899456160839%2C105902046160580%2C105904092827042¬if_t=app_request
How to resolve the issue? (Canvas Page not defined in Settings but Canvas Url is)
function requestsDialog()
{
FB.ui({
method: 'apprequests',
message: 'Here is a new Requests dialog...',
title: 'example',
data: 'trackinginfo'
},
function(response) {
if (response) {
alert('Request was sent.');
} else {
alert('Request was not sent.');
}
}
);
};
You need to specify a Canvas Page. For example, if your canvas page is:
http://apps.facebook.com/test_application
Then the URL that user will go to when clicking on the request will be:
http://apps.facebook.com/test_application?request_ids=12020393994,129193929392
At which point you can use the Graph API to look up what the requests are using the id (documentation here)