google form script not triggering - forms

I am trying to create a workflow in google forms. Its a simple leave application form that employees submit to get approval from their managers, HR, and finally management.
The form results feed into the google sheets as intended. i have written the following script in the form and later also in the sheet and set a trigger "on form submit". It worked fine last night and was able to sent the email confirmation i programmed into the script. For whatever reason it decided not to work today. Can someone tell me what they think went wrong? also is it best to create the script in the form or in the spreadsheet. My feeling is that in the spreadsheet might be better but i could be wrong. When the script did run last night, i am not sure which one worked (the one in the sheet or the one in the form). i only got one email for each test submission i made. here is the code:
function leaveProcessInput(e) {
var username = e.values [1];
var name = e.values [2];
var department = e.values [3];
var leaveType = e.values [4];
var fromDate = e.values [5];
var toDate = e.values [6];
var reason = e.values [7];
var releiver = e.values [8];
var contactAway = e.values [9];
var subject = "Your " + leaveType + "Application Form has been submitted";
var message = "Dear " + name + ", your " + leaveType + "from " + fromDate + "to " + toDate + "Application Form has been submitted at " + timestamp + ". You will be notified of its status once we have processed it. Regards, Finance & Admin team.";
MailApp.sendEmail(username, subject, message);
}
I would really appreciate help on the above.

this script (triggered on form submission) should be bound to the spreadsheet, not in the form.
I hope that solves it.
Try removing the spacing between 'e.values' and the [].
e.g. e.values [1] should be e.values[1]
The script should not be attached to the form, but only to the spreadsheet.

Related

Properly attaching pictures to an email with google scripts

