如何通过 API 更改 google 头像?
How to change google profile picture via API?
我正在寻找一种如何以编程方式更改用户个人资料照片的方法。
一般来说,我需要能换域GSuite用户的头像,不过如果有API换自己的头像也不错
已经尝试过:
- https://developers.google.com/admin-sdk/directory/v1/reference/users/photos/update - 此 API 有效,但仅更改管理面板本身中用户的小图标。主头像保持不变。
- https://developers.google.com/people/api/rest/v1/people/updateContactPhoto - 当我尝试替换我自己的个人资料图片时,这个 API 抛出一个错误
Resource name "people/10244712xxxxx1564465" is not a valid contact person resource.
。 people/me
也不起作用。
有 Contacts API
,但我正在尝试更改我自己的(或假冒的)个人资料图片,所以我认为这 API 不适合我的情况。
如果您能指出我搜索的方向,我将非常高兴。我就是不相信没有办法换头像,不可能是真的。
更新:
已检查 Contact API
- 也不起作用,看起来它只更改了我联系人列表中 me
的头像,其他人看不到更改,主要个人资料图片保留一样。
代码:
// 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',
],
});
好的,正如@Sudhakar 所说,没有这样的 API。
但我发现 admin 目录 API 实际上改变了大部分地方的配置文件。
技巧在于,用户需要手动从 https://aboutme.google.com/ Profile picture
中删除头像,因为这张照片相对于管理目录具有最高优先级。
如果用户从 aboutme.google.com 中删除照片,然后通过管理目录 v1 更改它 API 可以在日历、Gmail、通讯录中看到这张照片...
所以检查我的第一个代码示例:
// 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 targerUser = 'arsenyp@***.com';
const JWTClient = new google.auth.JWT(
GOOGLE.client_email,
null,
GOOGLE.private_key,
[
'https://www.googleapis.com/auth/admin.directory.user',
],
'gsync@***.com', // sub - this is service user with proper permissions, not a target user
);
const directory = google.admin({ version: 'directory_v1', auth: JWTClient });
directory.users.photos.update({}, targerUser);
const res = await directory.users.photos.update({
userKey: targerUser,
resource: {
photoData: encodedPhoto,
},
});
我正在寻找一种如何以编程方式更改用户个人资料照片的方法。
一般来说,我需要能换域GSuite用户的头像,不过如果有API换自己的头像也不错
已经尝试过:
- https://developers.google.com/admin-sdk/directory/v1/reference/users/photos/update - 此 API 有效,但仅更改管理面板本身中用户的小图标。主头像保持不变。
- https://developers.google.com/people/api/rest/v1/people/updateContactPhoto - 当我尝试替换我自己的个人资料图片时,这个 API 抛出一个错误
Resource name "people/10244712xxxxx1564465" is not a valid contact person resource.
。people/me
也不起作用。
有 Contacts API
,但我正在尝试更改我自己的(或假冒的)个人资料图片,所以我认为这 API 不适合我的情况。
如果您能指出我搜索的方向,我将非常高兴。我就是不相信没有办法换头像,不可能是真的。
更新:
已检查 Contact API
- 也不起作用,看起来它只更改了我联系人列表中 me
的头像,其他人看不到更改,主要个人资料图片保留一样。
代码:
// 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',
],
});
好的,正如@Sudhakar 所说,没有这样的 API。
但我发现 admin 目录 API 实际上改变了大部分地方的配置文件。
技巧在于,用户需要手动从 https://aboutme.google.com/ Profile picture
中删除头像,因为这张照片相对于管理目录具有最高优先级。
如果用户从 aboutme.google.com 中删除照片,然后通过管理目录 v1 更改它 API 可以在日历、Gmail、通讯录中看到这张照片...
所以检查我的第一个代码示例:
// 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 targerUser = 'arsenyp@***.com';
const JWTClient = new google.auth.JWT(
GOOGLE.client_email,
null,
GOOGLE.private_key,
[
'https://www.googleapis.com/auth/admin.directory.user',
],
'gsync@***.com', // sub - this is service user with proper permissions, not a target user
);
const directory = google.admin({ version: 'directory_v1', auth: JWTClient });
directory.users.photos.update({}, targerUser);
const res = await directory.users.photos.update({
userKey: targerUser,
resource: {
photoData: encodedPhoto,
},
});