pythonservice-accountspresentationgoogle-slides-apigoogle-slides

Replacing google slides images using slides api


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


Solution

  • From your question, I guessed the following issues.

    1. Image files that are not publicly shared might be included.
    2. Image files that are over the maximum image size might be included. Ref

    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?

    Modified script:

    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()
    

    Note:

    Reference