I have the following scripts to update the images in google slides, it works fine but sometimes it gives me 400 error, service account has a write permission to the drive/images and the presentation
image_mappings = {
"id_in_presenation": "name_of_the_image",
"id_in_presenation1": "name_of_the_image1",
}
# listing .png files
def get_png_files(drive_folder_id, drive_service):
query = f"'{drive_folder_id}' in parents and mimeType='image/png'"
results = drive_service.files().list(q=query, supportsAllDrives=True, fields="files(id, name, webViewLink, webContentLink)").execute()
drive_png_files = results.get('files', [])
print('drive_png_files', drive_png_files)
return drive_png_files`
# updating images in slides
def update_images_in_slides(drive_png_files, slides_service, presentation_id):
"""
Updates images in a Google Slides presentation.
Args:
drive_png_files: A list of .png files from Google Drive.
slides_service: The authenticated Google Slides service object.
presentation_id: The ID of the presentation to update.
"""
requests = []
for slide_image_id, new_image_name in info.image_mappings.items():
drive_file = next((item for item in drive_png_files if item['name'] == new_image_name), None)
if drive_file:
requests.append({
'replaceImage': {
'imageObjectId': slide_image_id,
'imageReplaceMethod': 'CENTER_INSIDE',
'url': f'https://drive.google.com/uc?id={drive_file["id"]}'
}
})
if requests:
body = {'requests': requests}
try:
response = slides_service.presentations().batchUpdate(presentationId=presentation_id, body=body).execute()
time.sleep(10)
print(f"\nUpdated the slide: {response}")
except Exception as exc:
raise ValueError(f"Failed to update the presentation.") from exc
gave editor and writer access permission to the service account for the drives, images, presentation did not help
From your question, I guessed the following issues.
When these issues occur, an error of the status code 400 occurs. But, unfortunately, I cannot know your actual error message from your question. When my guess was correct, how about the following modification?
In this modification, your function update_images_in_slides
is modified.
In order to use Drive API, drive_service
is added to the last argument. Please be careful about this.
def update_images_in_slides(drive_png_files, slides_service, presentation_id, drive_service):
"""
Updates images in a Google Slides presentation.
Args:
drive_png_files: A list of .png files from Google Drive.
slides_service: The authenticated Google Slides service object.
presentation_id: The ID of the presentation to update.
"""
# Images are publicly shared for inserting to Slide.
batch1 = drive_service.new_batch_http_request()
for e in drive_png_files:
batch1.add(drive_service.permissions().create(fileId=e["id"], body={"type": "anyone", "role": "reader"}, supportsAllDrives=True))
batch1.execute()
requests = []
for slide_image_id, new_image_name in info.image_mappings.items():
drive_file = next((item for item in drive_png_files if item['name'] == new_image_name), None)
if drive_file:
requests.append({
'replaceImage': {
'imageObjectId': slide_image_id,
'imageReplaceMethod': 'CENTER_INSIDE',
# 'url': f'https://drive.google.com/uc?id={drive_file["id"]}'
'url': f'https://drive.google.com/thumbnail?sz=w1000&id={drive_file["id"]}'
}
})
if requests:
body = {'requests': requests}
try:
response = slides_service.presentations().batchUpdate(presentationId=presentation_id, body=body).execute()
time.sleep(10)
print(f"\nUpdated the slide: {response}")
except Exception as exc:
raise ValueError(f"Failed to update the presentation.") from exc
# Permission of publicly shared images is removed.
batch2 = drive_service.new_batch_http_request()
for e in drive_png_files:
batch2.add(drive_service.permissions().delete(fileId=e["id"], permissionId="anyoneWithLink", supportsAllDrives=True))
batch2.execute()
This modified script supposes that your values of drive_png_files, slides_service, presentation_id, drive_service
and info.image_mappings
are valid values. Please be careful about this.
In this modification, the following flow is used.
I cannot know your current scopes. So, when an error is related to the scopes, please add a scope of https://www.googleapis.com/auth/drive
to your current scope, and test it again. Please be careful about this.
If the image sizes of all images are varied sizes, I guess that 'url': f'https://drive.google.com/uc?id={drive_file["id"]}'
might be able to be used.