Adding a button to an email - google-apps-script

I have a Google Apps Script that is contained in a Sheet (which is tied to a Form). When a person fills in the Form, it triggers a series of events within the Sheet. The details of that aren't relevant (I don't think).
I would like to create a script that sends a follow-up email to everyone who filled out the form with a "Yes" or "No" question. To keep it simple, I would like to have two buttons in the email. When they click the button, it logs their response onto a cell in the Sheet.
I am okay with the apps script (.gs) coding, but I'm not very good with html. I can put together the email (shown below) and send it to the recipient, but I don't know how to get the response back from their click. Right now I have the 'myFunction()' script tied to onclick and I have that script ready to go, I just don't know how to get the 'myFunction()' to actually trigger when they click the button in the email.
If you have any solutions for getting the responses from the email, I'd appreciate the help.
Here is the email file (checkIN.html):
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<style>
button {
color: white;
width: 250 px;
padding: 15px 32px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 16px;
}
</style>
</head>
<body>
<p style="font-size:150%;">Good afternoon,<br><br>
Yesterday you assigned <?= info.name ?> to academic recovery for <?= info.subject?>.<br>
Did the student complete the assignment?</p>
<button style = "background-color:#4CAF50;" id='yesButton' onclick='myFunction(True)'> Yes </button>
<button style = "background-color:#f44336;" id='noButton' onclick='myFunction(False)'> No </button>
</body>
</html>
Here are the scripts that send the email and the function ready for a response:
function emailTest() {
var infoDict =
{
name: "Teacher",
subject: "Computer Science",
};
sendEmail(infoDict);
}
function sendEmail(info) {
var templ = HtmlService.createTemplateFromFile('checkIn.html');
templ.info = info;
var ssMessage = templ.evaluate().getContent();
MailApp.sendEmail({
to: "somebody#something.com",
subject: "Academic Recovery",
htmlBody: ssMessage,
noReply: true
});
}
function myFunction(response) {
var ss = SpreadsheetApp.openById("ID goes here");
var tracking = ss.getSheetByName('Tracking');
if (response) {
tracking.getRange("I12").setValue("Yes!");
}
else {
tracking.getRange("I12").setValue("No");
}
}

You can publish the app as web app (accessible to anyone with link) and change the buttons to <a> tags linked to the web app with the query string
The doGet function can accept query parameters. You can embed the row number or other identification method in the URL through some encryption and then decrypt in the doGet. So you will have to rename myFunction to doGet and
e.parameter should give you the query params in doGet.
Workflow: Link generated e.g. http://appurl?complete=yes&row=20 for email.
User clicks the link and goes to the App URL, script gets both params values and updates the range in the row.

The first thing regarding sending buttons on email is that each email client has it's own limitations and that most modern email-services do not allow certain type of content including JavaScript, so it's not possible to use the following type of buttons on the email HTML body:
<button style = "background-color:#4CAF50;" id='yesButton' onclick='myFunction(True)'>
If you fill confortable with Google Apps Script server-side code (.gs) but not with HTML you might be more confortable by sending a Google Form by email with an on form submit trigger to pass the collected response to the corresponding place in your spreadsheet.
Another option, if the email recipients are using Gmail you might use one-click actions. Also you might opt to embed an html form, or make the buttons to open a link on the email HTML body.
Related (from oldest to newest)
How to Embed a Google Form in Email in Google App Script
Embed Google Form in Gmail using Apps Script
How to access or call "Send this form to others"?

Related

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);
}
}

Auto submit google form after a time limit

