How do I send an HTML Form in an Email .. not just MAILTO - html

I have an HTML form for people to fill out, and I want it so when they click the submit button, it will just send the email, not bring up their email and ask them to send the message themselves.
When I use:
<form action="MAILTO:emailaddress#email.com"... >
All that does is open up a new window and populates the body of the email, but I want it to just send an email.
And is there a way to format the output of what the email will look like? Instead of just a list of the field names and the entered value.
Thanks.

> 2021 Answer = Easy Way using GMail (5 Mins)
We had a similar challenge to solve yesterday, and we solved it using a Google Apps Script!
Send Email From an HTML Form Without a Backend (Server) via Google!
The solution takes 5 mins to implement and I've documented with step-by-step instructions: https://github.com/nelsonic/html-form-send-email-via-google-script-without-server
Brief Overview
A. Using the sample script, deploy a Google App Script
Deploy the sample script as a Google Spreadsheet APP Script:
google-script-just-email.js
remember to set the TO_ADDRESS in the script to where ever you want the emails to be sent.
and copy the APP URL so you can use it in the next step when you publish the script.
B. Create your HTML Form and Set the action to the App URL
Using the sample html file:
index.html
create a basic form.
remember to paste your APP URL into the form action in the HTML form.
C. Test the HTML Form in your Browser
Open the HTML Form in your Browser, Input some data & submit it!
Submit the form. You should see a confirmation that it was sent:
Open the inbox for the email address you set (above)
Done.
Everything about this is customisable, you can easily
style/theme the form with your favourite CSS Library
and Store the submitted data in a Google Spreadsheet
for quick analysis.
The complete instructions are available on GitHub:
https://github.com/nelsonic/html-form-send-email-via-google-script-without-server

You are making sense, but you seem to misunderstand the concept of sending emails.
HTML is parsed on the client side, while the e-mail needs to be sent from the server. You cannot do it in pure HTML. I would suggest writing a PHP script that will deal with the email sending for you.
Basically, instead of the MAILTO, your form's action will need to point to that PHP script. In the script, retrieve the values passed by the form (in PHP, they are available through the $_POST superglobal) and use the email sending function (mail()).
Of course, this can be done in other server-side languages as well. I'm giving a PHP solution because PHP is the language I work with.
A simple example code:
form.html:
<form method="post" action="email.php">
<input type="text" name="subject" /><br />
<textarea name="message"></textarea>
</form>
email.php:
<?php
mail('youremail#example.com', $_POST['subject'], $_POST['message']);
?>
<p>Your email has been sent.</p>
Of course, the script should contain some safety measures, such as checking whether the $_POST valies are at all available, as well as additional email headers (sender's email, for instance), perhaps a way to deal with character encoding - but that's too complex for a quick example ;).

I actually use ASP C# to send my emails now, with something that looks like :
protected void Page_Load(object sender, EventArgs e)
{
if (Request.Form.Count > 0)
{
string formEmail = "";
string fromEmail = "from#email.com";
string defaultEmail = "default#email.com";
string sendTo1 = "";
int x = 0;
for (int i = 0; i < Request.Form.Keys.Count; i++)
{
formEmail += "<strong>" + Request.Form.Keys[i] + "</strong>";
formEmail += ": " + Request.Form[i] + "<br/>";
if (Request.Form.Keys[i] == "Email")
{
if (Request.Form[i].ToString() != string.Empty)
{
fromEmail = Request.Form[i].ToString();
}
formEmail += "<br/>";
}
}
System.Net.Mail.MailMessage myMsg = new System.Net.Mail.MailMessage();
SmtpClient smtpClient = new SmtpClient();
try
{
myMsg.To.Add(new System.Net.Mail.MailAddress(defaultEmail));
myMsg.IsBodyHtml = true;
myMsg.Body = formEmail;
myMsg.From = new System.Net.Mail.MailAddress(fromEmail);
myMsg.Subject = "Sent using Gmail Smtp";
smtpClient.Host = "smtp.gmail.com";
smtpClient.Port = 587;
smtpClient.EnableSsl = true;
smtpClient.UseDefaultCredentials = true;
smtpClient.Credentials = new System.Net.NetworkCredential("testing#gmail.com", "pward");
smtpClient.Send(defaultEmail, sendTo1, "Sent using gmail smpt", formEmail);
}
catch (Exception ee)
{
debug.Text += ee.Message;
}
}
}
This is an example using gmail as the smtp mail sender. Some of what is in here isn't needed, but it is how I use it, as I am sure there are more effective ways in the same fashion.

Related

How to have Google Forms send automated email with new responses

