google apps script - form not automatically mailing spreadsheet response - javascript

I am new to Google Scripts but am getting the gist of it pretty quickly. I am trying to automate ordering of toner for our commercial printer. I set up a Google Form with 4 scale questions, one for each color (CMYK), with multiple choices from 1 through 5 toner cartridges.
Then, in the Google Spreadsheet that records responses, I created a script (mainly from internet examples) that gets the last entry of the spreadsheet (bottom row) and sends an email with the amount of toner cartridges needed, with a trigger onFormSubmit().
When I use the form and hit the submit button, nothing happens. There seems to be a disconnect between the form and the spreadsheet? Maybe some triggers are not working? I tried using the triggers from the script editor and also the programmable triggers and it still does not work from the form submission.
The "ScriptApp" part of the script's trigger doesn't seem to be recognized by the Google Scripts editor, as it's not in a particular color, different from the other code, which makes me wonder if I have to write some form of #include statement or something? All the internet examples show ScriptApp in color.
No bugs are found when "compiling"...
function sendFormByEmail(e)
{
ScriptApp.newTrigger("sendFormByEmail").forSpreadsheet(SpreadsheetApp.getActiveSpreadsheet()).onFormSubmit().create();
var email = "example#email.com";
var s = SpreadsheetApp.getActiveSheet();
var headers = s.getRange(1,2,1,s.getLastColumn()-1).getValues()[0];
var colors = s.getRange(s.getLastRow(),2,s.getLastRow(),s.getLastColumn()-1).getValues()[0];
var message = "";
var subject = "Toner order";
for(var i in headers)
message += headers[i] + ': ' + colors[i] + "\n\n";
MailApp.sendEmail(email, subject, message);
}

This is the answer that definitely works. Had to clear past triggers first, else it would send multiple emails because it was creating a new trigger with each submission:
var triggers = ScriptApp.getProjectTriggers();
for(var i in triggers) {
ScriptApp.deleteTrigger(triggers[i]);
}
ScriptApp.newTrigger("sendFormByEmail").forSpreadsheet(SpreadsheetApp.getActiveSpreadsheet()).onFormSubmit().create();
function sendFormByEmail(e)
{
var email = "example#email.com";
var s = SpreadsheetApp.getActiveSheet();
var headers = s.getRange(1,2,1,s.getLastColumn()-1).getValues()[0];
var colors = s.getRange(s.getLastRow(),2,s.getLastRow(),s.getLastColumn()-1).getValues()[0];
var message = "";
var subject = "toner order";
for(var i in headers) {
message += headers[i] + ': ' + colors[i] + "\n\n";
}
MailApp.sendEmail(email, subject, message);
}

Related

Google sheet Automation

Can you please help me, How to send dynamic mail every latest entry in google sheet?
function CustomEmail() {
var sheet = SpreadsheetApp.getActiveSheet();
var range = sheet.getRange("A2:C4");
var UserData = range.getValues();
for (i in UserData) {
var row = UserData[i];
var name = row[0];
var email = row[1];
var score = row[2];
MailApp.sendEmail(row[1], "Custom mail", "Hello " + name + ", This is an email report of your score. Your score is " + score);
}
}
Setup a trigger in your project: Trigger for "form submission". Whenever someone submits the form, script will send out the email to those whom the email wasn't sent. Also have a helper column in the sheet to update status for the script to filter out the people who already received the email, else others will keep receiving their scores everytime there's a form submission.

Creating a google script to automate google form submission, using values from a google sheet

