Copy and Share Google Document to new email but suppress notification - google-apps-script

I have the below code to copy a template and share it with the same people who has access to the template.
However, I have two issues here:
I do not want them to receive notification each time a copy is made and shared with them
I would also like to share with another person to edit it. The email of the person who can edit is in the google sheet, in column A. This new person should not also receive notificiation.
function onOpen() {
const ui = SpreadsheetApp.getUi();
const menu = ui.createMenu('Create My Checklist');
menu.addItem('New Checklist', 'createNewGoogleDocs')
menu.addToUi();
}
function createNewGoogleDocs() {
//This value should be the id of your document template that we created in the last step
const googleDocTemplate = DriveApp.getFileById('1qRQ07PDmz1il9IftM9GIJfY37vTusfQZhhNS1BRELJQ');
//This value should be the id of the folder where you want your completed documents stored
const destinationFolder = DriveApp.getFolderById('1JufckhwXlAXDAE3_-f60lHQQ-jqe9Mx1')
//Here we store the sheet as a variable
const sheet = SpreadsheetApp
.getActiveSpreadsheet()
.getSheetByName('Data')
//Now we get all of the values as a 2D array
const rows = sheet.getDataRange().getValues();
const emailAddresses = googleDocTemplate.getEditors().map(e => e.getEmail()); // Added
//Start processing each spreadsheet row
rows.forEach(function(row, index){
//Here we check if this row is the headers, if so we skip it
if (index === 0) return;
//Here we check if a document has already been generated by looking at 'Document Link', if so we skip it
if (row[10]) return;
//Using the row data in a template literal, we make a copy of our template document in our destinationFolder
const copy = googleDocTemplate.makeCopy("eResignation Checklist - " + row[2] + " - " + row[4] + " - " + row[5], destinationFolder)
copy.addEditors(emailAddresses);
//Once we have the copy, we then open it using the DocumentApp
const doc = DocumentApp.openById(copy.getId())
//All of the content lives in the body, so we get that for editing
const body = doc.getBody();
//In these lines, we replace our replacement tokens with values from our spreadsheet row
body.replaceText('{{Workday ID}}', row[1]);
body.replaceText('{{Full Name}}', row[2]);
body.replaceText('{{Management Level}}', row[3]);
body.replaceText('{{LoS}}', row[4]);
body.replaceText('{{Cost Centre}}', row[5]);
body.replaceText('{{Office Location}}', row[6]);
//We make our changes permanent by saving and closing the document
doc.saveAndClose();
//Store the url of our new document in a variable
const url = doc.getUrl();
//Write that value back to the 'Document Link' column in the spreadsheet.
sheet.getRange(index + 1, 11).setValue(url)
Drive.Permissions.insert({role: "writer", type: "user", value: row[0]}, copy.getId(), {sendNotificationEmails: false, supportsAllDrives: true});
})}

I believe your goal is as follows.
You want to share the copied file.
The email address for sharing can be retrieved from the column "A".
When the file is shared, you don't want to send a notification email.
In this case, how about the following modification?
Modified script:
In order to use the option of sendNotificationEmails, Drive API is used. So please enable Drive API at Advanced Google services.
From:
sheet.getRange(index + 1, 11).setValue(url)
})}
To:
sheet.getRange(index + 1, 11).setValue(url)
Drive.Permissions.insert({role: "writer", type: "user", value: row[0]}, copy.getId(), {sendNotificationEmails: false}); // Added
})}
Reference:
Permissions: insert
Edit:
From the following replying,
i am really unsure why it says file not found because the copied file is in the shared drive > folder ID: 1JufckhwXlAXDAE3_-f60lHQQ-jqe9Mx1
I noticed that you are using the shared Drive. And from the following replying,
I have edited the code again as per what I see in my script now. it seems to work partially - for the email in row [0] they are not getting any notification const emailAddresses = googleDocTemplate.getEditors().map(e => e.getEmail()); how to disable notification for this group?
I noticed that your script was changed from your initial script. In this case, please modify as follows.
From:
sheet.getRange(index + 1, 11).setValue(url)
})}
To:
sheet.getRange(index + 1, 11).setValue(url)
emailAddresses.concat(row[0]).forEach(v =>
Drive.Permissions.insert({role: "writer", type: "user", value: v}, copy.getId(), {sendNotificationEmails: false, supportsAllDrives: true})
);
})}