I have a Google Form which I would like to automatically email someone when a new response is submitted. So far, I have just a simple HTML page with text in the body, however I would like the email content to include the form data as well.
Currently, this is what I have written:
function sendEmail(e) {
//response
var html = HtmlService.createTemplateFromFile("email.html");
var htmlText = html.evaluate().getContent();
var emailTo = "jeffreyabr#gmail.com"
var subject = "New SAP Role Request"
var textBody = "This email requires HTML support. Please make sure you open it with an email client that supports HTML"
var options = {htmlBody: htmlText};
GmailApp.sendEmail(emailTo, subject, textBody, options);
This came from following this basic YouTube tutorial.
Is there more Google Apps Script that I can add to accomplish this? Can I do this from Forms or must I do it from within Sheets?
The e.response object also contains the form data, which can be accessed by using e.response.getItemResponses().
Then to get the question, use getItem().getTitle(). To get the answer, use getResponse().
If you do not need the HTML response, then you can append the questions and answers to the textBody to display them on the email. Otherwise, you would have to add a script in your email.html using HTML scripts or google.script.run.
References:
Event Objects | onFormSubmit(e)
Class FormResponse

Filling Google Forms with Google Sheets

I have an HTML form which saves its responses to a Google Sheet. The form contains the following fields:
Name:
Email:
Subject:
Message:
Now, what I want is I want to automate sending a thank you email to a recipient as soon as he/she fills the form to the address mentioned in the "Email" field. I don't want to use Google Forms as the backend as it is hard to bypass the "Response Recorded" Confirmation page. Also, avoiding PHP would be better for me!
Is there a way to send these e-mails automatically? The format of the email is as follows:
From: <my email address>
To: <email address from the "Email" field in the spreadsheet>
Subject: Re: Submission Received
Hey <name from the "Name" field in the spreadsheet>!
Body of the mail
If there is a way to bypass the confirmation page of Google Forms, please let me know! That would also do!
If you have the data in google sheets, then you can handle your automation there. I setup this sample file that you could probably base your data set on.
From there I attached the below script to the spreadsheet. You would then need to set a trigger to execute this script on a somewhat regular frequency (5 minutes? 1 minute?). I think it should accomplish what you are going for. There's a check built in to ensure that partial data is not sent.
const ss = SpreadsheetApp.getActiveSheet();
const sentMessageColumn = ss.getRange("E:E").getColumn();
function regularProcedure(){
var aCell = ss.getRange(ss.getLastRow(),sentMessageColumn)
while(aCell.isBlank()){
var eRow = aCell.getRow();
if(!(ss.getRange(eRow,2).isBlank() ||
ss.getRange(eRow,3).isBlank() ||
ss.getRange(eRow,4).isBlank()))
{
var newMail = GmailApp.createDraft(
ss.getRange(eRow,2).getValue(),
ss.getRange(eRow,3).getValue(),
ss.getRange(eRow,4).getValue());
newMail.send();
aCell.setValue(true);
}
aCell=aCell.offset(-1,0);
}
}

Is there functionality within Google Scripts to create rich HTML text emails using Google Sheets and Google Docs?

Apologies if this has already been answered - I am quite new to this and probably need some guidance; if this is the wrong forum for that I would happily take some advice :)
I am in the process of exploring solutions for a semi-automated email drafting script using a Google Sheet as the source data. I have used a script I found on the internet (probably a terrible idea, but again I am just starting out) here.
The source document is in rich HTML text but the resulting Gmail draft is in plain text. Is there a way to ensure it generates in rich HTML?
Thanks -
Hugo
EDIT UPDATED ANSWER:
I looked at your script more carefully. It's using a different function called createDraft(). It's not actually sending any emails, it's just created Drafts that you can send later. No problem. Here's the documentation for createDraft. createDraft can ALSO use "htmlBody" as a replacement parameter for the message body. That's what we'll do...
In your script code, change this:
// Create the email draft
GmailApp.createDraft(
config[emailField], // Recipient
emailSubjectUpdated, // Subject
emailBody // Body
);
to this:
// Create the email draft
GmailApp.createDraft({
to: config[emailField], // Recipient
subject: emailSubjectUpdated, // Subject
htmlBody : emailBody // Body
});
As long as your "emailBody" variable content is in html, your email draft should be saved as html tool.
But there's the rub. It's not trivial to convert a Google Document into a pure HTML file without additional external libraries. One solution is simply to forgo a Google Document, and create a real html file inside your script, and use that as your emailBody variable. HERE'S AN EXAMPLE implementation of this solution.
ORIGINAL ANSWER:
The script you linked to didn't appear to include the actual mail sending function. I wrote a script a while ago (for a spreadsheet) that automatically creates an email based on rows of a spreadsheet, and the email is composed with "rich" html.
Here's the mail sending function:
function sendEmail(to,sub,mes) {
var t = "";
var s = "";
var m = "";
sub == null || sub == undefined || sub == "" ? s = "Subject Failed" : s = sub;
mes == null || mes == undefined || mes == "" ? m = "Message Failed!" : m = mes;
to == null || to == undefined || to == "" ? t = "defaultemail#gmail.com" : t = to;
MailApp.sendEmail({to: t, subject: s, htmlBody: m});
}
In this function, I pass in a few variables (the recipient "to", the subject "sub", and the message body "mes") and I make sure the function still works even if any of the variables are for some reason blank. The "mes" is my message body, and it's a string that's written in html. This is all just how I draft the email. You can simplify this greatly if you want (I'll include a simplified version below).
The part that matters is the final line MailApp.sendEmail({to:t,subject:s,htmlBody: m}); PAY PARTICULAR ATTENTION to the "htmlBody" part. If the sendEmail function doesn't have "htmlBody" as the property name for your message body, then it will just send it in plain text. You'll likely just need to find the function that has the "MailApp.sendEmail()" function in it, and adjust it to include the "htmlBody" property name for your message body.
Here's that function simplified:
function sendEmail(recipient, sub, mes) {
MailApp.sendEmail({to: recipient, subject: sub, htmlBody: mes});
}
To read about all the options for sending email using Google Apps Script, read this page.

How to have One URL which sends to one-of-three Google Forms URLs?

I have a need to get equal populations in each of three surveys. The three surveys are identical except for one change - it contains different pictures.
I would like to distribute a single URL to my survey respondents.
I would like to count the number of previous responses I have, and add one.
I would like to redirect the session to one of three (Google Forms) URLs based upon the calculation
(Responses.Count + 1) MOD 3.
I think I need a Google Apps script to do this?
Here is some pseudocode:
var form0 = FormApp.openByUrl(
'htttps://docs.google.com/forms/d/e/2342f23f1mg/viewform'
);
var form1 = FormApp.openByUrl(
'htttps://docs.google.com/forms/d/e/23422333g/viewform'
);
var form2 = FormApp.openByUrl(
'htttps://docs.google.com/forms/d/e/2342wfeijqeovig/viewform'
);
var form0Responses = form0.getResponses();
var form1Responses = form1.getResponses();
var form2Responses = form2.getResponses();
var whichURL = (
form0Responses.length +
form1Responses.length +
form2Responses.length + 1
) % 3; // modulo three
// var goToForm = switch ( whichURL ) blah blah;
// redirect to goToForm;
// How do I redirect now?
Thanks!
Maybe there's a simpler solution possible but I don't think I know of it :)
The common link that you give out could be a link to a "proxy" page that doesn't contain anything but just redirects users to the correct page. Or it could be a link to the actual page with a necessary form embedded. Let's look at the options.
0) Publish your code as web app
In either case you'll need to have your code published as a web app. In GAS it's way simpler than it sounds, you'll find all the info here: https://developers.google.com/apps-script/guides/web
Make sure you set that Anyone, even anonymous can access the app and it always runs as you (if you choose User accessing the app, they'll have to go through authentication process which is not what you need here).
1) Redirect via GAS web app.
Your code in this case would look like so:
// I changed your function a bit so that it could be easier to work with
// in case the number of your forms changes later on
function getForm() {
var forms = [
{
// I'm using openById instead of openByUrl 'cause I've run into issues with
// the latter
form: FormApp.openById('1')
},
{
form: FormApp.openById('2')
},
{
form: FormApp.openById('3')
}
];
var whichURL = 0;
for (var i in forms) {
forms[i].responses = forms[i].form.getResponses().length;
whichURL += forms[i].responses;
}
whichURL++;
// we're returning the actual URL to which we should redirect the visitors
return forms[whichURL % forms.length].form.getPublishedUrl();
}
// doGet is Google's reserved name for functions that
// take care of http get requests to your web app
function doGet() {
// we're creating an html template from which getForm function is called
// as the template is evaluated, the returned result
// of the function is inserted into it
// window.open function is a client-side function
// that will open the URL passed to it as attribute
return HtmlService.createTemplate('<script>window.open("<?= getForm() ?>", "_top");</script>').evaluate();
}
So, after you've published your app, you'll get the link opening which the doGet function will run — and you're going to be redirected to your form.
The thing here is that the URL that you're getting this way is not rather beautiful, sth like https://script.google.com/macros/s/1234567890abcdefghijklmnopqrstuvwxyz/exec and it will also show a message at the top of the page "The app wasn't developed by Google" during those 1-2 seconds before redirect happens.
2) Embed your form into another webpage
The idea here is different: instead of giving your users a "proxy" link, you'll provide them with a page that'll ask a Google script for a correct form link and will display that form in the page in an iframe.
So, there are a couple of steps:
2.1) Change your doGet function (getForm will stay the same):
function doGet() {
return ContentService.createTextOutput(getForm());
}
In this case doGet will not return an html to render by browser but just a link to your form.
Sidenote: after changing the code you'll need to publish a new version of your code for the changes to take effect.
2.2) Create a Google site at sites.google.com
2.3) Insert an "Embed" block into your page, with the following code:
<script>
function reqListener(response) {
// change height and width as needed
document.body.insertAdjacentHTML('beforeend', '<iframe src="' + response.target.response + '" width="400" height="400"></iframe>');
}
var oReq = new XMLHttpRequest();
oReq.addEventListener("load", reqListener);
oReq.open("GET", "INSERT-YOUR-SCRIPT-URL");
oReq.send();
</script>
What it does: javascript code sends an http request to your script, gets the form URL and passes it on into the callback function, reqListener which in turn inserts it into document body within an iframe element.
The good thing is that your URL which will be much more user-friendly (you could use this approach on your own site, too).
As a result, you'll have sth like this:

How to add "Edit Response" link to Google Forms emails?

I have a simple Google Form that collects data, and, using AppScript, sends confirmation emails to users who fill it out. After user submits the form, on confirmation, s/he will see a link to edit his/her response.
I'd like to include that link as a part of the confirmation email (Right now, it only shows up on the page.) How can I obtain the URL to edit a submitted response?
I am able to get the link to the Form through SpreadsheetApp.getActiveSpreadsheet().getFormUrl(). It gives me the following format: https://docs.google.com/a/domain.com/spreadsheet/viewform?formkey=<formKey>
The link however doesn't include the edit key, which is required for users to edit his/her response. The expected URL should look like this: https://docs.google.com/a/domain.com/spreadsheet/viewform?formkey=<formKey>&edit=<editKey>
Thanks for the help in advance!
-K
Edited:
Added a feature request on this: http://code.google.com/p/google-apps-script-issues/issues/detail?id=1345&thanks=1345&ts=1337773007
The answer that this wasn't possible by #Henrique Abreu was true until very recently. Google seems to have added getEditResponseUrl() to the FormResponse class and with that it becomes possible to use code like this to get the edit URL for a bunch of existing forms:
function responseURL() {
// Open a form by ID and log the responses to each question.
var form = FormApp.openById('1gJw1MbMKmOYE40Og1ek0cRgtdofguIrAB8KhmB0BYXY'); //this is the ID in the url of your live form
var formResponses = form.getResponses();
for (var i = 0; i < formResponses.length; i++) {
var formResponse = formResponses[i];
Logger.log(formResponse.getEditResponseUrl());
}
}
To make it automatically email the user as they respond one could add a trigger on form submit. As The situation I'm working with doesn't require people to log in with an apps account I don't have access to an email address automatically so I have a text question that captures the user's email address.
It does ask the question about whether or not editing the forms is what you want. I've been grappling with the relative advantages of editing an existing response or sending a prefilled form using toPrefilledUrl() so that I can see how things have changed over time. I guess this comes down to the value that tracking this will provide you.
If you are using Google Apps your responders can edit there form responses.
See: How to Edit Form Responses
--edit this is now possible. See other answers.
After user submits the form, on confirmation, s/he will see a link to
edit his/her response. I'd like to include that link as a part of the confirmation email
That is not possible, period.
That link is not accessible anywhere and one can't guess/construct it. But, there's some workarounds that might suit you (some suggested here that I'll re-phrase), e.g.
Send a per-populated form link and have the user re-send it. You'd need to have some kind of control field (e.g. the username), so you can know and delete/ignore his older submits. Possibly automatically via a script.
You could also develop and publish an apps-script GUI and send a link to this apps script plus a parameter that you generate where you can determine which entry you should edit. The down-side of this approach is that it's somewhat cumbersome and overkill to re-design the whole form on Apps Script. But again, it works.
At last, you could open an "Enhancement Request" on Apps Script issue tracker and wait until they and Google Spreadsheet/Forms team get together to develop a solution.
Here is a clear blog post that shows you how to do it step by step and explains what's going on under the hood for AppsScripts newbies:
http://securitasdato.blogspot.com/2014/11/sending-confirmation-emails-from-google.html
While collectively you can get there from the all the excellent answers provided here, the script from that post worked best for me.
Does this help - I haven't tried it but I was looking for the same thing a while ago and noticed this.
From this page
https://developers.google.com/apps-script/reference/forms/
code from there contains this:
Logger.log('Published URL: ' + form.getPublishedUrl());
Logger.log('Editor URL: ' + form.getEditUrl());
Jon
Great, script works! Thanks.
For newbies, like me: Just paste the andre's code for function SendConfirmationMail(e) into your spreadsheet's code editor and set 'on form submit' trigger to run it. That's in spreadsheet script editor, not form script editor.
You need to hack in some values. Read the code. For me the confusing one was the need to replace the ********COLUMN SEQUENCE EX 14****** with the sheet column number where you want the edit urls to end up. I used 39 which is one column more than my form was using up.
However, I got runtime probs in this part:
for (var i in headers) {
value = e.namedValues[headers[i]].toString();
// Do not send the timestamp and blank fields
if ((i !== "0") && (value !== "")) {
message += headers[i] + ' :: ' + value + "<br>";
}
}
Dunno why, but I replaced it with this:
for (var keys in columns) {
var key = columns[keys];
if ( e.namedValues[key]) {
message += key + ' :: '+ e.namedValues[key] + "<br>";
}
}
Works for me.
Try This: (Credits is not for me, because i merge two solutions of the third part)
Source: Send Confirmation Email with Google Forms
/* Send Confirmation Email with Google Forms */
function Initialize() {
var triggers = ScriptApp.getScriptTriggers();
for (var i in triggers) {
ScriptApp.deleteTrigger(triggers[i]);
}
ScriptApp.newTrigger("SendConfirmationMail")
.forSpreadsheet(SpreadsheetApp.getActiveSpreadsheet())
.onFormSubmit()
.create();
}
function SendConfirmationMail(e) {
var form = FormApp.openById('***YOUR FORM CODE***');
//enter form ID here
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('***SHEET NAME***');
//Change the sheet name as appropriate
var data = sheet.getDataRange().getValues();
var urlCol = ***************COLUMN SEQUENCE EX 14******; // column number where URL's should be populated; A = 1, B = 2 etc
var responses = form.getResponses();
var timestamps = [], urls = [], resultUrls = [], url;
for (var i = 0; i < responses.length; i++) {
timestamps.push(responses[i].getTimestamp().setMilliseconds(0));
urls.push(responses[i].getEditResponseUrl());
}
for (var j = 1; j < data.length; j++) {
resultUrls.push([data[j][0]?urls[timestamps.indexOf(data[j][0].setMilliseconds(0))]:'']);
url = resultUrls[i-1]
}
sheet.getRange(2, urlCol, resultUrls.length).setValues(resultUrls);
try {
var ss, cc, sendername, subject, headers;
var message, value, textbody, sender;
// This is your email address and you will be in the CC
cc = Session.getActiveUser().getEmail();
// This will show up as the sender's name
sendername = "****YOUR NAME******";
// Optional but change the following variable
// to have a custom subject for Google Docs emails
subject = "Registro de Oportunidade submetido com sucesso";
// This is the body of the auto-reply
message = "Nós recebemos seu registro de oportunidade.<br>Muito Obrigado!<br><br>";
ss = SpreadsheetApp.getActiveSheet();
headers = ss.getRange(1, 1, 1, ss.getLastColumn()).getValues()[0];
// This is the submitter's email address
sender = e.namedValues["********COLUMN NAME OF DESTINATION E-MAIL************"].toString();
for (var i in headers) {
value = e.namedValues[headers[i]].toString();
// Do not send the timestamp and blank fields
if ((i !== "0") && (value !== "")) {
message += headers[i] + ' :: ' + value + "<br>";
}
}
message += "<br>Link to edit" + ' :: ' + url + "<br>";
textbody = message.replace("<br>", "\n");
GmailApp.sendEmail(sender, subject, textbody,
{cc: cc, name: sendername, htmlBody: message});
} catch (e) {
Logger.log(e.toString());
}
}
you can try to populate a form with the values given from that email address than delete previous answers ...
it's not a beautiful way but it can works ...
I don't think we have access to what that value is through the Spreadsheet API (which means Apps Script doesn't have it either). The closest I can think of would be the "key" value in this feed. You'd have to test to find out though. There's no other alternative that I know of other than accessing the Spreadsheet API directly. So first, you'd have to get the last row through the api use ?reverse=true&max-results=1