A way to bypass the per-ip limit retrieving profile picture? - facebook-graph-api

My app download all the user's friends pictures.
All the requests are of this kind:
https://graph.facebook.com/<friend id>/picture?type=small
But, after a certain limit is reached, instead of the picture I get:
{"error""message":"(#4) Application request limit reached","type":"OAuthException"}}
Actually, the only way I found to prevent this is to change the server ip (manually).
There isn't a better way?

For the record:
The limit is related to the Graph Api only, and the graph.facebook.com/<user>/picture url is a graph api call that returns a redirect.
So, to avoid the daily limit, simply fetch all the images url from FQL, like:
SELECT uid, pic_small, pic_big, pic, pic_square FROM user WHERE uid = me() or IN (SELECT uid2 FROM friend WHERE uid1=me())
now these are the direct urls to the images, for eg:
http://profile.ak.fbcdn.net/hprofile-ak-snc4/275716_1546085527_622218197_q.jpg
so don't store them since they continuously change.

If it's needed for an online app better way not to download those images, but use an online version, there is couple of reasons for doing so:
Users change pictures (some frequently), do you need an updated version?
Facebook's servers probably faster than yours and friends pictures probably cached within browser of your user.
Update:
Since limit you reach is Graph API call limit, not the image retrieval, another solution that comes to my head just now is using friends connection of user in Graph API and specifying picture in fields argument, eq: https://graph.facebook.com/me/friends?fields=picture, this will return direct URL-s for friends pictures so you can do only one call to get all needed info to download the images for every user...

Related

Amazon QuickSight embedded dashboard - how to cache user session in my webapp (billing and timing concern)

