使用Google Contacts API更新联系人照片遇错求助
解决Google Contacts API更新联系人照片的400和404错误
一、Node.js中400 "invalid image file" 错误的解决
我之前也踩过这个坑,核心问题是Axios默认会把响应数据解析成文本格式,而图片是二进制数据,直接传递被文本化处理后的二进制数据会导致文件损坏,服务器自然识别为无效图片。
修正步骤很明确:
- 在
axios.get请求图片时,必须设置responseType: 'arraybuffer',让Axios以二进制数组的形式返回图片数据; - PUT请求时直接传递这个二进制数组,同时确保
Content-Type和图片的实际类型完全匹配。
修正后的代码示例:
const axios = require('axios'); const querystring = require('querystring'); // 先获取授权令牌 axios.post('https://www.googleapis.com/oauth2/v4/token', querystring.stringify(formData), { headers: { "Content-Type": "application/x-www-form-urlencoded" } }).then(function(response) { // 获取图片二进制数据(关键:设置responseType为arraybuffer) axios.get('http://www.pngall.com/wp-content/uploads/2016/07/Facebook-Download-PNG.png', { responseType: 'arraybuffer' }).then(imgRes => { // 发起更新照片的PUT请求 axios.put('https://www.google.com/m8/feeds/photos/media/default/66b5930a931571', imgRes.data, { headers: { 'Content-Type': imgRes.headers['content-type'], 'Authorization': 'Bearer ' + response.data.access_token, 'GData-Version': '3.0' } }).then(updateRes => { console.log('照片更新成功:', updateRes.status); }).catch(err => { console.error('更新失败:', err.response?.data || err.message); }); }).catch(imgErr => { console.error('获取图片失败:', imgErr.message); }); }).catch(tokenErr => { console.error('获取令牌失败:', tokenErr.response?.data || tokenErr.message); });
额外提醒:一定要确认你的授权令牌已经申请了https://www.googleapis.com/auth/contacts的权限,权限不足也会引发各种莫名其妙的报错。
二、Python中gdata库返回404 "Photo not found" 错误的解决
gdata库是比较老旧的Google Data API客户端,官方现在更推荐用google-api-python-client来调用Contacts相关接口。404错误通常有两个核心原因:
- 端点路径不正确:旧的gdata端点需要指定用户邮箱而非
default; - 联系人ID无效,或者该联系人从未设置过照片(部分场景下需要先创建空照片条目再更新)。
更稳妥的方案:使用官方推荐的google-api-python-client实现
先安装依赖:
pip install google-api-python-client google-auth-httplib2 google-auth-oauthlib
然后用以下代码更新联系人照片(用People API替代旧的Contacts API,稳定性更高):
from google.oauth2.credentials import Credentials from googleapiclient.discovery import build import requests # 替换为你的授权凭据(可通过OAuth2流程获取,保存为token.json) creds = Credentials.from_authorized_user_file('token.json', ['https://www.googleapis.com/auth/contacts']) # 构建People API客户端 service = build('people', 'v1', credentials=creds) # 获取图片二进制数据 img_url = 'http://www.pngall.com/wp-content/uploads/2016/07/Facebook-Download-PNG.png' img_response = requests.get(img_url) img_data = img_response.content # 更新联系人照片 contact_id = '66b5930a931571' try: service.people().updateContactPhoto( resourceName=f'people/{contact_id}', body={'photoBytes': img_data}, updatePersonFields='photos' ).execute() print("照片更新成功!") except Exception as e: print(f"更新失败: {e}")
如果一定要坚持用gdata库,需要注意:
- 端点路径改为
https://www.google.com/m8/feeds/photos/media/{your_email}/{contact_id},替换{your_email}为授权用户的邮箱; - 提前确认联系人ID正确,且该联系人确实存在;
- 请求头必须包含
GData-Version: 3.0。
通用注意事项
- 确保图片格式是Google支持的类型(JPEG、PNG为主,尽量避免WebP等小众格式);
- 如果是更新已有照片,可能需要添加
If-Match头,值为现有照片的ETag(可通过GET请求获取照片时拿到); - 授权流程中,必须申请正确的权限范围(写联系人照片需要
https://www.googleapis.com/auth/contacts权限,只读权限无法完成更新)。
内容的提问来源于stack exchange,提问作者yonatan kreiner
相关产品推荐
相关产品推荐

