Git Product home page Git Product logo

Comments (12)

sgebr01 avatar sgebr01 commented on June 14, 2024 2

I deployed it and then tried out the form(I wasn't expecting it to work, I was trying to get some debugging info) and then it worked for some reason. I'm not sure why this happened. I was able to get the name to be appended with the pre-written string. Isn't the point of loggers to debug, not to fix?

from learn-to-send-email-via-google-script-html-no-server.

sgebr01 avatar sgebr01 commented on June 14, 2024 1

Here is all of of my code on Google App Scripts, I did change the email it is correct in the actual program..

/******************************************************************************
 * 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. *
 ******************************************************************************/

// if you want to store your email server-side (hidden), uncomment the next line
var TO_ADDRESS = "[email protected]";

// spit out all the keys/values from the form in HTML for email
// uses an array of keys if provided or the object to determine field order
function formatMailBody(obj, order) {
  var result = "";
  if (!order) {
    order = Object.keys(obj);
  }
  
  // loop over all keys in the ordered form data
  for (var idx in order) {
    var key = order[idx];
    result += "<h4 style='text-transform: capitalize; margin-bottom: 0'>" + key + "</h4><div>" + sanitizeInput(obj[key]) + "</div>";
    // for every key, concatenate an `<h4 />`/`<div />` pairing of the key name and its value, 
    // and append it to the `result` string created at the start.
  }
  return result; // once the looping is done, `result` will be one long string to put in the email body
}

// sanitize content from the user - trust no one 
// ref: https://developers.google.com/apps-script/reference/html/html-output#appendUntrusted(String)
function sanitizeInput(rawInput) {
   var placeholder = HtmlService.createHtmlOutput(" ");
   placeholder.appendUntrusted(rawInput);
  
   return placeholder.getContent();
 }

function doPost(e) {

  try {
    Logger.log(e); // the Google Script version of console.log see: Class Logger
    record_data(e);
    
    // shorter name for form data
    var mailData = e.parameters;

    // names and order of form elements (if set)
    var orderParameter = e.parameters.formDataNameOrder;
    var dataOrder;
    if (orderParameter) {
      dataOrder = JSON.parse(orderParameter);
    }
    
    // determine recepient of the email
    // if you have your email uncommented above, it uses that `TO_ADDRESS`
    // otherwise, it defaults to the email provided by the form's data attribute
    var sendEmailTo = (typeof TO_ADDRESS !== "undefined") ? TO_ADDRESS : mailData.formGoogleSendEmail;
    
    var emailSubject = String(mailData.name) + " - Take Action Form Submitted"

    // send email if to address is set
    if (sendEmailTo) {
      MailApp.sendEmail({
        to: String(sendEmailTo),
        subject: String(emailSubject),
        replyTo: String(mailData.email), 
        htmlBody: formatMailBody(mailData, dataOrder)
      });
    }

    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": error}))
          .setMimeType(ContentService.MimeType.JSON);
  }
}


/**
 * record_data inserts the data received from the html form submission
 * e is the data received from the POST
 */
function record_data(e) {
  var lock = LockService.getDocumentLock();
  lock.waitLock(30000); // hold off up to 30 sec to avoid concurrent writing
  
  try {
    Logger.log(JSON.stringify(e)); // log the POST data in case we need to debug it
    
    // select the 'responses' sheet by default
    var doc = SpreadsheetApp.getActiveSpreadsheet();
    var sheetName = e.parameters.formGoogleSheetName || "responses";
    var sheet = doc.getSheetByName(sheetName);
    
    var oldHeader = sheet.getRange(1, 1, 1, sheet.getLastColumn()).getValues()[0];
    var newHeader = oldHeader.slice();
    var fieldsFromForm = getDataColumns(e.parameters);
    var row = [new Date()]; // first element in the row should always be a timestamp
    
    // loop through the header columns
    for (var i = 1; i < oldHeader.length; i++) { // start at 1 to avoid Timestamp column
      var field = oldHeader[i];
      var output = getFieldFromData(field, e.parameters);
      row.push(output);
      
      // mark as stored by removing from form fields
      var formIndex = fieldsFromForm.indexOf(field);
      if (formIndex > -1) {
        fieldsFromForm.splice(formIndex, 1);
      }
    }
    
    // set any new fields in our form
    for (var i = 0; i < fieldsFromForm.length; i++) {
      var field = fieldsFromForm[i];
      var output = getFieldFromData(field, e.parameters);
      row.push(output);
      newHeader.push(field);
    }
    
    // more efficient to set values as [][] array than individually
    var nextRow = sheet.getLastRow() + 1; // get next row
    sheet.getRange(nextRow, 1, 1, row.length).setValues([row]);

    // update header row with any new data
    if (newHeader.length > oldHeader.length) {
      sheet.getRange(1, 1, 1, newHeader.length).setValues([newHeader]);
    }
  }
  catch(error) {
    Logger.log(error);
  }
  finally {
    lock.releaseLock();
    return;
  }

}

function getDataColumns(data) {
  return Object.keys(data).filter(function(column) {
    return !(column === 'formDataNameOrder' || column === 'formGoogleSheetName' || column === 'formGoogleSendEmail' || column === 'honeypot');
  });
}

function getFieldFromData(field, data) {
  var values = data[field] || '';
  var output = values.join ? values.join(', ') : values;
  return output;
}

from learn-to-send-email-via-google-script-html-no-server.

sgebr01 avatar sgebr01 commented on June 14, 2024 1

OK, I will try that out.

from learn-to-send-email-via-google-script-html-no-server.

nelsonic avatar nelsonic commented on June 14, 2024

@sgebr01 did you forget to include the } to terminate the if statement above? make sure it's there in your code. 💭

