45

I'm writing an email-based application using the gmail-api, and i need to retrieve user public images for email address originating from google. I've seen other applications do that, but i can't seem a way to reliably get this data.

some more information:

  • i'm using oauth2 to sign the user in - and i have no problem requesting any type of permissions there.
  • i've tried retrieving the image using the google+ api - but it requires a userID for that - and i don't know how to get the userId for the email address (gmail-api doesn't give it, afaik).
  • i've tried using the contacts API - but it only gives images for the user's contacts, while the email clients can display images from other users as well.

Thanks!

Edit:

I know i can receive the required images from google plus, if i have the other user's userid. however, i can't find a way to get the userid based on an email address.

shaish
  • 1,479
  • 1
  • 12
  • 23

10 Answers10

69

Is very easy

http://picasaweb.google.com/data/entry/api/user/<hereYourUserIdOrYourEmail>?alt=json

just has a little problem.

You only can get the picture of your Google+ profile, not directly from your gmail.

UPDATE:

This API is being deprecated and will be turned down in January 2019. Migrate to Google Photos Library API as soon as possible to avoid disruptions to your application.

More Info Here

jose920405
  • 7,982
  • 6
  • 45
  • 71
20

UPDATE:

This API is being deprecated and will be turned down in January 2019. Migrate to Google Photos Library API as soon as possible to avoid disruptions to your application.

Info Here

Based on @jose920405 answer, I have written this free public API service called Pikmail API. Here some advantages.

  • No authentication needed.
  • It's totally free and open source.
  • It's written in Kotlin.
  • You don't need to write some wrapper for mapping the response.

Here is the blog post about how Pikmail API works internally.

Usage:

Html

<img src="https://pikmail.herokuapp.com/eduardo.alejandro.pool.ake@gmail.com?size=50" alt="Profile Picture">

Profile Picture

Java Android

Picasso.with(context).load("https://pikmail.herokuapp.com/eduardo.alejandro.pool.ake@gmail.com?size=50").into(imageView);

Feel free to contribute with you pull requests, open bugs or request new features here.

Note: This service is based on an independent library called Pikmail that can be used as a Gradle dependency in your java projects(servers or Android apps).

epool
  • 6,710
  • 7
  • 38
  • 43
  • 1
    really awasome it works osm!! but it depends on picassaweb and it ll be turn of at january 2019. as per documentation https://developers.google.com/picasa-web/ so after that wt will be do? – Nikunj Paradva Oct 23 '18 at 06:22
  • @Nikunj Paradva that is a good question, probably there won't be a straightforward solution, so maybe I'll end up closing the project if we can't find a workaround to this. – epool Oct 23 '18 at 18:02
  • 1
    when you close that project please comment here ,its better for current live user who is used your api, – Nikunj Paradva Oct 24 '18 at 04:22
  • @android developer probably it won't, but we need to wait until Jan 2019 to know, and check possible alternatives. – epool Dec 06 '18 at 15:58
  • @epool OK I asked about it here: https://github.com/epool/pikmail/issues/1 – android developer Dec 06 '18 at 17:20
  • 1
    @epool And I asked for an alternative, here: https://stackoverflow.com/q/53714174/878126 – android developer Dec 10 '18 at 21:52
  • @epool is there any update? it's still working so far – Oded Harth Jan 12 '19 at 00:08
  • @Oded Harth it is still working, no updates so far, we need to wait until google closes the picassa web api to confirm that the api won't longer work. – epool Jan 14 '19 at 15:50
  • @epool Doesn't seem to work anymore. If you know how to use the new API, please write about it here: https://stackoverflow.com/q/53714174/878126 – android developer Jan 17 '19 at 11:30
  • AFAIK there is not a straightforward workaround. it looks like the api needs authentication now. – epool Feb 21 '19 at 15:15
5

Google+ is the right way to do this. This actually has nothing to do with the Gmail API. You don't need a the user's userid, just a valid access token with appropriate scopes.

https://www.googleapis.com/plus/v1/people/me?access_token=YOUR_ACCESS_TOKEN_HERE

Unless there is an error/invalid token/etc, this will return a bunch of information about the user as JSON. Included in this data will be a URI for the user's profile image.

EDIT:

To get the profile picture for a user based on the email address, first search for the user

https://www.google.com/m8/feeds/contacts/default/thin?q=EMAIL_ADDRESS_HERE

You can then retrieve the correct userID for that user from the returned JSON, and use it to get a profile image.

James
  • 2,272
  • 1
  • 21
  • 31
  • 4
    This is for getting the image of the user who is currently logged in - no problem with that. but i need to get the image of OTHER users. – shaish Sep 02 '14 at 20:24
  • Thanks for the edit. However, this just gives me the contacts feed of the requesting user. there's a profile image there (which is not the correct one), but i can't find the google+ userid in any field. Also i think it ignores the q= query, but probably that's easy to solve. – shaish Sep 03 '14 at 14:00
  • '`YOUR_ACCESS_TOKEN_HERE` doesn't expire? – kittu Jan 04 '17 at 09:48
2

If you are authenticating users in your app with Google using the OAuth 2.0 API -For example using passport -> https://www.npmjs.com/package/passport-google-oauth20

You can request the "profile" scope, which gives you a bunch of information from displayName to the users profile photos "profile.photos[0]"

Dan Perry
  • 123
  • 6
  • Is it possible to request someone's profile from my contacts while my user is authenticated? – Ievgen Oct 13 '20 at 16:53
2

I banged my head against this for days, since none of the answers seemed to work anymore. What did work and looks more robust against future changes was (it uses jQuery):

<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<script src="https://apis.google.com/js/api.js"></script>
<script type="text/javascript">
function image_attach(GA){
        user=GA.currentUser.get();
        url = user.getBasicProfile().getImageUrl();
        $('#thumbnail').attr('src', url);
}

function google_init() {
    gapi.load('auth2', function() {
            GA = gapi.auth2.init({
                    'client_id': '{YOUR_GOOGLE_CLIENT_ID}',
                    'fetch_basic_profile': true,
            });
            GA.then(function () {
                if (GA.isSignedIn.get()) {
                    image_attach(GA)
                }
                else {
                    GA.signIn().then( function() {
                        image_attach(GA)
                })}
            })
        });
}
</script>

You need a Google OAuth2 client id - see https://developers.google.com/identity/protocols/OAuth2UserAgent for the details. It does not seem to work just with an API Key - from the responses I was getting they have set the quota for unauthenticated access to the API (I.e. just using the Key and not the ClientID) to zero.

The Client ID is available from the cloud console as documented on the link - I think you need to create a project to create the credentials but if you are not using it they will not charge you so that is not a problem.The user does need to be logged in - if not this code will log then in. But if you are not using a Google login for your page anyway - why would you want their thumbnail? Because the image URL is available from the basic user profile . - the API request does not seem to need any particular scope and there is none in the API call in the code.

You will need to identify the url for page that you are calling from as part of your client credentials in the Google console - otherwise the request will be denied. There is a quota - I think it is 20,000 a day - of free API calls after which they will charge you for using the API. That is as much as I can gather.

Paul Harwood
  • 21
  • 1
  • 3
  • 1
    some more explanations would be cool (APIs used, TOKENS or whatever needed) – benzkji May 01 '18 at 13:42
  • You need a Google OAuth2 client id - see https://developers.google.com/identity/protocols/OAuth2WebServer for the details. It does not seem to work just with an API Key - from the responses I was getting they have set the quota for unauthenticated access to the API (I.e. just using the Key and not the ClientID) to zero. – Paul Harwood May 02 '18 at 21:04
  • The Client ID is available from the cloud console as documented on the link - I think you need to create a project to create the credentials but if you are not using it they will not charge you so that is not a problem.The user does need to be logged in - if not this code will log then in. But if you are not using a Google login for your page anyway - why would you want their thumbnail? Because the image URL is available from the basic user profile . - the API request does not seem to need any particular scope and there is none in the API call in the code. – Paul Harwood May 02 '18 at 21:11
  • You will need to identify the url for page that you are calling from as part of your client credentials in the Google console - otherwise the request will be denied. There is a quota - I think it is 20,000 a day - of free API calls after which they will charge you for using the API. That is as much as I can gather. – Paul Harwood May 02 '18 at 21:11
  • Sorry - that link should have been https://developers.google.com/identity/protocols/OAuth2UserAgent for the JS version :( – Paul Harwood May 02 '18 at 21:24
  • Thx! Best would be to integrate this into your answer? – benzkji May 03 '18 at 07:00
1

You can use google app profile API

here is the sample code to access profile pic

function getProfilePic(userName){
  userName = 'yourusername@myDomain.com'; 
  var scope = 'https://www.google.com/m8/feeds/';
  var fetchArgs = googleOAuth_('Profile', scope);
  fetchArgs.method = 'GET';
  var domain = UserManager.getDomain();
  var url = 'https://www.google.com/m8/feeds/photos/profile/'+domain+'/'+userName+'?v=3';
  var rawData = UrlFetchApp.fetch(url, fetchArgs).getContentText();

 //here you get data into rawData variable

}

//google oAuth
function googleOAuth_(name,scope) {
  var oAuthConfig = UrlFetchApp.addOAuthService(name);
  oAuthConfig.setRequestTokenUrl("https://www.google.com/accounts/OAuthGetRequestToken?scope="+scope);
  oAuthConfig.setAuthorizationUrl("https://www.google.com/accounts/OAuthAuthorizeToken");
  oAuthConfig.setAccessTokenUrl("https://www.google.com/accounts/OAuthGetAccessToken");
  oAuthConfig.setConsumerKey("anonymous");
  oAuthConfig.setConsumerSecret("anonymous");
  return {oAuthServiceName:name, oAuthUseToken:"always"};
}

you can get more information here

Satish Shinde
  • 2,878
  • 1
  • 24
  • 41
  • 1
    If i understand right, this API is used for google domains, not for general gmail users. furthermore, its deprecated.. and the new admin api doesn't looks like it solves my problem either. – shaish Sep 10 '14 at 00:02
1

May be too late in answering the question but the best way i found was to first use http://picasaweb.google.com/data/entry/api/user/?alt=json

from the JSON Response you will get author section which has uri: $t: https:picasaweb.google.com/0000000000000

now the numbers at the end is the USER ID which can be used to Retrieve user profile using this API

https:www.googleapis.com/plus/v1/people/userId

Ex: https:www.googleapis.com/plus/v1/people/0000000000000

Ricky
  • 19
  • 1
  • Besides the formatting issues, this answer worked perfectly for me. Also note, that you need a valid access key on the google console to query the last endpoint. `?key=XXX` must be added to that URL. – cameronmoreau Dec 13 '17 at 07:53
  • The Picasa API is deprecated since January 2019. You need to migrate to the Google Photos Library API – Peter Thoeny Aug 15 '20 at 01:23
1

a simple javascript to fetch public profile image from google:

<html>
<body>


<script type="text/javascript">
function getPhoto() {

    var xmlhttp = new XMLHttpRequest();
    xmlhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
        myArr = JSON.parse(this.responseText);
        try { 
            profilePic = myArr["feed"]["entry"][0]["media$group"]["media$thumbnail"][0]["url"]; 
            document.getElementById("demo").innerHTML="<img src='" + profilePic + "' width='160px' height='160px'>"
            }
        catch(err) { }

        }
    }
