Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
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
// 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 ');
}
@amullins65

This comment has been minimized.

Copy link

commented Jan 4, 2017

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.

@amullins65

This comment has been minimized.

Copy link

commented Jan 4, 2017

Figured out I could use this instead

`var reqs = [

{"replaceAllShapesWithImage": {

"imageUrl": img_url,
"replaceMethod": "CENTER_CROP",
"containsText": {
"text": "Main_Image",
"matchCase": "True",
}
},},`

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.