How to Trigger a Google Apps Script Function from an HTML Page

I lead a sports team and created a website for it. I'm interested in adding a button to an admin page that allows me to send a quick email to all team members at once. The message would typically read: "Important update - please check the website for more details."

I know using a distribution list in Outlook would be simpler, but I prefer to use Google Apps Script to gain a better understanding of its capabilities.

Currently, I have a Google Spreadsheet containing all the email addresses and a basic script function to send the emails. It works perfectly when executed inside the script editor, but I wonder if there's a way to trigger this functionality from an external website using a button and some JavaScript?

Answer №1

To integrate a Google UI object into your website, you will need to create a Script that can be deployed as a web app. This object will include a button that triggers a script function to send an email.

When publishing the web app, ensure that access is limited only to yourself so that the UI Blob created will not be functional for the public. Below is a basic script example with a single button:

function doGet() {
  var app = UiApp.createApplication();

  var button = app.createButton('Send Schedule Change Email');
  app.add(button);

  var handler = app.createServerHandler('myClickHandler');
  button.addClickHandler(handler);

  return app;
}

function myClickHandler(e) {
  var app = UiApp.getActiveApplication();

  TeamSpreadsheet.sendScheduleChanged();

  var label = app.createLabel('Message Sent')
                 .setId('statusLabel')
                 .setVisible(false);

  label.setVisible(true);

  app.close();
  return app;
}

In order to access your existing script from the web app, save a version of it and add it as a library in the new script. Make sure the utility script in the library opens the spreadsheet using SpreadsheetApp.openById() instead of SpreadsheetApp.getActiveSpreadsheet(). Handle any calls to "active" objects carefully to avoid errors.

Note that debugging may be challenging, as the app-script debugger might display server errors when tracing into library routines.

Hopefully, this information helps you get started with integrating a Google UI object into your site!

Answer №2

In addition to the detailed response from Mogsdad, I would like to offer a simpler solution tailored to your specific situation, considering you already have a functioning script.

You can simply take your existing script and incorporate a doGet() function as demonstrated in Mogsdad's example. Then, set up a button click handler that will trigger the execution of your email-sending function. In this function, make the necessary adjustments by replacing getActiveSpreadsheet() with

SpreadsheetApp.OpenById("the ID of the SS")
and getActiveSheet() with OpenByName().

After making these modifications, follow Mogsdad's guidance on deploying the script as a web application under your own credentials and utilize the provided URL to access it through a link on your website.

To safeguard against any unforeseen issues, it is advisable to work on a duplicate copy of your original spreadsheet so that you always have a functional version readily available. If you require more precise assistance or encounter difficulties during the process, do not hesitate to share your current script for personalized support with the necessary modifications.

Please note: This message is intended as a supplementary comment within an answer format for improved readability.

Answer №3

Simply deploy your script as a web application and then, with just a click of a button, run the following code:

window.open("https://script.google.com/macros/s/<id>/exec");

I'm not sure if this feature was available last year.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Enhancing CKEditor: Inserting new elements upon each dialog opening

