Is it possible to encrypt a converted google sheet into PDF before sending it as an attachment in an email ?
This is my current code: It hides the sheet I don't need to be converted and converting the other sheet into PDF. What I would like to achieve here is for the converted PDF to be password encrypted because it contains some personal information.
function myFunction() {
Utilities.sleep(200);
var sheet=SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Form Responses 1");
var pdfsheet=SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet2");
sheet.hideSheet();
var substringsubject = pdfsheet.getRange("B4:B4").getValues();
var substringnname = pdfsheet.getRange("B3:B3").getValues();
var substringidnum = pdfsheet.getRange("B7:B7").getValues();
var startRow =9; // First row of data to process B9:B9
var numRows =1; // Number of rows to process
// Fetch the range of cells B9:B9
var dataRange = pdfsheet.getRange(startRow, 1, numRows, 2)
// Fetch values for each row in the Range.
var data = dataRange.getValues();
for (var i = 0; i < data.length; ++i) {
var row = data[i];
var email = row[1];
var emailcc = row[2];
// Subject of email message
var subject = "USER ACCOUNT DETAILS " + substringsubject + " " + substringidnum + "";
var ss= SpreadsheetApp.getActiveSpreadsheet();
// Email Body can be HTML too
var body = '<body>' + ' Hi ' + substringnname +',<br><br>' +
'Please see attached file for your account details.</p>' +
//'<p> Click here to go to google.<p>'
'</body>'
var pdf = DriveApp.getFileById(ss.getId()).getAs("application/pdf");
pdf.setName(substringsubject+" "+substringidnum+" .pdf");
// If allowed to send emails, send the email with the PDF attachment
MailApp.sendEmail({
to:email,
cc:emailcc,
subject:subject,
htmlBody:body,
attachments:[pdf]
});
sheet.showSheet();
}
}
Thank you.
You can't protect your PDF directly from Apps script. See this previous SO question.
Related
I'm an Italian (sorry for bad English) system engineer but I accepted to help a friend so I had to achieve this goal.
He's trying to sponsor his products through Telegram but he's stingy and lazy and before investing wants to try something managed by a bot.
So I created the Telegram Bot, used his link of SpreadSheet, and tried to do this thing:
Column U is a link referral to an image and he wants to display that image, column B must be compared with a string and if it's the same then print the column A(integer), F(integer), L(string), J opens a chat with #someone if it's not the same than go to the next line.
As a newbie I past many time reading online and trying to find the way, but I've just reached this:
var token ="myToken";;
var telegramUrl = "https://api.telegram.org/bot" + token;
var webAppUrl = "https://script.google.com/macros/s/myLinkReferal/exec";
var ssId = "MyssId";
var ui = SpreadsheetApp.getUi();
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
var rangeData = sheet.getDataRange();
var lastColumn = rangeData.getLastColumn();
var lastRow = rangeData.getLastRow();
var searchRange = sheet.getRange(2,2, lastRow-1, lastColumn-1);
function getMe() {
var url = telegramAPI + "/getMe";
var response = UrlFetchApp.fetch(url);
Logger.log(response.getContentText());
}
function setWebhook() {
var url = telegramAPI + "/setWebhook?url=" + webAppAPI;
var response = UrlFetchApp.fetch(url);
Logger.log(response.getContentText());
}
function sendText(id,text) {
var url = telegramAPI + "/sendMessage?chat_id=" + id + "&text=" + text;
var response = UrlFetchApp.fetch(url);
Logger.log(response.getContentText());
}
function doPost(e) {
Logger.log(e);
for(i = 1; i < lastColumn; i++){
for (j = 1; j < lastRow ; j++){
var cell = searchRange.getCell(1,i).getValue();
if (cell === "DISPONIBILE"){
****visualize a photo taken form a link in datasheet cell Ux
print string taken from Ax
print string taken from Ax**
link to chat with #someone**
}else j=lastRow;
};
};
var text = data.message.text;
var what = data.message.text.split("-")[0]
var who = data.message.text.split("-")[1]
var response = "Hi " + name + ", this quote has been added to your database: " + text;
sendText(id,response);
SpreadsheetApp.openById(ssId).getSheets()[1].appendRow([text,response,what,who]);
}
I'm having an issue where I want to be able to send an email with CC's based off cell values. i.e. both the main recipient email and CC email are in the spreadsheet in the same row. The code should cycle through each row and send an email to the recipient and attaches the CC to that email.
My code is as follows:
function sendEmails() {
var sheet = SpreadsheetApp.getActiveSheet();
var startRow = 2; // Start at second row because the first row contains the data labels
var numRows = 10; // Put in here the number of rows you want to process
// Fetch the range of cells A2:B4
// Column A = Email Address, Column B = First Name
var dataRange = sheet.getRange("A2:C")
// Fetch values for each row in the Range.
var data = dataRange.getValues();
for (i in data) {
var row = data[i];
var name = row[0];
var emailAddress = row[1];
var daysAbsent = row[2];
var CC = row[3];
var message = "Hi " + name + ",\n. We see that you have been absent for " + daysAbsent + " days.";
var subject = "Attendance Notification";
MailApp.sendEmail(emailAddress, subject, message,{
cc: CC
});
}
}
This script works, except it sends multiple emails, This script check Column F for any value above 0 then sends an email.Column F is where i manually enter data. Trying to get it to only send one email and put a "Email Sent" in column H. Then check if column H has a "Email Sent" if so don't send email again.
Here Is what my sheet looks like
https://docs.google.com/spreadsheets/d/1o5jKMDECIFozrwAQx6EDvPL1NkoMQ1nbpkd6AdS9ULk/edit?usp=sharing
function sendEmails() {
var sSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Form Responses"); //get the sheet "Form Responses"
var data = sSheet.getRange(2, 1, sSheet.getLastRow(),sSheet.getLastColumn()).getValues(); //get the values of your table, without the header
var lastRow = sSheet.getLastRow();//gets the last row of entered data
var yourColumn = "H";//set your column
var yourFunction = ("Email Sent");//whatever function or formula or data you want,just don't forget to use lastRow do do the row number
sSheet.getRange(yourColumn+lastRow).setValue(yourFunction);
for (var i = 0; i < data.length; i++) { // For each element of your tab
var row = data[i];
if(row[5] > 0) { // If the person have got at least 1 report outstanding (column E)
var body = "Good day "+ row[0] + " you have " + row[5] + " Internal Audit reports outstanding.";
GmailApp.sendEmail(row[1],"Outstanding Internal Audit Reports", body); // Sending a mail to alert
}
}
}
Try This:
function sendEmailsToTechs() {
var ss=SpreadsheetApp.getActive();
var sh=ss.getSheetByName("Form Responses");
//var sh=ss.getActiveSheet();
var rg=sh.getDataRange();
var data=rg.getValues();
var hRange=sh.getRange(2,8,sh.getLastRow(),1);
var hValues=hRange.getValues();
for (var i=1;i<data.length;i++){
var row = data[i];
if(row[5] && row[7]!='Email Sent') {
var body = "Good day "+ row[0] + " you have " + row[5] + " Internal Audit reports outstanding.";
GmailApp.sendEmail(row[1],"Outstanding Internal Audit Reports", body);
//Logger.log(body);
hValues[i-1][0]='Email Sent';
}
}
hRange.setValues(hValues);//Puts the values into the spreadsheet all at one time.
}
I am hoping someone can help me with this issue. I am new to coding. I have a google spreadsheet with a script that pushes out an email. I am attempting to have the script ignore the rows where the script has already sent out an email on.
function onOpen() {
var ui = SpreadsheetApp.getUi();
// Or DocumentApp or FormApp.
ui.createMenu('Email Menu')
.addItem('Send Email', 'myFunction')
.addSeparator()
.addToUi();
};
function myFunction() {
var msg = 'Email sent!';
var ss = SpreadsheetApp.getActiveSpreadsheet()
var sheet = ss.getActiveSheet();
var range = sheet.getDataRange();
var values = range.getValues();
var EMAIL_SENT = "EMAIL_SENT";
var startRow = 2;
for (i=1; i<values.length;i++) {
//sent = values[i][4]; //added this in to try and skip a row if "X" was in Sent Column
//if (sent ==" ", ) //added this in to try and skip a row if "X" was in Send Column
var email = values[i][0];
var name = values[i][i];
var subject = values[i][2];
var body = values[i][3];
var sent = values[i][5];
if (sent != EMAIL_SENT){
MailApp.sendEmail(email, subject, body);
sheet.getRange(startRow + i,5).setValue(EMAIL_SENT);
SpreadsheetApp.getUi().alert(msg);
}
}}
Google spreadsheet
Implement the following changes in your for loop:
for (i=1; i<values.length;i++) {
var email = values[i][0];
var name = values[i][1]; //not [i][i] !
var subject = values[i][2];
var body = values[i][3];
var sent = values[i][4];
if (sent !== EMAIL_SENT){
sheet.getRange(i+1,5).setValue(EMAIL_SENT);
}
}
Basically get rid of the startRow variable (if you are not using elsewhere) and just use (i+1,5) to place "EMAIL_SENT" in the right column. I have removed parts of your code for the sake of clarity.
Small fix. Replace
sheet.getRange(startRow + i,5).setValue(EMAIL_SENT);
to
sheet.getRange(startRow + i - 1, 6).setValue(EMAIL_SENT);
According to the rest of the script, this should be the most simple fix. This assumes sent column is F (column 6) not E (column 5). Sample sheet including updated script is here.
And! You should change var name = values[i][i]; to var name = values[i][1]; as #jrook pointed. I missed it...
I am looking to get a few values from a previously submitted row from a google form response and then send these values, along with the title of the form, along to an end user.
however, I think I may be going about it the wrong way, I can pull up the spreadsheet and sheet and use this to edit a field, but i can not see how to pull the values back out from here, it just comes back as "range". what is the right syntax to get a values from a range?
is there any way to pull the title of the linked form? or the spreadsheet if that is not possible, as that is just "formName" +(responses).
here is the code i have so far, it is probably just missing something simple here (the e value that it accepts is a formatted URL):
function doGet(e){
var params = JSON.stringify(e);
var message = "thank you, your Decision has been sent.";
var id = '10kf5QDeBc-vr6XJnkFxQh-ch_poQhqBQWQbgJ';
var ss = SpreadsheetApp.openById(id);
// var ss = SpreadsheetApp.getActiveSpreadsheet();
// var sheet = ss.getActiveSheet();
var sheet = ss.getSheets()[0];
var column = 20;
var datecolumn = 5;
var row = e.parameter.row;
//var title = sheet.getTitle();
var sheetname = ss.getSheetName();
var sheetnamesheet = sheet.getName();
var eventDaterange = sheet.getRange(row, datecolumn);
var eventDate = eventDaterange.getvalues();
var approval_cell = sheet.getRange(row, column);
//set default to declined
approval_cell.setValue("declined");
var approvedMessage = "<HTML><body>"+
"<h2>your request has been Approved </h2><br />"
+"<P>" + title +" " + sheet
+"<p>" + " for this date: "+ eventDate;
var deniedMessage = "<HTML><body>"+
"<h2>your request has been denied </h2><br />"
+"<P>" + ss +" " + sheet
+"<p>" + " for this date: "+ eventDate;
var aprovalResponce = (e.parameter.approval == 'true') ? approvedMessage : deniedMessage;
//var msg = "Your manager said this: " + aprovalResponce;
var msg = aprovalResponce
var replyEmail = e.parameter.reply;
if (e.parameter.approval == 'true') {
approval_cell.setValue("APPROVED");
} else {
approval_cell.setValue("DECLINED");
}
//send the actual email out
//MailApp.sendEmail(replyEmail, "Approval Request", msg);
MailApp.sendEmail(replyEmail, "Approval Request", {htmlBody: msg});
return HtmlService.createHtmlOutput(message);
}
To get values from a range, you use var values = range.getValues(); This will return a result in an 2D array of values, which is like a grid representing the range, i.e. values[row][column]. So, if our range is, say, "A1:C3", and we want the values in A1 and C3, we could do this:
var range = sheet.getRange("A1:C3");
var values = range.getValues();
var valueOne = values[0][0];
var valueTwo = values[2][2];
var msg = '"Form name" + valueOne + ValueTwo'
I don't know how to get the form name though, perhaps something as simple as e.source.title? If not, if you are using multiple forms, you may have to do this by getting the form Id from the form being submitted, and then using a switch statement to match that ID to a list of form names within your script.