Related

google drive file link automatically change format in spreadsheet

I am implementing some download and upload file functionality in google drive through google app-script storing the drive link in google sheet. upload works fine but after some time the link is turn into some kind of hyperlink as like below
so that's why I am no longer able to get the link simply writting .getDisplayValue()
const ss = SpreadSheetApp.getActive().getActiveSheet() let url = ss.getRange().getDisplayValue()
Any Suggestion ...?
I tried Adding .getRichTextValue().getLinkUrl() But It also does not worked as It is not a HyperLink
Issue and workaround:
From your sample image, in your situation, the link of the file is changed to the smart chip. In the current stage, unfortunately, there are no methods for managing the smart chips on a Spreadsheet. So, in this case, it is required to use a workaround. The workaround is as follows.
Convert Google Spreadsheet to XLSX data.
By this, the file links of the smart chip are converted to simple strings and hyperlinks.
Convert XLSX data to Google Spreadsheet.
Retrieve the hyperlinks from the cells.
This method is from How to get in Apps Script the value of a dropdown in a Google Doc? and https://tanaikech.github.io/2022/10/27/retrieving-values-of-calendar-events-of-smart-chips-on-google-document-using-google-apps-script/ .
When this flow is reflected in a sample script, how about the following sample script?
Sample script:
Please copy and paste the following script to the script editor of Google Spreadsheet and set range that you want to retrieve the hyperlinks as A1Notation. In this sample, Drive API is used. So, please enable Drive API at Advanced Google services.
function myFunction() {
const range = "Sheet1!A1:A10"; // Please set the range you want to retrieve the hyperlinks.
const ss = SpreadsheetApp.getActiveSpreadsheet();
const url = "https://docs.google.com/spreadsheets/export?exportFormat=xlsx&id=" + ss.getId();
const blob = UrlFetchApp.fetch(url, { headers: { authorization: "Bearer " + ScriptApp.getOAuthToken() } }).getBlob();
const tempId = Drive.Files.insert({ mimeType: MimeType.GOOGLE_SHEETS, title: "temp" }, blob).id;
const tempFile = DriveApp.getFileById(tempId);
const tempSS = SpreadsheetApp.open(tempFile);
const res = tempSS.getRange(range).getRichTextValues().map((r, i) => r.map((c, j) => ({ value: c.getText(), url: c.getLinkUrl() || "", range: { row: i + 1, column: j + 1 } })));
tempFile.setTrashed(true);
console.log(res);
}
Testing:
When this script is run, the following result is obtained.
[
[{"value":"sample value","url":"https://drive.google.com/file/d/###/view?usp=share_link","range":{"row":1,"column":1}}],
,
,
,
]
Note:
As another approach, in your showing sample image, if you want to convert the file links of the smart chip to the normal value with the hyperlink, how about the following sample script? In this sample, range is overwritten by the normal values with the hyperlinks obtained by converting from XLSX data.
function myFunction2() {
const range = "Sheet1!A1:A10"; // Please set the range you want to retrieve the hyperlinks.
const ss = SpreadsheetApp.getActiveSpreadsheet();
const url = "https://docs.google.com/spreadsheets/export?exportFormat=xlsx&id=" + ss.getId();
const blob = UrlFetchApp.fetch(url, { headers: { authorization: "Bearer " + ScriptApp.getOAuthToken() } }).getBlob();
const tempId = Drive.Files.insert({ mimeType: MimeType.GOOGLE_SHEETS, title: "temp" }, blob).id;
const tempFile = DriveApp.getFileById(tempId);
const tempSS = SpreadsheetApp.open(tempFile);
const r = tempSS.getRange(range);
const tempSheet = r.getSheet().copyTo(ss);
tempSheet.getRange(r.getA1Notation()).copyTo(ss.getRange(range));
ss.deleteSheet(tempSheet);
tempFile.setTrashed(true);
}
References:
Retrieving Values of Calendar Events of Smart Chips on Google Document using Google Apps Script (Author: me)
Related thread
How to get in Apps Script the value of a dropdown in a Google Doc?

