Giter Site home page Giter Site logo

dwyl / learn-to-send-email-via-google-script-html-no-server Goto Github PK

View Code? Open in Web Editor NEW
3.1K 171.0 909.0 246 KB

:email: An Example of using an HTML form (e.g: "Contact Us" on a website) to send Email without a Backend Server (using a Google Script) perfect for static websites that need to collect data.

License: GNU General Public License v2.0

JavaScript 41.11% HTML 55.84% CSS 3.04%
email html-form google-spreadsheet no-server ajax tutorial howto static-site example form

learn-to-send-email-via-google-script-html-no-server's Introduction

Send Email from a Static HTML Form using Google Apps Mail!

Language : English | 한국어 | Español | Português


A Step-by-Step Example of using an HTML Form to send a "Contact Us" Message via Email without a Backend Server using a Google Script - No PHP, Python, Ruby, Java, Node.js etc.

See a working example here: https://dwyl.github.io/learn-to-send-email-via-google-script-html-no-server/

Note: With EU's GDPR, we strongly advise researching recommendations on user privacy; you may be held responsible for the safekeeping of users' personal data and should provide them a way to contact you.

Warning: Google's API has limits on how many emails it can send in a day. This may vary on your Google account, see the limits here. We recommend implementing this tutorial through Part 3, since the data will always be added to the spreadsheet first, then emailed if possible.

Why?

We needed a way of sending an email from a "static" HTML page when you don't (want to) have a server.

Key Advantages

  • No "Backend" to Deploy/Maintain/Pay for
  • Fully Customisable - every aspect is customisable!
  • Email sent via Google Mail which is Whitelisted Everywhere (high deliverability success)
  • Collect/Store any form data in a Spreadsheet for easy viewing (perfect if you need to share it with non-technical people)

What?

Instead of using a server to send your email, which is easy but requires maintenance, use Google to send mail on your behalf and use Google Spreadsheets to keep track of the data!

You could use a "free" service like https://formspree.io/ to process your form submissions if you don't care where you are sending your data and want to manage the data submitted in your email inbox (messy ... yuck!) Or... you can invest a few minutes and keep data private/manageable. Take your pick.

How?

1. Make a Copy of the Sample Spreadsheet

Sample: https://docs.google.com/spreadsheets/d/1Bn4m6iA_Xch1zzhNvo_6CoQWqOAgwwkOWJKC-phHx2Q/copy

Sign in to your Google account and click on "Make a copy..."

1-make-copy

This should give you something like this:

2-copy-of-sheet

Note: Feel free to change the name of the Copy to anything you want, it will not affect the outcome.

2. Open the Script Editor

Open the Apps Script editor by clicking "Extensions" > "Apps Script"

2 script-editor

Here's a snapshot of the script you need (at this point in the exercise): google-script-just-email.js

3. Set the TO_ADDRESS in the Script

Warning: If you do not uncomment and set your email as the value of TO_ADDRESS, it is possible for someone who has web skills to alter your form and send emailed data to an arbitrary email address.

This risk may not be very likely. Instead, if you wish, you can leave this variable commented out if you accept this possible risk but want the added convenience of setting this email variable inside your HTML form as a data-email attribute. This allows you to easily change where to send emails inside your HTML form without going back through steps 2-6. This functionality does require you to use the provided JS file in Part Two, Step 10.

If you do not want to accept that potential risk, please uncomment the code for the variable TO_ADDRESS, and set this value equal to the email which should receive the form's data when submitted.

3-script-editor-showing-script

4. Save changes to your Script

After making any code changes, you must first save them in the editor using the save icon.

4-apps-script-save-code

5. Publish the Updated Script as a Web App

5-1-publish-button

⚠️ Note: You must select the Anyone option for the 'Who has access' dropdown or form responses will not go through! ⚠️

5-2-deploy-new-version

6. Authorize the Script to Send Emails

6-1-auth-required

Unless you verify your script with Google, you will need to click on "Advanced" and "Go to ... (unsafe)" to give this app permissions.

6-2-auth-failed-verification

6-3-allow-sending-emails

Copy the web app URL to your clip board / note pad. Then Click "OK".

6-4-deploy-as-web-app

7. Create your basic HTML Form

Using the template in index.html in this repo, create your own html file with the basic form. (save the file)

⚠️ If you're already trying to use your own form by this step rather than the example one in this repo:

  • Each of your form elements must have a name attribute equal to that of your column name in the Google sheet
  • The form's class must be gform, i.e. <form class="gform">
    • If you want to alter this later, you will need to create your own version of form-submission-handler.js and amend the expected class

Remember to change the Form action URL to the one you copied in the previous step:

7-html-form

8. Open the HTML Form (page) in your Browser

Fill in some sample data in the HTML Form:

html form

Submit the form. You should see a confirmation that it was sent: form sent

9. Check the email inbox for the address you set

Open the inbox for the email address you set in Step 3 (above)

email received

Done. That's it. You just created an HTML form that sends email!

Part Two - Make It Look Good ...

We are going to keep this Super Lean by using PURE CSS for our Style (fix the "ugly" HTML Form in step 8). And submit the form using JQuery "AJAX" to keep the person on your page/site (avoid "ugly" response page)

10. Submit the Form using JavaScript "AJAX"

To prevent the page from changing to the JSON response/result we need to submit the form using AJAX.

Download the following Javascript file and update your index.html to point to it at the end of your file (*before the closing </body> tag)

<script data-cfasync="false" type="text/javascript" src="form-submission-handler.js"></script>

