One confirmation: trying to send only messages through the direct Send Dialog API leads (after around 60 messages sent) to errors (error 500, or even blank page) from the Facebook server's side.
The working way to acheive this is to
- try to send Feed messages through the direct Feed Dialog API,
- test if it's possible or done,
- if it doesn't succeed (Timeline is blocked by user), send an normal message through the Send Dialog API.
In all cases, there must be a redirect_uri
argument to the Dialog URL, which must point to an URL owned by the application. So app_id
is mandatory too.
This way, you do not send too much "normal" messages as not a lot of people block their wall, and thus your are not blocked.
Here is a sample GreaseMonkey/TamperMonkey code:
// ==UserScript==
// @name NameOfYourScript
// @namespace NamespaceOfYourScript
// @version VersionOfYourScript
// @description enter something useful
// @match https://*/*
// @copyright 2012+, You
// @require https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js
// @grant GM_getValue
// @grant GM_setValue
// @grant GM_openInTab
// ==/UserScript==
var baseapppage = "<URL of a page owned by your application>";
var baseapppagehost = "apps.facebook.com"; var baseapppagepath = "<path to your app>";
//Call baseapppage+"?startfbscript=0" to launch the script
//0 is the index at which you want to start
var appid = "<APP ID of the application>";
var titleofvideo ="<title of video>";
var facebook_ids = [
//put the list of the people to contact here
{"id":"<facebook id of one person>","":"<other arguments for the message>"},
//...
];
var video_url = "<URL of the video to share>";
var message = "<Template of the message to share, with <placeholders> for the person objects>"+
"\n\nLink of video:"+
"\n"+video_url+
"";
//"feed" or "send" (note that "send" only will block you...)
var default_mode = "feed";
//if you lower this, it will be quicker, but may lead to an error
var temporisation = 5*1000;
//updating placeholders in message
function updatemessage(o) {
var str = message;
for (var p in o) {
str = str.replace(new RegExp("<"+p+">","ig"),o[p])
}
return str;
}
var automatic = true;
//http://stackoverflow.com/questions/2090551/parse-query-string-in-javascript
function getQueryVariable(variable) {
var query = document.location.search.substring(1);
var vars = query.split('&');
for (var i = 0; i < vars.length; i++) {
var pair = vars[i].split('=');
if (decodeURIComponent(pair[0]) == variable) {
return decodeURIComponent(pair[1]);
}
}
console.log('Query variable %s not found', variable);
}
//creating URLs
function createURL(baseurl,data) {
var datastr = "";
for (var k in data) {
if (datastr.length) datastr += "&";
datastr += encodeURIComponent(k)+"="+ encodeURIComponent(data[k]);
}
var separator = baseurl.lastIndexOf("?") >= 0 ? "&" : "?";
return baseurl + separator + datastr;
}
//arguments for feed page
var feed_arguments = {
"app_id":appid,
"name":titleofvideo,
"link":video_url,
"redirect_uri":createURL(baseapppage,{"currentfbscript":"1"}),
//"":"", //caption, description...
};
//arguments for send page
var send_arguments = {
"app_id":appid,
"name":titleofvideo,
"link":video_url,
"redirect_uri":createURL(baseapppage,{"currentfbscript":"1"}),
//"":"",
};
//function to open direct dialog API, in mode "feed" or "send", directed to some facebook id
function relocateto(mode, to) {
var arguments = mode == "feed" ? feed_arguments : send_arguments;
var baseurl = mode == "feed" ? "https://www.facebook.com/dialog/feed" : "https://www.facebook.com/dialog/send";
arguments['to'] = to;
var new_url = createURL(baseurl,arguments);
if (parseInt(""+GM_getValue("indice",-1)) % 20 == 0) {
//note : fake reload in other tab because of Chrome memory "leak".
//Close finished tags to keep memory low.
console.log("run 'fake reload'...");
function fake_reload() {
console.log("...now");
GM_openInTab(new_url, {active: false, insert: true});
// close the current window some ms later to allow the insert magic to detect this' tab position
//note that it unfortunately doesn't work
window.setTimeout(window.close, 1);
}
window.setTimeout(fake_reload, 3000);
} else {
document.location = new_url;
}
}
//wall post page
if (document.location.host == "www.facebook.com" && document.location.pathname == "/dialog/feed") {
GM_setValue("mode","feed");
var indice = parseInt(""+GM_getValue("indice",-1));
if (indice < 0 || indice >= facebook_ids.length) return;
if (jQuery("input[name=publish]").length) {
var mes = updatemessage(facebook_ids[indice]);
setTimeout(function() {
jQuery("textarea#feedform_user_message").html(mes).val(mes);
if (automatic) jQuery("input[name=publish]").click();
},temporisation);
} else {
//impossible to send wall message -> send dialog
relocateto("send", getQueryVariable("to"));
}
}
//send post page
if (document.location.host == "www.facebook.com" && document.location.pathname == "/dialog/send") {
GM_setValue("mode","send");
var indice = parseInt(""+GM_getValue("indice",-1));
if (indice < 0 || indice >= facebook_ids.length) return;
if (jQuery("input[name=publish]").length) {
var mes = updatemessage(facebook_ids[indice]);
setTimeout(function() {
jQuery("textarea#feedform_user_message").html(mes).val(mes);
if (automatic) jQuery("input[name=publish]").click();
},temporisation);
} else {
//impossible to send normal message -> dialogue
alert("Impossible to send message... index="+indice+" for "+getQueryVariable("to")+"-"+facebook_ids[indice].id);
}
}
//start or end page
if (document.location.host == baseapppagehost && document.location.pathname == baseapppagepath) {
if (getQueryVariable("startfbscript")) {
GM_setValue("mode",default_mode);
var i = getQueryVariable("startfbscript")
GM_setValue("indice",i)
relocateto(default_mode, facebook_ids[i].id);
} else if (getQueryVariable("currentfbscript") && GM_getValue("mode","feed") == "feed" && document.location.search.indexOf("post_id") < 0) {
//it didn't work -> sending normal message
relocateto("send", GM_getValue("lastname",facebook_ids[0].id));
} else if (getQueryVariable("currentfbscript") && (
(GM_getValue("mode","feed") == "feed" && getQueryVariable("post_id"))
|| (GM_getValue("mode","feed") == "send" && getQueryVariable("success")))) {
//it worked -> next name !
var indice = parseInt(""+GM_getValue("indice",0));
indice++;
GM_setValue("indice",indice)
if (indice >= facebook_ids.length) {
jQuery("#pagelet_iframe_canvas_content").html("<br/><br/>Finished!");
return;
} else {
console.log("Next id to send to: "+facebook_ids[indice].id);
jQuery("#pagelet_iframe_canvas_content").html("<br><br/> Running script : "
+ indice +"/"+facebook_ids.length
+"<br> Next : "
+facebook_ids[indice].id);
}
var nextname = facebook_ids[indice].id;
//next post
setTimeout (function (){
relocateto(default_mode, nextname);
}, temporisation);
} else {
//why are we here if the script is running ? Problem with facebook...
if (parseInt(""+GM_getValue("indice",0)) < facebook_ids.length) {
alert("Impossible to post message. Current index = "+GM_getValue("indice",0)+" for "+facebook_ids[parseInt(""+GM_getValue("indice",0))].id);
}
}
}