Appscript save copy as docx

hey guys i found this guide https://jeffreyeverhart.com/2020/09/29/auto-fill-a-google-doc-template-from-google-sheet-data/ on transfering data for sheets to google docs but i am trying to get it to save the files as docx since the files will be sent out to customers.
Is there any easy way to get it to work?
function onOpen() {
const ui = SpreadsheetApp.getUi();
const menu = ui.createMenu('Oppdrettsbevis');
menu.addItem('Generer Oppdrettsbevis', 'createNewGoogleDocs')
menu.addToUi();
}
function createNewGoogleDocs() {
//This value should be the id of your document template that we created in the last step
const googleDocTemplate = DriveApp.getFileById('xxxxxxxx');
//This value should be the id of the folder where you want your completed documents stored
const destinationFolder = DriveApp.getFolderById('xxxxxxxxx')
//Here we store the sheet as a variable
const sheet = SpreadsheetApp
.getActiveSpreadsheet()
.getSheetByName('Data')
//Now we get all of the values as a 2D array
const rows = sheet.getDataRange().getValues();
//Start processing each spreadsheet row
rows.forEach(function(row, index){
//Here we check if this row is the headers, if so we skip it
if (index === 0) return;
//Here we check if a document has already been generated by looking at 'Document Link', if so we skip it
if (row[5]) return;
//Using the row data in a template literal, we make a copy of our template document in our destinationFolder
const copy = googleDocTemplate.makeCopy(`${row[1]}, ${row[0]} Employee Details` , destinationFolder)
//Once we have the copy, we then open it using the DocumentApp
const doc = DocumentApp.openById(copy.getId())
//All of the content lives in the body, so we get that for editing
const body = doc.getBody();
//In this line we do some friendly date formatting, that may or may not work for you locale
const friendlyDate = new Date(row[3]).toLocaleDateString();
//In these lines, we replace our replacement tokens with values from our spreadsheet row
body.replaceText('{{First Name}}', row[0]);
body.replaceText('{{Last Name}}', row[1]);
body.replaceText('{{Position}}', row[2]);
body.replaceText('{{Hire Date}}', friendlyDate);
body.replaceText('{{Hourly Wage}}', row[4]);
//We make our changes permanent by saving and closing the document
doc.saveAndClose();
//Store the url of our new document in a variable
const url = doc.getUrl();
//Write that value back to the 'Document Link' column in the spreadsheet.
sheet.getRange(index + 1, 6).setValue(url)
})
}
You are asking if it is possible to export a .docx
Try Using, from the crossreferenced post beolw the docToDocx() , which I modified to return the URL. Edited to include the Entire code with some Logger lines.
function onOpen() {
const ui = SpreadsheetApp.getUi();
const menu = ui.createMenu('AutoFill Docs');
menu.addItem('Create New Docs', 'createNewGoogleDocs')
menu.addToUi();
}
//include this function
function docToDocx(id) {
var format = 'docx',
exportLink =
'https://docs.google.com/document/d/' + id + '/export?format=' + format,
blob = UrlFetchApp.fetch(exportLink, {
headers: {
Authorization: 'Bearer ' + ScriptApp.getOAuthToken(),
},
});
var thisFile = DriveApp.createFile(blob);
return thisFile.getUrl()
}
function createNewGoogleDocs() {
//This value should be the id of your document template that we created in the last step
const googleDocTemplate = DriveApp.getFileById('xx YOUR TEMPLATE ID HERE xx');
//This value should be the id of the folder where you want your completed documents stored
const destinationFolder = DriveApp.getFolderById('xx YOUR FOLDER ID HERE xx')
//Here we store the sheet as a variable
const sheet = SpreadsheetApp
.getActiveSpreadsheet()
.getSheetByName('Data')
//Now we get all of the values as a 2D array
const rows = sheet.getDataRange().getValues();
//Start processing each spreadsheet row
rows.forEach(function(row, index){
//Here we check if this row is the headers, if so we skip it
if (index === 0) return;
//Here we check if a document has already been generated by looking at 'Document Link', if so we skip it
if (row[5])
{
Logger.log("Document Made already");
Logger.log(row[5]);
return; //Breaks this iteration of the loop should allow next row
}
//Using the row data in a template literal, we make a copy of our template document in our destinationFolder
const copy = googleDocTemplate.makeCopy(`${row[1]}, ${row[0]} Employee Details` , destinationFolder)
//Once we have the copy, we then open it using the DocumentApp
const doc = DocumentApp.openById(copy.getId())
//All of the content lives in the body, so we get that for editing
const body = doc.getBody();
//In this line we do some friendly date formatting, that may or may not work for you locale
const friendlyDate = new Date(row[3]).toLocaleDateString();
//In these lines, we replace our replacement tokens with values from our spreadsheet row
body.replaceText('{{First Name}}', row[0]);
body.replaceText('{{Last Name}}', row[1]);
body.replaceText('{{Position}}', row[2]);
body.replaceText('{{Hire Date}}', friendlyDate);
body.replaceText('{{Hourly Wage}}', row[4]);
//We make our changes permanent by saving and closing the document
doc.saveAndClose();
Logger.log("The Google Doc: " + doc.getUrl());
///Call the docToDocx Function and save the Url:
const url = docToDocx( doc.getId() );
Logger.log("The .docX URL: " + url);
//Write that value back to the 'Document Link' column in the spreadsheet.
sheet.getRange(index + 1, 6).setValue(url);
})
}
After Running the Script I can now see in my Execution log:
Cloud logs
Oct 19, 2022, 12:09:46 PM Info The Google Doc: https://docs.google.com/open?id=xx THIS FILE ID xx
Oct 19, 2022, 12:09:48 PM Info The .docX URL: https://docs.google.com/document/d/xx THIS FILE ID xx_/edit?usp=drivesdk&ouid=xx THIS TOKEN ID XX&rtpof=true&sd=true
Oct 19, 2022, 12:09:50 PM Info The Google Doc: https://docs.google.com/open?id=xx THIS FILE ID xx
Oct 19, 2022, 12:09:52 PM Info The .docX URL: https://docs.google.com/document/d/xx THIS FILE ID xx/edit?usp=drivesdk&ouid=xx THIS TOKEN ID XX&rtpof=true&sd=true
Oct 19, 2022, 12:09:54 PM Info The Google Doc: https://docs.google.com/open?id=xx THIS FILE ID xx
Oct 19, 2022, 12:09:56 PM Info The .docX URL: https://docs.google.com/document/d/xx THIS FILE ID xx/edit?usp=drivesdk&ouid=xx THIS TOKEN ID XX&rtpof=true&sd=true
That shows the Google docs url is different then the supplied uls that will lead to a download of a .docx file. Those docx Urls are also showing in column 5 of the spreadsheet.
The docX function was found at theWizEd's commented crossreference:
Converting a GDoc to docx through GAS produces corrupted document

