I am looking for a way how to change user profile photo programmatically.
Generally, I need to be able to change avatars of domain GSuite users, but if there are API for changing my own avatar is also good.
Had tried already:
- https://developers.google.com/admin-sdk/directory/v1/reference/users/photos/update - this API is working but only changes the small icon of a user in admin panel itself. The main profile picture remains the same.
- https://developers.google.com/people/api/rest/v1/people/updateContactPhoto - this API throws me an error
Resource name "people/10244712xxxxx1564465" is not a valid contact person resource.
when I am trying to replace my own profile image.people/me
also isn't working.
There are Contacts API
, but I am trying to change my own (or impersonated one) profile image, so I believe this API isn't for my case.
If you can point me in some direction to search I'll be very glad. I just do not believe that there is no way to change avatar, it can't be for real.
Update:
Checked Contact API
- also doesn't work, looks like it changes an avatar only on me
in my contact list, nobody else doesn't see changes, and the main profile picture remains the same.
Code:
// admin directory way
const { google } = require('googleapis');
const SafeBase64 = require('url-safe-base64');
const GOOGLE = require(process.env.GOOGLEAPIS_VAULT);
const encodedPhoto = SafeBase64.encode('R0lGODdhBAAEAIABAAMA/////ywAAAAABAAEAAACBkRiYJgHBQA7');
const JWTClient = new google.auth.JWT(
GOOGLE.client_email,
null,
GOOGLE.private_key,
[
'https://www.googleapis.com/auth/admin.directory.user',
],
'gsync@***.com', // sub
);
const directory = google.admin({ version: 'directory_v1', auth: JWTClient });
directory.users.photos.update({}, ctx.params.email);
const res = await directory.users.photos.update({
userKey: ctx.params.email,
resource: {
photoData: encodedPhoto,
},
});
// Contacts API way
const { google } = require('googleapis');
const SafeBase64 = require('url-safe-base64');
const GOOGLE = require(process.env.GOOGLEAPIS_VAULT);
const JWTClient = new google.auth.JWT(
GOOGLE.client_email,
null,
GOOGLE.private_key,
[
'https://www.google.com/m8/feeds/',
],
ctx.params.email, //sub
);
const res1 = await JWTClient.requestAsync({
headers: {
'GData-Version': 3.0,
},
params: {
alt: 'json',
q: 'arsenyp@***.com',
},
url: `https://www.google.com/m8/feeds/contacts/${ctx.params.email}/full`,
});
const contactIdFull = res1.data.feed.entry.filter((c) => c.gd$email[0].address === ctx.params.email)[0].id.$t;
const [, contactId] = /\/base\/([a-z0-9]+)$/.exec(contactIdFull);
// https://www.google.com/m8/feeds/contacts/{userEmail}/full/{contactId}
const res2 = await JWTClient.requestAsync({
headers: {
'GData-Version': 3.0,
},
params: {
alt: 'json',
},
url: `https://www.google.com/m8/feeds/contacts/${ctx.params.email}/full/${contactId}`,
});
const { href: image, gd$etag: etagJ } = res2.data.entry.link.filter((l) => l.rel === 'http://schemas.google.com/contacts/2008/rel#photo')[0];
const res3 = await axios({
method: 'GET',
url: image,
headers: {
Authorization: `Bearer "${(await JWTClient.getAccessTokenAsync()).token}"`,
},
responseType: 'arraybuffer',
});
const etag = JSON.parse(etagJ);
// PUT /m8/feeds/photos/media/default/contactId
// If-match: Etag
// Content-Type: image/*
const res4 = await axios({
method: 'PUT',
url: `https://www.google.com/m8/feeds/photos/media/default/${contactId}`,
headers: {
Authorization: `Bearer "${(await JWTClient.getAccessTokenAsync()).token}"`,
'Content-Type': 'image/png',
},
// responseType: 'arraybuffer',
data: Buffer.from('R0lGODdhBAAEAIABAAMA/////ywAAAAABAAEAAACBkRiYJgHBQA7', 'base64'),
});
// People API way (won't work, throwing an error)
const userId = '1024471xxxxx251564465';
const JWTClient = new google.auth.JWT(
GOOGLE.client_email,
null,
GOOGLE.private_key,
[
'https://www.googleapis.com/auth/contacts',
'profile',
],
ctx.params.email, // sub
);
const people = google.people({ version: 'v1', auth: JWTClient });
const res = await people.people.updateContactPhoto({
resourceName: `people/${userId}`,
resource: {
photoBytes: SafeBase64.encode('R0lGODdhBAAEAIABAAMA/////ywAAAAABAAEAAACBkRiYJgHBQA7'),
personFields: 'photos',
},
sources: [
'READ_SOURCE_TYPE_PROFILE',
],
});