Trigger an email notification in Google Sheets whenever a designated cell is populated

I am currently exploring ways to enhance collaboration in project management, especially when dealing with numerous stakeholders (Although there are free tools available, integrating new procedures into a public organization's projects can be quite challenging).

Check out the sample file I created here: Google Sheet for Test

The goal is to enable authors to select the menu item "Question" > "Send Question" whenever they input a new question. This action should trigger an automatic email sent to the specified Recipient email address (located in column C), provided that the Question cell is filled (condition checked in "I2").

However, the current script is not functioning as intended.

Please note: I am in the process of learning JavaScript.

Here is the code :

function onOpen() {
  var ui = SpreadsheetApp.getUi();
  ui.createMenu('Question')
      .addItem('Send Question', 'sendQuestion')
      .addSeparator()
      .addItem('Send Answer', 'sendAnswer')
      .addToUi();
}


function sendQuestion() {
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Questions");
  var range = sheet.getRange("A22:L2");
  var emailvalid = range.getCell(1,7).getValue();
  var question = range.getCell(1,5).getValue();
  var answer = range.getCell(1,6).getValue();
  var qvalid = range.getCell(1,8).getValue();
  var ansvalid = range.getCell(1,10).getValue();

  if(qvalid == "Nope"){
      Browser.msgBox("Please, write a question !"); 
    }
  else {
    return false};
  
    if(emailvalid == "Nope"){
      Browser.msgBox("Please, input a valid email address !"); 
    }
  else {
    return false};
  
  var from = range.getCell(1,1).getValue();
  var recipient = range.getCell(1,2).getValue();
  var emailTo = range.getCell(1,3).getValue();
  var subject = "Project Management | Your received a new question" + question;
  var link = "https://docs.google.com/spreadsheets/d/1QUbw0WNju55h5pk3l8QqVCYa_jSCzrIzMjf0N4v-z8c/edit?usp=sharing"
  var options = {}
        options.htmlBody = "Hi" + recipient +"," + "<br />"+ "<br />" + "You received a new question from " + from + "<br />" + "<br />" + "You can answer directly into the table here: "<"br />"+"<br />" + link + "<br />" + "<br />"+ "Thank you";
        GmailApp.sendEmail(emailTo, subject, " ", options);

}

function emailSent(){
  var ui = SpreadsheetApp.getUi();
  var sent = sendQuestion("Send Email ?",ui.ButtonSet.YES_NO);
    
  if(sent == ui.Button.YES) {
    ui.alert("Your Message has been sent.");
  } else {
    ui.alert("Email canceled");
  }
}
  

Answer №1

The main issue lies in the else return false statement within your code. This line is causing the function to terminate if the validation passes, when it should actually exit the function if the validation fails, after displaying an alert about the issue.

if(qValid == 'Nope') {
  Browser.msgBox('etc...');
  return; //Make sure to return here, not in the else block
}
//Apply the same logic for email validation as well

There are several other potential improvements that could be made to this function. However, the important thing is that it currently functions correctly as you continue to learn and grow in your programming skills.

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

Concealing Website Elements with javascript based on class assignments

Despite my hesitation, I have to ask this question after unsuccessful searches in related articles. In my code, I have 7 nav links all with the same class. Due to the length of the HTML, I am looking for a way to hide contents until the link is clicked, an ...

What is the reason behind the browser crashing when a scrollbar pseudo-class is dynamically added to an iframe?

1. Insert a new iframe into your HTML: <iframe id="iframe-box" onload=onloadcss(this) src="..." style="width: 100%; border: medium none; "></iframe> 2. Incorporate the following JavaScript code into your HTML file ...

What is the best method for iterating through an array and generating a glossary list organized by categories?

I have an array filled with definitions. How can I use Vue.js to iterate through this array and create a glossary list organized by letters? Desired Output: A Aterm: A definition of aterm B Bterm: A definition of bterm C Cterm: A definition of cterm ...

Using jQuery to locate the href attribute within a TD element with a specific

Update URL <td class="posts column-posts"><a href="edit.php?tshowcase-categories=ops&amp;post_type=tshowcase">2</a></td> Current URL: <span class="view"><a href="https://blog.company.com/team/tshowcase-categories/ops ...

The issue arises when attempting to update the input of a child component within a reactive form during the OnInit lifecycle

My dilemma arises in working with data stored in the ngrx entity store, as it gets displayed in chunks based on pagination. The issue lies with rxjs somehow remembering the paging history. For instance, when I fetch the first page of data from the server, ...

Emulate the utf8_general_ci collation in mysql database

I am in the process of integrating a javascript application with a third-party API that manages names in a database. The challenge I am facing is that the third-party application uses utf8_general_ci collation to determine name uniqueness, while my applica ...

Having difficulty controlling the DOM within an AngularJS template

My website utilizes AngularJS templates, specifically a Single Page Application (SPA). Within one of the templates, I am utilizing a tab control from the AngularUI library named Ui-Tabset. During the rendering process, this control generates a ul element ...

When working locally, Javascript runs smoothly on localhost, but encounters issues when deployed on GitHub Pages or Vercel

Could anyone shed some light on why my JavaScript code functions properly on localhost, but seems to stop working when deployed on Github Pages or Vercel? Code on GitHub: https://github.com/Marincor/Bx-Bank Deployed on GitHub Page: Deployed on Vercel: ...

Issue with BlobUrl not functioning properly when included as the source in an audio tag

I need help with playing an audio file on click. I tried to implement it but for some reason, it's not working as expected. The response from the server is in binary format, which I decoded using base64_decode(responseFromServer); On the frontend (Vu ...

Utilizing electron and Systemjs to import node modules

Is it feasible for systemjs to utilize require("remote").require("nodemodule") when the module cannot be located in its registry? A similar mechanism seems to be functioning when utilizing electron with typescript and commonjs modules... Has anyone succe ...

Is it possible to execute a function upon exiting my Node application?

Currently, I'm developing a project for my school using Node.js on a Raspberry Pi. The script I have created will be running for extended periods of time to control LEDs. Is there a method that allows me to execute a function upon exiting the program ...

Refreshing a Node.js server page upon receiving a JSON update

My web application serves as a monitoring interface for tracking changes in "objects" processed by the computer, specifically when they exceed a certain threshold. The Node Js server is running on the same machine and is responsible for displaying data in ...

Inspect the database using JavaScript

I'm currently working on a project using JSP and Servlets. On one of the pages, there is a dropdown list and I need to check if the selected value is present in the database. Right now, it only checks when I click a button but I want it to check whene ...

Using the "this" keyword in JavaScript to access the "rel"

Take a look at the JSFIDDLE , where you will notice that the rel attribute in the alert is shown as 'undefined' : var ItemTypeArray = $('input[name^=ItemType]:checked').map(function(){ alert(this.id + ' , r= ' + this.rel) ...

Identify changes in attributes on elements that are updated automatically

On my webpage, I want to have two select boxes that are connected so their values always match. Here's an example: Imagine a page with two selects: <select class="myselector"> <option value='1'>1 <br> < ...

Adjust the itinerary's color using leaflet-routing-machine

Is there a way to change the color of the itinerary from red to a different color using the Leaflet routing machine library? I need to modify the styles option with the L.Routing.Line, but I'm not sure how to do it. import L from 'leaflet' ...

Blending Angular5 and AngularJS in Polymer

We are considering launching two new projects - one using Angular 5 and the other utilizing Polymer. The second project is intended to serve as a component library for reuse in not only the Angular 5 project but also in other AngularJS projects. After res ...

Although it may not be a constructor, the types certainly align perfectly

Although this question has been asked countless times before, none of these solutions seem to work in my case. Whenever I try to call the Config constructor, I encounter a TypeError: Config is not a constructor. Despite researching on Stack Overflow and M ...

Is it necessary to include a request in the API route handler in Next.js when passing parameters?

In my API route handler, I have a function for handling GET requests: import { NextRequest, NextResponse } from "next/server"; export async function GET(req: NextRequest, { params }: { params: { id: string } }) { const { id } = params; try { ...

How can we redirect to another page after checking a box?

In the scenario where a checkbox is checked, how can the page be automatically redirected to @habit, simulating the behavior of clicking a submit button? habits/show <% if @habit.current_level_strike %> <div class="btn" id="red"> <l ...