My first time here in Stack overflow. I'm just an amateur programmer trying to learn Google Apps script. I created a google form to get answers from users. I have transferred the answers to a google doc formatted according to our use in the office. I need to email the google doc back to the for user in microsoft word format. Sending as pdf is not a problem, but msword is a bit tricky.
I tried copying the recommendations i found here but I can't seem to get it to run. I hope someone can tell me what i'm doing wrong and what i need to doe. here's the relevant portion of the code:
`doc.saveAndClose(); // end of the transfer from google sheet to google doc. now to email...
var filename= ts+"-"+c_name1;
var compfile = DriveApp.getFilesByName(filename);
if (!compfile.hasNext())
{
console.error("Could not open file "+filename);
return;
}
var template = HtmlService.createTemplateFromFile('email_message');
var message = template.evaluate().getContent();
MailApp.sendEmail({
to:em,
subject: "Automated Complaint Assistant",
htmlBody: message,
attachments: compfile.next()}) // attachment is pdf file type. HOW TO SEND AS WORD?
`
I tried this function i found here:
`function EmailCompAsWordDoc(email, name, newCopyID) {
var subject = "Word version of Complaint";
var body = "\n\nHere is the Microsoft Word version of the draft Complaint";
var url = 'https://docs.google.com/feeds/download/documents/export/Export?id=' + newCopyID + '&exportFormat=docx';
var options = {
headers: {
Authorization: "Bearer " + ScriptApp.getOAuthToken()
},
muteHttpExceptions: true
}
var response = UrlFetchApp.fetch(url, options);
var doc = response.getBlob();
//Create the docx file in my TEMP folder in Google Drive and send
var file = DriveApp.createFile(doc).setName('Draft Complaint '+ name + '.docx');
DriveApp.getFolderById('<ID of my TEMP folder in Google Drive>').addFile(file);
var blob = DriveApp.getFileById(file.getId());
if (MailApp.getRemainingDailyQuota() > 0)
GmailApp.sendEmail(email, subject, body, {
Body: body,
attachments:[blob]
});
//Remove the docx file from the TEMP folder
DriveApp.getFileById(file.getId()).setTrashed(true);
}
var compid = DriveApp.getFileById(filename.getId()) // error here. How to get the file ID for use by this custom function??
EmailCompAsWordDoc(em, c_name1, compid)
`
From your provided script, I understood that the value of filename is the string value of var filename = ts + "-" + c_name1;. I thought that this is the reason for your current issue of filename.getId is not a function.
In this case, how about the following modification?
From:
var compid = DriveApp.getFileById(filename.getId())
To:
var compid = DriveApp.getFilesByName(filename).next().getId();
In this case, it supposes that the values of filename and em and c_name1 of EmailCompAsWordDoc(em, c_name1, compid) are valid values. Please be careful about this.
Related
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.
I am editing an existing script that my team uses for a google form response sheet. The script automatically creates a message body using the headers and response cells for an order every time it is submitted, roughly like this:
Type of Order: Physical
Country: America
Digital Signature:
Favorite Color:
Favorite Food: Pasta
What I've been asked to do, is have the script read through the sheet and not include the header or response for questions that are not answered in any given submission. Like so, for the previous example:
Type of Order: Physical
Country: America
Favorite Food: Pasta
I should start by saying I have close to 0 experience in javascript or Google Apps. I have tried playing around with if clauses using both the len function and a negated isblank function to no avail. These all lead to undefined errors.
As you'll see, the original script was not created by me or the people who have been using it for the last few years.
Original script
function sendFormByEmail(e)
{
Logger.log('value of e is: ' + e);
var email = "xxx#xxx.com";
var s = SpreadsheetApp.getActiveSheet();
var headers = s.getRange(1,1,1,s.getLastColumn()).getValues()[0];
var message = "";
var subject = "Type A Request: ";
// The variable e holds all the form values in an array.
// Loop through the array and append values to the body.
// Insert variables from the spreadsheet into the subject.
// In this case, I wanted the new hire's name and start date in the
// email subject. These are the 3rd and 16th columns in my form.
for(var i in headers)
message += headers[i] + ': '+ e.namedValues[headers[i]].toString() + "\n\n";
subject += e.namedValues[headers[10]].toString() + " - " +
e.namedValues[headers[12]].toString();
MailApp.sendEmail(email, subject, message, {noReply:true});
// Based off of a script originally posted by Amit Agarwal - www.labnol.org
}
You can include a check for blank values inside the for loop.
if (e.namedValues[headers[i]].toString() === "") continue;
I have the following G.A.S script to email a google sheet as a pdf attachment.
var spreadsheet = SpreadsheetApp.getActive();
var subject = spreadsheet.getRange("U1:U1").getValues();
var emailTo = spreadsheet.getRange("V1:V1").getValues();
var message = spreadsheet.getRange("W1:W1").getValues();
var pdf = DriveApp.getFileById(spreadsheet.getId()).getAs('application/pdf').getBytes();
var attach = {fileName:subject,content:pdf, mimeType:'application/pdf'};
MailApp.sendEmail(emailTo, subject, message, {attachments:[attach]});
The above code works well except that the file attached to the email message has a bizarre name like "[Ljava.lang.Object_#4e63998c" with no ".pdf" extension!
I am looking for a way to set a name for the pdf file before being attached to the email. The file name should equal the "subject" variable.
Thanks in advance.
Omid
Values retrieved by getValues() is 2 dimensional array. I think that the filename becomes such string because the array is used as the filename. Please retrieve the element from the array and try again. So could you please modify as follows?
From :
var attach = {fileName:subject,content:pdf, mimeType:'application/pdf'};
To :
var attach = {fileName:subject[0][0],content:pdf, mimeType:'application/pdf'};
You can also use the following modification. In this case, getValue() can retrieve the value as a string from the cell "U1".
From :
var subject = spreadsheet.getRange("U1:U1").getValues();
To :
var subject = spreadsheet.getRange("U1:U1").getValue();
Reference :
getValue()
getValues()
If this was not what you want, please tell me. I would like to think of other solutions.
I'm a bit late, but another way to solve this problem might be:
var spreadsheet = SpreadsheetApp.getActive();
var subject = spreadsheet.getRange("U1:U1").getValues();
var emailTo = spreadsheet.getRange("V1:V1").getValues();
var message = spreadsheet.getRange("W1:W1").getValues();
var pdf = DriveApp.getFileById(spreadsheet.getId())
.getAs('application/pdf')
.getBlob()
.setName(subject);
MailApp.sendEmail(emailTo, subject, message, {attachments:[pdf]});
The Blob class has a setName method https://developers.google.com/apps-script/reference/base/blob#setName(String), that can be chained into a Blob object (which is the result of getBlob())
After that you just need to add the Blob object inside attachments array of function MailApp.sendEmail
I'm trying to send myself a form-based report as a pdf. The problem is, I don't receive any emails. Debugging doesn't help much, since that only tells me which values are "undefined" (they are being defined the instant one fills out the form and triggers the email by clicking send; in theory). My coding experience stems from the days of TurboPascal and .bat-files, and I have lately realised I need to shape up. Trying to figure out Android, and this is a little experiment at work. But I had forgotten the lost feeling of "what now?"...
Here's the code:
// Samfunnsutvikling kursrapport
var docTemplate = "TemplateIDinGoogleDoks";
var docName = "Kursrapport";
// When Form Gets submitted
function onFormSubmit(e) {
//Get information from form and set as variables
var email = "worker#work.no";
var namn = e.namedvalues.namn;
var arrangement = e.namedvalues.arrangement;
var dato = e.namedvalues.dato;
var referat = e.namedvalues.referat;
// Get document template, copy it as a new temp doc, and save the Doc’s id
var copyId = DocsList.getFileById(docTemplate)
.makeCopy(docName+' for '+namn)
.getId();
// Open the temporary document
var copyDoc = DocumentApp.openById(copyId);
// Get the document’s body section
var copyBody = copyDoc.getActiveSection();
// Replace place holder keys,in our google doc template
copyBody.replaceText('keynamn', namn);
copyBody.replaceText('keyarrangement', arrangement);
copyBody.replaceText('keydato', dato);
copyBody.replaceText('keyreferat', referat);
// Save and close the temporary document
copyDoc.saveAndClose();
// Convert temporary document to PDF
var pdf = DocsList.getFileById(copyId).getAs("application/pdf");
// Attach PDF and send the email
var subject = "Kursrapport";
var body = "Kursrapporten frå " + namn + "";
GmailApp.sendEmail(email, subject, body, {htmlBody: body, attachments: pdf});
// Delete temp file
DocsList.getFileById(copyId).setTrashed(true);
}
The script/document is authorized to send emails, but, oddly, I had to authorize it twice. It is saved.
In general, you can add Logger.log() to print variable values or just messages to see how far does it reach.
It looks as attachments parameter expects Blob[] type, however you are passing just Blob. So, it should be:
GmailApp.sendEmail(email, subject, body, {htmlBody: body, attachments: [pdf]});
You may also want to replace DocsList with DriveApp class as-is since the first one is depricated.
Update
It turned out also that getActiveSection() was renamed to getBody().
Please bear with me as I am very much a beginner at this. I am trying to write a Google script which creates a new spreadsheet of the relevant data after a form is submitted, converts this to a PDF, and sends it as an email attachment to an email address which is submitted to the form. I am writing the code in a script which is bound to the sheet which performs some calculations on the data once it is submitted. The form is also bound to the sheet. I will paste my code below and here is a link to the sheet:
https://docs.google.com/spreadsheets/d/1oQTeQFwl7IfWF8D17oK1Mutp4TXidQXUT4lv46ktuwM/edit?usp=sharing
I am trying to email the small green summary section on the sheet named INPUTS/OUTPUTS as a pdf.
The Template file "MyCalculations" is just an empty spreadsheet apart from one line saying "here are your calculation results".
The summary section updates itself well and correctly after a form is submitted I am just having real trouble accessing the sheet because I can't code!
Here is the code so far:
function onFormSubmit(e){
//Variables
var userEmail = SpreadsheetApp.getActiveSheet().getRange("H24").getValue();
var totalOutstandingPrincipalDebt = SpreadsheetApp.getActiveSheet().getRange("G22").getValue();
var totalOutstandingInterest = SpreadsheetApp.getActiveSheet().getRange("H22").getValue();
var totalOutstandingCompensation = SpreadsheetApp.getActiveSheet().getRange("I22").getValue();
var dailyInterestRate = SpreadsheetApp.getActiveSheet().getRange("J22").getValue();
var grandTotal = SpreadsheetApp.getActiveSheet().getRange("G23").getValue();
var docTemplate = DriveApp.getFilesByName("MyCalculations");
//Template Info
var docName="Calculations";
var copyDoc= docTemplate.makeCopy();
var copyId = copyDoc.getId();
var copyBody = docTemplate.getActiveSection();
copyBody.getRange(2, 1).setValue("Total Outstanding Principal Debt");
copyBody.getRange(2, 2).setValue("Total Outstanding Interest");
copyBody.getRange(2, 3).setValue("Total Outstanding Compensation");
copyBody.getRange(2, 4).setValue("Grand Total");
copyBody.getRange(2, 5).setValue("Daily Interest Rate");
copyBody.getRange(3, 1).setValue(totalOutstandingPrincipalDebt);
copyBody.getRange(3, 2).setValue(totalOutstandingInterest);
copyBody.getRange(3, 3).setValue(totalOutstandingCompensation);
copyBody.getRange(3, 4).setValue(grandTotal);
copyBody.getRange(3, 5).setValue(dailyInterestRate);
//Save as PDF and send e-mail
var pdf = getFileById(copyId).getAs("application/pdf");
var subject = "Calculations";
var body = "Thank you very much for using our online calculator. Please find your results attached.";
MailApp.sendEmail(userEmail, subject, body, {htmlBody: body, attachments: pdf});
//Deletes temporary Document
DriveApp.getFileById(copyId).setTrashed(true);
}
I also don't think that in this code, I have specified which sheet on my spreadsheet I am wanting to get the data from, but I don't know how to do that either!
Any help would be so so appreciated!
var docTemplate = DriveApp.getFilesByName("MyCalculations");
getFilesByName returns a FileIterator not a Spreadsheet so you have to change that to:
var docTemplate = DriveApp.getFilesByName("MyCalculations").next().getAs(MimeType.GOOGLE_SHEETS);
Next, in var copyBody = docTemplate.getActiveSection(); there is no such method called getActiveSection change that to:
var copyBody = docTemplate.getActiveSheet();
Lastly, the line var pdf = getFileById(copyId).getAs("application/pdf");
should be
var pdf = DriveApp.getFileById(copyId).getAs("application/pdf");
Implement those changes and let me know how it works. =)
Update
I fiddled around and as far as I can tell, DriveApp automatically converts almost all files to a PDF. So, as I understand it, you are using the MyCalculations spreadsheet as a template so that you can convert it into a PDF and send it.
We can accomplish this with a little bit of a roundabout way.
First, we create a new sheet in our original spreadsheet, and hide it from view so that the user can't see it.
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var myCalculations = spreadsheet.insertSheet("MyCalculations",spreadsheet.getNumSheets());
myCalculations.hideSheet();
Secondly, we set all the values that you want. So change
copyBody.setRange ...
to
myCalculations.setRange ...
Thirdly, once we have all our data set. We are going create a temporary Spreadsheet to copy all our data into so that we may export it as a PDF and send it in an email
var tempSpreadsheet = SpreadsheetApp.create('Temporary');
Fourth, we copy our calculations page into the temporary spreadsheet.
myCalculations.copyTo(tempSpreadsheet);
Perfect! Now we just convert the temporary spreadsheet into a PDF and do a little clean-up. Be sure to note the change to the line where we delete the temporary spreadsheet. I get the id by just calling the getId() method
var pdf = tempSpreadsheet.getAs(MimeType.PDF);
var subject = "Calculations";
var body = "Thank you very much for using our online calculator. Please find your results attached.";
MailApp.sendEmail(userEmail, subject, body, {htmlBody: body, attachments: pdf});
//Deletes temporary Document
DriveApp.getFileById(tempSpreadsheet.getId()).setTrashed(true);
That should do the trick. Comment how it works for you. =)
I managed to get this code working:
//Set out global variables
var docTemplate = ("1Ff3SfcXQyGeCe8-Y24l4EUMU7P9TsgREsAYO9W6RE2o");
var docName=("Calculations");
function onFormSubmit(e){
//Variables
var userEmail = SpreadsheetApp.getActiveSheet().getRange("H24").getValue();
var totalOutstandingPrincipalDebt =SpreadsheetApp.getActiveSheet().getRange("G22").getValue();
var totalOutstandingInterest = SpreadsheetApp.getActiveSheet().getRange("H22").getValue();
var totalOutstandingCompensation = SpreadsheetApp.getActiveSheet().getRange("I22").getValue();
var dailyInterestRate = SpreadsheetApp.getActiveSheet().getRange("J22").getValue();
var grandTotal = SpreadsheetApp.getActiveSheet().getRange("G23").getValue();
//Template Info
var copyId=DriveApp.getFileById(docTemplate).makeCopy(docName+' for '+userEmail).getId();
var copyDoc = DocumentApp.openById(copyId);
var copyBody = copyDoc.getActiveSection();
//Putting the data into the file
copyBody.insertParagraph(0,'Total Outstanding Principal Debt: ' + totalOutstandingPrincipalDebt);
copyBody.insertParagraph(1,'Total Outstanding Interest: '+ totalOutstandingInterest );
copyBody.insertParagraph(2,'Total Outstanding Compensation: '+ totalOutstandingCompensation);
copyBody.insertParagraph(3,'Grand Total: ' + grandTotal);
copyBody.insertParagraph(4,'Daily Interest Rate: '+ dailyInterestRate);
copyDoc.saveAndClose();
//email pdf document as attachment
var pdf = DriveApp.getFileById(copyId).getAs("application/pdf");
var subject = "Calculations";
var body = "Thank you very much for using our online calculator. Please find your results attached.";
MailApp.sendEmail(userEmail, subject, body, {htmlBody: body, attachments: pdf});
//Deletes temporary Document
DriveApp.getFileById(copyId).setTrashed(true);
}