I have script which creates a new sheet in a google spreadsheet under the names of the users who fill out the form of the spreadsheet.
I would like this script to be triggered whenever a new user fills out the form associated with this spreadsheet. of course, a new user means a new E-mail address is added to the automatically generated "Username" column in the spreadsheet.
This is my code currently:
function MakeSheet() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("default sheet");
var getEmail = Browser.inputBox("user Email: ");
var s1 = ss.getSheetByName("list of users and emails");
var index = s1.getRange(1,1,s1.getLastRow(),1).getValues();
var values = s1.getRange(1,2,s1.getLastRow(),1).getValues();
nextIndex: for( var i in index) { if( index[i][0] == getEmail ) { var getName = values[i][0];continue nextIndex;}}
ss.setActiveSheet(ss.getSheetByName("default sheet"));
SpreadsheetApp.getActiveSpreadsheet().duplicateActiveSheet();
ss.setActiveSheet(ss.getSheetByName("Copy of default sheet"));
SpreadsheetApp.getActiveSpreadsheet().renameActiveSheet(getName);
SpreadsheetApp.getActiveSheet().getRange('B3').setValue(getEmail);
SpreadsheetApp.getActiveSheet().getRange('C3').setValue(getName);
}
The solution is to have a trigger on form submit. In the trigger function, you can check if the user is a 'new user'. By the way, I'm not sure how you get the email address - you either have to be a Google Apps user or you should be asking the email address explicitly.
Related
I have a sheet named "Credentials" populated with the following data:
And another sheet in the same spreadsheet named "Clients" which is linked to a google form:
My goal here is to show on the confirmation message the data from the "Credentials" sheet which is in the same row as the row that is filled when a form is submitted. E.G: the form data that was stored in row 2 should show "usr a" and "pass a" on the confirmation message
I have this apps script to do so but it always shows the last data from the "Credentials" sheet on the form confirmation message and i can't see why:
function onEdit(e) {
var ss = SpreadsheetApp.getActiveSpreadsheet()
var sheet_clientes = ss.getSheetByName('Clients')
var sheet_demos = ss.getSheetByName('Credentials')
var form = FormApp.openByUrl(ss.getFormUrl())
var demosRange = sheet_demos.getRange('A2:B4')
var demosData = demosRange.getValues()
var lr = sheet_clientes.getLastRow()
var user = demosData[lr][0]
var password = demosData[lr][1]
form.setConfirmationMessage('Congratulations: Your user is:\n' + user + '\n Your password is:\n' + password)
}
You can use the Form Submit Trigger of Google Apps Script to run the script whenever a response was submitted.
But for setConfirmationMessage(message) Bryan P explained that
we can't conditionally set and immediately display a custom
message for the current user's response based on what their answers
were. The confirmation message is "front-loaded" in a sense.
Since we cannot use setConfirmationMessage() for this case, I created an alternative that will send the credentials to the email address the provided in the response.
Try this:
Code:
function onFormSubmit(e) {
var range = e.range;
var sheet = range.getSheet();
var row = range.getRow();
var spreadsheet = sheet.getParent();
var credSheet = spreadsheet.getSheetByName("Credentials");
var creds = credSheet.getRange(row, 1, 1, 2).getValues();
var values = e.namedValues;
var email = values['Email Address'];
var username = creds[0][0];
var password = creds[0][1];
var message = 'Your user is:' + username + '\nYour password is:' + password;
var subject = 'Credentials';
GmailApp.sendEmail(email, subject, message)
}
Trigger Setup:
In your Apps Script, go to the left side menu and click Triggers.
Click Add Trigger.
Copy the setup below.
Click Save
Note: Make sure to copy and save the code provided above before creating the trigger.
Example:
References:
Event Object
Class Range
Class Sheet
Class GmailApp
I'm trying to write a script that will allow me to email a list of 150 employees with their individual sales data for the week.
At the moment I have a main front sheet with a Column for Email, Subject, and Store number. Each store number correlates to a Sheet (tab) with the same name, for example joe#gmail.com at store number 5070 has a tab named '5070' with changing data.
The problem I'm having is referencing the changing variable sheet name.
function sendEmail() {
var ss = SpreadsheetApp.getActiveSpreadsheet()
var sheet1=ss.getSheetByName('Sheet1');
var n=sheet1.getLastRow();
for (var i = 2; i < n+1 ; i++ ) {
var emailAddress = sheet1.getRange(i,1).getValue();
var subject = sheet1.getRange(i,2).getValue();
var message = sheet1.getRange(i,3).getValue();
MailApp.sendEmail(emailAddress, subject, message);
}
}
I am very new to the whole thing and have been searching around but have not had much luck. Thank you in advance!
You can't send a sheet. You can send only a link to the sheet.
If you replace this:
var message = sheet1.getRange(i,3).getValue();
with this:
var sheet_name = sheet1.getRange(i,3).getValue();
var sheet = ss.getSheetByName(sheet_name);
var message = sheet.getUrl();
Your recipients will get the link to the spreadsheet (a whole sheet, not even to the particular sheet).
To send a link to a particular sheet of the spreadsheet you need a bit more complicated solution:
var sheet_name = sheet1.getRange(i,3).getValue();
var sheet = ss.getSheetByName(sheet_name);
var message = getSheetUrl(sheet);
function getSheetUrl(sht) {
// credits: https://webapps.stackexchange.com/questions/93305/
var ss = SpreadsheetApp.getActive();
var url = '';
sht = sht ? sht : ss.getActiveSheet();
url = (ss.getUrl() + '#gid=' + ss.getSheetId());
return url;
}
But all your recipients will see all the spreadsheet anyway with all its sheets. In case this is not the thing you want you have three options:
Option 1 -- Make a new spreadsheet, copy the data into it and send the link to this new spreadsheet.
Option 2 -- Make PDF from the sheet and send it. Actually you will need to perform Option 1 first, convert the new spreadsheet to PDF, and delete the new spreadsheet after you send it (as PDF).
Option 3 -- make a HTML table (or text table, why not?) from the data of the sheet and send the table.
https://docs.google.com/spreadsheets/d/1tf99kQdDSGxvj8f9B383W1NZRHRsd-b6bUcl9FJAOmQ/edit?usp=sharing
I want to send email from google sheets based on the criteria in column D and subject and messages choose as per criteria.I lost it in the line to choose the three different criteria(Yes,No,Confirm) and couldn't loop it.The email will be sent to different ids in sheet1 table.
How can i achieve this in google sheets scripts and how to send emails when new entry are made into the sheet?
Any solutions would be highly helpful for my project.
Googlesheet newbie.
function checkValue(e)
{
var ss = SpreadsheetApp.getActive();
var sheet = ss.getSheetByName(“Sheet1”);
var valueToCheck = sheet.getRange(“D2:D”).getValue();
var rangeEdit = e.range.getA1Notation();
var ss = SpreadsheetApp.getActiveSpreadsheet()
var sheet1=ss.getSheetByName('Sheet1');
var n=sheet1.getLastRow();
if(rangeEdit == “D2:D”)
{
if(valueToCheck = Yes )
{
function sendEmail() {
var ss = SpreadsheetApp.getActiveSpreadsheet()
var sheet1=ss.getSheetByName('Sheet1');
var n=sheet1.getLastRow();
for (var i = 2; i < n+1 ; i++ ) {
var emailAddress = sheet1.getRange(i,1).getValue();
var subject = sheet1.getRange(i,2).getValue();
var message = sheet1.getRange(i,3).getValue();
MailApp.sendEmail(emailAddress, subject, message);
}
}
You can add Google Forms as a way to populate the data in your sheet. Using forms will give you access to new entry data which you can use to send an email.
How to add Google Forms to Google Sheet?
In your spreadsheet, click on Insert and select Form
How to determine if new entry is added and how to access the data?
You can use Installable Triggers. Installable Triggers run a function automatically when a certain event, such as submitting a form, occurs. When a trigger fires, Apps Script passes the function an event object as an argument, typically called e. The event object contains information about the context that caused the trigger to fire. You can follow the steps here on how to create Installable Trigger.
Note: For this project, make sure to use On form submit as event type.
Example:
Form:
Code:
function sendEmail(e) {
var data = e.namedValues;
var msgContent = {
'Yes':{
'Subject': 'Receipt of your goods',
'Message': 'We acknowledge receipt of goods.',
},
'No':{
'Subject': 'Non delivery',
'Message': 'We have not received the goods.',
},
'Confirm':{
'Subject': 'Confirm',
'Message': 'Confirm your message.',
}
}
var emailAddress = data['Email'][0];
var criteria = msgContent[data['Criteria'][0]];
var subject = criteria['Subject'];
var body = criteria['Message'];
MailApp.sendEmail(emailAddress, subject, body);
}
Output:
Say I have a spreadsheet in google sheets with three columns EMAIL, TOPIC and TIME where I´d like to send an email to each of the EMAILs in the spreadsheet containing a link to a google form that has a question asking the preferred TIME for the given TOPIC in the spreadsheet. Is it doable to create such individualized google forms based on sheets?
The first thing that should be done is creating the forms and sending the emails. To do that, I wrote a function that loops through all the rows in your sheet (called "Sheet1", change it according to your preferences), creates a form for each row and sends it to the emails found in column A (in the sheet I've been working on, data starts at row 2 and columns are: A - email / B - topic / C - time):
function sendMails() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var values = ss.getSheetByName("Sheet1").getDataRange().getValues();
for(var i = 1; i < values.length; i++) {
var email = values[i][0];
var topic = values[i][1]
var formName = email + " - " + topic;
var form = FormApp.create(formName);
var url = form.getPublishedUrl();
form.setTitle(formName);
form.setDestination(FormApp.DestinationType.SPREADSHEET, ss.getId()); // This line bounds the created form to your spreadsheet so that responses will be written in here, in an automatically created sheet
// You can set another destination spreadsheet if you don't want all these sheets created in your spreadsheet
var question = form.addDateTimeItem();
question.setTitle("Please provide a preferred time for your assigned lecture on " + topic);
var userEmail = form.addCheckboxItem();
userEmail.setChoices([userEmail.createChoice(email)]);
var topicName = form.addCheckboxItem();
topicName.setChoices([topicName.createChoice(topic)]);
var checkBoxValidation = FormApp.createCheckboxValidation()
.requireSelectExactly(1)
.build();
userEmail.setValidation(checkBoxValidation);
topicName.setValidation(checkBoxValidation);
MailApp.sendEmail(email, topic, url);
}
}
Next, you need to install an onFormSubmit trigger in your spreadsheet. You can do this to run a function that will write the preferred TIME the user chose in the form every time a form is submitted. To create the trigger, run this function in your script, only once:
function createOnFormSubmitTrigger() {
var ss = SpreadsheetApp.getActive();
ScriptApp.newTrigger('writeTime')
.forSpreadsheet(ss)
.onFormSubmit()
.create();
}
Finally, below is the function that the trigger trigs when a form is submitted. It looks for the row where topic and email match the ones coming from the form, and sets the time:
function writeTime(e) {
var response = e.values;
var time = response[1];
var email = response[2];
var topic = response[3];
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet1");
var values = sheet.getDataRange().getValues();
for(var i = 1; i < values.length; i++) {
if(values[i][0] == email && values[i][1] == topic) {
sheet.getRange(i + 1, 3).setValue(time);
}
}
}
I hope this is useful to you.
I am completely new to coding anything related to Google Apps Script and JavaScript in general.
I've adapted a script to my needs, but I am getting the following error when I run it:
TypeError: Cannot find function getCell in object Sheet
Essentially, I am trying to get the value in cell D4 (4,4) and pass that value to the variable emailTo. I'm obviously not doing it correctly. The rest of the script should work fine. Any guidance is appreciated.
// Sends PDF receipt
// Based on script by ixhd at https://gist.github.com/ixhd/3660885
// Load a menu item called "Receipt" with a submenu item called "E-mail Receipt"
// Running this, sends the currently open sheet, as a PDF attachment
function onOpen() {
var submenu = [{name:"E-mail Receipt", functionName:"exportSomeSheets"}];
SpreadsheetApp.getActiveSpreadsheet().addMenu('Receipt', submenu);
}
function exportSomeSheets() {
// Set the Active Spreadsheet so we don't forget
var originalSpreadsheet = SpreadsheetApp.getActive();
// Set the message to attach to the email.
var message = "Thank you for attending ! Please find your receipt attached.";
// Construct the Subject Line
var subject = "Receipt";
// THIS IS WHERE THE PROBLEM IS
// Pull e-mail address from D4 to send receipt to
var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var emailTo = sheet.getCell(4, 4).getValue();
// Create a new Spreadsheet and copy the current sheet into it.
var newSpreadsheet = SpreadsheetApp.create("Spreadsheet to export");
var projectname = SpreadsheetApp.getActiveSpreadsheet();
sheet = originalSpreadsheet.getActiveSheet();
sheet.copyTo(newSpreadsheet);
// Find and delete the default "Sheet 1"
newSpreadsheet.getSheetByName('Sheet1').activate();
newSpreadsheet.deleteActiveSheet();
// Make the PDF called "Receipt.pdf"
var pdf = DocsList.getFileById(newSpreadsheet.getId()).getAs('application/pdf').getBytes();
var attach = {fileName:'Receipt.pdf',content:pdf, mimeType:'application/pdf'};
// Send the constructed email
MailApp.sendEmail(emailTo, subject, message, {attachments:[attach]});
// Delete the wasted sheet
DocsList.getFileById(newSpreadsheet.getId()).setTrashed(true);
}
The issue is that getCell() is a method of Range, not Sheet. Get a Range from the Sheet, then use getCell() on the Range object