Question

Like the video we made in 2010, we are again doing this year a Happy New Year video that contains the name of all our Facebook and non-Facebook friends.

In 2010 we had a custom application that used to post on the wall of each of our friends a customized message like "Dear XXX, I wish you a happy new year with this video where you appear at 1 minute ans 24 seconds."

We would like to do the same this year, that is, to post a customized message to display specific informations to each of our friend, but we noticed that Facebook has a limit for posting on walls and on private messages.

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

We might use a GreaseMonkey/Javascript and Dialog API script to use our application, but we still fear to receive some security warning.

So is this project feasible ? Our friends love our videos we are doing every year.

Was it helpful?

Solution

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

  1. try to send Feed messages through the direct Feed Dialog API,
  2. test if it's possible or done,
  3. 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);
        }
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top