I am trying to create a google script that helps me to automate the creation of google form responses, using values from a google sheet.
Here is the script that I am using.
function auto_data() {
var formURL="https://docs.google.com/forms/d/e/1FAIpQLSfmepj661gmkUgleFCLPrqeB0z9mPyI8DLZ4kTBI0Y3eByOCQ/viewform";
var wrkBk = SpreadsheetApp.getActiveSpreadsheet();
var wrkSht = wrkBk.getSheetByName("Data");
var numb = wrkSht.getRange("G11").getValue();
var time = wrkSht.getRange("H11").getValue();
var eaten = wrkSht.getRange("I11").getValue();
var randnumb = wrkSht.getRange("J11").getValue();
var datamap={
"entry.1108902288" :numb,
"entry.1493000579" :randnumb,
"entry.1582850009" :time,
"entry.908606572" :eaten
};
var options = {
"method": "post",
"payload": datamap
};
UrlFetchApp.fetch(formURL, options);
}
Unfortunately, I got this error:
Exception: Request failed for https://docs.google.com returned code 405. Truncated server response: <!DOCTYPE html><html lang="en"><head><meta name="description" content="Web word processing, presentations and spreadsheets"><meta name="viewport" c... (use muteHttpExceptions option to examine full response). (line 25, file "Code")
Can anyone help me? Thanks!
405 means that the request is not allowed
You cannot just make a post request to a Google Form.
What you can do is to create programmatically a prefilled form Url - all you have to do then is open this link in your browser and click on Submit.
To do so, pass the answers to the respective entries as e.parameters.
Sample:
function auto_data() {
var formURL="https://docs.google.com/forms/d/e/1FAIpQLSfmepj661gmkUgleFCLPrqeB0z9mPyI8DLZ4kTBI0Y3eByOCQ/viewform";
var wrkBk = SpreadsheetApp.getActiveSpreadsheet();
var wrkSht = wrkBk.getSheetByName("Data");
var numb = wrkSht.getRange("G11").getValue();
var time = wrkSht.getRange("H11").getValue();
var eaten = wrkSht.getRange("I11").getValue();
var randnumb = wrkSht.getRange("J11").getValue();
var datamap=[
"entry.1108902288=" + numb,
"entry.1493000579=" + randnumb,
"entry.1582850009=" + time,
"entry.908606572=" + eaten
];
var prefillUrl = formURL+"?"+ datamap[0] + "&" + datamap[1] + "&" + datamap[2] + "&" + datamap[3];
Logger.log(prefillUrl);
}

Setting up an email system from my google spreadsheet. I have everything else working except for adding an image into the body

I'm trying to add an image into the body of the emails. I've been able to get everything else working fine besides the image part. The images I'm trying to use are in the "M Column".
What do I need to add to get the value from the "M Column" and put it into the body of the emails?
-code is provided below
Thanks in advance. Everything I've tried has failed so I just removed everything I attempted and went to what I originally had before I decided to add images to the emails.
function sendEmails() {
var sheet = SpreadsheetApp.getActiveSheet();
var startRow = 2;
var numRows = 15;
var dataRange = sheet.getRange(startRow, 1, numRows, 15);
var data = dataRange.getValues();
for (var i in data) {
var row = data[i];
var emailAddress = row[4];
var message = row[10];
var subject = "Subject Test";
MailApp.sendEmail(emailAddress, subject, message);
}
}
[error message][1]
[1]: https://i.stack.imgur.com/nwAJG.png
If you want to send an email which contains images, you could use one of the following options:
If your images are stored as urls in your Spreadsheet
The following code snippet is used to create the attachment containing the image gathered from a url stored in your Spreadsheet.
var imageUrl = sheet.getRange("YOUR_RANGE_FOR_THE_IMAGE").getValue();
var imageBody = "<img src='cid:myImage'>";
var imageBlob = UrlFetchApp.fetch(imageUrl)
.getBlob()
.setName("imageBlob");
var message = row[10];
var subject = "Subject Test";
MailApp.sendEmail({
to: emailAddress,
subject: subject,
htmlBody: message +"<br/><br/>"+ imageBody,
inlineImages:{
myImage: imageBlob
}
});
The above code snippet uses InlineImages in order to attach the image as an attachment into the email you want to send.
If your images are stored in drive and you have their file ids
The following code snippet is used to create the attachment containing the image gathered from the id of the file which is stored in Drive.
var imageId = sheet.getRange("YOUR_RANGE_FOR_THE_IMAGE").getValue();
var image = DriveApp.getFileById(imageId);
var imageBlob = Utilities.newBlob('', 'image/jpeg');
var message = row[10];
var subject = "Subject Test";
MailApp.sendEmail({
to: emailAddress,
subject: subject,
body: message,
attachments: [image.getAs(MimeType.JPEG), imageBlob]
});
If your images are stored inside a cell and/or as overgrid images
Unfortunately, Google Sheets doesn't have the capacity to return the blob of an image, only a reference to the image which means that you cannot retrieve the images and attach them afterwards in an e-mail using Google Apps Script.
In this case, an alternative would be to use the =IMAGE() function to insert the images in a cell and afterwards you can retrieve them by using the Sheets API V4.
Reference
MailApp Class Apps Script;
Sheets Class Apps Script getRange;
DrivApp Class Apps Script getFileById;
Apps Script Reference;
Sheets API.

Google Script ui.button calling prompt from other function

