Search code examples
pythongoogle-drive-apigoogle-slides-api

unable to copy a google slide file using google drive api


I want to copy an existing template ppt present in my google drive. Then I want to change the placeholder text to some other text.

here is what I am trying.

from google.oauth2 import service_account
import googleapiclient.discovery


SCOPES = (
    'https://www.googleapis.com/auth/drive',
    'https://www.googleapis.com/auth/presentations',
)
SERVICE_ACCOUNT_FILE = 'cred.json'

credentials = service_account.Credentials.from_service_account_file(
        SERVICE_ACCOUNT_FILE, scopes=SCOPES) 

SLIDES = discovery.build('slides', 'v1', credentials=credentials)
DRIVE  = discovery.build('drive',  'v3', credentials=credentials)

TMPLFILE = 'title slide template' 

rsp = DRIVE.files().list(q="name='%s'" % TMPLFILE).execute().get('files')[0]
print(rsp)
DATA = {'name': 'Google Slides API template DEMO'}
print('** Copying template %r as %r' % (rsp['name'], DATA['name']))
DECK_ID = DRIVE.files().copy(body=DATA, fileId=rsp['id']).execute().get('id')
print(DECK_ID)

print('** Replacing placeholder text')

reqs = [
    {'replaceAllText': {
        'containsText': {'text': '{{text}}'},
        'replaceText': final_til[0]
    }},
]

SLIDES.presentations().batchUpdate(body={'requests': reqs},
        presentationId=DECK_ID).execute()
print('DONE')

But it is not working. I don't get any error. everything works fine but I don't see the new ppt.

Output:

{'kind': 'drive#file', 'id': '15mVjkrT7PkckKetK_q9aYRVxaDcwDdHpAh7xjrAWB6Q', 'name': 'title slide template', 'mimeType': 'application/vnd.google-apps.presentation'}  <--- rsp
** Copying template 'title slide template' as 'Google Slides API template DEMO'
11O97tySSNaboW6YRVD62Q7HLs8aVuS2pWyLYXImdSec   <-- DECK_ID
** Replacing placeholder text
DONE

If I change

SLIDES.presentations().batchUpdate(body={'requests': reqs},
            presentationId=DECK_ID).execute()

to

SLIDES.presentations().batchUpdate(body={'requests': reqs},
            presentationId=rsp.get('id')).execute()

then it does replace the text but in my template file which I don't want.

Why is this happening?


Solution

  • I believe your current situation and goal as follows.

    • From your script,
      • You are using googleapis for python.
      • You have already been able to use Drive API and Slides API using the service account.
      • an existing template ppt present is a Google Slides which is not the PowerPoint file.

    Modification points:

    • From your script and But it is not working. I don't get any error. everything works fine but I don't see the new ppt., I understood that you might want to see the Google Slides copied by the service account at your Google Drive.

      • When the Google Slides is copied by the service account, the copied Google Slides is put to the Drive of the service account. The Drive of service account is different from your Google Drive. By this, you cannot see the copied Google Slides on your Drive. I thought that this might be the reason of your issue.
    • In order to see the Google Slides copied by the service account at your Google Drive, for example, the following workarounds can be used.

      1. Share the copied Google Slides with your email of Google account.
        • In this case, you can see the shared file at the shared folder.
      2. At first, it creates new folder in your Google Drive and share the folder with the email of the service account. And when the Google Slides is copied, it sets the shared folder as the destination folder.

    Workaround 1:

    In this workaround, it shares the copied Google Slides with your email of Google account. When this is reflected to your script, it becomes as follows.

    Modified script:

    In this case, new permission is created to the copied file using "Permissions: create".

    From:
    print(DECK_ID)
    
    print('** Replacing placeholder text')
    
    To:
    print(DECK_ID)
    
    permission = {
        'type': 'user',
        'role': 'writer',
        'emailAddress': '###@gmail.com'  # <--- Please set the email of your Google account.
    }
    DRIVE.permissions().create(fileId=DECK_ID, body=permission).execute()
    
    print('** Replacing placeholder text')
    

    Workaround 2:

    In this workaround, the Google Slides is copied to the shared folder in your Google Drive. Before you use this script, please create new folder and share the folder with the email of service account. When this is reflected to your script, it becomes as follows.

    Modified script:

    In this case, the metadata is added to the request body of DRIVE.files().copy().

    From:
    DATA = {'name': 'Google Slides API template DEMO'}
    
    To:
    DATA = {'name': 'Google Slides API template DEMO', 'parents': ['###']}
    
    • Please set the folder ID of shared folder to ###.

    References: