Get Facebook 'share/post' event for share dialog - javascript

My site allows each user to share a link, say http://www.my-site.com, on facebook.
I'd like to count the number of times each user shared my url, as well as the date of the last share. This would have been pretty easy given one would have used the FB SDK (excuse the coffeescript):
link = "my-site.com"
FB.ui
method: "feed"
link: link
from: from
, (response) ->
unless response is null or response is undefined
$.ajax
dataType: "json"
data: response
url: some-url
success: (data, textStatus, jqXHR) ->
// Do stuff
I could have even let myself get more create and use one of facebook's event subscriptions, such as:
FB.Event.subscribe "message.send", message_send_callback
However, as far as I know, none of the dialogs offered by FB.ui() allows the user to choose which group/wall/friend he would like to post to, which is mandatory as far as I'm concerned. Fortunately, the non-SDK share dialog DOES allow for exactly that, but presents a bigger challenge when it comes to getting the post event and the response, as it forces me to add an onload event listener to the popup window (var popup = window.open(...); popup.addEventListener...), and then add another event listener to the post event, which is of course challenging because the popup opens another domain, facebook's, which I have no control over.
Is there a way to do what I'm trying to accomplish? Am I missing a FB.ui() dialog that enables the user to choose where to post? If not - is there a way to get the event and response for the share dialog?

No, I think there is no way as of now to use the Share dialog with FB.ui, or get it to give any feedback.
What you could try is using the feed dialog with the to parameter – if you are willing to put a dialog of your own in front of it that lets the user chose a post target.
Although that will limit you to their friends and pages you might be able to suggest – if the latter should be user specific, you will have to ask for permission to read their likes etc.

Related

Is there a better way to update user view instead of refreshing?

In the database I have something like Line, Word and Character. That is, a Word must belong to a specific Line, the same goes for Character (or you can think of a multi-level menu, each menu item can be another menu). I'm writing a management page to interact with the database. Each time the user insert/delete a record, the page must be refreshed to show the changes. However, this approach is too annoying for my users (although the refresh is automatic). Is it possible to show the changes without refreshing the whole page? If it is, how? Thank you.
UPDATE: The data is shown as multi-level list (the picture below is an example) and can be collapsed/expanded. When I refresh the page, they are all collapsed (which annoys my users).
You can do it using AJAX(Asynchronous JavaScript And XML). You can update a web page without reloading it using ajax. You can use jQuery ajax() which is so simple to integrate. http://api.jquery.com/jquery.ajax/
Here is an example-
$.ajax({
method: "get",
url: "/action.php",
data: {item_id: item_id, vote: vote},
dataType: "html"
})
.done(function(msg){
// Update view of the web page, it could be deleting or updating a div
})
.fail(function(msg){
alert(msg);
});
/*
method - get/post
url - which will handle your request
data - data you want to send to server
dataType - response type, html/json/text etc
*/
If it works without any problem then the done method will trigger otherwise fail method will trigger.
If you are saying something like a live suggestions display while you type on the search bar. The ajax. If you just want to show the newly updated record on the be view page, a redirect would do

Detect FB share dialog is ready

We need to display FB share dialog. It can be done with either FB.ui as:
FB.ui({
method: 'share',
display: 'iframe',
href: '{{postUrl}}'
});
or even using a link/REST.
I can add a second argument to FB.ui() as function(result){...}, and FB JavaScript SDK will invoke that as a callback after the dialog is closed [either with a share taking place, or without].
How could I detect that the dialog is displayed, not dismissed?
Thank you
You can only be sure if someone shared something if you authorize the user with the publish_actions permission. In that case, you will get the Post ID in the callback, as you can read in the docs: https://developers.facebook.com/docs/sharing/reference/share-dialog#response
Keep in mind that you are not allowed to reward users in any way for sharing, or incentivize sharing. You will not get publish_actions approved by Facebook just for checking if the user shared something.
Edit 1: If you just want to know if the dialog is visible...well, it is visible when you call FB.ui, and it is not visible anymore then the callback gets called.
Edit 2: I don´t see any use case for it (please do tell), but if you want to know if the dialog showed up (and did not get blocked by a popup blocker, for example), then i would say it is impossible to detect.

Correct way to use onbeforeunload?

I am trying to post data when user arrives my page. This works in chrome and explorer, and also firefox, but however, on firefox, it strangely only works if user closes the page. If they go back, or goes another site (by typing to address bar or whaever) it doesnt post the data. My question is, what is the correct way to use onbeforeunload to post data ?
$(window).bind('beforeunload', function () {
$.post("track.php", {
async: false,
ip: ip,
referer: referer,
clicks: kactane2,
scrolls: kactane,
time: time,
refid: refid,
country: country,
});
});
There isn't a good way because that is not how onbeforeunload was meant to be used.
The correct way to use onbeforeunload is to listen for this event and then unload any data or resources you might be using because the user is leaving the page. You should not use it to try to start new things. According to the HTML5 specification showModalDialog(), alert(), confirm() and prompt() are explicitly not allowed and the idea is to give you a moment to clean up any event handlers, web workers and other stuff cleanly.
If an event handler is defined then the user may be presented with a page that says "Are you sure you want to leave?" but for security reasons the form is generally not able to be customized, but it depends on the browser.
You will probably be better off setting the data in a cookie or something that can be done quickly and that is only occurring in the browser, then just look for that data on the next page load.

Capture details of Facebook message in application database