I have two separate scripts that are activated by buttons in a sheet. One sends an email (CALemail.js), and the other clears cells (clear.js). Both scripts prompt for confirmation before running. While the first one executes perfectly, my clear.js script first asks the prompt from CALemail and then asks the clear.js prompt before running. How can I separate them?
CALemail.js:
var ehtml =
'<body>' +
'<h2>Calendar Updated</h2>' +
'<p>You can access it by clicking here </p>' +
'</body>'
var ui = SpreadsheetApp.getUi();
var response = ui.alert('You are sending a link to the current version of this calendar. Do you want to continue?',
ui.ButtonSet.YES_NO);
if (response == ui.Button.YES) function CALemail() {
MailApp.sendEmail(
'example#gmail.com', // recipient
' Calendar Updated', // subject
'test', { // body
htmlBody: ehtml // advanced options
} );
} else {
}
clear.js:
function clearRange() {
var ui = SpreadsheetApp.getUi();
var response = ui.alert('STOP! You are attempting to clear the Calendar. THIS CANNOT BE UNDONE. Do you want to continue?',
ui.ButtonSet.YES_NO);
var sheet = SpreadsheetApp.getActive().getSheetByName('Calendar');
if (response == ui.Button.YES)
{
sheet.getRange('B4:V10').clearContent();
sheet.getRange('B12:V18').clearContent();
sheet.getRange('B20:V26').clearContent();
sheet.getRange('B28:V34').clearContent();
sheet.getRange('B36:V42').clearContent();
sheet.getRange('B44:C50').clearContent();
sheet.getRange('D3:D43').clearContent();
sheet.getRange('G3:G43').clearContent();
sheet.getRange('J3:J43').clearContent();
sheet.getRange('M3:M43').clearContent();
sheet.getRange('P3:P43').clearContent();
sheet.getRange('S3:S43').clearContent();
sheet.getRange('V3:V43').clearContent();
sheet.getRange('B53:V65').clearContent();
}
}
Whether you put them in separate files or in the same file, they need to be separate functions. Unless you want the to run every time you access a function.
function testEmail(){
var ehtml = '<body><h2>Calendar Updated</h2><p>You can access it by clicking here </p></body>';
var ui = SpreadsheetApp.getUi();
var response = ui.alert('You are sending a link to the current version of this calendar. Do you want to continue?',ui.ButtonSet.YES_NO);
if(response == ui.Button.YES) function CALemail() {
MailApp.sendEmail('example#gmail.com',' Calendar Updated','test',{htmlBody: ehtml});
}
}
function clearRange(){
var ui = SpreadsheetApp.getUi();
var response = ui.alert('STOP! You are attempting to clear the Calendar. THIS CANNOT BE UNDONE. Do you want to continue?', ui.ButtonSet.YES_NO);
var sheet = SpreadsheetApp.getActive().getSheetByName('Calendar');
if (response == ui.Button.YES){
sheet.getRange('B4:V10').clearContent();
sheet.getRange('B12:V18').clearContent();
sheet.getRange('B20:V26').clearContent();
sheet.getRange('B28:V34').clearContent();
sheet.getRange('B36:V42').clearContent();
sheet.getRange('B44:C50').clearContent();
sheet.getRange('D3:D43').clearContent();
sheet.getRange('G3:G43').clearContent();
sheet.getRange('J3:J43').clearContent();
sheet.getRange('M3:M43').clearContent();
sheet.getRange('P3:P43').clearContent();
sheet.getRange('S3:S43').clearContent();
sheet.getRange('V3:V43').clearContent();
sheet.getRange('B53:V65').clearContent();
}
}
Note: I didn't test them nor do I care too. That's upto you.

How do I make a response email be from the person submitting (Google App Script)

I have a Google form which submits to a spreadsheet. I then have written this code which sends an email with the results. Can anyone tell me how I make the email be submitted by the person who submitted the form?
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) {
try {
var ss, cc, subject, columns;
var message, value, textbody, sendername, sender;
// This is my email address and I will be in the CC
cc = e.namedValues["Username"].toString();
// This will show up as the sender's name
sendername = e.namedValues["Name"].toString();
subject = "Ticket Submitted";
message = "We have received your details.<br>Thanks!<br><br>";
ss = SpreadsheetApp.getActiveSheet();
columns = ss.getRange(1, 1, 1, ss.getLastColumn()).getValues()[0];
// This is the submitter's email address
sender = e.namedValues["Username"].toString();
// Only include form values that are not blank
for ( var keys in columns ) {
var key = columns[keys];
if ( e.namedValues[key] ) {
message += key + ' :: '+ e.namedValues[key] + "<br />";
}
}
textbody = message.replace("<br>", "\n");
GmailApp.sendEmail(sender, subject, textbody,
{cc: cc, name: sendername, htmlBody: message});
} catch (e) {
Logger.log(e.toString());
}
}
This is not possible, nor it should be. You want to impersonate someone else without their consent.
The archaic email system unfortunately allows that, therefore making easier the life of spammers and phishing scams. But Google and other Internet companies work hard to prevent and filter this kind of emails.
Bottom line, you will not be able to send an email as somebody else from a Google app unless it's an authorized account in your Gmail.
The best you can do is set the reply-to address.

Categories