From 1041a55158a5ede16acf4b80caf301a6c3d9e962 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Fri, 21 Nov 2025 22:13:12 +0000 Subject: [PATCH 1/2] fix(mashups): resolve type errors Fixes TypeScript check errors in the 'mashups' directory. - Adds JSDoc annotations to resolve implicit 'any' types. - Corrects argument types for API calls. - Defines a local type for the onEdit event object. - Refactors code to avoid variable reassignment with different types. --- mashups/sheets2calendar.gs | 5 +++-- mashups/sheets2chat.gs | 8 +++++++- mashups/sheets2docs.gs | 5 +++-- mashups/sheets2drive.gs | 5 +++-- mashups/sheets2forms.gs | 5 +++-- mashups/sheets2gmail.gs | 3 ++- mashups/sheets2maps.gs | 4 +++- mashups/sheets2slides.gs | 5 +++-- mashups/sheets2translate.gs | 2 +- 9 files changed, 28 insertions(+), 14 deletions(-) diff --git a/mashups/sheets2calendar.gs b/mashups/sheets2calendar.gs index b878b1f1f..5c1e20c7d 100644 --- a/mashups/sheets2calendar.gs +++ b/mashups/sheets2calendar.gs @@ -8,6 +8,7 @@ function createEventsFromSpreadsheet() { // Open the spreadsheet and get the data. var ss = SpreadsheetApp.openByUrl('ENTER SPREADSHEET URL HERE'); var sheet = ss.getSheets()[0]; + /** @type {string[][]} */ var data = sheet.getDataRange().getValues(); // Remove any frozen rows from the data, since they contain headers. @@ -17,10 +18,10 @@ function createEventsFromSpreadsheet() { data.forEach(function(row) { var title = row[0]; var description = row[1]; - var emails = row[2]; + var emailsStr = row[2]; // Split the emails into an array and remove extra whitespace. - emails = emails.split(',').map(function(email) { + var emails = emailsStr.split(',').map(function(email) { return email.trim(); }); diff --git a/mashups/sheets2chat.gs b/mashups/sheets2chat.gs index bf888b3ea..f279c3a6c 100644 --- a/mashups/sheets2chat.gs +++ b/mashups/sheets2chat.gs @@ -1,3 +1,9 @@ +/** + * @typedef {Object} SheetEditEvent + * @property {string} oldValue The old value of the cell. + * @property {string} value The new value of the cell. + */ + /** * Posts a message to a Hangouts Chat room every time the spreadsheet is edited. * This script must be attached to the spreadsheet (created in Google Sheets under @@ -8,7 +14,7 @@ * "From spreadsheet", "On edit". * - Click "Save". * - * @param {Object} e The onEdit event object. + * @param {SheetEditEvent} e The onEdit event object. */ function sendChatMessageOnEdit(e) { var range = SpreadsheetApp.getActiveRange(); diff --git a/mashups/sheets2docs.gs b/mashups/sheets2docs.gs index 1ee48553f..281ce719f 100644 --- a/mashups/sheets2docs.gs +++ b/mashups/sheets2docs.gs @@ -8,6 +8,7 @@ function createDocsFromSpreadsheet() { // Open the spreadsheet and get the data. var ss = SpreadsheetApp.openByUrl('ENTER SPREADSHEET URL HERE'); var sheet = ss.getSheets()[0]; + /** @type {string[][]} */ var data = sheet.getDataRange().getValues(); // Remove any frozen rows from the data, since they contain headers. @@ -17,10 +18,10 @@ function createDocsFromSpreadsheet() { data.forEach(function(row) { var title = row[0]; var content = row[1]; - var emails = row[2]; + var emailsStr = row[2]; // Split the emails into an array and remove extra whitespace. - emails = emails.split(',').map(function(email) { + var emails = emailsStr.split(',').map(function(email) { return email.trim(); }); diff --git a/mashups/sheets2drive.gs b/mashups/sheets2drive.gs index 61145921d..545319063 100644 --- a/mashups/sheets2drive.gs +++ b/mashups/sheets2drive.gs @@ -8,6 +8,7 @@ function createDriveFilesFromSpreadsheet() { // Open the spreadsheet and get the data. var ss = SpreadsheetApp.openByUrl('ENTER SPREADSHEET URL HERE'); var sheet = ss.getSheets()[0]; + /** @type {string[][]} */ var data = sheet.getDataRange().getValues(); // Remove any frozen rows from the data, since they contain headers. @@ -17,10 +18,10 @@ function createDriveFilesFromSpreadsheet() { data.forEach(function(row) { var fileName = row[0]; var htmlContent = row[1]; - var emails = row[2]; + var emailsStr = row[2]; // Split the emails into an array and remove extra whitespace. - emails = emails.split(',').map(function(email) { + var emails = emailsStr.split(',').map(function(email) { return email.trim(); }); diff --git a/mashups/sheets2forms.gs b/mashups/sheets2forms.gs index 0fec56774..263cacd23 100644 --- a/mashups/sheets2forms.gs +++ b/mashups/sheets2forms.gs @@ -8,6 +8,7 @@ function createFormsFromSpreadsheet() { // Open the spreadsheet and get the data. var ss = SpreadsheetApp.openByUrl('ENTER SPREADSHEET URL HERE'); var sheet = ss.getSheets()[0]; + /** @type {string[][]} */ var data = sheet.getDataRange().getValues(); // Remove any frozen rows from the data, since they contain headers. @@ -17,10 +18,10 @@ function createFormsFromSpreadsheet() { data.forEach(function(row) { var title = row[0]; var question = row[1]; - var emails = row[2]; + var emailsStr = row[2]; // Split the emails into an array and remove extra whitespace. - emails = emails.split(',').map(function(email) { + var emails = emailsStr.split(',').map(function(email) { return email.trim(); }); diff --git a/mashups/sheets2gmail.gs b/mashups/sheets2gmail.gs index 3a0c6ee6d..07e3393d9 100644 --- a/mashups/sheets2gmail.gs +++ b/mashups/sheets2gmail.gs @@ -8,6 +8,7 @@ function sendEmailsFromSpreadsheet() { // Open the spreadsheet and get the data. var ss = SpreadsheetApp.openByUrl('ENTER SPREADSHEET URL HERE'); var sheet = ss.getSheets()[0]; + /** @type {string[][]} */ var data = sheet.getDataRange().getValues(); // Remove any frozen rows from the data, since they contain headers. @@ -20,7 +21,7 @@ function sendEmailsFromSpreadsheet() { var emails = row[2]; // Send the email. - GmailApp.sendEmail(emails, subject, null, { + GmailApp.sendEmail(emails, subject, '', { htmlBody: htmlMessage }); }); diff --git a/mashups/sheets2maps.gs b/mashups/sheets2maps.gs index 97c592b61..62087fcb1 100644 --- a/mashups/sheets2maps.gs +++ b/mashups/sheets2maps.gs @@ -16,7 +16,9 @@ function COUNTY(address) { if (!results || results.length === 0) { throw new Error('Unknown address'); } - var counties = results[0].address_components.filter(function(component) { + /** @type {{long_name: string, types: string[]}[]} */ + var addressComponents = results[0].address_components; + var counties = addressComponents.filter(function(component) { return component.types.indexOf('administrative_area_level_2') >= 0; }); if (!counties.length) { diff --git a/mashups/sheets2slides.gs b/mashups/sheets2slides.gs index 551ab76b3..48736bd9f 100644 --- a/mashups/sheets2slides.gs +++ b/mashups/sheets2slides.gs @@ -8,6 +8,7 @@ function createPresentationsFromSpreadsheet() { // Open the spreadsheet and get the data. var ss = SpreadsheetApp.openByUrl('ENTER SPREADSHEET URL HERE'); var sheet = ss.getSheets()[0]; + /** @type {string[][]} */ var data = sheet.getDataRange().getValues(); // Remove any frozen rows from the data, since they contain headers. @@ -17,10 +18,10 @@ function createPresentationsFromSpreadsheet() { data.forEach(function(row) { var title = row[0]; var content = row[1]; - var emails = row[2]; + var emailsStr = row[2]; // Split the emails into an array and remove extra whitespace. - emails = emails.split(',').map(function(email) { + var emails = emailsStr.split(',').map(function(email) { return email.trim(); }); diff --git a/mashups/sheets2translate.gs b/mashups/sheets2translate.gs index 06b38c492..073c43f31 100644 --- a/mashups/sheets2translate.gs +++ b/mashups/sheets2translate.gs @@ -12,7 +12,7 @@ function onEdit() { var range = SpreadsheetApp.getActiveRange(); var value = range.getValue(); if (typeof value === 'string') { - var translated = LanguageApp.translate(value, null, 'en'); + var translated = LanguageApp.translate(value, '', 'en'); range.setNote(translated); } } From 26888477987eb04dece3a7b1a6b1e8d89c73fd83 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Fri, 21 Nov 2025 22:24:03 +0000 Subject: [PATCH 2/2] feat(mashups): resolve type errors and use let/const This commit addresses two main points: 1. Resolves all TypeScript check errors in the 'mashups' directory by: - Adding JSDoc annotations to resolve implicit 'any' types. - Correcting argument types for API calls. - Defining a local type for the onEdit event object. - Refactoring code to avoid variable reassignment with different types. 2. Refactors all `var` declarations to use `let` and `const` for improved scope management and code readability, following modern JavaScript standards. --- mashups/sheets2calendar.gs | 22 +++++++++++----------- mashups/sheets2chat.gs | 16 ++++++++-------- mashups/sheets2contacts.gs | 12 ++++++------ mashups/sheets2docs.gs | 16 ++++++++-------- mashups/sheets2drive.gs | 20 ++++++++++---------- mashups/sheets2forms.gs | 16 ++++++++-------- mashups/sheets2gmail.gs | 12 ++++++------ mashups/sheets2maps.gs | 6 +++--- mashups/sheets2slides.gs | 20 ++++++++++---------- mashups/sheets2translate.gs | 6 +++--- 10 files changed, 73 insertions(+), 73 deletions(-) diff --git a/mashups/sheets2calendar.gs b/mashups/sheets2calendar.gs index 5c1e20c7d..5461cb4ab 100644 --- a/mashups/sheets2calendar.gs +++ b/mashups/sheets2calendar.gs @@ -6,38 +6,38 @@ */ function createEventsFromSpreadsheet() { // Open the spreadsheet and get the data. - var ss = SpreadsheetApp.openByUrl('ENTER SPREADSHEET URL HERE'); - var sheet = ss.getSheets()[0]; + const ss = SpreadsheetApp.openByUrl('ENTER SPREADSHEET URL HERE'); + const sheet = ss.getSheets()[0]; /** @type {string[][]} */ - var data = sheet.getDataRange().getValues(); + const data = sheet.getDataRange().getValues(); // Remove any frozen rows from the data, since they contain headers. data.splice(sheet.getFrozenRows()); // Create an event for each row. data.forEach(function(row) { - var title = row[0]; - var description = row[1]; - var emailsStr = row[2]; + const title = row[0]; + const description = row[1]; + const emailsStr = row[2]; // Split the emails into an array and remove extra whitespace. - var emails = emailsStr.split(',').map(function(email) { + const emails = emailsStr.split(',').map(function(email) { return email.trim(); }); - var now = new Date(); + const now = new Date(); // Start the event at the next hour mark. - var start = new Date(now); + const start = new Date(now); start.setHours(start.getHours() + 1); start.setMinutes(0); start.setSeconds(0); start.setMilliseconds(0); // End the event after 30 minutes. - var end = new Date(start); + const end = new Date(start); end.setMinutes(end.getMinutes() + 30); // Create the calendar event and invite the guests. - var event = CalendarApp.createEvent(title, start, end) + const event = CalendarApp.createEvent(title, start, end) .setDescription(description); emails.forEach(function(email) { event.addGuest(email); diff --git a/mashups/sheets2chat.gs b/mashups/sheets2chat.gs index f279c3a6c..81ee9fe77 100644 --- a/mashups/sheets2chat.gs +++ b/mashups/sheets2chat.gs @@ -17,13 +17,13 @@ * @param {SheetEditEvent} e The onEdit event object. */ function sendChatMessageOnEdit(e) { - var range = SpreadsheetApp.getActiveRange(); - var value = range.getValue(); - var oldValue = e.oldValue; - var ss = range.getSheet().getParent(); + const range = SpreadsheetApp.getActiveRange(); + const value = range.getValue(); + const oldValue = e.oldValue; + const ss = range.getSheet().getParent(); // Construct the message to send, based on the old and new value of the cell. - var changeMessage; + let changeMessage; if (oldValue && value) { changeMessage = Utilities.formatString('changed from "%s" to "%s"', oldValue, value); @@ -32,17 +32,17 @@ function sendChatMessageOnEdit(e) { } else { changeMessage = 'cleared'; } - var message = Utilities.formatString( + const message = Utilities.formatString( 'The range %s was %s. <%s|Open spreadsheet>.', range.getA1Notation(), changeMessage, ss.getUrl()); // Follow these steps to create an incomming webhook URL for your chat room: // https://developers.google.com/hangouts/chat/how-tos/webhooks#define_an_incoming_webhook - var webhookUrl = 'ENTER INCOMMING WEBHOOK URL HERE'; + const webhookUrl = 'ENTER INCOMMING WEBHOOK URL HERE'; // Use the spreadsheet's ID as a thread key, so that all messages go into the // same thread. - var url = webhookUrl + '&threadKey=' + ss.getId(); + const url = webhookUrl + '&threadKey=' + ss.getId(); // Send the message. UrlFetchApp.fetch(url, { diff --git a/mashups/sheets2contacts.gs b/mashups/sheets2contacts.gs index 0eb90452c..746034396 100644 --- a/mashups/sheets2contacts.gs +++ b/mashups/sheets2contacts.gs @@ -5,18 +5,18 @@ */ function createContactsFromSpreadsheet() { // Open the spreadsheet and get the data. - var ss = SpreadsheetApp.openByUrl('ENTER SPREADSHEET URL HERE'); - var sheet = ss.getSheets()[0]; - var data = sheet.getDataRange().getValues(); + const ss = SpreadsheetApp.openByUrl('ENTER SPREADSHEET URL HERE'); + const sheet = ss.getSheets()[0]; + const data = sheet.getDataRange().getValues(); // Remove any frozen rows from the data, since they contain headers. data.splice(sheet.getFrozenRows()); // Send a contact for each row. data.forEach(function(row) { - var firstName = row[0]; - var lastName = row[1]; - var email = row[2]; + const firstName = row[0]; + const lastName = row[1]; + const email = row[2]; ContactsApp.createContact(firstName, lastName, email); }); } diff --git a/mashups/sheets2docs.gs b/mashups/sheets2docs.gs index 281ce719f..7b0c78c61 100644 --- a/mashups/sheets2docs.gs +++ b/mashups/sheets2docs.gs @@ -6,27 +6,27 @@ */ function createDocsFromSpreadsheet() { // Open the spreadsheet and get the data. - var ss = SpreadsheetApp.openByUrl('ENTER SPREADSHEET URL HERE'); - var sheet = ss.getSheets()[0]; + const ss = SpreadsheetApp.openByUrl('ENTER SPREADSHEET URL HERE'); + const sheet = ss.getSheets()[0]; /** @type {string[][]} */ - var data = sheet.getDataRange().getValues(); + const data = sheet.getDataRange().getValues(); // Remove any frozen rows from the data, since they contain headers. data.splice(sheet.getFrozenRows()); // Create a document for each row. data.forEach(function(row) { - var title = row[0]; - var content = row[1]; - var emailsStr = row[2]; + const title = row[0]; + const content = row[1]; + const emailsStr = row[2]; // Split the emails into an array and remove extra whitespace. - var emails = emailsStr.split(',').map(function(email) { + const emails = emailsStr.split(',').map(function(email) { return email.trim(); }); // Create the document, append the content, and share it out. - var doc = DocumentApp.create(title); + const doc = DocumentApp.create(title); doc.getBody().appendParagraph(content); doc.addEditors(emails); }); diff --git a/mashups/sheets2drive.gs b/mashups/sheets2drive.gs index 545319063..8d869f0b9 100644 --- a/mashups/sheets2drive.gs +++ b/mashups/sheets2drive.gs @@ -6,31 +6,31 @@ */ function createDriveFilesFromSpreadsheet() { // Open the spreadsheet and get the data. - var ss = SpreadsheetApp.openByUrl('ENTER SPREADSHEET URL HERE'); - var sheet = ss.getSheets()[0]; + const ss = SpreadsheetApp.openByUrl('ENTER SPREADSHEET URL HERE'); + const sheet = ss.getSheets()[0]; /** @type {string[][]} */ - var data = sheet.getDataRange().getValues(); + const data = sheet.getDataRange().getValues(); // Remove any frozen rows from the data, since they contain headers. data.splice(sheet.getFrozenRows()); // Create a PDF in Google Drive for each row. data.forEach(function(row) { - var fileName = row[0]; - var htmlContent = row[1]; - var emailsStr = row[2]; + const fileName = row[0]; + const htmlContent = row[1]; + const emailsStr = row[2]; // Split the emails into an array and remove extra whitespace. - var emails = emailsStr.split(',').map(function(email) { + const emails = emailsStr.split(',').map(function(email) { return email.trim(); }); // Convert the HTML content to PDF. - var html = Utilities.newBlob(htmlContent, 'text/html'); - var pdf = html.getAs('application/pdf'); + const html = Utilities.newBlob(htmlContent, 'text/html'); + const pdf = html.getAs('application/pdf'); // Create the Drive file and share it out. - var file = DriveApp.createFile(pdf).setName(fileName); + const file = DriveApp.createFile(pdf).setName(fileName); file.addEditors(emails); }); } diff --git a/mashups/sheets2forms.gs b/mashups/sheets2forms.gs index 263cacd23..fe14a8536 100644 --- a/mashups/sheets2forms.gs +++ b/mashups/sheets2forms.gs @@ -6,27 +6,27 @@ */ function createFormsFromSpreadsheet() { // Open the spreadsheet and get the data. - var ss = SpreadsheetApp.openByUrl('ENTER SPREADSHEET URL HERE'); - var sheet = ss.getSheets()[0]; + const ss = SpreadsheetApp.openByUrl('ENTER SPREADSHEET URL HERE'); + const sheet = ss.getSheets()[0]; /** @type {string[][]} */ - var data = sheet.getDataRange().getValues(); + const data = sheet.getDataRange().getValues(); // Remove any frozen rows from the data, since they contain headers. data.splice(sheet.getFrozenRows()); // Create a form for each row. data.forEach(function(row) { - var title = row[0]; - var question = row[1]; - var emailsStr = row[2]; + const title = row[0]; + const question = row[1]; + const emailsStr = row[2]; // Split the emails into an array and remove extra whitespace. - var emails = emailsStr.split(',').map(function(email) { + const emails = emailsStr.split(',').map(function(email) { return email.trim(); }); // Create the form, append the question, and share it out. - var form = FormApp.create(title); + const form = FormApp.create(title); form.addTextItem().setTitle(question); form.addEditors(emails); }); diff --git a/mashups/sheets2gmail.gs b/mashups/sheets2gmail.gs index 07e3393d9..7d5ed23ff 100644 --- a/mashups/sheets2gmail.gs +++ b/mashups/sheets2gmail.gs @@ -6,19 +6,19 @@ */ function sendEmailsFromSpreadsheet() { // Open the spreadsheet and get the data. - var ss = SpreadsheetApp.openByUrl('ENTER SPREADSHEET URL HERE'); - var sheet = ss.getSheets()[0]; + const ss = SpreadsheetApp.openByUrl('ENTER SPREADSHEET URL HERE'); + const sheet = ss.getSheets()[0]; /** @type {string[][]} */ - var data = sheet.getDataRange().getValues(); + const data = sheet.getDataRange().getValues(); // Remove any frozen rows from the data, since they contain headers. data.splice(sheet.getFrozenRows()); // Send an email for each row. data.forEach(function(row) { - var subject = row[0]; - var htmlMessage = row[1]; - var emails = row[2]; + const subject = row[0]; + const htmlMessage = row[1]; + const emails = row[2]; // Send the email. GmailApp.sendEmail(emails, subject, '', { diff --git a/mashups/sheets2maps.gs b/mashups/sheets2maps.gs index 62087fcb1..33e4d29c6 100644 --- a/mashups/sheets2maps.gs +++ b/mashups/sheets2maps.gs @@ -12,13 +12,13 @@ * @customFunction */ function COUNTY(address) { - var results = Maps.newGeocoder().geocode(address).results; + const results = Maps.newGeocoder().geocode(address).results; if (!results || results.length === 0) { throw new Error('Unknown address'); } /** @type {{long_name: string, types: string[]}[]} */ - var addressComponents = results[0].address_components; - var counties = addressComponents.filter(function(component) { + const addressComponents = results[0].address_components; + const counties = addressComponents.filter(function(component) { return component.types.indexOf('administrative_area_level_2') >= 0; }); if (!counties.length) { diff --git a/mashups/sheets2slides.gs b/mashups/sheets2slides.gs index 48736bd9f..6a140911a 100644 --- a/mashups/sheets2slides.gs +++ b/mashups/sheets2slides.gs @@ -6,30 +6,30 @@ */ function createPresentationsFromSpreadsheet() { // Open the spreadsheet and get the data. - var ss = SpreadsheetApp.openByUrl('ENTER SPREADSHEET URL HERE'); - var sheet = ss.getSheets()[0]; + const ss = SpreadsheetApp.openByUrl('ENTER SPREADSHEET URL HERE'); + const sheet = ss.getSheets()[0]; /** @type {string[][]} */ - var data = sheet.getDataRange().getValues(); + const data = sheet.getDataRange().getValues(); // Remove any frozen rows from the data, since they contain headers. data.splice(sheet.getFrozenRows()); // Create a presentation for each row. data.forEach(function(row) { - var title = row[0]; - var content = row[1]; - var emailsStr = row[2]; + const title = row[0]; + const content = row[1]; + const emailsStr = row[2]; // Split the emails into an array and remove extra whitespace. - var emails = emailsStr.split(',').map(function(email) { + const emails = emailsStr.split(',').map(function(email) { return email.trim(); }); // Create the presentation, insert a new slide at the start, append the content, // and share it out. - var presentation = SlidesApp.create(title); - var slide = presentation.insertSlide(0, SlidesApp.PredefinedLayout.MAIN_POINT); - var textBox = slide.getShapes()[0]; + const presentation = SlidesApp.create(title); + const slide = presentation.insertSlide(0, SlidesApp.PredefinedLayout.MAIN_POINT); + const textBox = slide.getShapes()[0]; textBox.getText().appendParagraph(content); presentation.addEditors(emails); }); diff --git a/mashups/sheets2translate.gs b/mashups/sheets2translate.gs index 073c43f31..a863e8378 100644 --- a/mashups/sheets2translate.gs +++ b/mashups/sheets2translate.gs @@ -9,10 +9,10 @@ * under "Tools > Script editor"). */ function onEdit() { - var range = SpreadsheetApp.getActiveRange(); - var value = range.getValue(); + const range = SpreadsheetApp.getActiveRange(); + const value = range.getValue(); if (typeof value === 'string') { - var translated = LanguageApp.translate(value, '', 'en'); + const translated = LanguageApp.translate(value, '', 'en'); range.setNote(translated); } }