Image and Data Merge Sheets to Slides Apps Script - Update - google-apps-script

I 'm very new to both Apps Script and coding in general.
I'm trying to take a google slides presentation, and merge with a csv to create multiple images.
I cannot get the merge function to work. I'm pretty sure I am not loading the csv data correctly - I can get it to show the data range in the execution log but it does not merge into the new presentation. I know I have my tags correct, because I've used them in a 3rd party extension and it works.
I know I'm probably just missing something stupid, but I cannot figure it out. Any help would be appreciated!
Below is the code I currently have:
Update 1
I was able to figure out how to call the data correctly, and am now able to replace the text correctly. However, when I use replaceAllShapesWithImage I get the following error:
GoogleJsonResponseException: API call to slides.presentations.batchUpdate failed with error: Invalid requests[2].replaceAllShapesWithImage: There was a problem retrieving the image. The provided image should be publicly accessible, within size limit, and in supported formats.
The images are being called from google drive, and are accessible by anyone with the link. Any ideas? Updated code below:
const spreadsheetId = '1JSXC0XrfUAtcRLXCgVnB-SAQjwk_-YG7W_kGefowONE';
const thetemplateId = '1Pug2cPiGsPL9iKPEnBAhvBVqfSTMyJERCRaSGkyFOr0';
const dataRange = 'Monthly Top Producers!A2:F';
function generateTopPro(){
var Presentation=SlidesApp.openById(thetemplateId);
let values = SpreadsheetApp.openById(spreadsheetId).getRange(dataRange).getValues();
for (let i = 0; i < values.length; ++i) {
const row = values[i];
const agent_name = row[0]; // name in column 1
const agent_phone = row[3]; // phone in column 4
const agent_photo = row[4]; // agent photo url column 5
const logo_state = row[5]; // state logo url column 6
// Duplicate the template presentation using the Drive API.
const copyTitle = agent_name + ' September';
let copyFile = {
title: copyTitle,
parents: [{id: 'root'}]
};
copyFile = Drive.Files.copy(copyFile, templateId);
const presentationCopyId = copyFile.id;
// Create the text merge (replaceAllText) requests for this presentation.
const requests = [{
replaceAllText: {
containsText: {
text: '{{agent_name}}',
matchCase: true
},
replaceText: agent_name
}
}, {
replaceAllText: {
containsText: {
text: '{{agent_phone}}',
matchCase: true
},
replaceText: agent_phone
}
}, {
replaceAllShapesWithImage: {
imageUrl: agent_photo,
imageReplaceMethod: 'CENTER_INSIDE',
containsText: {
text: '{{agent_photo}}',
matchCase: true
}
}
}, {
replaceAllShapesWithImage: {
imageUrl: logo_state,
imageReplaceMethod: 'CENTER_INSIDE',
containsText: {
text: '{{logo_state}}',
matchCase: true
}
}
}];
// Execute the requests for this presentation.
const result = Slides.Presentations.batchUpdate({
requests: requests
}, presentationCopyId);
// Count the total number of replacements made.
let numReplacements = 0;
result.replies.forEach(function(reply) {
numReplacements += reply.replaceAllText.occurrencesChanged;
});
console.log('Created presentation for %s with ID: %s', agent_name, presentationCopyId);
console.log('Replaced %s text instances', numReplacements);
}
}

There was a problem retrieving the image. The provided image should be publicly accessible, within size limit, and in supported formats is a known issue when trying to use an image from Google Drive
See for example Google slides API replaceAllShapesWithImage returns error for Google Drive file (2020)
There are workarounds like Google script replaceAllShapesWithImage with image from drive doesn"t work any more that work for some users/ images but not always.
There are several related issues filed on Google's Issue Tracker and a feature request asking for a full support of the functionality.
If no workaround work for you, the only two things you can do in the current state are:
"Star" the feature request to increase visibility which will hopefully accelerate implementation
Use the thumbnailLink that oyu can retrieve with Files: get as imageUrl - this gives you an image in low quality, but better than nothing

Related

Swap Google Doc images with new images from Google Drive

