一个确认:尝试通过直接发送对话框 API仅发送消息(在发送大约 60 条消息之后)从 Facebook 服务器端导致错误(错误 500,甚至是空白页面)。
实现这一目标的工作方法是
- 尝试通过直接的Feed Dialog API发送 Feed 消息,
- 测试它是否可能或完成,
- 如果不成功(时间线被用户阻止),则通过发送对话框 API发送正常消息。
在所有情况下,redirect_uri
Dialog URL 都必须有一个参数,该参数必须指向应用程序拥有的 URL。所以app_id
也是强制性的。
这样,您就不会发送太多“正常”消息,因为没有很多人封锁他们的墙,因此您不会被封锁。
这是一个示例 GreaseMonkey/TamperMonkey 代码:
// ==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);
}
}
}