If a user clicks 'Accept' on a request, they will see an iframe with my site in it.
The facebook url (that has the iframe), looks something like this:
https://apps.facebook.com/[request_id]/?fb_source=notification&request_ids=[request_ids]&ref=notif&app_request_type=user_to_user¬if_t=app_request
How can i get the 'request_id' from the iframe url??
Is there a method/API for that in the JS library?
If you are using php
you can retrieve request_id by $_GET['request_id'] or $_REQUEST['request_id']
if you are using javascript
This is just one implementation of getting requests parameters in javascript, there are better implementations as well, i stated an example.
var Request = {
parameter: function(name) {
return this.parameters()[name];
},
parameters: function() {
var result = {};
var url = window.location.href;
var parameters = url.slice(url.indexOf('?') + 1).split('&');
for(var i = 0; i < parameters.length; i++) {
var parameter = parameters[i].split('=');
result[parameter[0]] = parameter[1];
}
return result;
}
}
var request_id = parameters['request_id'];
Get url from iframe
document.getElementById("iframe_id").contentWindow.location.href
Hope this is what you require
Related
In our Android project (download manager) we need to show built-in web browser so we able to catch downloads there with the all data (headers, cookies, post data) so we can handle them properly.
Unfortunately, WebView control we use does not provide any way to access POST data of the requests it makes.
So we use a hacky way to get this data. We inject this javascript code in the each html code the browser loads:
<script language="JavaScript">
HTMLFormElement.prototype._submit = HTMLFormElement.prototype.submit;
HTMLFormElement.prototype.submit = formSubmitMonitor;
window.addEventListener('submit', function(e) {
formSubmitMonitor(e);
}, true);
function formSubmitMonitor(e) {
var frm = e ? e.target : this;
formSubmitMonitor_onsubmit(frm);
frm._submit();
}
function formSubmitMonitor_onsubmit(f) {
var data = "";
for (i = 0; i < f.elements.length; i++) {
var name = f.elements[i].name;
var value = f.elements[i].value;
//var type = f.elements[i].type;
if (name)
{
if (data !== "")
data += '&';
data += encodeURIComponent(name) + '=' + encodeURIComponent(value);
}
}
postDataMonitor.onBeforeSendPostData(
f.attributes['method'] === undefined ? null : f.attributes['method'].nodeValue,
new URL(f.action, document.baseURI).href,
data,
f.attributes['enctype'] === undefined ? null : f.attributes['enctype'].nodeValue);
}
XMLHttpRequest.prototype.origOpen = XMLHttpRequest.prototype.open;
XMLHttpRequest.prototype.open = function(method, url, async, user, password) {
// these will be the key to retrieve the payload
this.recordedMethod = method;
this.recordedUrl = url;
this.origOpen(method, url, async, user, password);
};
XMLHttpRequest.prototype.origSend = XMLHttpRequest.prototype.send;
XMLHttpRequest.prototype.send = function(body) {
if (body)
{
postDataMonitor.onBeforeSendPostData(
this.recordedMethod,
this.recordedUrl,
body,
null);
}
this.origSend(body);
};
const origFetch = window.fetch;
window.fetch = function()
{
postDataMonitor.onBeforeSendPostData(
"POST",
"test",
"TEST",
null);
return origFetch.apply(this, arguments);
}
</script>
Generally, it works fine.
But in Google Mail web interface, it's not working for some unknown reason. E.g. when the user enters his login name and presses Next. I thought it's using Fetch API, so I've added interception for it too. But this did not help. Please note, that we do not need to intercept the user credentials, but we need to be able to intercept all, or nothing. Unfortunately, this is the way the whole system works there...
Addition #1.
I've found another way: don't override shouldInterceptRequest, but override onPageStarted instead and call evaluateJavascript there. That way it works even on Google Mail web site! But why the first method is not working then? We break HTML code somehow?
For SEO purposes I wanted to copy this blog post design this website
the specific part I want to copy is the div with id="enter-posts" which has the title, the author, date, labels of the post
I tried to put tags like:
<div class='author-profile' itemprop='author' itemscope='itemscope' itemtype='http://schema.org/Person'>
<meta expr:content='data:post.authorProfileUrl' itemprop='url'/>
<b:if cond='data:post.authorPhoto.url'><a expr:href='data:post.authorProfileUrl' itemprop='url'>
<div class='auhtor-image'><img expr:src='data:post.authorPhoto.url' itemprop='image'/></div></a></b:if>
<div><span class='author-about'>About </span><a class='g-profile' expr:href='data:post.authorProfileUrl' rel='author' title='author profile'><span itemprop='name'><data:post.author/></span></a></div><p class='description' itemprop='description'><data:post.authorAboutMe/></p></div>
for author and so on for the other elements I want to add but the problem is:
Nothing is displayed, BUT when I put these tags inside the post body before the title or at the end of the post they appear normally. what should I do?
Though this is an old post, may I post some clarification for those looking for an answer. Fact is, there is no data:post.authorPhoto.url provided by blogger.
Most template writers take the data from /feeds/posts/default and parse the JSON and update the HTML after page load. Then they obfuscate the js code, making new comers think it was all fetched from blogger. Along with that fetch, who knows what else was fetched.
For example, for the above blog, you can fetch the JSON from http://www.th3professional.com/feeds/posts/default?alt=json-in-script
My implementation
Image is fetched directly from the feed
Author description is fetched from 'Introduction' part of user profile. Since that's CORS, I'm using a CORS proxy (https://github.com/Rob--W/cors-anywhere/) for that purpose.
-
var HttpClient = function() {
this.get = function(aUrl, aCallback) {
var anHttpRequest = new XMLHttpRequest();
anHttpRequest.onreadystatechange = function() {
if (anHttpRequest.readyState == 4 && anHttpRequest.status == 200)
aCallback(anHttpRequest.responseText);
}
anHttpRequest.open("GET", "https://cors-anywhere.herokuapp.com/"+aUrl, true);
anHttpRequest.send(null);
}
}
$(document).ready(function($){
// This is one way to get post id, other ways are possible too
var post_id = $("div[itemprop='articleBody']").attr('id');
post_id = post_id.match(/.*post-body-(\d+).*/);
post_id = ((post_id!==null && post_id.length>0) ? post_id[1] : null);
if(post_id!==null) {
$.ajax({
url: "/feeds/posts/default/"+post_id+"?alt=json-in-script",
type: 'get',
dataType: "jsonp",
success: function(data) {
var image = ((data.entry.author[0]["gd$image"].src!==null) ? data.entry.author[0]["gd$image"].src : false);
if(image!=false) { //site correct class here
$('.author-image').attr('src', image);
}
var description = false;
var client = new HttpClient();
client.get((data.entry.author[0].uri["$t"]).replace("http", "https"), function(response) {
var doc = document.documentElement.cloneNode();
doc.innerHTML = response;
$content = $(doc.querySelectorAll('tr'));
for(var lk=0; lk<$content.find('th.item-key').length; lk++) {
if($content.find('th.item-key')[lk].innerText=="Introduction" && $content[lk].querySelectorAll('td')[0]!==null) {
description = $content[lk].querySelectorAll('td')[0].textContent;
break;
}
}
if(description!=false) { //site correct class here
$('.description').text(description);
}
});
}
}); } });
I have a web application that allows users to post custom stories to their Facebook timeline with the list of fitness exercises they have performed.
The first version is looping through the exercises and calling FP.api for each exercise and it works fine.
Now I would like to make a single call to FB.api with a batch request to speed up the posting and that's where I'm having trouble.
Here is the code with the loop that works fine (exids is an array of numbers):
function postToFB(exids)
{
fbi = 0;
fblength = exids.length;
for (var i = 0; i < fblength; i++)
{
FB.api(
'me/' + vitNamespace + ':perform',
'post',
{
exercise: "http://www.vitalclub.net/scripts/getExforFB.php?exid=" + exids[i],
'fb:explicitly_shared': true
},
function(response) {
...
});
}
}
and here is the code with the batch request that returns an error:
function postToFB(exids)
{
var batcharr = [];
for (var i = 0; i < exids.length; i++)
batcharr.push({ method: 'post', relative_url: 'me/' + vitNamespace + ':perform', body: "exercice=http://www.vitalclub.net/scripts/getExforFB.php%3Fexid%3D" + exids[i] + "&fb:explicitly_shared=true" });
FB.api(
'/',
'post',
{ batch: batcharr, include_headers: false },
function(response) {
...
});
}
The error I get (for each exercise) is the following: The action you're trying to publish is invalid because it does not specify any reference objects. At least one of the following properties must be specified: exercise.
I presume this has to do with the way the body in the batch request is formatted but I cannot find the right way to format it. I have tried using encodeURIComponent on the URL representing the exercise but the error is the same.
Anybody has an idea of what the problem is?
Thanks,
Jean
OK, my bad. It was really a stupid error. I had written the parameter "exercise" in French instead of English (so "exercice" instead of "exercise") and that's where the problem was.
I'm also now using $.param to format the parameters so I now have:
var batcharr = [];
var opts;
for (var i = 0; i < exids.length; i++)
{
opts = { exercise: "http://www.vitalclub.net/scripts/getExforFB.php?exid=" + exids[i], 'fb:explicitly_shared': true };
batcharr.push({ method: 'post', relative_url: 'me/' + vitNamespace + ':perform', body: $.param(opts) });
}
before calling FB.api and it works like a charm!
I am creating Facebook application which get insights for user's page for multiple metric. Ex. for "page_active_users" and "page_active_users in one batch request.
I am using Facebook C# SDK. But not able to get data from Facebook insights (GraphAPI).
I used 5 different way to get the data but not succeed. By using Graph API method in browser shows data for a page but in batch request it returns empty array of data.
//type1
var para1 = new FacebookBatchParameter(HttpMethod.Get, "MyPageId/insights/")
{
Data = new { access_token = aToken, since = "2012-01-01", metric = "page_active_users" }
};
//type2
var para2 = new FacebookBatchParameter(HttpMethod.Get, "fql/", new
{
q = new[]{
"SELECT value,end_time FROM insights WHERE object_id=MyPageId AND metric='page_active_users' AND end_time=end_time_date('2012-01-01') AND period=86400"
}
}) { Data = new { access_token = aToken } };
//type 3
var para3 = new FacebookBatchParameter().Query(
"SELECT value,end_time FROM insights WHERE object_id=MyPageId AND metric='page_active_users' AND end_time=end_time_date('2012-01-01') AND period=86400");
//type 4
var para4 = new FacebookBatchParameter
{
Path = "MyPageId/insights/",
//Parameters = new {since = "2012-01-01"},
Data = new { access_token = aToken, since = "2012-01-01", metric = "page_active_users" },
HttpMethod = HttpMethod.Get
};
//type 5
var para5 = new FacebookBatchParameter
{
Path = "MyPageId/insights/page_active_users?since=2012-01-01",
//Parameters = new {since = "2012-01-01"},
Data = new { access_token = aToken },
HttpMethod = HttpMethod.Get
};
//Executed all above type by passing it to below method one by one.But always return empty data array while data is exists on Facebook which I tested using Grap API tool.
var result = client.Batch(para1-5);
Any help appreciated.
Thanks in advanced.
Dharmendra Mistry
I found solution on my own. Hope this will help someone. Here is the solution.
///I created an enum for list of metrics that facebook is providing
public enum FacebookMatricType
{
page_active_users,
page_active_users_locale
}
//Created a list of Facebook batch request for each metric using LINQ to Object and //concatenate string using string.format method.
var batchParameters = (from FacebookMatricType matricType in Enum.GetValues(typeof (FacebookMatricType))
select new object[]
{
pPageAccessToken,"insights",matricType.ToString(),pFromDate.Date.ToString("yyyy-MM-dd"),pPageId
}
into objectParamter
select new FacebookBatchParameter
{
HttpMethod = HttpMethod.Get,
Path =
string.Format(
"https://graph.facebook.com/{0}/{1}/{2}?since={3}&access_token={4}",
objectParamter)
}).ToList();
//Once I get the list of request I execute it using facebook web client using C# SDK.
var facebookClient = new FacebookClient(pProfileAccessToken);
var results = facebookClient.Batch(batchParameters.ToArray());
//Results are ready to deserialize.
Thank you. ;)
Dharmendra Mistry
I'm trying to use Facebook graph in Chrome extensions, but I'm having trouble in using access token to have permissions. My extension folder has a background.html file with the this code:
function displayUser(user) {
var userName = document.getElementById('userName');
var greetingText = document.createTextNode('Greetings, ' + user.name + '.');
userName.appendChild(greetingText);
}
var appID = "XXXXX";
if (window.location.hash.length == 0) {
var path = 'https://www.facebook.com/dialog/oauth?';
var queryParams = ['client_id=' + appID,'redirect_uri=https://www.facebook.com/connect/login_success.html', 'response_type=token'];
var query = queryParams.join('&');
var url = path + query;
window.open(url);
} else {
var accessToken = window.location.hash.substring(1);
var path = "https://graph.facebook.com/me?";
var queryParams = [accessToken, 'callback=displayUser'];
var query = queryParams.join('&');
var url = path + query;
// use jsonp to call the graph
var script = document.createElement('script');
script.src = url;
document.body.appendChild(script);
}
When I run the extension, it opens a new tab with the app authorization. When I accept it, it just says "Success" and the url of this tab is like this:
https://www.facebook.com/connect/login_success.html#access_token=AAABtoJwdQQgBAP8KK6QYmlQ1CJOSjQxWjXoa7qgUthF507BGPgLeWEplB87fZBpDZBZBd7CKoIWb4Fa3S2laBuZAUf795p1N3QZDZD&expires_in=5549
So now how can I use this access token in background.html and close that authorization tab?
You should watch (in the extension code) for the tab changes with success url like this
chrome.tabs.onUpdated.addListener(onTabUpdated);
Then the handler function:
function onTabUpdated(tabId, changeInfo, tab) {
if (changeInfo.url && changeInfo.url.indexOf(SUCCESS_URL) == 0) {
// extract access token from url
Extract function:
function accessTokenFromSuccessURL(url) {
var hashSplit = url.split('#');
if (hashSplit.length > 1) {
var paramsArray = hashSplit[1].split('&');
for (var i = 0; i < paramsArray.length; i++) {
var paramTuple = paramsArray[i].split('=');
if (paramTuple.length > 1 && paramTuple[0] == 'access_token')
return paramTuple[1];
}
}
return null;
}
Judging by redirect_uri=https://www.facebook.com/connect/login_success.html, I'm assuming you're building a desktop or a client side app.
Try adding var RedirectURI = window.location;
And change the redirect URI in the queryParams array to redirect_uri= RedirectURI
If required, you can add http://localhost to the Site URL entry in https://developers.facebook.com/apps
Once the token is obtain, it is redirected to your previous page with the authorization token added as a hash which is automatically handled by the else { } block in your code.