I am trying to insert chart to Google Slides presentation using CreateSheetsChartRequest.
Request fails with error:
Execution failed: GoogleJsonResponseException: Invalid value at 'requests[0].create_sheets_chart.chart_id' (TYPE_INT32), "u1935822328711"
Sample code:
var ss = SpreadsheetApp.getActiveSpreadsheet();
var chartSheet = ss.getSheets()[0];
// get chart id via Sheets API
// returns string like 'u1935822328711'
var chartId = chartSheet.getCharts()[0].getId();
var slidesReqs = [];
slidesReqs.push({
createSheetsChart: {
objectId: 'someSlideChartId',
elementProperties: {
pageObjectId: slideId,
size: {
width: {
magnitude: (7/9)*900,
unit: 'PT'
},
height: {
magnitude: (7/9)*560,
unit: 'PT'
}
},
transform: {
scaleX: 1,
scaleY: 1,
translateX: 100000,
translateY: 100000,
unit: 'EMU'
}
},
spreadsheetId: ss.getId(),
chartId: chartId,
linkingMode: 'NOT_LINKED_IMAGE'
}
});
// throws error
// Execution failed: GoogleJsonResponseException: Invalid value at 'requests[0].create_sheets_chart.chart_id' (TYPE_INT32), "u1935822328711"
Slides.Presentations.batchUpdate({'requests': slidesReqs}, presentationFileId);
I see that CreateSheetsChartRequest expects field chartId to be integer, but Google Sheets API returns string like "u1935822328711" for chart id.
How do I get Google Sheets chart inserted to slide?
Short answer
Use getChartId() instead of getId().
Explanation
EmbeddedChart.getId() returns an ID that is only useful in the context of UiApp, a deprecated service for building component-based UIs.
However, as of today, there is now a method on the EmbeddedChart class called getChartId() that returns a unique, stable integer identifying the chart.
If you change the one line in your code to
var chartId = chartSheet.getCharts()[0].getChartId();
your CreateSheetsChartRequest should now work.
Source: https://issuetracker.google.com/issues/79784012#comment2
Related
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
I'm playing around with a dynamic signage project and need a little help finishing off some GAS in Slides. All I want to do is replace some text in the active presentation with some text from (one cell) in a Google spreadsheet. I think I have the Request syntax correct but not sure how to execute the Request on the current presentation as everything I've tried seems to fail. Any help would be much appreciated. Code below which includes the full script which copies some slides etc (and is working) - it's just the last request section that I need help with...
function updateRBFixtures() {
var srcPresentationId = "1zRvc0H64yvxxxxxxxxxxxxxznmb2usZ_4w6bvRA";
var copysrcSlideIndex = 0;
var copydstSlideIndex = 1;
var src = SlidesApp.openById(srcPresentationId).getSlides()[copysrcSlideIndex];
SlidesApp.getActivePresentation().insertSlide(copydstSlideIndex, src);
var selection = SlidesApp.getActivePresentation().getSelection();
var slide = SlidesApp.getActivePresentation().getSlides()[0];
slide.remove();
var dataRangeNotation = 'slideInfo!B2:B2';
var value =
SpreadsheetApp.openById("1jiYxxxxxxxxxxxxxxMqtwXnc").getRange(dataRangeNotation).getValues();
requests = [{
replaceAllText: {
containsText: {
text: '{fixtureOneMatch}',
matchCase: false
},
replaceText: value
}
}];
}
How about this answer?
Modification points:
getValues() returns 2 dimensional array. In your case, the value is retrieved from one cell. So you can use getValue().
In your case, after the slide was inserted, I think that it is required to use saveAndClose().
In your script, requests is not used.
When above points are reflected to your script, it becomes as follows.
Modified script:
From:
SlidesApp.getActivePresentation().insertSlide(copydstSlideIndex, src);
var selection = SlidesApp.getActivePresentation().getSelection();
var slide = SlidesApp.getActivePresentation().getSlides()[0];
slide.remove();
var dataRangeNotation = 'slideInfo!B2:B2';
var value =
SpreadsheetApp.openById("1jiYxxxxxxxxxxxxxxMqtwXnc").getRange(dataRangeNotation).getValues();
requests = [{
replaceAllText: {
containsText: {
text: '{fixtureOneMatch}',
matchCase: false
},
replaceText: value
}
}];
To:
var s = SlidesApp.getActivePresentation();
s.insertSlide(copydstSlideIndex, src);
s.getSlides()[0].remove();
s.saveAndClose();
var dataRangeNotation = 'slideInfo!B2:B2';
var value = SpreadsheetApp.openById("###").getRange(dataRangeNotation).getValue();
var requests = [{
replaceAllText: {
containsText: {
text: '{fixtureOneMatch}',
},
replaceText: value,
}
}];
Slides.Presentations.batchUpdate({requests: requests}, s.getId());
In this case, please enable Slides API at Advanced Google services.
References:
getValues()
getValue()
saveAndClose()
Method: presentations.batchUpdate
1) I am trying to create a complete script that will take input data from a google form/google sheet and use the top row as as field names for a Freshdesk ticket while taking the last row (most current) as the data to input as the ticket data ..
2) I have coded onFormSubmit portion so it creates the general ticket however i would the data from the backend to be used as the certain field data
function onFormSubmit(e) {
if ((typeof GasFreshdesk)==='undefined') {
eval(UrlFetchApp.fetch('https://raw.githubusercontent.com/zixia/gas-freshdesk/master/src/gas-freshdesk-lib.js').getContentText())
}
var MyFreshdesk = new GasFreshdesk('https://***.freshdesk.com', 'API KEY'); // REPLACE redacted with real key
// Custom fields passed in. Use this for now - to test (then replace later with other valid values).
var customFields = {"email": "firstnamelastname#org.org",
"room": "IT",
"building": "**",
"devicesystem": "Device",
"problem": "problem"
};
var ticket = new MyFreshdesk.Ticket({description: "We have provided you with a loaner",
subject: "** - Device - Problem- " + "FullName", email: "firstnamelastname#org.org",
type: "Support Request", custom_fields: customFields});
}
What i'm looking for is a way to grab the values in the last row of data since that data is what will need to be inputted into the ticket.
function LastRow() {
var ss= SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Form Responses 1");
var lr = getLastRow();
Logger.log(lr);
}
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.
I am working on a Google Apps Script that links with a REST API and puts the data into a Google Sheet.
I have successfully done this once, but upon accessing some different data I get the error message
"The coordinates or dimensions of the range are invalid"
when they work perfectly fine on my other script. All data accessed is JSON so I am bit confused and is from the same source. The code I am using is:
function stats () {
var logIn = {
"Authorization" : "Basic " + Utilities.base64Encode("XXXX" + ':' + "XXXX")
};
var url = "XXXXX";
var params = {
"method":"GET",
"headers":logIn, };
var response = UrlFetchApp.fetch(url, params);
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("XXXX");
var dataAll = JSON.parse(response.getContentText()); //
var dataSet = dataAll;
var rows = [],
data;
for (i = 0; i < dataSet.length; i++) {
data = dataSet[i];
rows.push([XXXX]); //your JSON entities here
}
dataRange = sheet.getRange(1, 1, rows.length, 1);
dataRange.setValues(rows);
}
I have combined pieces of code from around the web and this works on my other script. The error appears on this line:
dataRange = sheet.getRange(1, 1, rows.length, 1);
I believe the issue is with the data I am accessing but I do not know how to alter the script for it to work.
The JSON data that works is shown like:
{
id: XXX,
group: XX,
text: "XXXX?",
creation_date: XXXX,
created_by: "XXXXX",
tags: [
"XXXX"
]
}
And the data that is causing the error is shown as:
{
2016-02-29: {
XXX: 0,
XXX: 0
},
I have had to 'XXXX' out a lot of the private information - apologies. Any help would be appreciated.
Javascript's length property is for indexed arrays and does not apply to Objects so dataSet.length returns undefined and the loop never executes.
To get the length of the object you can use Object.keys(dataSet).length as outlined here.