I am facing a challenge where I need to dynamically add varying numbers of elements to a dialog window each time it is opened. Below is the code I am working with: CKEDITOR.on( 'dialogDefinition', function(ev) { var dialogName = ev.data.name ...

What is the best location to manage errors within a sequelize ORM query?

I am working with the Sequelize ORM within a Node/Express environment. My database has two tables: one for Users and another for Items. The Item table includes a foreign key that is linked to the UserId in the User table. Whenever I attempt to create an ...

Learn how to dynamically import and load components in VueJS while rendering a list

I am currently rendering a list. <div v-for="msg in messages"> <div v-if="msg.type==='component'"> <component v-bind:is="getComponent(msg.component)" :data="msg.data" :text="msg.text"></component> </div> ...

Guidance on invoking the navigate function from a component displayed at the highest level of rendering

Within the react-navigation documentation, it is explained that you can initiate navigation from the top-level component using the following method: import { NavigationActions } from 'react-navigation'; const AppNavigator = StackNavigator(SomeA ...

Is Swiper carousel navigation secretly operating without being seen?

I've got a website that utilizes the Swiper carousel from SwiperJS, find it here: An issue I am facing is that the navigation elements are invisible but functional, with the pagination feature unaffected. This peculiar behavior is observed only in Sa ...

The smooth scroll feature is not functioning properly on the animated mouse-scroll down button

I've recently added an Animated Mouse Scroll Down button on my website. However, when I click the button, the smooth scroll feature is not working as expected. Important Note: I already have a separate button for navigating to the next section where ...

The Mantine date picker is causing an error stating that objects are not valid as a React child

I'm currently experimenting with utilizing Mantine Date in NextJS. The goal is to have the selected date displayed in the HTML text heading when a user clicks on it. For instance, if a user selects January 1st, 2023, the text should show like this: Da ...

Unable to retrieve a string from one function within another function

Three functions are responsible for triggering POST API calls, with the intention of returning a success or failure message to whoever invokes them (Observable<string>). In an effort to avoid repetition, I introduced a new function to retrieve succe ...

Navigating nested loops within multidimensional arrays

Currently, I am experimenting with nested loops to search through nested arrays in order to find a specific value called "codItem". Below is a test model for the array (as I do not have access to the original fetch request on weekends): let teste = [{ it ...

Combining the power of Vuforia with the capabilities of Three

I'm having difficulty with the integration of three.js and Vuforia, as I have limited knowledge about OpenGl which makes it challenging to troubleshoot. Our team is working on a small AR app where we aim to utilize Vuforia for tracking and recognitio ...

encountering a problem with npm while trying to execute the project

Encountering a persistent issue when attempting to run my project with npm start, even after downgrading my node version. Despite trying various solutions found on platforms like stackoverflow and stackexchange, such as deleting the node_modules folder, ru ...

Tips for updating a React state while using the history API

In an effort to simplify and stay focused on the problem, I recently wrote a brief piece of code. Within this code, there is a component containing a Dialog that plays a role in a commercial process. This Dialog allows users to input information such as no ...

Enhance your React Native app: Utilizing dynamic string variables with react-native-google-places-autocomplete query

I have encountered an issue while attempting to pass a dynamic country code to restrict search results. Here is the code in question: let loc = 'de' <GooglePlacesAutocomplete placeholder="Search" autoFocus={true} onPress ...

Verify if JavaScript is enabled on the browser and show a notification if it is not using a custom ASP control

I am currently working with a combination of Javascript, ASP.net, and C# for my project. My goal is to create a custom control that checks if Javascript is enabled in the user's browser and displays a message accordingly. Here is the approach I have t ...

Unravel the JSON structure

Here is the JSON response I received from an AJAX call: [{"id":null,"period":null,"until":null,"agent_id":"15","agent_zlecajacy_id":"15","offer_id":null,"status":"1","tytul":"Pobranie ksi\u0105g","tresc":"Pobranie ksi\u0105g","data_aktualizacji" ...

Strategies for managing the #document element within an iframe

While testing the current portal, I encountered an issue where I couldn't create any xpath locators. After some investigation, I realized that the problem stemmed from an '#document' causing the path to be cut off and redirecting the "copy x ...

Steps to store chosen option from dropdown list into a database's table

I am currently populating a dropdown list in my PHP file by fetching data from a database. Here is the code snippet: <script type="text/JavaScript"> //get a reference to the select element var $select = $('#bananas'); //reques ...

How to retrieve the object's property with the highest numerical value using JavaScript

My current object is structured as follows: const obj = { happy: 0.6, neutral: 0.1, said: 0.3 } I'm trying to determine the best method to retrieve the property with the highest value (in this case, it would be "happy"). Any suggestions o ...

Angularfire2: Access Denied Error When User Logs Out

When utilizing the following method: login() { this.afAuth.auth.signInWithPopup(new firebase.auth.GoogleAuthProvider()) .then(() => { this.router.navigate(['']); }); } An error occurs during logout: zone.js:915 Unca ...

What is the best way to create floating text that appears when clicked, similar to the mechanics

https://i.stack.imgur.com/nRKG1.jpg Upon clicking the "big cookie" in my game, a popup appears displaying the number of cookies earned (like +276.341 septillion in this image). The popup slowly moves upward and then fades out. I successfully incorporated ...