Warning: If you did not set the TO_ADDRESS variable in Step 3, then you need to include a data-email="[email protected]" attribute inside the main form element. See the example form for more details. Otherwise, if you did set this variable, then you do not need this form attribute.

This keeps the person on the same page. No refresh. Next step is making a thank you message appear.

11. Add a customised Thank You Message Shown when Form Submitted

After following step 10, you can choose to add a thank you message after submitting. Add the following code between the <form> and </form> tags:

<div style="display:none" class="thankyou_message">
 <!-- You can customize the thankyou message by editing the code below -->
 <h2><em>Thanks</em> for contacting us! We will get back to you soon!
 </h2>
</div>

This will now display a "Thank You" message when the form is submitted:

thankyou message

Tailor your message by editing the thankyou_message div.

12. Use CSS to Make the Form Look Good

For this example we are using Pure CSS: https://purecss.io/start/ because its light weight (4.0KB minified and gzipped) and solves our current "problem": Making it Look Good.

PureCSS-Logo-Intro

PureCSS-module-sizes

Without spending too much time on this, we can make the form look a lot nicer:

contact form with pure css

13. Make the email look good too!

By default, the sent email's body contains the key-value pairs from the form, with the key as an <h4> and the value as a <div>. This is a fairly basic, and foolproof view for the data.

You should get something that looks roughly like: Nicely formatted email

Bear in mind that this is a work in progress and does potentially open you up to getting more than you bargained for in the email. Because the email content is now looping over all the data sent in the form, if a robot or malicious user decides to POST more than you've asked for, you'll likely get it in your inbox. Use with caution for now. We're investigating improvements.

You can modify this though, via the script editor. The line:

result += "<h4 style='text-transform: capitalize; margin-bottom: 0'>" + key + "</h4><div>" + obj[key] + "</div>";

has all you need. You can adjust the markup to suit you. We chose an <h4> because it was the best size for the email, and added the small amount of CSS to it to fix the capitalisation (the keys are all lower case in the JS object) and a bit of default spacing. While inline styles like this are generally bad practice on normal web pages, for email HTML they're about the only reliable way to do CSS! We went with a <div> for the value part, because it could be anything - single-line, multiline (a <p> for example wouldn't cut it).

While we're here, there's also a replyTo option for the sendEmail() method which is commented out by default:

MailApp.sendEmail({
  to: TO_ADDRESS,
  subject: "Contact form submitted",
  // replyTo: String(mailData.email), // This is optional and reliant on your form actually collecting a field named `email`
  htmlBody: formatMailBody(mailData)
});

You can uncomment that if you want to add a reply-to field to your email. The example in the script will set the reply-to as the email submitted in the form.

Google's documentation provides more information about MailApp.sendEmail (for example cc/bcc etc.) if you're interested: https://developers.google.com/apps-script/reference/mail/mail-app

Part Three - Store Submitted Contact Form Data in a Spreadsheet

Sending the form data directly to your email inbox is a good first step, but we can do better. Also, as noted above, Google has limits on how many emails you can send in a day, so storing the data into a spreadsheet is safer and less prone to data loss.

14. Add the record_data Function to your Google Apps Script

record_data example

This will record the data received from the POST as a row in the spreadsheet. See: google-apps-script.js for the full code you can copy-paste.

15. Save a New Version and Re-Publish it

Follow Steps 4, 5 & 6 to save a new version and re-publish the script.

16. Re-Test Submitting the Form

submit the form

17 Confirm the Data was Inserted into the Spreadsheet

17-confirm-data-inserted

Live Server (on your localhost)

Because we are loading external .js files, our web browser will not allow us to simply open the index.html from a local directory for testing out the form.

Open your terminal and run this command to install the node modules and start the live server:

npm install live-server --save-dev && node_modules/.bin/live-server --port=8000

It will take a minute to install, but once that's done your live-server will start up.

That starts a node.js HTTP server on port 8000 and opens the form you just created in your default browser. If you wish to update the form styles in style.css or the client-side Javascript in form-submission-handler.js, please be sure to edit index.html to load those resources locally rather than via GitHub.

Note: This is a light taste of Node.js for absolute beginners. You do not need node.js to "deploy" this form, you can run it on an any web server that serves HTML/CSS/JavaScript. If you have never used Node.js before, see: http://nodeguide.com/beginner.html but for the purposes of this exercise (submitting a form without a server) you don't need node.js or live-server it's just a nice thing to have when you are creating your form because it automatically re-loads the page when you make changes in your text editor!

Want more?

If you want us to take this tutorial further, please let us know!

For your convenience, we have hosted a working demo of the field on GitHub Pages, check it out to see the code and how it works: https://dwyl.github.io/learn-to-send-email-via-google-script-html-no-server/

Add your own fields!

In response to Henry Beary's request we made the form handler generic which means you can now add any fields you want to the form.

We also created a form, test.html, which uses all kinds of form input elements so you can just copy and paste elements as desired into your own form. Just be sure to update their names and IDs. You can find a working example of this test form here: https://dwyl.github.io/learn-to-send-email-via-google-script-html-no-server/test.html

Remember to include the fields inside the form that has the class gform and ensure that the name of the form element matches the new column heading in your spreadsheet. e.g:

<fieldset class="pure-group">
  <label for="color">Favourite Color: </label>
  <input id="color" name="color" placeholder="green" />
</fieldset>

This will allow you to capture the person's favourite color: e.g: new-field-contains-data

Let us know if you have any questions!

Uploading Files

This resource may help you get started on uploading files to Google Drive from the Google Script.

