英文:
Access to the provided image was forbidden using batchUpdate of Google Docs REST API
问题
我正在使用Google Docs REST API的batchUpdate功能来替换文档中的图片。当我第一次创建代码时,出现了权限错误,我看到了一些解决这个问题的帖子:
- https://stackoverflow.com/questions/63309338/using-google-docs-api-to-insert-image-from-google-drive
- https://stackoverflow.com/questions/70311191/access-to-the-provided-image-was-forbidden-even-though-it-was-uploaded-from-the
这段代码一直在运行,但是不知何故,过了一段时间后,我仍然会遇到相同的错误,尽管没有任何变化。我使用的图片仍然是公开共享的(任何有链接的人都可以访问)。
我需要使用一个服务帐号来解决这个问题。
我得到的错误信息:
error={message=Invalid requests[12].replaceImage: Access to the provided image was forbidden., code=400.0, status=INVALID_ARGUMENT}
我的代码片段:
function postGoogleAPI(url, payload){
var service = getOAuthService();
service.reset();
var response = UrlFetchApp.fetch(url, {
method: "POST",
contentType : "application/json",
headers: {
Authorization: 'Bearer ' + service.getAccessToken() // 获取访问令牌的函数
},
payload: JSON.stringify(payload),
muteHttpExceptions: true
});
return JSON.parse(response);
}
function getGoogleAPI(url) {
var service = getOAuthService();
service.reset();
var response = UrlFetchApp.fetch(url, {
headers: {
Authorization: 'Bearer ' + service.getAccessToken() // 获取访问令牌的函数
},
muteHttpExceptions: true
});
return response;
}
function getReplaceImageRequest(imageFileId, docsFileId, mergeField) {
let requestData = [];
let url = Utilities.formatString("https://www.googleapis.com/drive/v3/files/%s?supportsAllDrives=true&fields=webContentLink", imageFileId);
let response = getGoogleAPI(url);
let logoUri = JSON.parse(response).webContentLink
url = Utilities.formatString("https://docs.googleapis.com/v1/documents/%s?fields=inlineObjects", docsFileId);
response = getGoogleAPI(url);
let inlineObjects = JSON.parse(response.getContentText());
for(const key in inlineObjects.inlineObjects){
let title = inlineObjects.inlineObjects[key].inlineObjectProperties.embeddedObject.title;
if(title != null && title == mergeField){
requestData.push({
"replaceImage": {
"imageObjectId": key,
"uri": logoUri,
"imageReplaceMethod": "CENTER_CROP"
}
});
}
}
return requestData;
}
getReplaceImageRequest(<图片文件的ID>, <文档文件的ID>, <合并字段的标识符>);
let url = "https://docs.googleapis.com/v1/documents/<文档文件的ID>:batchUpdate";
let payload = {
"requests" : requests
}
let response = postGoogleAPI(url, payload); // 错误发生在这里
我已经尝试手动重置了通用访问类型,但没有成功。如果我上传一个新图片,它可以正常工作。
总结一下,这段代码在某个时候停止工作,即使图片仍然是可访问的,访问类型仍然设置为“任何有链接的人”。希望有人能帮忙,提前感谢!
英文:
I'm using Google Docs REST API batchUpdate to replace images in a Docs file. When I first created the code, I had a permission error and I saw a couple of posts that actually solved this:
- https://stackoverflow.com/questions/63309338/using-google-docs-api-to-insert-image-from-google-drive
- https://stackoverflow.com/questions/70311191/access-to-the-provided-image-was-forbidden-even-though-it-was-uploaded-from-the
This has been working, but for some reason after some time I get the same error even though nothing has changed. The image I used is still shared publicly (Anyone with the link).
I need to use a service account for this one.
The error I get:
error={message=Invalid requests[12].replaceImage: Access to the provided image was forbidden., code=400.0, status=INVALID_ARGUMENT}
My code snippet:
function postGoogleAPI(url, payload){
var service = getOAuthService();
service.reset();
var response = UrlFetchApp.fetch(url, {
method: "POST",
contentType : "application/json",
headers: {
Authorization: 'Bearer ' + service.getAccessToken() // a function that gets the access token
},
payload: JSON.stringify(payload),
muteHttpExceptions: true
});
return JSON.parse(response);
}
function getGoogleAPI(url) {
var service = getOAuthService();
service.reset();
var response = UrlFetchApp.fetch(url, {
headers: {
Authorization: 'Bearer ' + service.getAccessToken() // a function that gets the access token
},
muteHttpExceptions: true
});
return response;
}
function getReplaceImageRequest(imageFileId, docsFileId, mergeField) {
let requestData = [];
let url = Utilities.formatString("https://www.googleapis.com/drive/v3/files/%s?supportsAllDrives=true&fields=webContentLink", imageFileId);
let response = getGoogleAPI(url);
let logoUri = JSON.parse(response).webContentLink
url = Utilities.formatString("https://docs.googleapis.com/v1/documents/%s?fields=inlineObjects", docsFileId);
response = getGoogleAPI(url);
let inlineObjects = JSON.parse(response.getContentText());
for(const key in inlineObjects.inlineObjects){
let title = inlineObjects.inlineObjects[key].inlineObjectProperties.embeddedObject.title;
if(title != null && title == mergeField){
requestData.push({
"replaceImage": {
"imageObjectId": key,
"uri": logoUri,
"imageReplaceMethod": "CENTER_CROP"
}
});
}
}
return requestData;
}
getReplaceImageRequest(<id of image file>, <Docs file id>, <identifier of merge field>);
let url = "https://docs.googleapis.com/v1/documents/<id of Docs file>:batchUpdate";
let payload = {
"requests" : requests
}
let response = postGoogleAPI(url, payload); // Error occurs here
I've tried manually resetting the general access type with no success. If I upload a new image, it works though.
So in summary, the code works until for some reason the image is not accessible anymore, even with access type still set to 'Anyone with the link'.
I hope anyone can help here, thanks in advance!
答案1
得分: 1
我认为我解决了这个问题,至少到目前为止我的更新没有失败。问题出在获取图片链接的代码中(/?supportsAllDrives=true&fields=webContentLink)。我将它更改为/?supportsAllDrives=true&fields=thumbnailLink,目前这样可以正常工作。因此,由于某种原因,webContentLink字段的值在一段时间后发生了变化,导致了我遇到的错误。
英文:
I think I solved the problem, at least my update has not failed so far. The problem was in the code that gets the link of the image (/?supportsAllDrives=true&fields=webContentLink). I changed it to /?supportsAllDrives=true&fields=thumbnailLink and this works so far. So for some reason the webContentLink field value changes after some time, and results in the error I encountered.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论