I have a Google Doc with images (let's say 4 but in reality there are many). I want to replace those with four new images available in Google Drive. I know I can get all images available in the Doc as:
var images = docFile.getBody().getImages();
All are InlineImage when displayed on the console, although a few are in the paragraph and others are inside table cells. The logic I have in my mind is:
Getting the list of images (as done above)
Getting the location of those images (Don't know how)
Delete the image and use appendImage method.
The exact code I tried is:
function imageExtract() {
const tempFile = DocumentApp.openById(idOfFile) //idOfFile is id of Doc file
var images = tempFile.getBody().getImages();
const blob=DriveApp.getFileById(idOfImage) //idOfImage is id of Doc file
for (var i = 0; i < images.length; i++){
Logger.log(images[i].getAttributes())
Logger.log(images[i])
// Here I want to delete the images[i]
// And put blob there
}
}
I believe your current situation and your goal are as follows.
Your Google Document has 4 images. The images are put into the paragraph, list, and table.
You have a list including 4 URLs of the direct links of image data.
You want to replace 1st image in Google Document with the 1st URL of the list.
You want to achieve this using Google Apps Script.
I thought that in this case, when Google Docs API is used, the script might be simple. So, how about the following sample script?
Sample script:
This script uses Google Docs API. So, please enable Docs API at Advanced Google services.
function myFunction() {
// Please set your 4 URLs.
const urls = [
"https://url1",
"https://url2",
"https://url3",
"https://url4",
];
// Retrieve the original title of images and set the unique image titles using Docs API.
const doc = DocumentApp.getActiveDocument();
const images = doc.getBody().getImages();
const titles = images.reduce((m, e, i) => {
const org = e.getAltTitle();
e.setAltTitle(`sample${i}`);
m.set(`sample${i}`, { title: org, uri: urls[i] });
return m;
}, new Map());
doc.saveAndClose();
// Create request body of Docs API.
const { inlineObjects } = Docs.Documents.get(doc.getId(), { fields: "inlineObjects" });
const requests = Object.entries(inlineObjects).reduce((ar, [imageObjectId, { inlineObjectProperties: { embeddedObject } }]) => {
if (embeddedObject.hasOwnProperty("imageProperties")) {
const { uri } = titles.get(embeddedObject.title);
ar.push({ replaceImage: { imageObjectId, uri } });
}
return ar;
}, []);
// Request Docs API using the created request body.
Docs.Documents.batchUpdate({ requests }, doc.getId());
// Set the original titles to the images.
const ar = [...titles];
DocumentApp.getActiveDocument().getBody().getImages().forEach((e, i) => e.setAltTitle(ar[i][1].title));
}
When this script is run, 4 images in Google Document are replaced with the images of 4 URLs.
References:
Method: documents.batchUpdate
ReplaceImageRequest
Added:
I think that your provided sample Document and your provided current script have 2 issues.
When I saw your sample Document, I saw 4 images. But, when I retrieve the images using Google Docs API, 5 images are existing. It seems that one image is not shown. Unfortunately, the reason for TypeError: Cannot destructure property 'uri' of 'titles.get(...)' as it is undefined. is due to this.
From this situation, in my added sample script, the unshown images are ignored. By this, this error is avoided.
I had thought that you have a list including 4 URLs of the direct links of image data. But, unfortunately, when I saw your provided script, the URLs are not the direct link like https://drive.google.com/file/d/{fileId}. In this case, an error occurs when Docs API is requested. I think that this will be your 2nd issue.
When these points are reflected in my proposed sample script, it becomes as follows.
Sample script:
In this sample, Google Docs API and Google Drive API are used. So, please enable Docs API and Drive API at Advanced Google services.
And, please set the file IDs of the image file on your Google Drive. The file ID is ### of https://drive.google.com/file/d/###. Please be careful about this.
function myFunction() {
// Please set the file IDs of the images in your Google Drive.
const fileIds = [
"### file ID 1 ###",
"### file ID 2 ###",
"### file ID 3 ###",
"### file ID 4 ###",
];
// Create direct links of the images.
const urls = fileIds.map(id => Drive.Files.get(id).thumbnailLink.replace(/\=s.+/, "=s512"));
// Retrieve the original title of images and set the unique image titles using Docs API.
const doc = DocumentApp.getActiveDocument();
const images = doc.getBody().getImages();
const titles = images.reduce((m, e, i) => {
const org = e.getAltTitle();
e.setAltTitle(`sample${i}`);
m.set(`sample${i}`, { title: org, uri: urls[i] });
return m;
}, new Map());
doc.saveAndClose();
// Create request body of Docs API.
const { inlineObjects } = Docs.Documents.get(doc.getId(), { fields: "inlineObjects" });
const requests = Object.entries(inlineObjects).reduce((ar, [imageObjectId, { inlineObjectProperties: { embeddedObject } }]) => {
if (embeddedObject.hasOwnProperty("imageProperties") && embeddedObject.title) {
const { uri } = titles.get(embeddedObject.title);
ar.push({ replaceImage: { imageObjectId, uri } });
}
return ar;
}, []);
// Request Docs API using the created request body.
Docs.Documents.batchUpdate({ requests }, doc.getId());
// Set the original titles to the images.
const ar = [...titles];
DocumentApp.getActiveDocument().getBody().getImages().forEach((e, i) => e.setAltTitle(ar[i][1].title));
}

Google Apps Script to Refresh Google Slide Presentation containing linked Google Sheet Charts: Fails after 10000 Calls?

Our non-profit information display is a simple looping Google Slides presentation, which works well for static content. Our dynamic content are composed of some current weather textual charts sourced from a Google Sheet (populated using API). These charts are 'refreshed' using a Google Apps Script every minute. Why every minute? Since one of the dynamic charts is the current time -- and this is the only way we have found to maintain a real-time clock in a Google Slide display.
In any case, this works fine -- but after running an entire week, every minute (10000 calls?) the linked charts fail with an 'exclamation mark in a triangle' symbol (and the message 'Image could not be loaded'). Re-embedding the charts does not help -- it is as if the entire Google Slide presentation is now corrupted and unusable for this purpose. We 'fix' this by merely creating a replacement copy of the presentation -- which (after re-activating our triggers to refresh) works just fine. It would be great if we did not need to maintain our presentation this way every week. Help? Suggestions? Thanks!
UPDATE: Here is our Google Slides 'refresh' code:
function refreshCharts(){
var gotSlides = SlidesApp.getActivePresentation().getSlides();
for (var i = 0; i < gotSlides.length; i++) {
var slide = gotSlides[i];
var sheetsCharts = slide.getSheetsCharts();
for (var k = 0; k < sheetsCharts.length; k++) {
var shChart = sheetsCharts[k];
shChart.refresh();
}
}
}
Description
If you are interested to try batch update I put together a simple example script.
Code.gs
function updateCharts() {
try {
let id = SlidesApp.getActivePresentation().getId();
let chartIds = [];
let slides = SlidesApp.getActivePresentation().getSlides();
slides.forEach( slide => { let charts = slide.getSheetsCharts();
charts.forEach( chart => chartIds.push(chart.getObjectId()) );
}
);
console.log(chartIds);
let charts = chartIds.map( id => { return { refreshSheetsChart: { objectId: id } } } );
console.log(charts);
let requests = { requests: charts };
Slides.Presentations.batchUpdate(requests,id);
}
catch(err) {
console.log(err);
}
}
Execution log
6:54:40 AM Notice Execution started
6:54:40 AM Info [ 'g139f22bb9da_0_0' ]
6:54:40 AM Info [ { refreshSheetsChart: { objectId: 'g139f22bb9da_0_0' } } ]
6:54:42 AM Notice Execution completed
Reference
Slides.batchUpdate()

Google script replaceAllShapesWithImage with image from drive doesn"t work any more

Since yesterday one of my google script doesn't work anymore.
The script
take an image on the drive
copie a slide
replace a shape with an image
But I got this error:
"The provided image is in an unsupported format."
-> I give all access to the image: it doesn't change anything
-> The script work if I take an url outside the drive
Any idea
function test_image(){
var imageUrls = DriveApp.getFilesByName("DSC_3632.png");
var file = "undefined";
while ( imageUrls.hasNext()) {
var file = imageUrls.next();
}
var imageUrl = file.getDownloadUrl() + "&access_token=" + ScriptApp.getOAuthToken();
var model_file = DriveApp.getFileById("your-id");
var presentation = model_file.makeCopy("totot");
var presentation =Slides.Presentations.get(presentation.getId())
var requests = [{
"replaceAllShapesWithImage":
{
"imageUrl": imageUrl,
"imageReplaceMethod": "CENTER_INSIDE",
"containsText": {
"text": "toto",
"matchCase": false,
}
}
}];
var presentationId = presentation.presentationId
var createSlideResponse = Slides.Presentations.batchUpdate({
requests: requests
}, presentationId);
}
How about this answer? Please think of this as just one of several possible answers.
Issue and workaround:
I think that the reason of your issue is due to the following modification of official document.
First, we’re making changes to authorization for the Google Drive API. If you authorize download requests to the Drive API using the access token in a query parameter, you will need to migrate your requests to authenticate using an HTTP header instead. Starting January 1, 2020, download calls to files.get, revisions.get and files.export endpoints which authenticate using the access token in the query parameter will no longer be supported, which means you’ll need to update your authentication method.
By above situation, the URL of var imageUrl = file.getDownloadUrl() + "&access_token=" + ScriptApp.getOAuthToken(); cannot be used. For example, when it accesses to the URL, the login screen is displayed even when the access token is used.
In order to avoid this issue, how about the following modification?
Modification points:
The file is shared publicly and put to Google Slides. Then, the sharing file is closed.
In this case, even when the share of file is closed, the put image on Slides is not removed.
The webContentLink is used as the URL.
It's like https://drive.google.com/uc?export=download&id=###.
Modified script:
When your script is modified, it becomes as follows.
function test_image(){
var imageUrls = DriveApp.getFilesByName("DSC_3632.png");
var file; // Modified
while (imageUrls.hasNext()) {
file = imageUrls.next();
}
file.setSharing(DriveApp.Access.ANYONE_WITH_LINK, DriveApp.Permission.VIEW); // Added
var imageUrl = "https://drive.google.com/uc?export=download&id=" + file.getId(); // Modified
var model_file = DriveApp.getFileById("your-id");
var presentation = model_file.makeCopy("totot");
var presentation =Slides.Presentations.get(presentation.getId())
var requests = [{
"replaceAllShapesWithImage": {
"imageUrl": imageUrl,
"imageReplaceMethod": "CENTER_INSIDE",
"containsText": {
"text": "toto",
"matchCase": false,
}
}
}];
var presentationId = presentation.presentationId
var createSlideResponse = Slides.Presentations.batchUpdate({requests: requests}, presentationId);
file.setSharing(DriveApp.Access.PRIVATE, DriveApp.Permission.NONE); // Added
}
References:
Upcoming changes to the Google Drive API and Google Picker API
setSharing()
If I misunderstood your question and this was not the direction you want, I apologize.

Is it possible to load google photos metadata into google sheets?

I have a project where I have scanned 10,000 family pictures from as far back as the 1900's and I am organizing them in Google Photos. I have a spreadsheet where I was keeping track of the proper dates and captions for the entire collection. I would organize a few at a time but then recently found out about the google photos API.
I would like to use something like the methods Method: mediaItems.list or Method: mediaItems.search to get the data from my photos into the spreadsheet to manage.
The output from these examples is exactly what I'm looking for and would want to load that into a spreadsheet.
It would be super awesome if there was a way to update back from the sheet again as well.
I found this article but the code provided does not work for me.
I have this function now in my sheet
function photoAPI() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var albums_sh = ss.getSheetByName("albums") || ss.insertSheet("albums", ss.getSheets().length);
albums_sh.clear();
var narray = [];
var api = "https://photoslibrary.googleapis.com/v1/albums";
var headers = { "Authorization": "Bearer " + ScriptApp.getOAuthToken() };
var options = { "headers": headers, "method" : "GET", "muteHttpExceptions": true };
var param= "", nexttoken;
do {
if (nexttoken)
param = "?pageToken=" + nexttoken;
var response = UrlFetchApp.fetch(api + param, options);
var json = JSON.parse(response.getContentText());
json.albums.forEach(function (album) {
var data = [
album.title,
album.mediaItemsCount,
album.productUrl
];
narray.push(data);
});
nexttoken = json.nextPageToken;
} while (nexttoken);
albums_sh.getRange(1, 1, narray.length, narray[0].length).setValues(narray);
}
When I run it in debug mode, I get the following error
({error:{code:403, message:"Request had insufficient authentication scopes.", status:"PERMISSION_DENIED"}})
I know this means I need to authenticate but don't know how to make that happen.
I have an API key and a secret from the Google photos API pages.
Edit
I used the links from #Tanaike to figure out how to add scopes to my project.
I added these three.
spreadsheets.currentonly
photoslibrary
script.external_request
Now when I run in debug mode, I get a 403 error indicating I need to set up my API. Summary of the error is below:
error:
code:403
Photos Library API has not been used in project 130931490217 before or it is disabled. Enable it by visiting
https://console.developers.google.com/apis/api/photoslibrary.googleapis.com/overview?project=130931490217
Google developers console API activation
type.googleapis.com/google.rpc.Help
"PERMISSION_DENIED"
When I try to go to the listed URL though, I just get a message that says "Failed to load."
I got my code working with the help of #Tanaike in my comments above. I had two issues.
1) I needed to specify the oauthScopes in appsscript.json which is hidden by default in google scripts. It can be revealed by going to the menu and selecting View > Show Manifest File.
2) I was using a default GCP project which did not have authorization to use the photos API and could not be enabled. I needed to switch to a standard GCP project which I had created earlier and had enabled the photos API.
Here is my original posted function with additional comments after I got it working:
function photoAPI_ListAlbums() {
// Modified from code by Stackoverflow user Frç Ju at https://stackoverflow.com/questions/54063937/0auth2-problem-to-get-my-google-photos-libraries-in-a-google-sheet-of-mine
// which was originally Modified from http://ctrlq.org/code/20068-blogger-api-with-google-apps-script
/*
This function retrieves all albums from your personal google photos account and lists each one with the name of album, count of photos, and URL in a new sheet.
Requires Oauth scopes. Add the below line to appsscript.json
"oauthScopes": ["https://www.googleapis.com/auth/spreadsheets.currentonly", "https://www.googleapis.com/auth/photoslibrary", "https://www.googleapis.com/auth/photoslibrary.readonly", "https://www.googleapis.com/auth/script.external_request"]
Also requires a standard GCP project with the appropriate Photo APIs enabled.
https://developers.google.com/apps-script/guides/cloud-platform-projects
*/
//Get the spreadsheet object
var ss = SpreadsheetApp.getActiveSpreadsheet();
//Check for presence of target sheet, if it does not exist, create one.
var albums_sh = ss.getSheetByName("albums") || ss.insertSheet("albums", ss.getSheets().length);
//Make sure the target sheet is empty
albums_sh.clear();
var narray = [];
//Build the request string. Default page size is 20, max 50. set to max for speed.
var api = "https://photoslibrary.googleapis.com/v1/albums?pageSize=50";
var headers = { "Authorization": "Bearer " + ScriptApp.getOAuthToken() };
var options = { "headers": headers, "method" : "GET", "muteHttpExceptions": true };
var param= "", nexttoken;
//Make the first row a title row
var data = [
"Title",
"Item Count",
"ID",
"URL"
];
narray.push(data);
//Loop through JSON results until a nextPageToken is not returned indicating end of data
do {
//If there is a nextpagetoken, add it to the end of the request string
if (nexttoken)
param = "&pageToken=" + nexttoken;
//Get data and load it into a JSON object
var response = UrlFetchApp.fetch(api + param, options);
var json = JSON.parse(response.getContentText());
//Loop through the JSON object adding desired data to the spreadsheet.
json.albums.forEach(function (album) {
var data = [
"'"+album.title, //The prepended apostrophe makes albums with a name such as "June 2007" to show up as that text rather than parse as a date in the sheet.
album.mediaItemsCount,
album.id,
album.productUrl
];
narray.push(data);
});
//Get the nextPageToken
nexttoken = json.nextPageToken;
//Continue if the nextPageToaken is not null
} while (nexttoken);
//Save all the data to the spreadsheet.
albums_sh.getRange(1, 1, narray.length, narray[0].length).setValues(narray);
}
And here is another function which I created in the same style to pull photo metadata directly. This is what I was originally trying to accomplish.
function photoAPI_ListPhotos() {
//Modified from above function photoAPI_ListAlbums
/*
This function retrieves all photos from your personal google photos account and lists each one with the Filename, Caption, Create time (formatted for Sheet), Width, Height, and URL in a new sheet.
it will not include archived photos which can be confusing if you happen to have a large chunk of archived photos some pages may return only a next page token with no media items.
Requires Oauth scopes. Add the below line to appsscript.json
"oauthScopes": ["https://www.googleapis.com/auth/spreadsheets.currentonly", "https://www.googleapis.com/auth/photoslibrary", "https://www.googleapis.com/auth/photoslibrary.readonly", "https://www.googleapis.com/auth/script.external_request"]
Also requires a standard GCP project with the appropriate Photo APIs enabled.
https://developers.google.com/apps-script/guides/cloud-platform-projects
*/
//Get the spreadsheet object
var ss = SpreadsheetApp.getActiveSpreadsheet();
//Check for presence of target sheet, if it does not exist, create one.
var photos_sh = ss.getSheetByName("photos") || ss.insertSheet("photos", ss.getSheets().length);
//Make sure the target sheet is empty
photos_sh.clear();
var narray = [];
//Build the request string. Max page size is 100. set to max for speed.
var api = "https://photoslibrary.googleapis.com/v1/mediaItems?pageSize=100";
var headers = { "Authorization": "Bearer " + ScriptApp.getOAuthToken() };
var options = { "headers": headers, "method" : "GET", "muteHttpExceptions": true };
//This variable is used if you want to resume the scrape at some page other than the start. This is needed if you have more than 40,000 photos.
//Uncomment the line below and add the next page token for where you want to start in the quotes.
//var nexttoken="";
var param= "", nexttoken;
//Start counting how many pages have been processed.
var pagecount=0;
//Make the first row a title row
var data = [
"Filename",
"description",
"Create Time",
"Width",
"Height",
"ID",
"URL",
"NextPage"
];
narray.push(data);
//Loop through JSON results until a nextPageToken is not returned indicating end of data
do {
//If there is a nextpagetoken, add it to the end of the request string
if (nexttoken)
param = "&pageToken=" + nexttoken;
//Get data and load it into a JSON object
var response = UrlFetchApp.fetch(api + param, options);
var json = JSON.parse(response.getContentText());
//Check if there are mediaItems to process.
if (typeof json.mediaItems === 'undefined') {
//If there are no mediaItems, Add a blank line in the sheet with the returned nextpagetoken
//var data = ["","","","","","","",json.nextPageToken];
//narray.push(data);
} else {
//Loop through the JSON object adding desired data to the spreadsheet.
json.mediaItems.forEach(function (MediaItem) {
//Check if the mediaitem has a description (caption) and make that cell blank if it is not present.
if(typeof MediaItem.description === 'undefined') {
var description = "";
} else {
var description = MediaItem.description;
}
//Format the create date as appropriate for spreadsheets.
var d = new Date(MediaItem.mediaMetadata.creationTime);
var data = [
MediaItem.filename,
"'"+description, //The prepended apostrophe makes captions that are dates or numbers save in the sheet as a string.
d,
MediaItem.mediaMetadata.width,
MediaItem.mediaMetadata.height,
MediaItem.id,
MediaItem.productUrl,
json.nextPageToken
];
narray.push(data);
});
}
//Get the nextPageToken
nexttoken = json.nextPageToken;
pagecount++;
//Continue if the nextPageToaken is not null
//Also stop if you reach 400 pages processed, this prevents the script from timing out. You will need to resume manually using the nexttoken variable above.
} while (pagecount<400 && nexttoken);
//Continue if the nextPageToaken is not null (This is commented out as an alternative and can be used if you have a small enough collection it will not time out.)
//} while (nexttoken);
//Save all the data to the spreadsheet.
photos_sh.getRange(1, 1, narray.length, narray[0].length).setValues(narray);
}
Because of the limitations of the ListPhotos function and the fact that my library is so enormous, I am still working on a third function to pull photo metadata from all the photos in specific albums. I'll edit this answer once I pull that off.

Image from Google Drive to Google Slides via DriveApp.getFileById

I want to import an image to Google Slides over Google Apps Script after the instruction Google Developers - How to...
function createImage(presentationId) {
// Add a new image to the presentation page. The image is assumed to exist in
// the user's Drive, and have 'imageFileId' as its file ID.
var requests = [];
var pageId = 'g1fe0c....';
var imageId = 'MyImage_01';
var imageUrl = DriveApp.getFileById('0B6cQESmLJfX...').getUrl();
var emu4M = {
magnitude: 4000000,
unit: 'EMU'
};
requests.push({
createImage: {
objectId: imageId,
url: imageUrl,
elementProperties: {
pageObjectId: pageId,
size: {
height: emu4M,
width: emu4M
},
transform: {
scaleX: 1,
scaleY: 1,
translateX: 100000,
translateY: 100000,
unit: 'EMU'
}
}
}
});
// Execute the request.
var response = Slides.Presentations.batchUpdate({
requests: requests
}, presentationId);
}
But for every image-format I tried, there is an error message in Google Apps Script:
Invalid requests[0].createImage: The provided image is in an
unsupported format.
Drive- and Slides API is activated in Google Advanced Services. The folder and the file has a public share.
Does anyone use the command DriveApp.getFileById() with subsequent export to Google Slides successfully?
How about a following modification?
From :
var imageUrl = DriveApp.getFileById('0B6cQESmLJfX...').getUrl();
To :
var imageUrl = DriveApp.getFileById('0B6cQESmLJfX...').getDownloadUrl() + "&access_token=" + ScriptApp.getOAuthToken();
From this document, it seemed that the access token is required. https://developers.google.com/slides/how-tos/add-image
Updated: February 7, 2020
From January, 2020, the access token cannot be used with the query parameter like access_token=###. Ref So please use the access token to the request header instead of the query parameter.
In OP's case, I think that this answer can be used.