I'm trying to replace a Google slides shape filled with a placeholder text with an image via API. The image in question is allocated in a team Drive unit. I've read several solutions like this and this, and I have tried to set the permissions in the image as "reader" and "anyone with link", both via API and manually, and nothing works. I get a "Access to the provided image was forbidden" error everytime. However, I can download the image wihout problems via API and without giving extra permissions. I'm using v3 of the Drive API and v1 for Slides API.
Below is the code I'm using:
def replace_shape_with_image(slides_service, url, presentation_id, contains_text):
requests = [
{
"replaceAllShapesWithImage": {
"imageUrl": url,
"replaceMethod": "CENTER_INSIDE",
"containsText": {
"text": "{{" + contains_text + "}}",
}
}
}]
body = {
'requests': requests
}
response = slides_service.presentations().batchUpdate(presentationId=presentation_id,body=body).execute()
return response
def create_public_permissions(drive_service, file_id):
request = drive_service.permissions().create(
fileId=file_id,
supportsAllDrives=True,
fields='id, type, role',
body={
'role':'reader',
'type':'anyone'
}
)
response = request.execute()
return response
file_id = '123'
presentation_id = '789'
# drive_service = etc
# slides_service = etc
create_public_permissions(drive_service, file_id) # Here I put the actual service object and file ID. Manually verified and it works
url = f'https://drive.google.com/uc?export=download&id={file_id}'
# also tried url = https://drive.google.com/uc?id={file_id}&export=download
replace_shape_with_image(slides_service, url, presentation_id, 'test') # shape in slide has "test" as text
The following error is returned:
googleapiclient.errors.HttpError: <HttpError 400 when requesting https://slides.googleapis.com/v1/presentations/1cDSov4IKFHSyzaXjFYNYPB7EYlMMtInamYv0AwXiazw:batchUpdate?alt=json returned "Invalid requests[0].replaceAllShapesWithImage: Access to the provided image was forbidden.">
For downloading the file I use this code, which works without problem:
import io
from googleapiclient.http import MediaIoBaseDownload
tmp_file_path = r'C:\Users\me\tmp\testimage.png'
fh = io.FileIO(tmp_file_path, 'wb')
downloader = MediaIoBaseDownload(fh, request)
done = False
while done is False:
status, done = downloader.next_chunk()
I know there have been changes in the Drive API recently (over the last year), and most questions about this are old and the solutions are deprecated, and more recent ones doesn't seem to work for me. Any ideas in how to solve this issue, if possible?
Thanks in advance!