I'm trying to make a script with google forms and sheets to help with the automation and tracking our technicians pictures on the jobsite.
The setup is they take pictures of the jobsite and fill out a google form with the information and attach the pictures there. When the form gets submitted, it runs this script to send an email to a predetermined email that everyone in the office can see.
So far I am able to get the email to send the information from the form besides the pictures.
The information for the attached pictures come in as a drive url that is all dumped into one cell as a string.
"https://drive.google.com/open?id=xxxxxxxx, https://drive.google.com/open?id=yyyyyyyy, https://drive.google.com/open?id=zzzzzzzz"
I convert this string to an array using .split(" ,) which outputs this.
[https://drive.google.com/open?id=xxxxxxxx, https://drive.google.com/open?id=yyyyyyyy, https://drive.google.com/open?id=zzzzzzzz]
I then iterate through the array and use.slice(33) to get rid of the url so all that I'm left with is the drive id (there is probably a better way of doing this but it works for now).
[xxxxxxxx, yyyyyyyy, zzzzzzzz]
This is the part where I'm having trouble.
I then iterate agian through that array and grab the driveID and the get the file as a JPEG.
I then use .push to put it into another array that I'm using to attachment them to the email.
The issue is that I think I'm not doing this step properly by not pushing the correct thing into the array and/or assuming that MailApp.sendEmail can even take an array for attachments.
I'm also not entirely sure how [Blobs] work and how to use them properly and that's probably where I'm getting stuck.
Again, this is code is made with very little experience and could probably be optimized futher but at the moment, I just need to have it attach the pictures properly to show that it works.
function onFormSubmit(e) {
//for testing purposes
var values = e.namedValues;
//gets the form's values
var pureValues = e.values;
//sets the values
var email = pureValues[1];
var woNum = pureValues[2];
var firstN = pureValues[3];
var lastN = pureValues[4];
var desc = pureValues[5];
var superDuperRawPics = pureValues[6];
//splits the picture urls into an array
var superRawPics = superDuperRawPics.split(", ");
//slices the url part off to get the drive ID
var i, rawPics =[]
for (i = 0; i < superRawPics.length; ++i) {
rawPics.push(superRawPics[i].slice(33))
}
//takes the array of ID's and gets the drive file
var j, picAttach =[]
for (j = 0; j < rawPics.length; ++j) {
var driveID = DriveApp.getFileById(rawPics[j]);
var drivePic = driveID.getAs(MimeType.JPEG);
picAttach.push(drivePic);
}
//sets the subject of the email to be Jobsite Pictures and the work number
var subject = "Jobsite Pictures" + " " + woNum;
//sets the body of the email
var body = "Technician: " + email + " \n" +
"WO#: " + woNum + " \n" +
"Customer: " + firstN + " " + lastN + " \n" +
"Description: " + desc;
//for checking if the vars are set correctly
Logger.log(superDuperRawPics);
Logger.log(superRawPics);
Logger.log(rawPics);
Logger.log(picAttach);
Logger.log(subject);
Logger.log(body);
//sends email to me with the new info
MailApp.sendEmail('example#domian.com', subject, body, {attachments: [picAttach]});
}
If you just want to attach them then use options attachments
I was being dumb and added brackets to the attachments: when it didn't need them.
The correct way is this.
MailApp.sendEmail('example#domian.com', subject, body, {attachments: picAttach});
Changing this has the script sending emails with the pictures attached.

What is the procedure to email the test score of a test conducted on google forms?

I have created a test through google form, and I want to send the score result to the participants. I have created a copy of the response and put scoring through if functions. And then in the next worksheet, I have summed the score. Now I want to send that calculated score to the participants. I have entered the script in the script editor and set trigger on form submit but I am getting errors.
Would the error be because the script takes the default sheet and not the one where I have created score function? If so, how do I change that?
Here is the code that I used:
function myFunction(e)
{
var userName = e.values[1];
var userEmail = e.values[2];
var score = e.values[3];
var subject = "Thank you for your participation: Find your Score";
var message = "Thank you, " + userName + " for choosing to participate in this test. Your score is " + score;
MailApp.sendEmail(userEmail, subject, message);
}
There are two ways. Send an e-mail from the form or send a notification from the result collection spreadsheet (limited to spreadsheet collaborators).
For the first, you have to use the script editor found under tools. There are several examples to get you started. I'd recommend you take a look at: http://www.labnol.org/internet/auto-confirmation-emails/28386/
For the second, you use the notifications option, see: https://www.maketecheasier.com/send-email-notifications-google-forms/
Here is the code that I used
function myFunction(e){
var userName = e.values[1];
var userEmail = e.values[2];
var score = e.values[3];
var subject = "Thank you for your participation: Find your Score";
var message = "Thank you, " + userName + " for choosing to participate in this test. Your score is " +score;
MailApp.sendEmail (userEmail, subject, message);}

Add trigger to form

I have been working on a simple "Time off request" form using Google Apps. The I have associated a script with the form which detects the respondents' supervisor and sends them a link to a new form for their approval.
Here is the code from the script I used to create the new form.
//create approval form as part of the Message Creation process.
var approvalForm = FormApp.create("Approve Days off Request")
approvalForm.setTitle("Approval form for " + user.Name)
// truncated ...
var approvalItem = approvalForm.addMultipleChoiceItem(); //Item on First Page
var disapproveReasonPage = approvalForm.addPageBreakItem(); //Page Break Item
var disapproveReason = approvalForm.addParagraphTextItem(); //Item on Second Page
// truncated ...
//Question 1, Page 1
approvalItem.setTitle(user.Name + " has requested " + daysOff + " day(s) off starting on " + firstDate+".")
approvalItem.setHelpText("Would you like to approve this request?")
approvalItem.setRequired(true);
approvalItem.setChoices ([
approvalItem.createChoice('Yes', FormApp.PageNavigationType.SUBMIT),
approvalItem.createChoice('No', FormApp.PageNavigationType.CONTINUE)
]);
//Question 2, Page 2
disapproveReason.setTitle("Would you like to give a reason?");
disapproveReason.setHelpText("Optional")
disapproveReasonPage.setGoToPage(FormApp.PageNavigationType.SUBMIT)
Then a link is generated and sent to the supervisor to approve the request.
I am wanting to add a trigger to the form created above (approvalForm). I would imagine that there is a way, but haven't been able to find the greatest documentation on it. The closest I've come is TriggerBuilder Class. I tried creating one associated to the target form with
var approveScript = ScriptApp.newTrigger('Approval')
.forForm(approvalForm.getId())
.onFormSubmit()
.create();
but couldn't get it to work the way I wanted it. I did have a function named Approval just to see if I could manipulate the form with it
function Approval(){
$form.setAcceptingResponses(false);
}
Any help would be appreciated. Thanks in advance.
The script was originally being added as a container bound script. Changing it to a Standalone installable script fixed this problem. Hopefully this answer will be to someone else having a similar issue.

Getting a Google Form Script generated email to pipe data into Reponse Sheet

I am currently trying to setup an approval workflow. I'm fairly junior when it comes to some of this stuff. But so far have it working at respectable level to fit our needs with the assistance of an example.
I was using the template/example from Email Approval using Google Script and a Form.
The issue I am running into, with a lack of functionality is that at the time of Accept or Deny via the Email that is generated for approval I would like it to then record that data back into the Google Form row in the last column that the email was generated from.
I may end up adding 2nd timestamp, reply email etc later.
So then that row would show the initial form filled out and then either blank/accepted/deny as the status.
Thank you for any time or assistance.
The approval workflow that James Ferreira originally wrote was intentionally very basic. Enhancing it to provide correlation between approvals and the original requests is simple in concept, yet complicates the code because of details and limitations.
Things that need to considered:
Form responses include a timestamp, which we can use as a sort of "serial number" for responses, since it has a very high probability of being unique in an application like this.
We can pass this identifier along with the rest of the URL embedded in the approval email, which will give it back as a parameter to the webapp, in turn.
Passing an object like a timestamp between applications can be troublesome. To ensure that the URL embedded in the approval email works, we need to encode the string representation of the timestamp using encodeURIComponent(), then decode it when the webapp consumes it.
Searching for matches is simplified by use of ArrayLib.indexOf() from Romain Vaillard's 2D Array library. This function converts all array data to strings for comparisons, so it fits nicely with our timestamp.
Alternatively, we could put effort into creating some other identifier that would be "guaranteed" to be unique.
The approval-response web app (doGet()) does not understand what "activeSpreadsheet" means, even though it is a script contained within a spreadsheet. This means that we need a way to open the spreadsheet and record the approval result. To keep this example simple, I've assumed that we'll use a constant, and update the code for every deployment. (Ick!).
So here's the Better Expense Approval Workflow script.
// Utilizes 2D Array Library, https://sites.google.com/site/scriptsexamples/custom-methods/2d-arrays-library
// MOHgh9lncF2UxY-NXF58v3eVJ5jnXUK_T
function sendEmail(e) {
// Response columns: Timestamp Requester Email Item Cost
var email = e.namedValues["Requester Email"];
var item = e.namedValues["Item"];
var cost = e.namedValues["Cost"];
var timestamp = e.namedValues["Timestamp"];
var url = ScriptApp.getService().getUrl();
// Enhancement: include timestamp to coordinate response
var options = '?approval=%APPROVE%&timestamp=%TIMESTAMP%&reply=%EMAIL%'
.replace("%TIMESTAMP%",encodeURIComponent(e.namedValues["Timestamp"]))
.replace("%EMAIL%",e.namedValues["Requester Email"])
var approve = url+options.replace("%APPROVE%","Approved");
var reject = url+options.replace("%APPROVE%","Rejected");
var html = "<body>"+
"<h2>Please review</h2><br />"+
"Request from: " + email + "<br />"+
"For: "+item +", at a cost of: $" + cost + "<br /><br />"+
"Approve<br />"+
"Reject<br />"+
"</body>";
MailApp.sendEmail(Session.getEffectiveUser().getEmail(),
"Approval Request",
"Requires html",
{htmlBody: html});
}
function doGet(e){
var answer = (e.parameter.approval === 'Approved') ? 'Buy it!' : 'Not this time, Keep saving';
var timestamp = e.parameter.timestamp;
MailApp.sendEmail(e.parameter.reply, "Purchase Request",
"Your manager said: "+ answer);
// Enhancement: store approval with request
var sheet = SpreadsheetApp.openById(###Sheet-Id###).getSheetByName("Form Responses");
var data = sheet.getDataRange().getValues();
var headers = data[0];
var approvalCol = headers.indexOf("Approval") + 1;
if (0 === approvalCol) throw new Error ("Must add Approval column.");
// Record approval or rejection in spreadsheet
var row = ArrayLib.indexOf(data, 0, timestamp);
if (row < 0) throw new Error ("Request not available."); // Throw error if request was not found
sheet.getRange(row+1, approvalCol).setValue(e.parameter.approval);
// Display response to approver
var app = UiApp.createApplication();
app.add(app.createHTML('<h2>An email was sent to '+ e.parameter.reply + ' saying: '+ answer + '</h2>'))
return app
}
So, I tried this, but there an issue with the formatting for date when it's in the data array. In order to get this to work, you have to reformat the time stamp in the doGet using formatDate.
I used the following to get it to match the formatting that appears in the array.
var newDate = Utilities.formatDate(new Date(timestamp) , "PST", "EEE MMM d yyyy HH:mm:ss 'GMT'Z '(PST)'");
Lastly, of course update the indexof parameter that is passed to newDate.

Alternative or fix for "\n" in google script

First time I put up a question here (been searching before posting) so please bear with possible mistakes done on my end.
To the problem:
I am currently working on a website with google sites. Made some forms there and am adding a script to those forms to get the info input there emailed away once the form is submitted and saved on the spreadsheet, which works just fine, but the message inside the email that arrives is pretty messed up.
All the "\n" expressions in the code get simply ignored.
I got the base for the code from www.labnol.org and just edited it a little.
For the start, the code:
function sendFormByEmail(e)
{
//I took the two mail addresses out here, but they are working in the original
var email = "first mail address";
var email2 = "second mail address";
var subject = "New Announce your visit form submitted";
var s = SpreadsheetApp.getActiveSheet();
var headers = s.getRange(1,1,1,s.getLastColumn()).getValues()[0];
var message = "A new 'Announce your visit' form has been submitted on the website: \n\n" + "\n\n";
for(var i in headers) {
message = message + "\n \n";
message += headers[i] + ' = '+ e.namedValues[headers[i]].toString() + "\n\n";
}
var senderEmail = e.namedValues[headers[6]].toString();
MailApp.sendEmail(email, senderEmail, subject, message);
MailApp.sendEmail(email2, senderEmail, subject, message);
}
As you can see, I have been trying around a lot to place the \n in different places as alternative, though it gets ignored no matter where I place it.
the original loop looked like this:
for(var i in headers)
message += headers[i] + ' = '+ e.namedValues[headers[i]].toString() + "\n\n";
Before I did some modifications to the code it worked just fine. But even though I didn't touch these lines, nor any of the other parts of the code that contribute to getting the message, the \n stopped working.
I kept trying to fix it (as the messed up \n placing above shows), but without success.
So now I am trying to find a way to fix them, or at least a work-around and hoped that any of you might know what is going on with the \n's or how to get them working again.
Thanks in advance.
ps: if you need any more information on it, just let me know
A solution is to use the GmailApp.sendEmail method instead of the MailApp.sendEmail method. The GmailApp's sendMail handles \n correctly.
Here's an alternate solution to what you're doing: HtmlTemplate
Some sample code:
function sendEmailWithTemplateExample() {
var t = HtmlService.createTemplateFromFile("body.html");
t.someValue = "some dynamic value";
var emailBody = t.evaluate().getContent();
MailApp.sendEmail("your#email.here", "test email", emailBody);
}
And here's the corresponding template code in body.html (Click "File -> New -> Html File"):
Body goes here
<?= someValue ?>