Google Scripts not skipping rows

Pretty new to using google scripts, so forgive me if I'm doing something silly.
I am trying to write a program to take a large spreadsheet of data and fill an invoice template I have created. I have successfully done this in the past, but now when I tried to apply the app to a new spreadsheet of data, it is no longer functioning properly.
The problem is because the sheet is so large, the scripts times out, then when I go to restart the script, it starts again all the way at the beginning instead of starting where it left off. Originally the function was set to write the URL of the new invoice in the last column of spreadsheet, and the function would skip any rows with entries in that column. This was not happening, so to simplify I added another row that once the invoice is created, the word "DONE" is entered, and then I tried to set it up to skip any row with "DONE" in that column, this still is not working.
Any ideas on how I can get this to work?
function onOpen() {
const ui = SpreadsheetApp.getUi();
const menu = ui.createMenu('AutoFill Docs');
menu.addItem('Create New Docs', 'createNewGoogleDocs')
menu.addToUi();
}
function createNewGoogleDocs() {
//This value should be the id of your document template that we created in the last step
const googleDocTemplate = DriveApp.getFileById('1yXfcXTESCHqKsfMcgkhYJ9MdVwYoLYPhH1MRv4RyPk0');
//This value should be the id of the folder where you want your completed documents stored
const destinationFolder = DriveApp.getFolderById('1TXEumNJXfgFzPtKLBOAKJBXG-yNnjseQ')
//Here we store the sheet as a variable
const sheet = SpreadsheetApp
.getActiveSpreadsheet()
.getSheetByName('Export Worksheet')
//Now we get all of the values as a 2D array
const rows = sheet.getDataRange().getValues();
//Start processing each spreadsheet row
rows.forEach(function(row, index){
//Here we check if this row is the headers, if so we skip it
if (index === 0) return;
//Here we check if a document has already been generated by looking at 'Document Link', if so we skip it
if (row[31]=== 'DONE') return;
//Using the row data in a template literal, we make a copy of our template document in our destinationFolder
const copy = googleDocTemplate.makeCopy(`${row[4]}, ${row[0]} Invoice` , destinationFolder)
//Once we have the copy, we then open it using the DocumentApp
const doc = DocumentApp.openById(copy.getId())
//All of the content lives in the body, so we get that for editing
const body = doc.getBody();
//In this line we do some friendly date formatting, that may or may not work for you locale
const friendlyDate = new Date(row[3]).toLocaleDateString();
//In these lines, we replace our replacement tokens with values from our spreadsheet row
body.replaceText('{{Full Address}}', row[4]);
body.replaceText('{{unit}}', row[5]);
body.replaceText('{{Total}}', row[15]);
body.replaceText('{{Account Num}}', row[2]);
body.replaceText('{{Owner 1}}', row[6]);
body.replaceText('{{Owner 2}}', row[7]);
body.replaceText('{{CO Name}}', row[17]);
body.replaceText('{{St Address}}', row[20]);
body.replaceText('{{Address 1}}', row[18]);
body.replaceText('{{City}}', row[21]);
body.replaceText('{{State}}', row[22]);
body.replaceText('{{CO Zip}}', row[23]);
body.replaceText('{{invoice #}}', row[0]);
//We make our changes permanent by saving and closing the document
doc.saveAndClose();
//Store the url of our new document in a variable
const url = doc.getUrl();
//Write that value back to the 'Document Link' column in the spreadsheet.
sheet.getRange(index + 1, 30).setValue(url)
//Write that value back to the 'Document Link' column in the spreadsheet.
sheet.getRange(index + 1, 31).setValue("DONE")
})
}
Try this:
You were checking for DONE in the wrong location
function createNewGoogleDocs() {
const googleDocTemplate = DriveApp.getFileById('1yXfc...');
const destinationFolder = DriveApp.getFolderById('1TXE...');
const ss = SpreadsheetApp.getActive();
const sh = ss.getSheetByName('Export Worksheet');
const vs = sh.getRange(2, 1, sh.getLastRow() - 1, sh.getLastColumn()).getValues();
vs.forEach((r, i) => {
if (r[30] != 'DONE') {
const copy = googleDocTemplate.makeCopy(`${r[4]}, ${r[0]} Invoice`, destinationFolder);
const doc = DocumentApp.openById(copy.getId());
const body = doc.getBody();
body.replaceText('{{Full Address}}', r[4]);
body.replaceText('{{unit}}', r[5]);
body.replaceText('{{Total}}', r[15]);
body.replaceText('{{Account Num}}', r[2]);
body.replaceText('{{Owner 1}}', r[6]);
body.replaceText('{{Owner 2}}', r[7]);
body.replaceText('{{CO Name}}', r[17]);
body.replaceText('{{St Address}}', r[20]);
body.replaceText('{{Address 1}}', r[18]);
body.replaceText('{{City}}', r[21]);
body.replaceText('{{State}}', r[22]);
body.replaceText('{{CO Zip}}', r[23]);
body.replaceText('{{invoice #}}', r[0]);
doc.saveAndClose();
const url = doc.getUrl();
sh.getRange(i + 2, 30).setValue(url);
sh.getRange(i + 2, 31).setValue("DONE");
}
});
}