from learn-to-send-email-via-google-script-html-no-server.

sgebr01 avatar sgebr01 commented on June 14, 2024

@nelsonic Yes, I did, I just forgot to put it in the post. I've also tried concatenating the two in a variable and then passing them as the subject but that didn't work either. Here is the code.


    var sendEmailTo = (typeof TO_ADDRESS !== "undefined") ? TO_ADDRESS : mailData.formGoogleSendEmail;
    
    var emailSubject = String(mailData.name) + " - Take Action Form Submitted"

    // send email if to address is set
    if (sendEmailTo) {
      MailApp.sendEmail({
        to: String(sendEmailTo),
        subject: String(emailSubject),
        replyTo: String(mailData.email), 
        htmlBody: formatMailBody(mailData, dataOrder)
      });
    }

from learn-to-send-email-via-google-script-html-no-server.

nelsonic avatar nelsonic commented on June 14, 2024

Hmm, that code looks like it should work. 💭
Consider sharing more of your code (temporarily) so we can help debug.

from learn-to-send-email-via-google-script-html-no-server.

nelsonic avatar nelsonic commented on June 14, 2024

If you haven't already done it, consider adding some Logger statements to your doPost code to try and debug it:

// send email if to address is set
var emailData = {
    to: String(sendEmailTo),
    subject: String(mailData.name) + " - Take Action Form Submitted",
    replyTo: String(mailData.email), 
    htmlBody: formatMailBody(mailData, dataOrder)
}

Logger.log(emailData);

if (sendEmailTo) {
  MailApp.sendEmail(emailData);
}

from learn-to-send-email-via-google-script-html-no-server.

nelsonic avatar nelsonic commented on June 14, 2024

@sgebr01 sometimes just the act of logging something helps to see what the "problem" was ... 🔍
I could not see why the code wasn't working if it's any consolation, hence the Logger suggestion above. 💭

from learn-to-send-email-via-google-script-html-no-server.

sgebr01 avatar sgebr01 commented on June 14, 2024

How can I see what data the loggers returned now so that I can see why it wasn't working before?

from learn-to-send-email-via-google-script-html-no-server.

nelsonic avatar nelsonic commented on June 14, 2024

https://developers.google.com/apps-script/guides/logging#stackdriver_logging

from learn-to-send-email-via-google-script-html-no-server.

mckennapsean avatar mckennapsean commented on June 14, 2024

with some of the tips, it sounds like the form started working for you (albeit, why we are not quite sure). is that right, @sgebr01 ?

did you learn anything else from the logger, or do you need any more assistance here? closing if things are otherwise good now :) thanks for posting all your findings so far!

from learn-to-send-email-via-google-script-html-no-server.

sgebr01 avatar sgebr01 commented on June 14, 2024

Yes, the form did work, I'm still curious as to why though. I would be interested in finding out more from the logger, since I have noticed that changes take several tries for them to go into effect(such as changing the email that the responses will be sent to) - but I've been confused with the logger and don't have much experience with it.

from learn-to-send-email-via-google-script-html-no-server.

Related Issues (20)

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.