I have embedded Amazon QuickSight dashboard in my web application by using amazon-quicksight-embedding-sdk (followed https://learnquicksight.workshop.aws/en/dashboard-embedding.html).
The user session seems to last many hours as mentioned in https://docs.aws.amazon.com/quicksight/latest/APIReference/API_GetDashboardEmbedUrl.html
When I requested the embed URL directly from my web browser, I could see that it was valid for many hours.
But my web app will request a new embed URL when user restarts it (by closing/reopening tab/browser). Does that mean a new user session was created and billed.
Is it possible to store the embed URL and to reuse it (as long as the user session lasts) for the case the same user closes the tab/browser and open the web app and the dashboard again (of course in the same browser)?
I tried to store the embedURL as a cookies named "embed_url". But calling amazon-quicksight-embedding-sdk.embedDashboard({url: embed_url}) resulted in
"Embedding failed because of invalid URL or authorization code. Both
of these must be valid and the authorization code must not be expired
for embedding to work."
I was sure the embed_url was still valid because requesting it by the browser directly worked.
Which "authorization code" is mentioned in the above error message? What did I miss or is it actually not possible?
Beside the billing concern, I've noticed that the call to get the embedURL took time (more than 5 seconds, eu-central-1) while the embedding took less (3 seconds). I thought I could improve the dashboard loading time by reusing the gotten embedURL. Any comments about the timing? Is it normal or did I do something wrong so that it was so slow? My test dashboard has only 1 diagram with unchanged dataset.
As per the Quicksight Pricing Page, if you're creating an embedded dashboard for a Quicksight "Reader", then you're paying $0.30/session per 30-minute logged-in-session for this Reader.
The validity of the session can be set in the SessionLifetimeInMinutes parameter of the GetDashboardEmbedUrl API, and has an upper bound of 600 minutes (10 hours).
As an example, suppose you set SessionLifetimeInMinutes to 600 mins for your Reader user. Also suppose that this user stayed logged in and uses the dashboard for 10 hours continuously, then that would equate to 20 sessions of usage (since the billing is in increments of 30-min chunks). At first glance it would seem that this would cause $0.30/session * 20 session-chunks = $6 to be billed.
However, as per the pricing page, there is an upper bound of $5.00 per month for every Reader. Which means that this Reader can never exceed $5 per month regardless of how many Quicksight sessions (of whatever duration) are created for them. So no matter how many times you call the GetDashboardEmbedUrl API for a given Reader, you're capped to $5/month for this user.
Also of use as to what constitutes a Reader session (from the pricing page):
When does a Reader Session start and end?
A Reader Session starts with user-initiated action (e.g., login, dashboard load, page refresh, drill-down or filtering) and runs for next 30-minutes.
Keeping Amazon QuickSight open in a background browser window/tab does not result in active sessions until the Reader initiates action on page.
But my web app will request a new embed URL when user restarts it (by closing/reopening tab/browser). Does that mean a new user session was created and billed.
I'm not 100% sure about this, but yes I believe a refresh (or open/close) of the tab results in a new session for the same user.
A Reader Session starts with user-initiated action (e.g., login, dashboard load, page refresh, drill-down or filtering) and runs for next 30-minutes.
The above excerpt is from the pricing page. So it does seem that page refresh (and thus another call to GetDashboardEmbedUrl) will trigger a new session for the user.
Which "authorization code" is mentioned in the above error message?
The GetEmbedDashboardUrl API response is a JSON object that looks like this:
{
"Status": 200,
"EmbedUrl": "https://us-east-1.quicksight.aws.amazon.com/embed/f4147cd0d4d_BLAH_BLAH_...",
"RequestId": "c15a7bad-629e-444a-b643-ff3142c9ae41"
}
If you look closer at the EmbedUrl, apart from the dashboard url itself, there are also these query-string parameters:
isauthcode
code
identityprovider
statePersistenceEnabled
potentially: other params too
The code parameter (embedded within the embedUrl) is the "authorization code" that you asked about.
Is it possible to store the embed URL and to reuse it (as long as the user session lasts) for the case the same user closes the tab/browser and open the web app and the dashboard again (of course in the same browser)?
No, that can't be done. As it says in the link you shared:
The following rules apply to the combination of URL and authorization code:
- They must be used together.
- They can be used one time only.
- They are valid for 5 minutes after you run this command.
So the embedURL and its associated auth code can only be used once together. Makes sense since this will prevent MITM replay attacks among other scenarios. Also I actually tried to cache the response and then re-use the embedUrl in case of a cache-hit, since this would improve the end-user experience. But this didn't work - a "replay" of the embedUrl is blocked by QuickSight, as mentioned in their doc.
Any comments about the timing?
This has been our experience also. The GetDashboardEmbedUrl REST API takes around 5-7 seconds (us-east-1) for our app and then the actual embedding takes another 3-5 seconds. Not great, but I don't see a way around this poor user experience as of now.

How to change users while preserving the store?

I want to implement a "fast login".
I'm developing an enterprise software where a lot of users work in the same organization with the same data in the same computer and I want to be able to know who did what and when. Right now they have to log out and log in and load the data has to be loaded into the store all over again.
What I want is for them to be able to, without logging out, click on a user, from the organization, insert his password and the user is switched while preserving the store.
Any idea how I can accomplish this?
I'm using ember-simple-auth v1.1.0 and ember v2.10.2
The simpliest solution would be disabling page reload when user logs out. As far as I know, it's a reload causes data loss from store, not a logging out by itself. To do this, you need to overwrite sessionInvalidated method in your application route. For example,
sessionInvalidated() {
this.transitionTo('/login');
},
But remember - you lower security with this method: if someone will log out and leave webpage with app open, other person will have a possibility to extract data (if they have enough technical background to at least install ember inspector).
Other solution will require heavy research. I think it should be possible to implement custom authenticator which would allow to authenticate new user without logging out previous, by simply replacing tokens in store. But I don't know how hard it will be to implement and what obstacles you can meet. You will need to read ember-simple-auth's sources a lot, that's for sure.
I was actually able to solve it by simply using authenticate() with another user but never calling invalidateSession() which is the function that calls sessionInvalidated() that looks like this:
sessionInvalidated() {
if (!testing) {
if (this.get('_isFastBoot')) {
this.transitionTo(Configuration.baseURL);
} else {
window.location.replace(Configuration.baseURL);
}
}
}
So by not calling sessionInvalidated() the user isn't redirected or the page refreshed and the new user is able to keep using the store without switching pages.

Selecting Categories using API in Amazon MWS

I am developing a integration between a desktop application and Amazon MWS and need to be able to offer users a choice of categories to put the product they are listing into. My problem is that I can't find any way of programmatically getting the current categories from MWS using the API.
Additionally once I have a category reference to use I will need a way to the pull in and add the category specific XML child of ProductData (eg Home, Jewelry, Computers, etc) but they don't seem to be linked in any well defined way. For example, I can't say "if the chosen category is reference nnnnn ask them to populate the Computers specific ProductData", unless I write something myself to map them.
Has anyone else come across these problems and found a workable solution?
Any help appreciated...
I am currently exploring the option of limiting users to only selling products already listed on Amazon but still can't figure out how to pull in the correct category specific XML.
There are various product look-ups but they all seem to work from either my SKU (which will not yet be there) or Amazons ASIN (which I don't yet know)
You can use amazon advertizement api for this.
You have to create account on amazon affiliate programme.From that you have to get security credentials also .
After That go to BrowseNode Tree Page and download root categories list and save it to file or database.From there you get categoryname and their browseNodeId.
Then call BrowseNodeApi to get Child Categories for parent Category.
Please Follow This Link
http://docs.aws.amazon.com/AWSECommerceService/latest/DG/ProgrammingGuide.html
code for calling BrowseNodeApi
SignedRequestHelper helper =
new SignedRequestHelper(appConfig["AWSAccessKey"], appConfig["AWSSecretKey"], appConfig["endpoint"]);
string url = helper.Sign("http://ecs.amazonaws.com/onca/xml?Service=AWSECommerceService&Operation=BrowseNodeLookup&BrowseNodeId=" + value + "&AssociateTag=beginners00-00&Version=2011-08-01");
HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
// Get response
using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
{
}
and also download SignatureGenerator class HMAC

Facebook Graph API 2.1 feed attachments

According to Facebook Platform Changelog
/v2.1/{post-id} will now return all photos attached to the post: In previous versions of the API only the first photo was returned with a post. This removes the need to use FQL to get all a post's photos.
Though this statement is applicable only for separate API calls per post that looks follows:
https://graph.facebook.com/v2.1/{post_id}?fields=attachments
Since I need to retrieve all possible data that user posts to timeline, I use corresponding feed edge to do so.
https://graph.facebook.com/v2.1/me?fields=feed
So when I make a post with more than one picture attached to it, retrieved API response doesn't reflects that (and as I understand it's is per design). However I found that Graph API Explorer allows to choose attachments edge while constructing feed query that in this case appears like this
https://graph.facebook.com/v2.1/me?fields=feed{attachments}
but execution of such request triggers "Unsupported get request" exception.
Summing it up, the whole issue with the approach to make separate API calls for pictures is that it will dramatically increase number of calls which in turn not only decreases overall performance of the processing algorithm, but also leads to failing API call limits restrictions that in my case is unacceptable.
So I'm curious, is there any possibility to retrieve all post attachments (i.e. pictures) while working with feed edge or any alternative approach?
Thanks.
This should work.
me/home?fields=attachments,<other stuff>
The issue eventually resolved itself.
I found that Graph API Explorer allows to choose attachments edge while constructing feed
query that in this case appears like this
https://graph.facebook.com/v2.1/me?fields=feed{attachments}
but execution of such request triggers "Unsupported get request" exception.
It seems like non-working attachment edge for feed was unimplemented feature or a bug, because, surprisingly, now all attachments are retrieved successfully as subattachments collection.
Thanks, everybody.

batch update link_urls in the creative

We are trying to attach some parameters to existing link_urls for creatives.
For example:
http://www.adchemy.com -> http://www.adchemy.com?param_ad_id=23423424242 for tracking
purposes, where is such id is an adgroup id for that creative.
We'll maintain one to one relation between creative and adgroup.
To update existing creative we have to create new and associate it with the ad.
We need to update around 5000 creatives.
Is there a way to update them in the batch rather than doing 10000 requests?
(5000 for new creatives and 5000 to update appropriate ads)?
There is a way in facebook API provides batch updates https://developers.facebook.com/docs/reference/api/batch/ not sure about the limit though it says 20.You can create Adgroups and insert creative element in the form of JSON or object and post information to adgroups url which is available at Open graph API
https://developers.facebook.com/docs/reference/ads-api/adgroup/