Getting Google+ profile picture url with user_id - google-api

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.

Related

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

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.

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.

Is it possible to hide passed parameters in url while using redirect in controller? Yii 1.1

I am trying to pass parameter from my controller to my view.
My code is like this:
$this->redirect(array('marketingEmail/mailToSend','lot'=>$lotNum));
public function actionMailToSend()
{
$lotValue = Yii::app()->request->getQuery('lot');
$model=new Marketing();
$this->render('_mailList',array(
'lotVal'=>$lotValue,'model'=>$model,
));
}
My current url is like: http://localhost/test/marketingEmail/mailToSend/lot/1.
I want my url like: http://localhost/test/marketingEmail/mailToSend.
how can I achieve this?
No, it is not possible.
You can use session variable for your purpose. Save your id in session and get this id in your redirected page.
For more solution you can refer this URL.
No, it's impossible to make HTTP POST redirect using PHP. The only way to do it using user's browser side. For example generate page with form and submit it from window.onload.
You could perhaps use curl_exec on a REST API function that accepts a POST.
David Walsh wrote an article in 2008 entitled: Execute a HTTP POST Using PHP CURL
Quoting from the blog post:
//open connection
$ch = curl_init();
//set the url, number of POST vars, POST data
curl_setopt($ch,CURLOPT_URL, $url);
curl_setopt($ch,CURLOPT_POST, count($fields));
curl_setopt($ch,CURLOPT_POSTFIELDS, $fields_string);
//execute post
$result = curl_exec($ch);
//close connection
curl_close($ch);
Otherwise, use javascript.

Avoid URL length limitation via POST

I am currently working on a web2print project based on Adobes Scene7. The full url to a print product (pdf) is very long and exceeds all browser limitation of url length. So to get the final print product I assume I have to submit the url in a different way via POST method.
There seem to be two ways: First, use a html form (method=post) and create all url parameters as (hidden) input fields. Second, make an ajax call (e.g. jQuery.ajax) with post.
Actually if I would open the print url in the browser, the ready pdf would be opened within the browser. So I need a way to send the very long url via POST to the server and open the PDF I get back from it. Testing the ajax version I ran into the same-origin-policy and get an error, as I call a url not on my local server. This must be a standard situation in web2print projects, how is this handled?
Thx in advance
Michbeck
I got the problem solved. I did it in two steps. First I use ajax to send the base url and the url parameters to a php script on my local server. It is easily done with jQuery:
jQuery.ajax({
type : "POST",
url : './includes/php/userdata.php',
data: { method: 'get_print_version',
url: base_url,
parameter: query_parameter,
num: num_parameter },
error: function(error) {
console.log("Print version failed");
},
success: function(reault) {
console.log("What is the result?");
}
});
The server script uses cURL to send the data to the final server. Therefore the base url and the parameters are not posted as one url but seperated by the use of CURLOPT_POST and CURLOPT_POSTFIELDS. The server response (a pdf) can be written to file with file_put_contents. If the PDF gets to big, you will get a memory limitation error here. Than it is better to write the answer from cURL directly to the pdf file.
if ($_method == 'get_print_version')
{
$url = $_REQUEST['url'];
$parameter = $_REQUEST['parameter'];
$num = $_REQUEST['num'];
$post = curl_init();
curl_setopt($post, CURLOPT_URL, $url);
curl_setopt($post, CURLOPT_POST, $num);
curl_setopt($post, CURLOPT_POSTFIELDS, $parameter);
/* write calendar directly to file */
$pdf = fopen('./Calendar.pdf', 'w');
curl_setopt($post, CURLOPT_FILE, $pdf);
curl_exec($post);
curl_close($post);
echo $result;
}

In codeigniter, How to get the token returned from google login as parameter to controller?

I am working with AuthSub to view portfolios of google finance api on codeigniter framework.
after successful login of google it redirects to the url we provide.
I have provided url like: www.finance.mysite.com/google/token/
google will append its token like:
www.finance.mysite.com/google/token/?token=1/gyXbtvKT4XaIuUIhEBAsuxyDgATMDk3ztAG3MocNkKI
How can I get it inside a function token() inside google controller.
I don't know that you have control over "how" it gives it to you. For a controller parameter, you'll need to redirect after the Auth callback "gives" you the token. This is probably unnecessary though, as you can simply grab it out of the query string.
<?php
$token = $this->input->get('token');
if ($token)
{
// Option 1: redirect to a controller action that
// takes the token as the parameter
redirect('/google/token/'.$token);
// Option 2: do something directly with the token
// right now (why bother redirecting?)
var_dump($token);
exit;
}
die('Access token? We didn\'t get no access token!');
?>
Storing the token in the session or database is an alternative to the redirect, but the redirect would how to "get the token as parameter to controller" like you ask.
Just extract the token, and route it to controller of your choice.
You can extract the params like this
$params = "http://www.finance.mysite.com/google/token/?token=1/gyXbtvKT4XaIuUIhEBAsuxyDgATMDk3ztAG3MocNkKI";
$parsed = parse_url($params);
$pieces = explode("=", $parsed['query']);
$searchIndex = array_search("token", $pieces);
if($searchIndex) {
$token = $pieces[$searchIndex+1];
//now use it as you need
redirect("controller/google/$token");
}
Note: The code above will only work, if there is only single parameter on the url, or else not.

Resources