Frequently Asked Questions (FAQ's)

  1. How can I get help using this tutorial?
  1. Can I get edit access to the example spreadsheet?
  • No. This is being used to show a working example for anyone to copy, and an editable version could be broken accidentally, or maliciously, by any user.
  1. Why is the webpage forwarding to a bunch of text when I hit submit?
  • You are not properly loading the required Javascript which submits the data via AJAX, or your browser does not support AJAX. Please see Part 2 and check your console logs in case you are finding errors.
  1. Why is the webpage not successfully submitting the form?
  • Check your Javascript console logs. There could be an error while reading in the Javascript we have provided. There could be errors while submitting the form. It is required that your form have a class of gform, and also a data-email attribute if you have not set the TO_ADDRESS variable inside the Google Script file. Furthermore, the provided Javascript code also expects to see an email form element which it uses to check, a warning message for that element when an improper email is submitted, and then a thank-you div as well, which is shown after a form is successfully submitted. Please ensure that all of these HTML elements are in your form. See the sample file for code you can copy and paste. When you have all of these elements and a proper form set up, you should not see any error messages in your Javascript console when you hit submit.
  1. The webpage is saying my data was submitted, but why isn't my data being saved or sent to me?
  • When you copied the spreadsheet and published the Google Script, did you set the permissions to "Anyone, even Anonymous"? This is required for the form to work, since anyone on the internet can hit send to give you their data. Be sure that you have deployed the proper version of the script and used "Manage versions..." when making changes.
  1. How do I change the emails this script sends?
  • You can tweak the Google Script on the server to send emails to anyone and in whatever format you wish. This could be used to send a confirmation email to those contacting you, but we have not added this feature to this tutorial to avoid potential spamming. The sender of the email will always be the Google account you use to create the form/script, however. Further details on how to customize the email can be found in the MailApp API. You can instead use the GmailApp API which may be more flexible for certain use-cases.
  1. Is this secure? Can I use it for sensitive data?
  • No. While data that is sent over POST may be more protected, the information could easily be intercepted by a third party or middleman, and Google has complete access to the data inside a Google Spreadsheet. Email is also not a very secure communication medium by default. We would recommend you invest in a secure platform and server for storing your data if this is a requirement.
  1. What if my data is sent or stored in the wrong order?
  • If your data is in the wrong order, it is recommended to verify that you are loading the clientside JS correctly. The most effective way to do this is to place a debugger call inside the handleFormSubmit() function, and, if it hits the debugger and opens the respective Dev Tools for the broswer/environment, then the clientside JS is being loaded correctly. If the debugger isn't hit, then the JS is not either not loaded or not targeting your form, defaulting the data to a plain object which will have its own alphabetic ordering instead.

Background Reading

learn-to-send-email-via-google-script-html-no-server's People

Contributors

arhell avatar cristianofromagio avatar dalton-cole avatar denyncrawford avatar gimunlee avatar ibsenvalath avatar iteles avatar krizalys avatar lesander avatar martynhoyer avatar mckennapsean avatar mhaddy avatar nelsonic avatar omartan avatar saintsilver avatar timvink avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

learn-to-send-email-via-google-script-html-no-server's Issues

add multi-field demo

It would be excellent to have a simple form demo with a variety of different fields showcasing the variety we now support. It could be hosted on a web playground site like jsfiddle or codepen, at least till we build up the examples to be more robust? We would just need someone to maintain the spreadsheet on Google Drive for it.

We could also mention it in the documentation as an advanced/next step for others.

Multiple Radio Selections

Love this repo!! Awesome, awesome work - > thank you !!

1 - Got everything working great except for multiple radio options. If I choose 2 radio options, it only enters one of the options in my Google Sheet. Any idea how to fix it?

2 - not super important, but is there a way I can edit the email that is sent to me upon the form being submitted? I'd like to clean it up a bit . . . thanks !

IE 11 asking to download the json

When I use this script in IE11 it asks the user the user to "save echo.json from...". And it doesn't show the confirmation message. Anyway to stop it from asking this and just show the success message?

Error on spreadsheet part (Help Wanted)

Hi, first of all, awesome tutorial!

Been making something for about 2-3hours now, fixed some errors I had. But I can't seem to narrow this one down, anyone has a clue on the following error?: (type error: Can not call method getId null. (Rule 38 file 'Code')):

test

adding more fields to a form

I would like some info to customize "html-form-send-email-via-google-script-without-server". I need to add additional text labels but it's, apparently, not as easy as it looks!

Spreadsheet stopped Updating Suddenly - But Email Functionality Working

Hello,

I created a spreadsheet yesterday as instructed (by making a copy) and updated the email ID on the script of the new sheet. It was working fine and I tested it with some dummy entries using a form in my test website.

However, it stopped updating itself since today morning and 'Run'ing and Managing Version of the script did not help. I can vouch that I did not make any change in between.

The email functionality, though, is working normally.

Can you please help me with this?

My script.gs


/******************************************************************************
 * This tutorial is based on the work of Martin Hawksey twitter.com/mhawksey  *
 * But has been simplified and cleaned up to make it more beginner friendly   *
 * All credit still goes to Martin and any issues/complaints/questions to me. *
 ******************************************************************************/

var TO_ADDRESS = "[email protected]"; // confirmation email will be sent to this ID

function doPost(e) {

  try {
    Logger.log(e); // the Google Script version of console.log see: Class Logger
    MailApp.sendEmail(TO_ADDRESS, "Contact Form Submitted",
                      JSON.stringify(e.parameters));
    record_data(e);
    return ContentService    // return json success results
          .createTextOutput(
            JSON.stringify({"result":"success",
                            "data": JSON.stringify(e.parameters) }))
          .setMimeType(ContentService.MimeType.JSON);
  } catch(error) { // if error return this
    Logger.log(error);
    return ContentService
          .createTextOutput(JSON.stringify({"result":"error", "error": e}))
          .setMimeType(ContentService.MimeType.JSON);
  }
}

// new property service GLOBAL
var SCRIPT_PROP = PropertiesService.getScriptProperties();
// see: https://developers.google.com/apps-script/reference/properties/

/**
 * select the sheet
 */
function setup() {
    var doc = SpreadsheetApp.getActiveSpreadsheet();
    SCRIPT_PROP.setProperty("key", doc.getId());
}

/**
 * record_data inserts the data received from the html form submission
 * e is the data received from the POST
 */
function record_data(e) {
  Logger.log(JSON.stringify(e)); // log the POST data in case we need to debug it
  try {
    var doc     = SpreadsheetApp.openById(SCRIPT_PROP.getProperty("key"));
    var sheet   = doc.getSheetByName('responses'); // select the responses sheet
    var headers = sheet.getRange(1, 1, 1, sheet.getLastColumn()).getValues()[0];
    var nextRow = sheet.getLastRow()+1; // get next row
    var row     = [ new Date() ]; // first element in the row should always be a timestamp
    // loop through the header columns
    for (var i = 1; i < headers.length; i++) { // start at 1 to avoid Timestamp column
      if(headers[i].length > 0) {
        row.push(e.parameter[headers[i]]); // add data to row
      }
    }
    // more efficient to set values as [][] array than individually
    sheet.getRange(nextRow, 1, 1, row.length).setValues([row]);
  }
  catch(error) {
    Logger.log(e);
  }
  finally {
    return;
  }

}

The screenshot of the last entries of the spreadsheet is given below:
(some entries are being made by someone in the stackoverflow community after I asked for help in solving a particular scenario with my code in codepen.)

screen shot 2016-09-12 at 17 00 25

Getting a mail response but Google spreadsheet is not being updated.

My script.gs is

var TO_ADDRESS = "[email protected]";

function doPost(e) {

  try {
    Logger.log(e); // the Google Script version of console.log see: Class Logger
    MailApp.sendEmail(TO_ADDRESS, "Contact Form Submitted",
                      JSON.stringify(e.parameters));
    record_data(e);
    return ContentService    // return json success results
          .createTextOutput(
            JSON.stringify({"result":"success",
                            "data": JSON.stringify(e.parameters) }))
          .setMimeType(ContentService.MimeType.JSON);
  } catch(error) { // if error return this
    Logger.log(error);
    return ContentService
          .createTextOutput(JSON.stringify({"result":"error", "error": e}))
          .setMimeType(ContentService.MimeType.JSON);
  }
}

// new property service GLOBAL
var SCRIPT_PROP = PropertiesService.getScriptProperties();
// see: https://developers.google.com/apps-script/reference/properties/

/**
 * select the sheet
 */
function setup() {
    var doc = SpreadsheetApp.getActiveSpreadsheet();
    SCRIPT_PROP.setProperty("key", doc.getId());
}

/**
 * record_data inserts the data received from the html form submission
 * e is the data received from the POST
 */
function record_data(e) {
  Logger.log(JSON.stringify(e)); // log the POST data in case we need to debug it
  try {
    var doc     = SpreadsheetApp.openById(SCRIPT_PROP.getProperty("key"));
    var sheet   = doc.getSheetByName('responses'); // select the responses sheet
    var headers = sheet.getRange(1, 1, 1, sheet.getLastColumn()).getValues()[0];
    var nextRow = sheet.getLastRow()+1; // get next row
    var row     = [ new Date() ]; // first element in the row should always be a timestamp
    // loop through the header columns
    for (var i = 1; i < headers.length; i++) { // start at 1 to avoid Timestamp column
      if(headers[i].length > 0) {
        row.push(e.parameter[headers[i]]); // add data to row
      }
    }
    // more efficient to set values as [][] array than individually
    sheet.getRange(nextRow, 1, 1, row.length).setValues([row]);
  }
  catch(error) {
    Logger.log(e);
  }
  finally {
    return;
  }

}

and custom html form code is

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
  </head>
  <body>
    <form action="https://script.google.com/macros/s/AKfycbxl4FQgZZi6H6ASxfjxoP6DxLOKbn9LKB7gmu6x1RvzrEuK7f0/exec/" method="POST" autocomplete="on"><br><br>
                  <form action="action_page.php">
                     <span style="display:inline-block; width:50px;"></span><input type="text" name="fname" placeholder="First name" maxlength="10" required><br><br>
                     <span style="display:inline-block; width:50px;"></span><input type="text" name="lname" placeholder="Last name" maxlength="10" required><br><br>
                     <span style="display:inline-block; width:50px;"></span><input type="email" name="email" placeholder="Email" maxlength="20" required><br><br>
                     <span style="display:inline-block; width:50px;"></span><input type="number" name="quantity" placeholder="Mobile Number" size="10" required><br><br>
                     <span style="display:inline-block; width:50px;"></span><textarea name="message" placeholder="Message" rows="10" cols="30" required></textarea><br><br>
                     <span style="display:inline-block; width:50px;"></span><input type="submit" value="Submit">
                     <span style="display:inline-block; width:10px;"></span><input type="reset" value="Reset" />
                  </form>
               </form>
  </body>
</html>

Please let me know what I am doing wrong.
TIA.

Assistance needed: Form not submitting to spreadsheet

Here is the issue I see in my console and I have attached a screenshot as well!
screenshot 72

form-submission-handler.js:47 contact form submission handler loaded successfully
form-submission-handler.js:16 Object {name: "[email protected]", message: "[email protected]", email: "[email protected]", color: "[email protected]"}
form-submission-handler.js:43 POST https://script.google.com/a/macros/resilientcoders.org/s/AKfycbzScpu_YmPT5tiG7ZAH3F47MEP_Wx2yT9nvkrQo2WBUVQETrIFW/exec handleFormSubmit @ form-submission-handler.js:43
index.html:1 XMLHttpRequest cannot load https://script.google.com/a/macros/resilientcoders.org/s/AKfycbzScpu_YmPT5tiG7ZAH3F47MEP_Wx2yT9nvkrQo2WBUVQETrIFW/exec. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access. The response had HTTP status code 401.
form-submission-handler.js:33 0 ""
form-submission-handler.js:34

Unable to Display form submission "Thank You" message in the same page - Newbie

Hello,

The instruction for setting up this script is very elaborate and I need you to congratulate on that.

At one point however, either I'm unable to understand the instruction or I'm doing it wrong, when a user submits the form, a blank page is being displayed. However the data is being correctly entered into the spreadsheet.

I wanted that after a user submits the form a thank you message is displayed in the same page below the form (and the form resets itself). Can you please guide me as to how can I implement the same using your code?

Thanks and Regards
AB

Stuck on #11: adding JavaScript "AJAX"

My form was submitting properly and sending to the correct email address before adding this script code:

<script data-cfasync="false" type="text/javascript" src="https://cdn.rawgit.com/dwyl/html-form-send-email-via-google-script-without-server/master/form-submission-handler.js"></script>

After adding in the code I keep receiving these errors in the console:
XMLHttpRequest cannot load https://script.google.com/macros/s/AKfycbxZcN3Cih22AOi28IUTtexOPPWdj1zIT3d2nkvbZTguwhQ8we4V/exec. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access.
Uncaught TypeError: Cannot read property 'style' of null

I've tried troubleshooting but can't figure out the issue. Does anyone have any suggestions? My html file is attached for reference.
index.txt

Help with e var individual elements: Custom Email Message

Hello,
I am new to this, so any help/direction would be appreciated. I have this script working with my website form. I am now trying to edit the script to allow for the email that is sent to be a little more readable. I am having issues pulling out the individual form elements. Here is an example of my edited code, from the master code line #13:
MailApp.sendEmail({to: TO_ADDRESS, subject: "New Message from CamillaFlynn.com", htmlBody: "Hello Friend,

You Have a new message from " + e["name"] + ". Here it is:
" + e["message"] + "

If you want to write back, here is their email address: " + e["email"]});

When I submit a new form, the email sends and the Google spreadsheet is updated properly (as I did not change that part of the code). However the email that is sent does not recognize my code e["message"] etc. For reference, my "id" and "name" elements in the form match what I am trying to call in the above code: "name", "message" and "email".

Here is an example of the email that I receive, as you can see, the form elements are noted as "undefined":
Hello Friend,

You Have a new message from undefined. Here it is:
undefined

If you want to write back, here is their email address: undefined

Can anyone give direction on how to properly pull out the form elements from the Form variable "e"? I have also tried using the format: e[0], e[1], e[2], but that also returned "undefined"

target sheet inside the sheet?

Would it be possible to have a form target a specific sheet inside the document for collecting the results.

Right now it is hard coded to go to the "responses" sheet. What if on a form you could have a hidden input that specified which tab the data was to go to? This way I could have one doc for collecting many types of data from many different forms without having to replicate the whole spreadsheet.

Message contents of email are empty

Hi,

The script is sending an email, however the contents of the email are blank when there should be data inside: {}

This is my request processed screen: {"result":"success","data":"{}"}
This is the script I have:

/******************************************************************************
 * This tutorial is based on the work of Martin Hawksey twitter.com/mhawksey  *
 * But has been simplified and cleaned up to make it more beginner friendly   *
 * All credit still goes to Martin and any issues/complaints/questions to me. *
 ******************************************************************************/

var TO_ADDRESS = "[email protected]"; // change this ...

function doPost(e) {

  try {
    Logger.log(e); // the Google Script version of console.log see: Class Logger
    MailApp.sendEmail(TO_ADDRESS, "Contact Form Submitted",
                      JSON.stringify(e.parameters));
    record_data(e);
    return ContentService    // return json success results
          .createTextOutput(
            JSON.stringify({"result":"success",
                            "data": JSON.stringify(e.parameters) }))
          .setMimeType(ContentService.MimeType.JSON);
  } catch(error) { // if error return this
    Logger.log(error);
    return ContentService
          .createTextOutput(JSON.stringify({"result":"error", "error": e}))
          .setMimeType(ContentService.MimeType.JSON);
  }
}

// new property service GLOBAL
var SCRIPT_PROP = PropertiesService.getScriptProperties();
// see: https://developers.google.com/apps-script/reference/properties/

/**
 * select the sheet
 */
function setup() {
    var doc = SpreadsheetApp.getActiveSpreadsheet();
    SCRIPT_PROP.setProperty("key", doc.getId());
}

/**
 * record_data inserts the data received from the html form submission
 * e is the data received from the POST
 */
function record_data(e) {
  Logger.log(JSON.stringify(e)); // log the POST data in case we need to debug it
  try {
    var doc     = SpreadsheetApp.openById(SCRIPT_PROP.getProperty("key"));
    var sheet   = doc.getSheetByName('responses'); // select the responses sheet
    var headers = sheet.getRange(1, 1, 1, sheet.getLastColumn()).getValues()[0];
    var nextRow = sheet.getLastRow()+1; // get next row
    var row     = [ new Date() ]; // first element in the row should always be a timestamp
    // loop through the header columns
    for (var i = 1; i < headers.length; i++) { // start at 1 to avoid Timestamp column
      if(headers[i].length > 0) {
        row.push(e.parameter[headers[i]]); // add data to row
      }
    }
    // more efficient to set values as [][] array than individually
    sheet.getRange(nextRow, 1, 1, row.length).setValues([row]);
  }
  catch(error) {
    Logger.log(e);
  }
  finally {
    return;
  }

}

And this is my HTML code for my form:

<form action="https://script.google.com/macros/s/AKfycbxFQcPIQYXI3wSwo14dRTJ4lyF_Ci5xWxk0HYOxdoY5n2d291I/exec" method="post" enctype="text/plain" attribute>
<label for="First-Name"><span>First Name <span class="required">*</span></span><input type="text" class="input-field" name="First-Name" value="" /></label><br>
<label for="Last Name"><span>Last Name <span class="required">*</span></span><input type="text" class="input-field" name="Last-Name" value="" /></label><br>
<label for="field2"><span>Email <span class="required">*</span></span><input type="text" class="input-field" name="Email" value="" /></label><br>
<!--<label><span>Telephone</span><input type="text" class="tel-number-field" name="tel_no_1" value="" maxlength="4" />-<input type="text" class="tel-number-field" name="tel_no_2" value="" maxlength="4"  />-<input type="text" class="tel-number-field" name="tel_no_3" value="" maxlength="10"  /></label>-->
<label for="field4"><span>Select an image from above <span class="required">*</span></span><br><select name="Image-Selected" class="select-field">
<option value="A">A</option>
<option value="B">B</option>
<option value="C">C</option>
<option value="D">D</option>
<option value="E">E</option>
</select></label>
<label for="field5"><span>Comments </span><textarea name="Comments" class="textarea-field"></textarea></label>
<label><span>&nbsp;</span><input type="submit" value="Submit" /></label>
</form>

How can I send an email that has all the data in it?
Thank you!

Customizing the received email

Hi:
I installed your script according to your directions and it's working perfectly. Thank you very much for it.
I love it! Now I would like to style the out-going emails from the un-styled format in which they go out and are received now:

{"name":["Visitor"],"message":["Testing Google send mail script."],"email":["[email protected]"]}

Would you please post directions on where and how to do this?

Thanks,

Billy Joe

Email received but content is blank

I have followed the instructions but when I test the form and press "Submit" I get this on the browser:

{"result":"success","data":"{}"}

And this in the Email:

{}

This is what I entered in the form:

Name: test 123
Email: [email protected]
Message: this is a test message

Here is the form HTML:

<div class="modal fade" id="modal1" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
    <div class="modal-dialog">
        <div class="modal-content modal-popup">
            <a href="#" class="close-link"><i class="icon_close_alt2"></i></a>
            <h3 class="white">Contact Techpubs</h3>
            <form action="https://script.google.com/macros/s/AKfycbwedovtuJ5dGWLH4agdQcjxsqWJaOz92KPZmiQxAlGIt3Ik7Ds/exec" method="POST" class="popup-form">
                <input type="text" class="form-control form-white" placeholder="Full Name">
                <input type="text" class="form-control form-white" placeholder="Email Address">
                <!--<input type="textarea" class="form-control form-white" placeholder="How can we help you?"> -->
                <textarea class="form-control form-white" rows="3" placeholder="How can we help you?"></textarea>

                <button type="submit" class="btn btn-submit">Submit</button>
            </form>
        </div>
    </div>
</div>

And here is the script.gs:

/******************************************************************************

  • This tutorial is based on the work of Martin Hawksey twitter.com/mhawksey *
  • But has been simplified and cleaned up to make it more beginner friendly *
  • All credit still goes to Martin and any issues/complaints/questions to me. *
    ******************************************************************************/

var TO_ADDRESS = "[email protected]"; // change this ...

function doPost(e) {

try {
Logger.log(e); // the Google Script version of console.log see: Class Logger
MailApp.sendEmail(TO_ADDRESS, "Contact Form Submitted",
JSON.stringify(e.parameters));
record_data(e);
return ContentService // return json success results
.createTextOutput(
JSON.stringify({"result":"success",
"data": JSON.stringify(e.parameters) }))
.setMimeType(ContentService.MimeType.JSON);
} catch(error) { // if error return this
Logger.log(error);
return ContentService
.createTextOutput(JSON.stringify({"result":"error", "error": e}))
.setMimeType(ContentService.MimeType.JSON);
}
}

// new property service GLOBAL
var SCRIPT_PROP = PropertiesService.getScriptProperties();
// see: https://developers.google.com/apps-script/reference/properties/

/**

  • select the sheet
    */
    function setup() {
    var doc = SpreadsheetApp.getActiveSpreadsheet();
    SCRIPT_PROP.setProperty("key", doc.getId());
    }

/**

  • record_data inserts the data received from the html form submission
  • e is the data received from the POST
    */
    function record_data(e) {
    Logger.log(JSON.stringify(e)); // log the POST data in case we need to debug it
    try {
    var doc = SpreadsheetApp.openById(SCRIPT_PROP.getProperty("key"));
    var sheet = doc.getSheetByName('responses'); // select the responses sheet
    var headers = sheet.getRange(1, 1, 1, sheet.getLastColumn()).getValues()[0];
    var nextRow = sheet.getLastRow()+1; // get next row
    var row = [ new Date() ]; // first element in the row should always be a timestamp
    // loop through the header columns
    for (var i = 1; i < headers.length; i++) { // start at 1 to avoid Timestamp column
    if(headers[i].length > 0) {
    row.push(e.parameter[headers[i]]); // add data to row
    }
    }
    // more efficient to set values as [][] array than individually
    sheet.getRange(nextRow, 1, 1, row.length).setValues([row]);
    }
    catch(error) {
    Logger.log(e);
    }
    finally {
    return;
    }

}

Appreciate any assistance you can give! Thanks!

Not able to link my form to sheets AND not able to Redirect to any page on Submit.

MY CODE IS

<head>
    <meta charset="utf-8" />
    <title>Email Enquiry - Formoid css form</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">


</head>
<body class="blurBg-false" style="background-color:#EBEBEB">



<!-- Start Formoid form-->
<link rel="stylesheet" href="formoid_files/formoid1/formoid-solid-green.css" type="text/css" />
<script type="text/javascript" src="formoid_files/formoid1/jquery.min.js"></script>
<form class="formoid-solid-green" style="background-color:#FFFFFF;font-size:14px;font-family:'Roboto',Arial,Helvetica,sans-serif;color:#34495E;max-width:480px;min-width:150px" method="post" action="https://script.google.com/macros/s/AKfycbyPsVYfIewWT_jqz_D9fUyTlb28JLfTdEc_lR9JVJiKHdnmzEQ/exec" onSubmit="alert('Thank you for your feedback.')"><div class="title"><h2>Email Enquiry</h2></div>
    <div class="element-input" title=" Enter Name of Parent"><label class="title"><span class="required">*</span></label><div class="item-cont"><input class="large" type="text" name="input" required="required" placeholder="Name of Parent"/><span class="icon-place"></span></div></div>
    <div class="element-phone" title="Enter parent's Contact number"><label class="title"><span class="required">*</span></label><div class="item-cont"><input class="large" type="tel" pattern="[+]?[\.\s\-\(\)\*\#0-9]{3,}" maxlength="24" name="phone" required="required" placeholder="Cell Phone" value=""/><span class="icon-place"></span></div></div>
    <div class="element-email" title="Enter Parent's email"><label class="title"><span class="required">*</span></label><div class="item-cont"><input class="large" type="email" name="email" value="" required="required" placeholder="Email"/><span class="icon-place"></span></div></div>
    <div class="element-input" title="Enter Name of Student"><label class="title"><span class="required">*</span></label><div class="item-cont"><input class="large" type="text" name="input1" required="required" placeholder="Name of Student"/><span class="icon-place"></span></div></div>
    <div class="element-date" title="Enter Student's Date of Birth"><label class="title"></label><div class="item-cont"><input class="large" data-format="yyyy-mm-dd" type="date" name="date" placeholder="Date of Birth"/><span class="icon-place"></span></div></div>
    <div class="element-multiple" title="Select the class the student is applying for"><label class="title"></label><div class="item-cont"><div class="large"><select data-no-selected="Nothing selected" name="multiple[]" multiple="multiple" >

        <option value="Class VIII">Class VIII</option>
        <option value="Class IX">Class IX</option>
        <option value="Class X">Class X</option>
        <option value="Class XI">Class XI</option>
        <option value="Class XII">Class XII</option></select><span class="icon-place"></span></div></div></div>
    <div class="element-textarea" title="Enter Your message here"><label class="title"></label><div class="item-cont"><textarea class="medium" name="textarea" cols="20" rows="5" placeholder="Coments"></textarea><span class="icon-place"></span></div></div>
<div class="submit"><input type="submit" value="Submit"/></div></form><p class="frmd"><script type="text/javascript" src="formoid_files/formoid1/formoid-solid-green.js"></script>


</body>

AFTER SUBMIT, IT SHOWS-

fullscreen capture 15-05-2016 080149 bmp

Thank you page

Dear,
I´d like to say thank you. Everything works except Thanky you page. I have still result page. My opinion is, that is something missing script.gs (I have ther only doPost, setup and record_data), handleResponse is missing.
Thank you for your answer.
Ben

cors issue with jquery

so i'm having a cors issue when i include the jquery cdn, and my messages never actually get sent, but the form does disappear, with a thank you message showing up. i've downloaded the cors add-on for chrome just as a work around for the moment, but still no data actually is passed through.

Newbie can't follow instruction

Hello guys,
It is most probably due to my lack of skills, but I'm not getting the form to work as described in the article on https://www.npmjs.com/package/html-form-send-email-via-google-script-without-server
First in step 1, the code included in the Sheet's script is much more than what step 2 mentions. No clue what to omit or keep.
Second in step 14, the file https://cdn.rawgit.com/nelsonic/html-form-send-email-via-google-script-without-server/master/jquery-ajax-form-handler.js gives a 404 error.

Two feature request:

  1. is it possible to validate with all the new domain extension from http://data.iana.org/TLD/tlds-alpha-by-domain.txt ?
  2. Is it possible to make the email that the script sends us to look better?

Is it possible to attach files?

Thousands of thanks for the tutorial!

Is it possible to attach files and save them into google drive and pass link to the file in email?

Remove required fields

Hi guys thanks for the awesome code! Is there a way to remove the required email? I tried removing the
"if( !validEmail(data.email)...return false;" in form-submission-handler.js. But that made it so my thank you page didn't show up. I need to have just a message field in my form and email is preventing me from doing so. Thanks for the help! -Lando

Hosting HTML form directly from Google Apps Script web app

Is it possible to host this website project through Google Apps Script without using an external web host?

Looking in the setup guide, I did not see a way to upload the HTML form to GAS or display it straight from the web app URL (in the guide, it is only rendered using the local file and a web browser)

I would like to use this application with an existing web app I have been building if that is possible.

Thanks!

Send email to various emails

Hey,
First of all, thanks for the great work.
Is there a way to send the email to various email addresses (get an email address from a form and pass it through to the app to impact the TO_ADDRESS variable ?).
Thanks for your help!

Custom HTML not updating Google Spreadsheets (NEED HELP)

Hi, I'm having some issues with getting the information accepted by the form into the Google Spreadsheet. I believe that I have updated the name and id tags with the column names, but for some reason my form still is not working.

I really need your help. Please let me know what I can do as soon as possible.

Solution to problem with Spreadsheets August 2016

It seems that recently Google has updated its way to create forms, so now the names of the fields are in hidden inputs below the normal ones (https://github.com/heaversm/google-custom-form).

I have also tried the @nelsonic approach, and it emails the answers in JSON format properly, but it doesn't load them into the Google Spreadsheet, at least for me. That's why I wanted to combine two methods to always save the users data in case of more obfuscation changes are taken in the future by Google.

So I recommend you to have a webpage with a iframe inside of it. This iframe would contain your own custom form, from another webpage or –as in my example for convenience reasons– from itself using the srcdoc attribute.

Then, you copy the names of those hidden inputs as well as the action form url from your Google Form Preview Page and paste them into the custom form.

And finally, with Ajax we can easily send one copy of the form data to the normal Google Spreadsheet, and the other to our mail with the @nelsonic script solution.

This way, with the iframe and the Ajax, we are avoiding the url redirection to the 'Response registered' page when the form is submitted to Google, but we can hide the iframe from the parent view to be 100% sure.

I post here all my code for you to test it:

Google Spreadsheet with @nelsonic solution: https://docs.google.com/spreadsheets/d/1LUcidZln8fk-VymjyOXX4gfVusmCf8-G-SghraOPNyA/edit?usp=sharing

Custom Form:

<!doctype html>
    <html lang="en">
    <head>
      <meta charset="utf-8">
      <title>Custom Form to Google SpreadSheets</title>
    </head>

    <body>
      <script type="text/javascript">
        function hideIframeAndShowThankYouMessage(){
          document.getElementById('iframe').style.display = "none";
          document.getElementById('thankyou').style.display = "block";
        }
      </script>
       <iframe id="iframe" width="760" height="500" frameborder="0" marginheight="0" marginwidth="0" srcdoc="<html><head></head><body>
       <script src='https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js'></script>
       <script type='text/javascript'>

        $(document).ready(function(){

          $('#form').submit(function(e) {

            // You could also here, for example, valid an email address input

            // It shouldn't appear, but just in case the iframe loads the Google Forms 'Answer registered' page, we hide the iframe from parent js:

            window.top.hideIframeAndShowThankYouMessage();

            // Now we send the same form to two different locations: the first is the ordinary Google Spreadsheet, the second is the Google Apps Script which allows us to receive an email with the form info in JSON format

            var url_sheet = 'https://docs.google.com/forms/d/e/1FAIpQLSdxucfxPO2TgTh4DOKTty6VCykJ6v4RX0nbKjsz1Pc5fLR9gA/formResponse';

            var url_script = 'https://script.google.com/macros/s/AKfycby2xOphkRsr8Uf3mD44-H68yC0U3bUqvKV0bxXrTISTQ7QKDxw/exec';

            $.ajax({
              type: 'POST',
              url: url_sheet,
              data: $('#form').serialize(),
              success: function(data){}
            });

            $.ajax({
              type: 'POST',
              url: url_script,
              data: $('#form').serialize(),
              success: function(data){}
            });

            e.preventDefault();

          });
        });


        </script>

        <!--
            *** TO-DO!! ***        
            1. Copy your form ACTION url from your Google Form Preview Page

            2. Replace value of var url_sheet with that form ACTION url in line 31

            3. Copy your Spreadsheet WEB APP url from Google Script Editor

            4. Replace value of url_script with that WEB APP url in line 33

            3. Look into the source of your Google Form Preview Page and search for the names of the HIDDEN fields which are each one close to the normal input type (... <input type='hidden' name='entry.314619096' jsname='L9xHkb'> ...). We don't need the jsname, only the name

            4. Replace the NAMES fields of every field of the custom form below
         --> 

       <form id='form' method='POST'>

          <label for='name'>Name: </label>
          <input type='text' name='entry.314619096' placeholder='This is easy!' />
          <br/>
          <label for='message'>Message:</label>
          <input type='text' name='entry.2039301116' placeholder='Tell me something! ;)'/>
          <br/>
          <input type='submit' value='Submit'>
      </form></body></html>">Loading...</iframe>
      <h1 id="thankyou" style="display: none">Thank you!</h1>
    </body>
    </html>

Hope it could help someone!

Generic Form Handler?

Can we build a generic form handler that can submit any type of input/data to google?
relates to #17

missing data from radio buttons in Edge

Edge seems to return the radio button grouped items as an HTML Collection and needs some special-casing to get the field names & values.

I have the fix already made for a survey I just built & tested. Can push a fix in a bit.

Adding fields

How do you change the script for account for inputs of type radio or multiple choice? Please and thank you!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.