2

就像我们在 2010 年制作的视频一样,今年我们再次制作了一个包含我们所有 Facebook 和非 Facebook 朋友姓名的新年快乐视频。

2010 年,我们有一个自定义应用程序,用于在我们每个朋友的墙上发布一条自定义消息,例如“亲爱的 XXX,祝你新年快乐,这个视频你出现在 1 分 24 秒。”

今年我们也想做同样的事情,即发布一条自定义消息,向我们的每个朋友显示特定信息,但我们注意到 Facebook 对在墙上和私人消息上发帖有限制。

http://www.facebook.com/help/326534794098501/

我们可能会使用 GreaseMonkey/Javascript 和 Dialog API 脚本来使用我们的应用程序,但我们仍然害怕收到一些安全警告。

那么这个项目可行吗?我们的朋友喜欢我们每年制作的视频。

4

1 回答 1

1

一个确认:尝试通过直接发送对话框 API仅发送消息(在发送大约 60 条消息之后)从 Facebook 服务器端导致错误(错误 500,甚至是空白页面)。

实现这一目标的工作方法是

  1. 尝试通过直接的Feed Dialog API发送 Feed 消息,
  2. 测试它是否可能或完成,
  3. 如果不成功(时间线被用户阻止),则通过发送对话框 API发送正常消息。

在所有情况下,redirect_uriDialog 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);
        }
    }
}
于 2013-01-09T08:53:20.623 回答