Having Trouble with Sending Emails Using Google Scripts - Javascript POST Request Issue

I have been working on setting up a basic form on my website where users can input their name, email, and a short message. This information is then sent to Google Apps Script which forwards the message to me via email. Unfortunately, I keep encountering an issue with the Google Apps Script showing a status of failed. I attempted using Logger.log() for debugging purposes, but no logs are visible in the cloud log when I try to check. Below is the JavaScript code snippet for the front end:

      const url = "https://script.google.com/macros/s/AKfycbyedfmVexnnu9oTATVADIbe5oYQbrDpmNWGLcrtSpKtFBZWA9RgnugohF9mLCHeGJc4/exec"
        const data = {
            name: $emailName.val(),
            email: $emailEmail.val(),
            message: $emailMessage.val()
        }
        // const payload = JSON.stringify(data)
        const options = {
            method: 'POST',
            mode: "no-cors",
            contentType: 'application/json',
            payload: JSON.stringify(data)
        }
        console.log(options)
        fetch(url, options)
        .then((response) => {
            console.log("success", response);
        }).catch((error) => {
            console.log(error)
        })
        
    })

})
.catch((error) => {
    console.log(error);
})

Below is the Google Script that I have implemented:

function doPost(e) {

Logger.log(e);

var reply = JSON.parse(e.parameters.email);
var name = JSON.parse(e.parameters.name);
var message = JSON.parse(e.parameters.message);

newMessage = "You have a new email from " + name + ", and you can reply back to them at email " + reply + ". Message below. \n\n\n\n" + message;

object = {
  to: "************",
  replyTo: reply,
  subject: "New Message from " + name,
  body: newMessage
};

  MailApp.sendEmail(object);

return ContentService.createTextOutput(JSON.stringify(e.parameter));


}

If anyone could assist in diagnosing this problem effectively, it would be greatly appreciated as I have spent hours troubleshooting without success. Thank you!

SOLUTION

Front End:

       const url = "https://script.google.com/macros/s/******/exec"
        const data = {
            name: $emailName.val(),
            email: $emailEmail.val(),
            message: $emailMessage.val()
          }
          const options = {
            method: 'POST',
            body: JSON.stringify(data),
          }
          console.log(options)
          fetch(url, options)
          .then((response) => response.text())
          .then((response) => console.log(response))
          .catch((error) => console.log(error))
        
    })

GOOGLE SCRIPT:

function doPost(e) {
  var {name, email, message} = JSON.parse(e.postData.contents);
  var reply = email;
  newMessage = "You have a new email from " + name + ", and you can reply back to them at email " + reply + ". Message below. \n\n\n\n" + message;
  object = {
    to: "*****",
    replyTo: reply,
    subject: "New Message from " + name,
    body: newMessage
  };
  MailApp.sendEmail(object);
  return ContentService.createTextOutput(object);
}

Don't forget to refresh your browser after making changes. It solved my problem after struggling for hours. Huge thanks to Tanaike for the guidance!

Answer №1

Changes to Implement:

  • For your JavaScript code:
    • When using the fetch function, make sure to set the data to body instead of payload.
    • There is no property called contentType in this context.
    • The use of mode: "no-cors" is not necessary for this case.
  • Regarding your Google Apps Script:
    • In this scenario, retrieve the value from body using e.postData.contents.

Once you incorporate the above modifications into your script, it should look like the following:

Updated script:

JavaScript Code:

const url = "<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="9eeaffe7f2f1ecf6ebf9f6fbedaca7afdef9f3fff7f2b0fdf1f3">[email protected]</a>"
const data = {
  name: $emailName.val(),
  email: $emailEmail.val(),
  message: $emailMessage.val()
}
const options = {
  method: 'POST',
  body: JSON.stringify(data),
}
console.log(options)
fetch(url, options)
.then((response) => response.text())
.then((response) => console.log(response))
.catch((error) => console.log(error))

Google Apps Script:

function doPost(e) {
  var {name, email, message} = JSON.parse(e.postData.contents);
  var reply = email;
  newMessage = "You have a new email from " + name + ", and you can reply back to them at email " + reply + ". Message below. \n\n\n\n" + message;
  object = {
    to: "<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="9eeaffe7f2f1ecf6ebf9f6fbedaca7afdef9f3fff7f2b0fdf1f3">[email protected]</a>",
    replyTo: reply,
    subject: "New Message from " + name,
    body: newMessage
  };
  MailApp.sendEmail(object);
  return ContentService.createTextOutput(JSON.stringify(e));
}

Note:

  • If you made changes to the Google Apps Script for Web Apps, remember to update the deployment as a new version. This ensures that the modifications are applied to the Web Apps. Please proceed with caution when doing this.
  • For more information, refer to the guide on "Redeploying Web Apps without Changing URL of Web Apps for new IDE".

References:

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

The JSON ticker for BTC/LTC has stopped functioning