Copy and share Google Doc with the same people

Hi I am trying to copy a template and want it to be shared with the same people (similar to how we do it manually). I am a total noob and get by with just doing the basic stuff, so I am not able to fix
function onOpen() {
const ui = SpreadsheetApp.getUi();
const menu = ui.createMenu('Create My Checklist');
menu.addItem('New Checklist', 'createNewGoogleDocs')
menu.addToUi();
}
function createNewGoogleDocs() {
//id of the document template
const googleDocTemplate = DriveApp.getFileById('1qRQ07PDmz1il9IftM9GIJfY37vTusfQZhhNS1BRELJQ');
//id of the folder where the completed documents stored
const destinationFolder = DriveApp.getFolderById('1JufckhwXlAXDAE3_-f60lHQQ-jqe9Mx1')
//Here we store the sheet as a variable
const sheet = SpreadsheetApp
.getActiveSpreadsheet()
.getSheetByName('Data')
//get all of the values as a 2D array
const rows = sheet.getDataRange().getValues();
//Start processing each spreadsheet row
rows.forEach(function(row, index){
//check if this row is the headers, if yes, skip it
if (index === 0) return;
//check if a document has already been generated by looking at 'Document Link', if yes, skip it
if (row[10]) return;
//Using the row data in a template literal, make a copy of the template document in the destinationFolder
const copy = googleDocTemplate.makeCopy("My Checklist - " + row[2] + " - " + row[4] + " - " + row[5], destinationFolder)
//Copy, then open it using the DocumentApp
const doc = DocumentApp.openById(copy.getId())
//Get contents for editing
const body = doc.getBody();
//replace token with values from spreadsheet row
body.replaceText('{{Employee ID}}', row[1]);
body.replaceText('{{Name}}', row[2]);
body.replaceText('{{Level}}', row[3]);
body.replaceText('{{Department}}', row[4]);
body.replaceText('{{Business Unit}}', row[5]);
body.replaceText('{{Location}}', row[6]);
//We make our changes permanent by saving and closing the document
doc.saveAndClose();
//Store the url of our new document in a variable
const url = doc.getUrl();
//Write that value back to the 'Document Link' column in the spreadsheet.
sheet.getRange(index + 1, 11).setValue(url)
})}
I believe your goal is as follows.
You want to share the copied file of const copy = googleDocTemplate.makeCopy("My Checklist - " + row[2] + " - " + row[4] + " - " + row[5], destinationFolder) with other users.
the same people (similar to how we do it manually) means share with the same people.
In this case, how about the following modification?
From:
//Start processing each spreadsheet row
rows.forEach(function(row, index){
//check if this row is the headers, if yes, skip it
if (index === 0) return;
//check if a document has already been generated by looking at 'Document Link', if yes, skip it
if (row[10]) return;
//Using the row data in a template literal, make a copy of the template document in the destinationFolder
const copy = googleDocTemplate.makeCopy("My Checklist - " + row[2] + " - " + row[4] + " - " + row[5], destinationFolder)
//Copy, then open it using the DocumentApp
To:
const emailAddresses = googleDocTemplate.getEditors().map(e => e.getEmail()); // Added
//Start processing each spreadsheet row
rows.forEach(function(row, index){
//check if this row is the headers, if yes, skip it
if (index === 0) return;
//check if a document has already been generated by looking at 'Document Link', if yes, skip it
if (row[10]) return;
//Using the row data in a template literal, make a copy of the template document in the destinationFolder
const copy = googleDocTemplate.makeCopy("My Checklist - " + row[2] + " - " + row[4] + " - " + row[5], destinationFolder)
copy.addEditors(emailAddresses); // Added
//Copy, then open it using the DocumentApp
From your question, I couldn't understand whether you wanted to share the file as the editor. So if you wanted to share it with the viewer, please modify it as follows.
From
copy.addEditors(emailAddresses);
To
copy.addViewers(emailAddresses);
References:
addEditors(emailAddresses)
addViewers(emailAddresses)

How to export spreadsheet header and last row value to csv file using Google apps script

I'm new here and try to seek some expertise to help to create a google apps script.
I have a spreadsheet and want to export the header and the new added row value to csv file and save it into my local c drive and send an alert email with column B value as a subject.
eg. spreadsheets has 14 columns and I would like to export start from column 2 to csv with values like: "column2 value; column3 value; column4 value; column5 value; column6 value; .....column14 value "
Below is my description workflow :
So everytime when people filled up the value in the google forms and press submit, i will received a new row value in a google sheet. Then i will export the header and the latest row value to csv file into my local c drive and send an alert email with column B value as a subject.
Much appreciated if some expertise can help me on this. Thank you so much. :)
Excel sample.xlsx
See if this helps you:
We'll assume you have the spreadsheet configured as follows:
You've a sheet for submission called Responses
You've a helper sheet needed for the script called Temp which has
the same headers in the first row than the Responses sheet
In the illustrated example below, you want to save as CSV file the headers (Orange) along with the last row submitted (Green)
When you access the script you'll change the following:
The Spreadsheet ID of the whole document
The ID of the tab Temp (numbers found after edit#gid=)
The email address of the recipient
Code:
// Example: https://docs.google.com/spreadsheets/d/1kXaTto1ktqX0XNKQ035897FGX5tV75o7wuYHiNCOqEFfI/edit#gid=1269457815
// In this link the ID of the Spreadsheet is everything after /d/
// which is: 1kXaTto1ktqX0XNKQ035897FGX5tV75o7wuYHiNCOqEFfI
// THE ID of the sheet Temp would be something like: 1269457815
// ---------- Menu ----------
function onOpen() {
var ui = SpreadsheetApp.getUi();
ui.createMenu('CSV File')
.addItem('Step 1: Email CSV', 'EmailRange')
.addItem('Step 2: Save CSV file', 'showurl')
.addToUi();
}
// Choose how do want to export the: csv,pdf,xlsx
EXPORT_TYPE="csv";
function EmailRange() {
// Enter Sheet ID in between ""
var sheetId = "ID GOES HERE";
var ss = SpreadsheetApp.openById(sheetId);
var sheet=ss.getSheetByName("Responses");
// You can set up the headers beforehand
var temp = ss.getSheetByName("Temp");
//Copy range onto Temp sheet
var rangeToCopy = sheet.getRange("A"+(ss.getLastRow())+":N"+(ss.getLastRow()));
// It will erase any previous data
rangeToCopy.copyTo(temp.getRange(2, 1));
// Temporarily hide the sheet
ss.getSheetByName('Responses').hideSheet()
//Authentification
var params = {method:"GET",headers:{"authorization":"Bearer "+ ScriptApp.getOAuthToken()}};
var url="https://docs.google.com/spreadsheets/d/"+ss.getId()+"/export?format="+EXPORT_TYPE;
//Fetch URL of active spreadsheet
var fetch=UrlFetchApp.fetch(url,params);
//Get content as blob
var blob=fetch.getBlob();
var mimetype;
if(EXPORT_TYPE=="pdf"){
mimetype="application/pdf";
}else if(EXPORT_TYPE=="csv"){
mimetype="text/csv";
}else if(EXPORT_TYPE=="xlsx"){
mimetype="application/xlsx";
}else{
return;
}
// OP: send an alert email with column B value as a subject
var subject = sheet.getRange("B"+(ss.getLastRow()));
var timestamp = sheet.getRange("A"+(ss.getLastRow()));
var Title = subject.getValues();
var signature = timestamp.getValues();
//Change Email Recipient underneath
GmailApp.sendEmail('s.nabil#arrowad.sch.sa',
'Job ID: '+Title,
'Hi there,' + '\n\n' + 'A new entry has been submitted, please find the details in the attached CSV file.' + '\n\n' + 'Submitted on: '+signature,
{
attachments: [{
fileName: Title + "."+EXPORT_TYPE,
content: blob.getBytes(),
mimeType: mimetype
}]
});
//Reshow Response sheet
ss.getSheetByName('Responses').showSheet()
}
function showurl() {
// Enter Spreadsheet ID after d/ and the TAB ID of Temp after gid=
var htmlOutput = HtmlService
.createHtmlOutput('Click here My File to download')
.setWidth(250) //optional
.setHeight(50); //optional
SpreadsheetApp.getUi().showModalDialog(htmlOutput, 'Download CSV File');
}
STEP 1: Sending an email to the defined recipient in the script with the subject being the value of the last row in column B, and the signature the submission date & time, like this:
The CSV file will be attached to the email:
STEP 2: From the CSV File Menu which is created when opening the spreadsheet:
Save file to your Local desktop: