As the title suggests, I'm looking for a way to set the alt title of an image in a slideshow.
Currently this is what i have tried, but for some reason it doesn't seem to update:
var resource = {"requests": [
{"updatePageElementAltText": {
"objectId": id,
"description": "",
"title": elementTitle
}
}]};
Slides.Presentations.batchUpdate(resource, presentationId);
It might be worth noting that the script is running in the Script Editor of a google sheet. The variables id, elementTitle and presentationId are all defined earlier in the script and I've checked that they are correct.
Can anyone spot the issue with this or suggest an easier way to do it?
Edit: Tanaike helped me make this specific part of the script work, but it isn't working in the larger picture, hence this edit.
What the script is supposed to do, is basically do a find/replace on all Image elements in the slideshow.
Based on keys in a sheet in Column A it should replace the Image URL in with the corresponding URL in column B. The script then cycles through all elements in the slideshow, finds the images, and then cycles through them to check if any of the titles have the 'key' as the title. The image URL should then be replaced with the URL on the same row in sheet. This part of the script is tested and works, but the key is removed from the object when the URL is updated. This shouldn't be happening as the Image should be able to be replaced again later.
For this reason, I tried to save the title before updating the URL and the put it back with the above-mentioned batchUpdate, but for some reason, it isn't working properly.
Here is the full script:
function imageReplacer() {
var newPresentationSlides = SlidesApp.openByUrl(myslidesurl).getSlides();
var imageTitles = SpreadsheetApp.openByUrl(mysheeturl).getRange("'Image Replace List'!A2:A").getValues();
var imageURLs = SpreadsheetApp.openByUrl(mysheeturl).getRange("'Image Replace List'!B2:B").getValues();
var presentationId = 'myslidesid';
for (y = 0; y < newPresentationSlides.length; y++) {
var pageElements = newPresentationSlides[y].getPageElements();
for (x = 0; x < pageElements.length; x++) {
for (a = 0; a < imageTitles.filter(String).length; a++) {
if (pageElements[x].getPageElementType() == "IMAGE") {
if(pageElements[x].asImage().getTitle() == imageTitles[a]) {
var elementTitle = pageElements[x].asImage().getTitle();
var id = pageElements[x].getObjectId();
pageElements[x].asImage().replace(imageURLs[a]);
var id = pageElements[x].getObjectId();
var resource = {"requests": [
{"updatePageElementAltText": {
"objectId": id,
"description": "Sample description",
"title": elementTitle
}
}]};
Slides.Presentations.batchUpdate(resource, presentationId);
}
}
}
}
}
}
As you can see the middle part of the script is exactly the same as tanaike suggested, but it's just not working properly (I even tested that specific part as a stand-alone script and it worked fine.).
Second edit:
Examples:
Sheet: https://docs.google.com/spreadsheets/d/1npWyONio_seI3bRibFWxiqzHxLZ-ie2wbszgROkLduE/edit#gid=0
Slides: https://docs.google.com/presentation/d/1rfT7TLD-O7dBbwV5V3UbugN1OLOnBI2-CZN2GPnmANM/edit#slide=id.p
I think that your script works. You can confirm the updated result on the slide.
But if you want to retrieve the title and description using Slides services like getTitle()
and getDescription()
after the title and description are updated using Slides API, it seems that those results are not updated. The updated results couldn't be retrieved even if saveAndClose()
is used. And also, unfortunately, in the current stage, I couldn't find the methods like setTitle()
and setDescription()
in my environment. So how about this workaround? In this workaround, the title and description are updated by Slides API and those are retrieved by Slides API.
var presentationId = "###"; // Please set this.
var objectId = "###"; // Please set this.
// Update title and description
var resource = {"requests": [
{"updatePageElementAltText": {
"objectId": objectId,
"description": "Sample description",
"title": "Sample title"
}
}]};
Slides.Presentations.batchUpdate(resource, presentationId);
// Retrieve updated title and description
var res = Slides.Presentations.get(presentationId);
var slides = res.slides;
for (var i = 0; i < slides.length; i++) {
var pe = slides[i].pageElements;
for (var j = 0; j < pe.length; j++) {
if (pe[j].objectId == objectId) {
Logger.log(pe[j].title)
Logger.log(pe[j].description)
break;
}
}
}
If I misunderstand what you want, I'm sorry.
If my understanding is correct, how about this modification?
function imageReplacer() {
var spreadsheetId = "### spreadsheetId ###"; // Please modify this.
var sheetName = "Image Replace List";
var presentationId = "### presentationId ###"; // Please modify this.
var sheet = SpreadsheetApp.openById(spreadsheetId).getSheetByName(sheetName);
var values = sheet.getRange(2, 1, sheet.getLastRow(), 2).getValues().filter(function(e) {return e[0] && e[1]});
var s = SlidesApp.openById(presentationId);
var slides = s.getSlides();
var requests = slides.reduce(function(reqs, slide) {
var r = slide.getPageElements().reduce(function(ar, e) {
if (e.getPageElementType() == "IMAGE") {
var key = values.filter(function(v) {return v[0] == e.getTitle()});
if (key.length == 1) {
var id = e.getObjectId();
var rq = [
{"replaceImage":{"imageObjectId":id, "url": key[0][1]}},
{"updatePageElementAltText":{"objectId":id, "title": key[0][0]}}
];
Array.prototype.push.apply(ar, rq);
}
}
return ar;
}, []);
if (r.length > 0) Array.prototype.push.apply(reqs, r);
return reqs;
}, []);
Slides.Presentations.batchUpdate({requests: requests}, presentationId);
}