I've been relying on this JSON ticker for the past month and it's been smooth sailing. However, today it suddenly stopped working. Any ideas on what might have caused this issue? $(function () { startRefresh(); }); function startRefresh() { ...

"Custom object fails to deserialize properly using Json.NET, resulting in a null value

I'm struggling with converting a JSON string to a C# object using Json.NET. I utilized the AJAX call .ashx $.ajax({ url: "/Handler/Handler.ashx?WorkType=SaveData", type: "POST", data: JSON.stringify({ 'DataInfo': Info }), / ...

Converting MySQL tables into JSON files

Currently, I am working on a remote CentOS machine without graphical access, relying solely on the terminal. On this machine, there is a MySQL database with a table from which I am fetching the first 10 entries using the command SELECT * FROM MY_TABLE LIMI ...

How to utilize JavaScript to convert a string into a function name

In this specific scenario, I am required to trigger a function based on the data attributes associated with an HTML element. function func1(arg1){ alert("func1"); } function func2(arg2){ alert("func2"); } jQuery(document).on('click', & ...

Alter certain terms in HTML and update background using JavaScript

I want to create a filter that replaces inappropriate words and changes the background color using JavaScript. Here is what I have so far: $(document).ready(function () { $('body').html(function(i, v) { return v.replace(/bad/g, &apos ...

The plugin 'vue' specified in the 'package.json' file could not be loaded successfully

There seems to be an issue with loading the 'vue' plugin declared in 'package.json': The package subpath './lib/rules/array-bracket-spacing' is not defined by the "exports" in C:\Users\<my_username>\Folder ...

Retrieve an array of existing fields in MongoDB by comparing a collection with an array of objects

I'm a newbie when it comes to Mongo and I'm attempting to compare an array with a collection of documents, returning a list of matching records. Let me break it down:First Array I have a collection (user) with the following documents: > db. ...

Utilizing a modular perspective in JavaScript to load JSON files as a view

I've been working on implementing a modular view approach for retrieving data from a JSON file in my JavaScript code, but I'm facing some issues. The snippet of code where I am trying to load the JSON file is contained within a separate JS file a ...

Using Angular 2 to trigger an event when a native DOM element is loaded

I am working towards my main objective of having a textarea element automatically focused upon creation. I recently came up with an idea to use e.target.focus() on the onload event. It would look something like this: <textarea rows="8" col="60" (load)= ...

How do I incorporate a standalone checkbox in a React Material-UI table without affecting row selection upon clicking?

I would like to have a distinction between clicking on a checkbox and clicking on a row. Specifically, I want the following behavior: when I click on the checkbox, only the checkbox should be checked; and when I click on the row, only the row should be se ...

Leveraging scanner-js within an Angular2 environment

Exploring ways to incorporate Scanner-JS into my Angular2 project, a tool I discovered while tinkering with the framework. Being a novice in Angular2, this question might be elementary for some. I successfully installed scanner-js via npm npm install sc ...

What is the procedure for eliminating an event listener that does not directly invoke a function?

I have implemented an event listener in my JS file following a successful AJAX request: var pageButtonsParentElement = document.getElementById("page-buttons"); pageButtonsParentElement.addEventListener('click', event => { ...

Guide to creating a set of three spinners containing options for district, subdistrict head, and urban village head selection

Is there a way to create three spinner elements that contain data related to district, subdistrict head, and urban village head using JSON webservice? How can I connect a query to the JSON webservice in order to populate the three spinner elements? Encou ...

Using JavaScript to dynamically write content to the document in the

What is the correct way to write the HTML break tag "<br>" in JavaScript without it causing a line break? I want the tag to be displayed as text. For example, "the break tag in html is ..." See below for an example of what I am looking for. <scr ...

Creating a unique directive specifically designed to be used within an ng

I have a unique custom directive that I implemented in AngularJS. The directive is called within an ng-repeat loop, as shown below: The array of objects, selectedMealCalc.calculated_foods, is aliased as 'items' <!-- CUSTOM DIRECTIVE --&g ...

Testing for connected components with a specific property (React/Redux)

Having a React component with Redux @connect decorator, a situation arises like this: import React, { Component } from 'react' import { connect } from 'react-redux' @connect(mapStateToProps, { onPress: () => {...code}) // The ...

Loading texts with the same color code via ajax will reveal there are differences among them

I am currently designing a webshop with green as the primary color scheme. Everything is functioning perfectly, but I have noticed that the text within an ajax loaded div appears brighter than it should be. The text that loads traditionally is noticeably d ...

Generating Data into JSON Array/Object

I have some JSON data here, { "cleaning" : [ { "MOPS" : [ { "id" : "123", "name" : "best mops", "price" : "123" }, { ...

Navigate back to the previous page without reloading

Initially, I must clarify that the title of my query may not be entirely representative of what I wish to convey. The situation at hand is as follows: I have developed a jQuery table designed for exhibiting video records. Embedded within this table is a hy ...

How can I execute a function when ng-click is triggered on an <a> tag, and ensure it opens in a new tab?

I am facing an issue with an element in my code, which is as follows: <a ng-click="vm.openPage(page)">{{page.pageId}}</a> Within the vm.openPage() function, there are validations that need to be performed before redirecting to the page refere ...