In my Facebook application I am displaying a message window using FB.ui { method: 'send' ...}. I would like to capture the list of recipients (stored in the 'recipitents []' hidden form field) as well as the message text in my application database.
Is there a way to do that?
Here's what I have come up with so far:
Dynamically set the onclick attribute in the DOM element (which corresponds to the Send button. So far I have been able to do that using the browser development tools (e.g. F12 in IE9) but not in code; it could be tricky since the dialog doesn't exist at load time). Unfortunately I haven't been able to define a Javascript function that was in the right scope (I thought there was only a global scope) for the onclick callback to find it.
Construct the Facebook Send dialog from more elementary building block (e.g., friend picker, send method invocation) so I 'own' the click event.
Clone the FB.ui() code and modify it to include additional parameters when calling the redirect url.
Require the user to include me in the To list (really only last resort), or default the 'to' field to the application's user id.
Finally, I expect to be able to call my web service from Javascript to record the message details in my application database.
I'm pretty sure this is not available via the API by design. The Send button operates in an iframe so browser security will prevent you from accessing its internal state via Javascript.
Some other methods (such as using FB.ui dialogs to post to the user's wall) provide a post ID in the callback and you can check this in the Graph API, but the Send button doesn't return anything like this.
For the Send button you can subscribe to the message.send event in the Javascript SDK and receive a callback with the URL which was sent, but not who it was sent to. ( https://developers.facebook.com/docs/reference/javascript/FB.Event.subscribe/ - the event itself isn't currently listed there, but does exist)
I can't think of why you'd want to do this type of tracking, it seems like a use-case with very few policy compliant applications.

JavaScript/jQuery: How to make sure cross-domain click tracking event succeeds before the user leaves the page?

I'm implementing click tracking from various pages in our corporate intranet in order to add some sorely needed crowd-sourced popular link features ("most popular links in your department in the last 24 hours", etc.)
I'm using jQuery's .live() to bind to the mousedown event for all link elements on the page, filter the event, and then fire off a pseudo-ajax request with various data to a back-end server before returning true so that the link action fires:
$("#contentarea a").live("mousedown", function(ev) {
//
// detect event, find closest link, process it here
//
$.ajax({
url: 'my-url',
cache: false,
dataType: 'jsonp',
jsonp: 'cb',
data: myDataString,
success: function() {
// silence is golden -- server does send success JSONP but
// regardless of success or failure, we allow the user to continue
}
});
return true; // allow event to continue, user leaves the page.
}
As you can probably guess from the above, I have several constraints:
The back-end tracking server is on a different sub-domain from the calling page. I can't get round this. That's why I am using JSONP (and GET) as opposed to proper AJAX with POST. I can't implement an AJAX proxy as the web servers do not have outbound network access for scripts.
This is probably not relevant, but in the interest of full disclosure, the content and script is inside a "main content" iframe (and this is not going to change. I will likely eventually move the event listener to the parent frame to monitor it's links and all child content, but step 1 is getting it to work properly in the simplified case of "1 child window"). Parent and child are same domain.
The back-end is IIS/ASP (again, a constraint -- don't ask!), so I can't immediately fork the back-end process or otherwise terminate the response but keep processing like I could on a better platform
Despite all this, for the most part, the system works -- I click links on the page, and they appear in the database pretty seamlessly.
However it isn't reliable -- for a large number of links, particularly off-site links that have their target set to "_top", they don't appear. If the link is opened in a new tab or window, it registers OK.
I have ruled out script errors -- it seems that either:
(a) the request is never making it to the back-end in time; or
(b) the request is making it, but ASP is detecting that the client is disconnecting shortly afterwards, and as it is a GET request, is not processing it.
I suspect (b), since latency to the server is very fast and many links register OK. If I put in an alert pop-up after the event fires, or set the return value to false, the click is registered OK.
Any advice on how I can solve this (in the context that I cannot change my constraints)? I can't make the GET request synchronous as it is not true AJAX.
Q: Would it work better if I was making a POST request to ASP? If (b) is the culprit would it behave differently for POST vs GET? If so, I could use a hidden iframe/form to POST the data. however, I suspect this would be slower and more clunky, and might still not make it in time. I wouldn't be able to listen to see if the request completes because it is cross-domain.
Q: Can I just add a delay to the script after the GET request is fired off? How do I do this in a single-threaded way? I need to return true from my function, to ensure the default event eventually fires, so I can't use setTimeout(). Would a tight loop waiting for 'success' to fire and set some variable work? I'm worried that this would freeze up things too much and the response would be slowed down. I assume the jQuery delay() plugin is just a loop too?
Or is something else I haven't thought of likely to be the culprit?
I don't need bullet-proof reliability. If all links are equally catchable 95% of the time it is fine. However right now, some links are catchable 100% of the time, while others are uncatchable -- which isn't going to cut it for what I want to achieve.
Thanks in advance.
I would try a different approach. You can bind to a different event like:
$(window).unload(function(event) {
// tracking code here
});
I would try to return false from the link event handler, remember the URL and navigate away only when JSONP request succeeds. Hopefully it shouldn't add too much latency. Considering you are on the inranet, it might be OK.
Solved!
The short answer is: there is no reliable way to do this cross-domain with a GET request. I tried all sorts, including storing the event and trying to replay the event later, and all manner of hacks to try to get that to work.
I then tried tight loops, and they weren't reliable either.
Finally, I just gave in and used a dynamically created form that POSTed the results, with the target set to a hidden iFrame.
That works reliably -- it seems the browser pauses to finish its POST request before moving on, and ASP honours the POST. Turns out it's not 'clunky' at all. Sure, due to the browser security model I can't see the result... but it doesn't matter in this case.
I am now kicking myself that I didn't try that option first.

Categories