With this script I am releasing two different emails (index1 or index 2) depending on some fields in sheets but I needed to add a .docx file from google drive as an attachment to the released email
This is the script I have so far and it is working I just need to add the docx as attachment file from google drive.. Please helpp
//Pulling all data from spreadsheet variables
var SpreadsheetID = "sheet id";
var SheetName = "namesheet";
var now = new Date();
var ss = SpreadsheetApp.openById(SpreadsheetID)
var sheet = ss.getSheetByName(SheetName);
var range = sheet.getDataRange();
var data = range.getValues();
function project_Notification() {
Logger.log(sheet.getLastRow() + " Is the last Row.");
for (var row = 1; row < sheet.getLastRow(); row++) {
var Notification = (data[row][12])
var Email_sent = (data[row][13])
var Admin_email = (data[row][5])
if (Notification == "Yes" && Email_sent == "" && Admin_email != "") {
Logger.log(Notification)
SendEmailConfirmation(data[row][5], data[row][1], data[row][14], data[row][3], data[row][6], data[row][9], data[row][10], data[row][11])
var Notification_cell = sheet.getRange("N" + (row + 1));
Logger.log("N" + (row + 1))
var Today = Utilities.formatDate(new Date(), "GMT", "dd/MM/yyyy");
Notification_cell.setValue(now);
}
}
}
function SendEmailConfirmation(email, Company, Admin_Name, Manager_Email, Landing_Page, QL_code, QL_url, PS_code) {
if (email != "" && Landing_Page != "") {
Logger.log(email)
var admin = {
"name": Admin_Name,
"company": Company,
"landingPage": Landing_Page,
"QLcode": QL_code,
"QLurl": QL_url,
"PScode": PS_code
};
var html1 = HtmlService.createTemplateFromFile('Index1.html');
html1.name = admin.name;
html1.comp = admin.company;
html1.landingPage = admin.landingPage;
html1.qlcode = admin.QLcode;
html1.qlurl = admin.QLurl;
var html2 = HtmlService.createTemplateFromFile('Index2.html');
html2.name = admin.name;
html2.comp = admin.company;
html2.landingPage = admin.landingPage;
html2.qlcode = admin.QLcode;
html2.qlurl = admin.QLurl;
html2.pscode = admin.PScode;
var aliases = GmailApp.getAliases();
Logger.log(aliases);
if (aliases.length > 0 && Landing_Page == "Product1") {
GmailApp.sendEmail(email, "Get started with your trial on Product1", '', {
'from': "product1#gmail.com",
replyTo: "product1#product.com",
cc: Manager_Email,
htmlBody: html1.evaluate().getContent()
});
} else if (Landing_Page == "Product2") {
GmailApp.sendEmail(email, "Get started with your trial on Product2", '', {
'from': "product2#gmail.com",
replyTo: "product2#product.com",
cc: Manager_Email,
htmlBody: html2.evaluate().getContent()
});
}
else {
GmailApp.sendEmail("products-admins#gmail.com", 'Script error', 'Please check the Products overview sheet for errors.');
}
}
}
//Send email for a confirmation that the script run correctly
How to send attachments from Drive via Email with Apps Script.
There is an attachments advanced parameter for GmailApp.sendEmail(). The parameters are:
GmailApp.sendEmail(recipient, subject, plainTextBody, options);
Using your example, the current state of the script is:
GmailApp.sendEmail(email, "Get started with your trial on Product1", '', {
'from': "product1#gmail.com",
replyTo: "product1#product.com",
cc: Manager_Email,
htmlBody: html1.evaluate().getContent()
});
Within options you can use many advanced parameters. You are using:
{
'from': "product1#gmail.com",
replyTo: "product1#product.com",
cc: Manager_Email,
htmlBody: html1.evaluate().getContent()
}
To this you can add the attachments parameter as list of BlobSource.
To get the blob source from a Drive file, you will need to obtain the ID of this file, once you have it, you can get the blob like this:
const file = DriveApp.getFileById("[FILE_ID]")
const blob = file.getBlob()
Just remember to include it in an array of blobs when you pass it to sendEmail, like this:
const file = DriveApp.getFileById("[FILE_ID]")
const blob = file.getBlob()
GmailApp.sendEmail(email, "Get started with your trial on Product1", '', {
'from': "product1#gmail.com",
replyTo: "product1#product.com",
cc: Manager_Email,
htmlBody: html1.evaluate().getContent(),
attachments: [blob]
});
EDIT
To do various attachments you can just include more in the list:
const file1 = DriveApp.getFileById("[FILE_ID1]")
const file2 = DriveApp.getFileById("[FILE_ID2]")
const blob1 = file1.getBlob()
const blob2 = file2.getBlob()
GmailApp.sendEmail(email, "Get started with your trial on Product1", '', {
'from': "product1#gmail.com",
replyTo: "product1#product.com",
cc: Manager_Email,
htmlBody: html1.evaluate().getContent(),
attachments: [blob1, blob2]
});
References
sendEmail
BlobSource
getFileById(id)
getBlob()
Related
Currently I'm working on a script that checks values of one column and based on that send email containing information from another column. Everything works perfectly except one thing - it send one email per value and I'd like to send all the values in one email. Can someone please help with the issue ?
const helpsheet = SpreadsheetApp.openById("ID").getSheetByName('Sheet');
const date = helpsheet.getRange(1,10).getValue();
const ss = SpreadsheetApp.openById("ID2");
const sh = ss.getSheetByName('Sheet2');
const data = sh.getRange('A2:c'+sh.getLastRow()).getValues();
var recipients = 'EMAIL#EMAIL';
var subject = 'SUBJECT';
data.forEach(r=>{
let overdueValue = r[2];
if (overdueValue > date)
{
let path = r[0];
MailApp.sendEmail({
to: recipients,
subject: subject,
htmlBody: 'Hi guys ' + path +'!<br><br>Best regards,'
});
}
});
} ```
Of course I can't test this because 1st I don't want a bunch of emails to myself and 2nd I don't have a data set that matches your data, but I'm pretty sure this will do what you want. What I do is build an array of rows that pass the sniff test using the Array push method below. Then when I have all the rows that pass I send one email.
I have edited this post to include functions to create an html table.
function test() {
try {
const helpsheet = SpreadsheetApp.openById("ID").getSheetByName('Sheet');
const date = helpsheet.getRange(1,10).getValue();
const ss = SpreadsheetApp.openById("ID2");
const sh = ss.getSheetByName('Sheet2');
const data = sh.getRange('A2:c'+sh.getLastRow()).getValues();
var pre = "Hello";
var post = "Best regards";
var recipients = 'EMAIL#EMAIL';
var subject = 'SUBJECT';
var passed = [];
data.forEach( r => {
let overdueValue = r[2];
if (overdueValue > date) {
passed.push(r);
}
});
if( passed.length > 0 ) { // maybe nothing passed the test
var html = createHTMLfile(true);
html = html.concat("<p>"+pre+"</p>");
html = html.concat(createTable(passed));
html = html.concat(createHTMLfile());
html = html.concat("<p>"+post+"</p>");
MailApp.sendEmail( {
to: email,
subject: subject,
htmlBody: html });
};
}
}
catch(err) {
console.log(err);
}
}
I have added the additional functions to create the table. You are welcome to play with the <style>s.
function createHTMLfile(pre) {
if( pre ) {
return "<html><head><style>table, td { border: thin solid black; border-collapse:collapse; text-align:center }</style></head><body>";
}
else {
return "</body></html>";
}
}
function createTable(data) {
try {
var width = 600/data[0].length;
var table = "<table>";
function addCell(value) {
table = table.concat("<td style=width:"+width+"px>");
table = table.concat(value.toString());
table = table.concat("</td>");
}
function addRow(row) {
table = table.concat("<tr>");
row.forEach( addCell );
table = table.concat("</tr>");
}
data.forEach( addRow )
table = table.concat("</table>");
return table;
}
catch(err) {
console.log(err);
}
}
I am trying to get a script running that takes multiple file IDs from a Google Sheet and attaches them to an email. I cannot get multiple files to be attached using DriveApp.getFileById.
The script runs and fires off an email, but with no attachments.
function createAndSendDocument(values) {
// Get the email address of the active user
var email = Session.getActiveUser().getEmail();
// Get the name of the document to use as an email subject line.
var subject = 'New Paperwork';
//Let's add the attachments variables
var attachmentstring = values["Which documents do you want to attach?"];
var array = attachmentstring.toString().split(",");
var blobs = [];
var x = 0;
for (var i = 0; i < array.length; i++) {
//check if even
if (i % 2 === 0) {
blobs[x] = array[i];
x++;
}
}
// Append a new string to the "url" variable to use as an email body.
var body = 'your doc: ' + blobs[0] + blobs[1] + array[0] + array[1] + "length:" + array.length;
// Send yourself an email with a link to the document.
GmailApp.sendEmail(email, subject, body, {attachments: blobs});
}
I edited the original post to include the snippet of code. Here is the output of the blobs and array.
undefinedundefinedW-4 2019.pdf1YjQqFNze8VX0L6wZ9O3Y9AJNznR8jfxqlength:4
This code worked:
function createAndSendDocument(values) {
// Get the email address of the active user
var email = Session.getActiveUser().getEmail();
// email subject line.
var subject = 'New Paperwork';
// add the attachments variables
var attachmentstring = values["Which documents do you want to attach?"];
var array = attachmentstring.toString().split(",");
var blobs = [];
var x = 0;
for (var i = 0; i < array.length; i++) {
//check if even
if (i % 2 === 0) {
}
else
{
blobs[x] = DriveApp.getFileById(array[i]).getBlob();
x++;
}
}
// an email body.
var body = 'Hello';
// Send an email with attachments
GmailApp.sendEmail(email, subject, body, {attachments: blobs});
}
I have a script that forwards all of my emails that come in during specific times to email#domain.com.
The problem I am having, is that sometimes email#domain.com sends me an email during that time.
Can anyone suggest a way to add a rule that it should forward to all addresses except forwarding address?
function forwardEmails() {
try {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var settings = ss.getSheetByName('Settings').getDataRange().getValues();
if (settings[1][1] == 'No')
return;
if (settings[2][1] == "")
throw new Error('Please set Forward Email!');
var email = PropertiesService.getScriptProperties().getProperty('email');
if (!email)
throw new Error('First authorize script by clicking on menu: Email Forwarder >> Authorize Script');
var today = (new Date());
var applicableRules = validRules(today);
if (applicableRules) {
var unread = GmailApp.getInboxUnreadCount();
if (!unread)
return;
var threads = GmailApp.getInboxThreads(0, unread>100?100:unread);
var cutOff = today.getTime() - (MINUTES*60*1000 + 100); // 10 mins + 100 ms
for (var i=0; i<threads.length; i++) {
var msgs = threads[i].getMessages();
for (var j=0; j<msgs.length; j++) {
var from = msgs[j].getFrom();
var msgDate = msgs[j].getDate();
var msgTime = (new Date(msgDate)).getTime();
var diff1 = msgTime - cutOff;
if (diff1 > 0 && from.indexOf(email) == -1) {
var to = msgs[j].getTo();
var subject = msgs[j].getSubject();
var attach = msgs[j].getAttachments();
var body = msgs[j].getBody();
var plainBody = msgs[j].getPlainBody();
var replyTo = msgs[j].getReplyTo();
var options = {replyTo: from};
if (attach.length > 0)
options.attachment = attach;
GmailApp.sendEmail(settings[2][1], subject, plainBody, options );
}
}
}
}
} catch (error) {
var html = '<p>'+ error + '</p><br><br>Email Forwarder Rules & Settings<p>Line: '+ error.lineNumber + ', Filename: ' + error.fileName + '</p>';
if (!email)
email = Session.getActiveUser().getEmail();
MailApp.sendEmail(email, 'Email Forwarder Script Failed!', error + '\n\nEmail Forwarder Rules & Settings URL: ' + ss.getUrl(), {htmlBody: html});
}
}
Instead of using getInboxThreads() use search().
getInboxThreads() will return threads in your inbox while search() will return those that meet the search query. The following query will include include messages in your inbox but exclude those from email#domain.com
in:inbox -from:email#domain.com
You could add a check in the second loop of the "forwardEmails" function. The code below would skip any unread emails which have arrived from the forwarding address (I'm assuming the forwarding email is referenced in "settings[2][1]".
for (var i=0; i<threads.length; i++) {
var msgs = threads[i].getMessages();
for (var j=0; j<msgs.length; j++) {
var from = msgs[j].getFrom();
var msgDate = msgs[j].getDate();
var msgTime = (new Date(msgDate)).getTime();
var diff1 = msgTime - cutOff;
// New code
if (from === settings[2][1]) {
continue;
}
I have been using this script to send google-spreadsheet to my e-mail when modified. Can anybody help to replace the authentication section with an OAuth2 for Apps Script. OAuth 1.0 support was deprecated in 2012 and is scheduled to be shut down on April 20, 2015.
Thanks.
function onOpen() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var menuEntries = [ {name: "Send Email", functionName: "sendEmail"}];
ss.addMenu("Scripts", menuEntries);
};
function sendEmail() {
var ssID = SpreadsheetApp.getActiveSpreadsheet().getId();
var sheetName = SpreadsheetApp.getActiveSpreadsheet().getName();
//var email = Session.getUser().getEmail();
var email = Session.getEffectiveUser();
var subject = "this is my subject";
var body = "this is my body :)";
var oauthConfig = UrlFetchApp.addOAuthService("google");
oauthConfig.setAccessTokenUrl("https://www.google.com/accounts/OAuthGetAccessToken");
oauthConfig.setRequestTokenUrl("https://www.google.com/accounts/OAuthGetRequestToken?scope=https://spreadsheets.google.com/feeds/");
oauthConfig.setAuthorizationUrl("https://www.google.com/accounts/OAuthAuthorizeToken");
oauthConfig.setConsumerKey("anonymous");
oauthConfig.setConsumerSecret("anonymous");
var requestData = {"method": "GET", "oAuthServiceName": "google", "oAuthUseToken": "always"};
var url = "https://spreadsheets.google.com/feeds/download/spreadsheets/Export?key="
+ ssID + "&gid=0&portrait=true" +"&exportFormat=xls";
var result = UrlFetchApp.fetch(url , requestData);
var contents = result.getContent();
MailApp.sendEmail(email,subject ,body, {attachments:[{fileName:sheetName+".xls", content:contents, mimeType:"application//xls"}]});
};
This is an easy fix. The fetch requests requires a scope allowing drive access. You can force Apps Script to add this scope by making a call to DriveApp. Then in your fetch you add the users OAuth token to the header of the call.
function onlyToAddTheDriveScope(){
DriveApp.getRootFolder()
}
function onOpen() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var menuEntries = [ {name: "Send Email", functionName: "sendEmail"}];
ss.addMenu("Scripts", menuEntries);
};
function sendEmail() {
var ssID = SpreadsheetApp.getActiveSpreadsheet().getId();
var sheetName = SpreadsheetApp.getActiveSpreadsheet().getName();
//var email = Session.getUser().getEmail();
var email = Session.getEffectiveUser();
var subject = "this is my subject";
var body = "this is my body :)";
var requestData = {"method": "GET",
"headers":{"Authorization":"Bearer "+ScriptApp.getOAuthToken()}
};
var url = "https://spreadsheets.google.com/feeds/download/spreadsheets/Export?key="
+ ssID + "&gid=0&portrait=true" +"&exportFormat=xls";
var result = UrlFetchApp.fetch(url , requestData);
var contents = result.getContent();
MailApp.sendEmail(email,subject ,body, {attachments:[{fileName:sheetName+".xls", content:contents, mimeType:"application//xls"}]});
};
I want to build a chart to google fusion table. I know there is an option to do it with fusion table but I need to do that using google spreadsheet.
How do I import a private fusion table to a spreadsheet?
function getdata(authToken) {
query = encodeURIComponent("SELECT * FROM tableid");
var URL = "http://www.google.com/fusiontables/api/query?sql=" + query;
var response = UrlFetchApp.fetch(URL, {
method: "get",
headers: {
"Authorization": "GoogleLogin auth=" + authToken,
}
});
return response.getContentText();
}
The code above gives me the table headers only.
Don't set each cell individually as in the example below unless you need to process each bit of data. Using this is about 10x faster:
var rows = o.length;
var columns = o[0].length;
cell.offset(<startrow>, <startcolumn>, rows, columns).setValues(o);
After a deep research, finally i figured it out after a deep search and reading here.
This is how it looks for the code google docs spreadsheet app script:
function onOpen()
{
var tableID = '00000' // Add the table ID of the fusion table here
var email = UserProperties.getProperty('email');
var password = UserProperties.getProperty('password');
if (email === null || password === null) {
email = Browser.inputBox('Enter email');
password = Browser.inputBox('Enter password');
UserProperties.setProperty('email',email);
UserProperties.setProperty('password', password);
} else {
email = UserProperties.getProperty('email');
password = UserProperties.getProperty('password');
}
var authToken = getGAauthenticationToken(email,password);
query = encodeURIComponent("SELECT * FROM tableID");
var URL = "http://www.google.com/fusiontables/api/query?sql=" + query;
var response = UrlFetchApp.fetch(URL, {
method: "get",
headers: {
"Authorization": "GoogleLogin auth=" + authToken,
}
});
var tableData = response.getContentText();
var o = Utilities.parseCsv(response.getContentText());
var doc = SpreadsheetApp.getActiveSpreadsheet();
var cell = doc.getRange('a1');
var index = 0;
for (var i in o) {
var row = o[i];
var col = 0;
for (var j in row) {
cell.offset(index, col).setValue(row[j]);
col++;
}
index++;
}
}
function getGAauthenticationToken(email, password) {
password = encodeURIComponent(password);
var response = UrlFetchApp.fetch("https://www.google.com/accounts/ClientLogin", {
method: "post",
payload: "accountType=GOOGLE&Email=" + email + "&Passwd=" + password + "&service=fusiontables&Source=testing"
});
var responseStr = response.getContentText();
responseStr = responseStr.slice(responseStr.search("Auth=") + 5, responseStr.length);
responseStr = responseStr.replace(/\n/g, "");
return responseStr;
}
After that you can do whatever you want in the spreadsheet.
BTW, I still think there is a simple way to import a private table into a spreadsheet automaticly.