How to Get Public Data or Tags from Instagram Using the New API? - ajax

Is there any way to get Instagram public profile data as per new API?
According to Instagram, these are the steps that I need to follow:
Create an application by providing site url and redirect url.
Redirect your user using oAuth and generate access token.
Now using the proper url and access token we can get user data.
I did each step and generate access token properly now I am using ajax to hit the url
https://api.instagram.com/v1/users/searchq='+inst.instagramId+'&access_token='+inst.accessToken
where inst.instagramId is user id and inst.accessToken is access token.
Response contain code 200 that is ok but data is empty.
Thanks for any help.

Actually with the new Instagram api it is impossible to get public data or tags. The only information you can get with instagram's new api is your data, or access token's owner data.

I wrote a proxy API for this exact purpose: https://github.com/whizzzkid/instagram-proxy-api
Let's take an example of #nyc:
Instagram's tag explorer: https://www.instagram.com/explore/tags/nyc
Getting the same results as JSON: https://igpi.ga/explore/tags/nyc/media
You can find more examples in the repo. Here is the code that does all this: https://github.com/whizzzkid/instagram-reverse-proxy/blob/master/app.js
A demo application using jquery will be:
$.ajax({
url: "https://igpi.ga/explore/tags/yyc/media",
dataType: "jsonp",
data: { count: 3 },
success: function (json){
for(var i in json.posts) {
var img = document.createElement("IMG");
img.src = json.posts[i].display_url;
document.body.appendChild(img);
}
}
});
Demo: http://plnkr.co/edit/4oCwpbMm6p9cyJb1UWld?p=preview
hope this helps.

Related

springsecurity: using CSRF token obtained from CrossOrigin REST service to POST data

I have this REST service on domainA:
#CrossOrigin(origins={"http://domainB"})
#RequestMapping(value="/csrf", method=RequestMethod.GET)
public #ResponseBody
CsrfToken getCsrfToken(HttpServletRequest request) {
CsrfToken token = (CsrfToken)request.getAttribute(CsrfToken.class.getName());
return token;
}
Then I want to obtain CSRF token from above service (by using javascript on domainB) and add it to a <form action="http://domainA> on domainB and send this form to domainA (it is a simple form that has a submit button).
The problem is I get HTTP Status 403 – Forbidden.
As the opposite: when I manually set the _csrf value (obtained manually in the other browser tab pointing to domainA/csrf) in the <form action="http://domainA> and submit it then it works.
The difference which I noticed is that when I manually refresh browser's tab domainA/csrf then I get constantly the same value (and this value works), but when the domainA/csrf is obtained by the javascript from the domainB it is each time different and when using it - it does not work.
Can anyone help?
domainA: www.fridayweekend.com/rest/csrf
domainB: www.friwee.com/register (hit F12 and observe what call to www.fridayweekend.com/rest/csrf returns....)
As #dur said - the problem was in the JavaScript code. I used:
$.getJSON(domainA/csrf, callback)
which was ending up each time with a new session and a new CSRF token for it.
The solution was to use cors_ajax_call function except $.getJSON, defined as below:
var cors_ajax_call = function(address, callback){
$.ajax({
url: address,
context: document.body,
xhrFields: {
withCredentials: true
}
}).success(callback);
}
Thank you for your input! Hope this help someone :)

Angular2 + Web API + token based authentication

I am trying to learn Angular2
and I am trying to create a simple blog with authentication.
this here is my add a new post method:
[Authorize]
// POST: api/Post
public PostModel Post([FromBody]PostViewModel model)
{
var post = new PostModel
{
Body = model.Body,
Title = model.Title,
AuthorId = IdentityExtensions.GetUserId(User.Identity),
};
var res = blogRepo.AddPost(post);
return res;
}
everything works fine, but IdentityExtension.GetUserId() do not return the most current logged in user but the first user since the app started.
basically I am looking for a way to make sure that the current user logs out on the server as well as on the client (the client side is just a simple removal of the localStorage.removeItem("jwt");)
also there is a good chance that what I am doing is totally wrong, but I can't access the ApplicationUserManager in this controller.
ok I have found the problem, although I haven't managed to solve it yet but I will update this when i do, and I am writing this as an answer since the problem is totally different from what I asked and thought to be.
the problem is related to sending the authentication hints as Thierry Templier suggested. I have a file that exports headers like this:
export const authHeaders = new Headers();
authHeaders.append('Accept', 'application/json');
authHeaders.append('Content-Type', 'application/json');
authHeaders.append('Authorization', 'Bearer ' + localStorage.getItem('jwt'));
And I Import this header where ever I need it. but I am not sure why it always sends a cached value (i.e the first value stored on the client and it has nothing to do with the server side as my question implies).
to solve this issue I just have to make sure the latest access-token stored on localstorage is sent to the server.
EDIT: for now I am constructing the headings in the constructor.