I want to use app script in my Google form to automatically submit the form in 20 minutes if the user doesn't click on submit within 20 minutes. Anyway to implement this????
No, you cannot control the client-side of Google Forms, even if you add an Apps Script to it, because Apps Script runs on the server.
One possible solution is to serve your form as a Google Apps Script web app. At that point you can write client-side JavaScript and use window.setTimeout to submit the form after 20 minutes.
Here are some example files, Code.gs and quiz.html, that can provide a basic skeleton to start the web app. A blank project will have Code.gs as the default file, then you have to add File > New > HTML file to start the other file.
You can enter the id of any spreadsheet you own in the commented out lines in Code.gs to append the response into that spreadsheet. (You can also automate that process by creating a new spreadsheet as needed. Example of creating spreadsheet to hold data for Apps Script example can be found here.
// file Code.gs
function doGet() {
return HtmlService.createHtmlOutputFromFile("quiz");
}
function doPost(request) {
if (request.answer) {
console.log(request.answer); // View > Execution transcript to verify this
//var ss = SpreadsheetApp.openById(id).getSheetByName("Quiz Responses");
//ss.appendRow([request.answer /* additional values comma separated here */ ]);
}
}
<!DOCTYPE html>
<!-- file quiz.html -->
<html>
<head>
<base target="_top">
</head>
<body>
<h1>Quiz</h1>
<form>
What is Lorem Ipsum?
<input name="loremipsum" type="text"/>
<button>Submit</button>
</form>
<script>
const button = document.querySelector("button");
const timeLimitMinutes = 1; // low number for demo; change to 20 for application
const timeLimitMilliseconds = timeLimitMinutes * 60 * 1000;
// For this demo we are not going to serve a response page, so don't try to.
button.addEventListener("submit", submitEvent => submitEvent.preventDefault());
// attach our custom submit to both the button and to the timeout
button.addEventListener("click", submitForm)
window.setTimeout(submitForm, timeLimitMilliseconds)
function submitForm() {
button.setAttribute("disabled", true);
document.querySelector("h1").textContent = "Quiz submitted";
// for demo: submitting just a single answer.
// research Apps Script documentation for rules on submitting forms, certain values not allowed
// consider a helper function `makeForm()` that returns a safe object to submit.
const answer = document.querySelector("input").value;
google.script.run.doPost({ answer });
}
</script>
</body>
</html>
Test with Publish > Deploy as web app...

How to have a Google Form retrieve spreadsheet data and display it on a Google Site?

Desired Outcome: To be able to enter a search term in a Google Form (presumably but not necessarily; could be a form in a standard web page) and have the relevant data retrieved from a Google Sheet and displayed in Google Site web app.
I learnt how to retrieve data from a parameterized URL and display in a Google Site in this question: How to include data in a URL for a Google Apps Script web app to read?
So the "tech" for retrieving and displaying spreadsheet data is there but I don't know where to start when it comes to pulling the data from a online form rather than a URL. Perhaps on submit, read the form values somehow, create a parameterized URL and go to that page to display the data?
How about this sample? This is a very simple sample script. Please modify it to your environment. This sample retrieves data on Spreadsheet using the search text, and displays the matched row. In order to use this sample, please carry out as follows.
Copy and paste the following scripts to your script editor.
Input spreadsheet ID and sheet name which is used for searching data.
Deploy Web Apps and run script.
Input search text and push "ok" button.
Script :
Google Apps Script : code.gs
function doGet() {
return HtmlService.createTemplateFromFile('index').evaluate();
}
function getData(e) {
var id = "### Spreadsheet ID ###";
var sheetname = "### Sheet name ###";
var data = SpreadsheetApp.openById(id).getSheetByName(sheetname).getDataRange().getValues();
var ar = [];
data.forEach(function(f) {
if (~f.indexOf(e.searchtext)) {
ar.push(f);
}
});
return ar;
}
HTML : index.html
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<form>
<input type="text" name="searchtext">
<input type="button" value="ok" onClick="getData(this.parentNode)" />
</form>
<pre id="disp"></pre>
<script>
function dispData(e) {
$('#disp').text(JSON.stringify(e));
}
function getData(e) {
google.script.run.withSuccessHandler(dispData).getData(e);
}
</script>
Sample spreadsheet :
Result :
If I misunderstand your question, I'm sorry.

Customize invitation email in Google Forms

I want to custom the invitation email when I share a google form. I have looking up in Google Script documentation and I haven't found some method or class useful. How can I customize this invitation email?.
Normally this email looks like:
I want to add a corporative image in the footer and maybe some text.
There isn't a method to create your own customized message. Below I am going to propose an alternate solution.
You can create a function that sends a customized mail. Just create an HTML file with your customized HTML content.
// i called this share.html in the apps script project
<h1>This is a header 1</h1>
<p>This is a paragraph</p>
<img src="<<SOME IMAGE SRC HERE>>" />
Then back in your code.gs file create a function like below:
function shareForm() {
var html = HtmlService.createHtmlOutputFromFile('share').getContent();
var recipient = '<<EMAIL ADDRESS>>';
var subject = 'this is the subject';
var body = 'this will get overridden by the HTML service';
var options = {
htmlBody: html
};
MailApp.sendEmail(recipient, subject, body, options)
}
You can run this function from the script editor, or you can build a button to add into the add-ons drop down options.

Send form data to Google Spreadsheet from client side

I have some form on my pure JS/HTML/CSS site (without server side). And have Google account. My purpose is send filled form from web client direct to Google Spreadsheet. Is it possible?
Yes, this is possible. I would do it by creating an Apps Script and deploying it as a web app. Here is a sample script: fill in the Id of the spreadsheet and the name of one of its sheets.
function doPost(event) {
var params = event.parameter;
var sheet = SpreadsheetApp.openById('..Id..').getSheetByName('..Name..');
if (params.data !== undefined) {
sheet.getRange(1, 1).setValue(params.data);
return ContentService.createTextOutput("Success");
}
else {
return ContentService.createTextOutput("Oops");
}
}
Publish the script as a web app, allowing access to everyone (unless you want to deal with authentification). This will give you a URL such as https://script.google.com/macros/s/..../exec
On the client side, you send POST request to that URL. The script expects data to be in parameter "data".
var url = 'https://script.google.com/macros/s/..../exec';
$.post(url, {data: 'hello world'});
(I'm using jQuery here just to have a shorter example; you can send a POST request in plain JavaScript.)
The cell A1 of the sheet you chose will have "hello world".