Last active
March 23, 2021 10:54
-
-
Save mhawksey/b5e3e2b60f1927c6994f9071922fc77c to your computer and use it in GitHub Desktop.
Port of Wesley Chun's 'Using the Google Slides API with Python' to Google Apps Script. Read more at https://mashe.hawksey.info/?p=17385
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Port of Slides API demo by Wesley Chun to Google Apps Script | |
// Source: http://wescpy.blogspot.co.uk/2016/11/using-google-slides-api-with-python.html | |
function slides_template() { | |
/* | |
from apiclient import discovery | |
from httplib2 import Http | |
from oauth2client import file, client, tools | |
*/ | |
/* DIFF | |
No comand line imports but some setup required. | |
1. Resources > Advance Services and enable the Slides API | |
[Also change the identifier in the Libraries dialog to SLIDES to make it easy to compare to Wesley's code | |
2. Resources > Developer Console Project click on the project link and enable Slides API | |
*/ | |
var IMG_FILE = 'logo_slides_128px.png' // use your own or copy https://goo.gl/hJwcoa ! | |
var TMPLFILE = 'Google Slides API template DEMO' // use your own or use https://goo.gl/FdQ9AH ! | |
/* | |
SCOPES = ( | |
'https://www.googleapis.com/auth/drive', | |
'https://www.googleapis.com/auth/presentations', | |
) | |
store = file.Storage('storage.json') | |
creds = store.get() | |
if not creds or creds.invalid: | |
flow = client.flow_from_clientsecrets('client_secret.json', SCOPES) | |
creds = tools.run_flow(flow, store) | |
HTTP = creds.authorize(Http()) | |
DRIVE = discovery.build('drive', 'v3', http=HTTP) | |
SLIDES = discovery.build('slides', 'v1', http=HTTP) | |
*/ | |
/* DIFF | |
Tip by Romain Vialard that if you use DriveApp you can use the project token | |
Running the function also automatically triggers any authorization required | |
https://plus.google.com/u/0/+MartinHawksey/posts/aPEdvRiFV9Y | |
*/ | |
// SLIDES.setTokenService(function(){return ScriptApp.getOAuthToken()}); | |
/* | |
rsp = DRIVE.files().list(q="name='%s'" % TMPLFILE).execute().get('files')[0] | |
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') | |
*/ | |
/* DIFF | |
As Google Apps Script has built-in DriveApp service we can use this to get out template | |
and copy it | |
*/ | |
Logger.log('** Copying template **'); | |
var DECK_ID = DriveApp.getFilesByName(TMPLFILE).next().makeCopy().getId(); | |
/* | |
print('** Get slide objects, search for image placeholder') | |
slide = SLIDES.presentations().get(presentationId=DECK_ID, | |
fields='slides').execute().get('slides')[0] | |
obj = None | |
for obj in slide['pageElements']: | |
if obj['shape']['shapeType'] == 'RECTANGLE': | |
break | |
*/ | |
/* DIFF | |
None really other than a slighlty difference call and port from py to js | |
*/ | |
Logger.log('** Get slide objects, search for image placeholder'); | |
// var slide = SLIDES.presentationsGet(DECK_ID).slides[0]; | |
var slide = SLIDES.Presentations.get(DECK_ID).slides[0]; | |
var obj | |
for (var i in slide['pageElements']){ | |
var obj = slide['pageElements'][i]; | |
if (obj['shape']['shapeType'] == 'RECTANGLE'){ | |
break; | |
} | |
} | |
/* | |
print('** Searching for icon file') | |
rsp = DRIVE.files().list(q="name='%s'" % IMG_FILE).execute().get('files')[0] | |
print(' - Found image %r' % rsp['name']) | |
img_url = '%s&access_token=%s' % ( | |
DRIVE.files().get_media(fileId=rsp['id']).uri, creds.access_token) | |
*/ | |
/* DIFF | |
Using built-in DriveApp. The 'https://drive.google.com/uc?id=XXX' tip | |
thanks to Romain Vialard https://plus.google.com/+MartinHawksey/posts/aaMshWDR1PZ | |
*/ | |
Logger.log('** Searching for icon file'); | |
var rsp = DriveApp.getFilesByName(IMG_FILE).next(); | |
Logger.log(Utilities.formatString(' - Found image %s', rsp.getId())); | |
// var img_url = 'https://drive.google.com/uc?id='+rsp.getId(); // requires share access | |
var img_url = rsp.getDownloadUrl()+"&access_token="+ScriptApp.getOAuthToken(); | |
/* | |
print('** Replacing placeholder text and icon') | |
reqs = [ | |
{'replaceAllText': { | |
'containsText': {'text': '{{NAME}}'}, | |
'replaceText': 'Hello World!' | |
}}, | |
{'createImage': { | |
'url': img_url, | |
'elementProperties': { | |
'pageObjectId': slide['objectId'], | |
'size': obj['size'], | |
'transform': obj['transform'], | |
} | |
}}, | |
{'deleteObject': {'objectId': obj['objectId']}}, | |
] | |
*/ | |
/* DIFF | |
None other than Logger | |
*/ | |
Logger.log('** Replacing placeholder text and icon'); | |
var reqs = [ | |
{'replaceAllText': { | |
'containsText': {'text': '{{NAME}}'}, | |
'replaceText': 'Hello World!' | |
}}, | |
{'createImage': { | |
'url': img_url, | |
'elementProperties': { | |
'pageObjectId': slide['objectId'], | |
'size': obj['size'], | |
'transform': obj['transform'], | |
} | |
}}, | |
{'deleteObject': {'objectId': obj['objectId']}}, | |
]; | |
/* | |
SLIDES.presentations().batchUpdate(body={'requests': reqs}, | |
presentationId=DECK_ID).execute() | |
*/ | |
/* DIFF | |
Slightly different call presentationsBatchUpdate(presentationId,BatchUpdatePresentationRequestResource,options) | |
*/ | |
// SLIDES.presentationsBatchUpdate(DECK_ID, {'requests': reqs}); | |
SLIDES.Presentations.batchUpdate({'requests': reqs}, DECK_ID); | |
Logger.log('DONE '); | |
} |
Figured out I could use this instead
`var reqs = [
{"replaceAllShapesWithImage": {
"imageUrl": img_url,
"replaceMethod": "CENTER_CROP",
"containsText": {
"text": "Main_Image",
"matchCase": "True",
}
},},`
ReferenceError: "SLIDES" is not defined.
at slides_template(Playground:95)
it should be written as "Slides" instead of "SLIDES", e.g.
SLIDES.Presentations.batchUpdate({'requests': reqs}, DECK_ID);
-> correct:
Slides.Presentations.batchUpdate({'requests': reqs}, DECK_ID);
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thank you for this! I was having a hard time getting started on the slides API. I do have a question though. When I run this with my own slide template and photo it seems as though the photo ends up being skewed and smaller than the original shape. Is there a way to have it center crop the photo into the shape? I've been messing with the transform parameter a bit but don't seem to understand how it works.