xmlhttp.open("GET", "https://picasaweb.google.com/data/feed/api/user/<EMAIL>?kind=album&alt=json", true);
xmlhttp.send();
}

</script>

<div id="demo" onclick="javascript:getPhoto();">click here to load photo</div>

</body>
</html>
eyal
  • 19
  • 1
1

Here are most useful links to get google profile picture.

1) Configure a project https://developers.google.com/identity/sign-in/web/sign-in#before_you_begin

2) ENABLE THE GOOGLE PHOTOS LIBRARY API https://developers.google.com/photos/library/guides/get-started

After setting up above steps you will be getting user's profile picture link in response after authentication.

Note: After enabling google photos library API, you also get another Client ID and Client Secret, you can use any of above client secret and client id from above steps. Make sure you should provide a redirect URL in both of above steps so that user can be redirected to that URL after successful authentication.

Hasan Badshah
  • 773
  • 1
  • 6
  • 16
-1

You can try something like :

<?php 
$email = "YOUR_EMAIL_TO_FETCH";
$fetch_profile = "http://picasaweb.google.com/data/entry/api/user/".$email."?alt=json";
    $jsonURL = file_get_contents($fetch_profile);
    $json = json_decode($jsonURL);
    $profile_img = get_object_vars($json->entry);
    $profile_img = get_object_vars($profile_img['gphoto$thumbnail']);
    $profile_img = $profile_img['$t'];
?>

I hope this will work.