ExtJS 4 auto-parse metadata

Ok, in my application, I have extra information sent with the data, which the Sencha docs define as metadata. If there was an error retrieving data, say for a grid, i want the server to be able to tell the client to inform the user that it was unable to complete the request. But I want to do this for EVERYTHING, and not have to redefine a callback to check on every store in my application. Is there a way to do this? Or am I trying to do this all wrong? Also, how can I go about utilizing the JSON Reader without using stores or models? That way I can do the same thing, intrepting server instructions, without having to redefine it in an Ext.Ajax success callback?
For a store, you can
Ext.define('myNewCustomStore',{
constructor:function(config){
this.callParent(arguments);
this.on('load',function(store,records,e){myCustomMetaDataHandler()});
}
});
And then instead of using
Ext.create('Ext.data.Store' or Ext.define('myStore',{extends:Ext.data.Store
You create / extend myNewCustomStore
And Json without models?
Ext.Ajax.request({
url: 'page.php',
params: {
id: 1
},
success: function(response){
var text = response.responseText;
var json = Ext.JSON.decode(text);
//now do stuff
}
});

dojo.io.script.get vs dojo.xhrGet

I have spent days working on this and really feel dumb. I have been working on demos and samples that never work when I try it locally with my own url. I have a web service that returns results back in json and am just basically trying to call it using dojo and for now just view the results. I took the search google example and just substituted the url and parameters. Now perhaps I still do not understand the basics so:
- io.script.get vs xhrGet
if using cross domain urls it is better to use io.script.get? correct?
now what is the callbackparam? is this the function that is being called in the webservice?
My webservice url is as follows:
http://xxx.xxx.x.xxx/WcfServices/WcfInstance/Service1.svc/RetrievData?query=Word
when I use the following code I get nothing displayed.
function searchGoogle() {
// Look up the node we'll stick the text under.
var targetNode = dojo.byId("rules");
// The parameters to pass to xhrGet, the url, how to handle it, and the callbacks.
var jsonpArgs = {
url: "http://xxx.xxx.x.xxx/WcfServices/WcfInstance/Service1.svc/RetrieveData?",
callbackParamName: "callback",
content: {
query:"dojowords"
},
load: function (data) {
// Set the data from the search into the viewbox in nicely formatted JSON
targetNode.innerHTML = "<pre>" + dojo.toJson(data, true) + "</pre>";
},
error: function (error) {
targetNode.innerHTML = "An unexpected error occurred: " + error;
}
};
dojo.io.script.get(jsonpArgs);
}
dojo.ready(searchGoogle);
Here is what the webservice results look like:
"{\"rules\":[{\"value\":\"AllState\"},
{\"value\":\"Cidade de Goa beach\"},{\"value\":\"Euro 2012\"},
{\"value\":\"Euro2012\"},{\"value\":\"European&Championship\"},
{\"value\":\"Holiday Inn Resort\"},
{\"value\":\"Holiday Inn Resort goa\"},
{\"value\":\"Hotel Goa\"},{\"value\":\"Hyatt Goa\"},{\"value\":\"I buy car\"},...
If I get this part correct then at least I know I have data which I can then bind to a datagrid or chart.
dojo.io.script.get is for all cross domain requests.
xhrGet is for same domain requests.
dojo.io.script.get uses a hack which expects jsonp or json padding as a result. This wraps the response of the web service call inside a self executing function. The function name is the callback name. This has to be wired before the call so it knows what already defined function to call when a response comes back.
All of the arguments are well documented http://dojotoolkit.org/reference-guide/1.7/dojo/io/script.html
My guess as to why your service isn't working is because you wrote the web service and it does not handle jsonp. It is not wrapping its response inside the callbackparamname.
your results should look something like
callback({json});
where callback is whatever you set up in callbackParamName
you can also remove the ? from your url, that should be handled for you.

Getting Google+ profile picture url with user_id

I know that lots of social network APIs provide a way to construct a url to the profile picture of a user, using their user_id or username. For Facebook it looks like this:
http://graph.facebook.com/user_id/picture?type=square
Now is there something like this for Google Plus? Or any other way to get user's pic without an API call??
Google had changed their policy so the old way for getting the Google profile image will not work now, which was
https://plus.google.com/s2/photos/profile/(user_id)?sz=150
New Way for doing this is
Request URL
https://www.googleapis.com/plus/v1/people/115950284...320?fields=image&key={YOUR_API_KEY}
That will give the Google profile image url in json format as given below
Response :
{
"image":
{
"url": "https://lh3.googleusercontent.com/-OkM...AANA/ltpH4BFZ2as/photo.jpg?sz=50"
}
}
More parameters can be found to send with URL which you may need from here
For more detail you can also check the given question where I have answered for same type of problem
How to get user image through user id in Google plus?
UPDATE: The method below DOES NOT WORK since 2015
It is possible to get the profile picture, and you can even set the size of it:
https://plus.google.com/s2/photos/profile/<user_id>?sz=<your_desired_size>
Example: My profile picture, with size set to 100 pixels:
https://plus.google.com/s2/photos/profile/116018066779980863044?sz=100
Usage with an image tag:
<img src="https://plus.google.com/s2/photos/profile/116018066779980863044?sz=100" width="100" height="100">
Hope you get it working!
UPDATE: Google stopped support for this method, that now returns a 404 (not found) error.
All this urls fetch the profile picture of a user:
https://www.google.com/s2/photos/profile/{user_id}
https://plus.google.com/s2/photos/profile/{user_id}
https://profiles.google.com/s2/photos/profile/{user_id}
They redirect to the same image url you get from Google API, an ugly link as
lh6.googleusercontent.com/-x1W2-XNKA-A/AAAAAAAAAAI/AAAAAAAAAAA/ooSNulbLz8U/photo.jpg
The simplest is to directly use like image source:
<img src="https://www.google.com/s2/photos/profile/{user_id}">
Otherwise to obtain exactly the same url of a Google API call you can read image headers,
for example in PHP:
$headers = get_headers("https://www.google.com/s2/photos/profile/{user_id}", 1);
echo "<img src=$headers[Location]>";
as described in article Fetch Google Plus Profile Picture using PHP.
Approach 1: (no longer works)
https://plus.google.com/s2/photos/profile/<user_id>?sz=<your_desired_size>
Approach 2: (each request counts in your api rate limits which is 10k requests per day for free)
https://www.googleapis.com/plus/v1/people/<user_id>?fields=image&key={YOUR_API_KEY}
with the following response format:
{ "image": { "url": "lh5.googleusercontent.com/-keLR5zGxWOg/.../photo.jpg?sz=50"; } }
Approach 3: (donot require api key)
http://picasaweb.google.com/data/entry/api/user/<user_id>?alt=json
in the json response you get a property named "gphoto$thumbnail", which contains the profile picture url like the following:
http://lh6.ggpht.com/-btLsReiDeF0/AAAAAAAAAAI/AAAAAAAAAAA/GXBpycNk984/s64-c/filename.jpg
You may notice in the url the portion "s64-c" which means the image size to be 64, I've tried using other values like "s100-c" and they worked. Also if you remove the "s64-c" part and append the "?sz=100" parameter, that will also work as of now. Though this is not very good way of getting the profile picture of a gplus user, but the advantage is it do not require any api key.
Google, no API needed:
$data = file_get_contents('http://picasaweb.google.com/data/entry/api/user/<USER_ID>?alt=json');
$d = json_decode($data);
$avatar = $d->{'entry'}->{'gphoto$thumbnail'}->{'$t'};
// Outputs example: https://lh3.googleusercontent.com/-2N6fRg5OFbM/AAAAAAAAAAI/AAAAAAAAADE/2-RmpExH6iU/s64-c/photo.jpg
CHANGE: the 64 in "s64" for the size
If you want to show the profile picture for the currently logged in user, you do not even need to know the {user_id}. Simply using https://plus.google.com/s2/photos/profile/me will be enough.
2020 Solution
Please comment if no longer available.
In order to get profile URL from authenticated user.
GET https://people.googleapis.com/v1/people/[THE_USER_ID_OF_THE_AUTHENTICATED_USER]?personFields=photos&key=[YOUR_API_KEY] HTTP/1.1
Authorization: Bearer [YOUR_ACCESS_TOKEN]
Accept: application/json
Response:
{
"resourceName": "people/[THE_USER_ID_OF_THE_AUTHENTICATED_USER]",
"etag": "12345",
"photos": [
{
"metadata": {
"primary": true,
"source": {
"type": "PROFILE",
"id": "[THE_USER_ID_OF_THE_AUTHENTICATED_USER]"
}
},
"url": "https://lh3.googleusercontent.com/a-/blablabla=s100"
}
]
}
and the link can be used as:
<img src="https://lh3.googleusercontent.com/a-/blablabla=s100">
You can get the URL for the profile image using the people.get method of the Google+ API. That does require an extra round trip, but is the most reliable way to get the image.
You technically can also use the URL https://s2.googleusercontent.com/s2/photos/profile/{id}?sz={size} which will then redirect to the final URL. {id} is the Google user ID or one of the old Google Profiles usernames (they still exist for users who had them, but I don't think you can create new ones anymore). {size} is the desired size of the photo in pixels. I'm almost certain this is not a documented, supported feature, so I wouldn't rely on it for anything important as it may go away at anytime without notice. But for quick prototypes or small one-off applications, it may be sufficient.
trying to access the /s2/profile/photo url works for most users but not all.
The only full proof method is to use the Google+ API. You don't need user authentication to request public profile data so it's a rather simple method:
Get a Google+ API key on https://cloud.google.com/console
Make a simple GET request to: https://www.googleapis.com/plus/v1/people/+< username >?key=
Note the + before the username.
If you use user ids instead (the long string of digits), you don't need the +
you will get a very comprehensive JSON representation of the profile data which includes:
"image":{"url": "https://lh4.googleusercontent.com/..... the rest of the picture url...."}
If you use Flutter, then you can access it via people.googleapis.com endpoint, code uses google_sign_in library
import 'package:google_sign_in/google_sign_in.dart';
Future<String> getPhotoUrl(GoogleSignInAccount account, String userId) async {
// final authentication = await account.authentication;
final url = 'https://people.googleapis.com/v1/people/${userId}?personFields=photos';
final response = await http.get(
url,
headers: await account.authHeaders
);
final data = json.decode(response.body);
return data['photos'].first['url'];
}
You will get something like
{
resourceName: people/998812322529259873423,
etag: %EgQBAzcabcQBAgUH,
photos: [{metadata: {primary: true, source: {type: PROFILE, id: 107721622529987673423}},
url: https://lh3.googleusercontent.com/a-/abcdefmB2p1VWxLsNT9WSV0yqwuwo6o2Ba21sh_ra7CnrZ=s100}]
}
where url is an accessible image url.
Tried everything possible.. here is final piece of working code. Hope it helps someone who is looking for it.
<?
$url='https://www.googleapis.com/plus/v1/people/116599978027440206136?fields=image%2Furl&key=MY_API_KEY&fields=image';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_PROXYPORT, 3128);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
$response = curl_exec($ch);
curl_close($ch);
$d = json_decode($response);
$avatar_url = $d->{'image'}->{'url'};
echo $avatar_url;
?>
Simple answer: No
You will have to query the person API and the take the profile image.url data to get the photo. AFAIK there is no default format for that url that contains the userID.

Resources