Google script custom trigger onEdit(e) issue - google-apps-script

I am getting error in line 29. But the same code works when pasted in another sheet. Separate trigger is used. Edit-> Current project's trigger.
var Team_email='abc#gmail.com';
function TriggerOnEdit(e)
{
Logger.log("stg1");
sendEmailOnassigned(e);
}
function showMessageOnApproval(e)
{
var edited_row = checkStatusIsAssigned(e);
if(edited_row > 0)
{
SpreadsheetApp.getUi().alert("Row # "+edited_row+" approved!");
}
}
function showMessageOnUpdate(e)
{
var range = e.range;
SpreadsheetApp.getUi().alert("range updated " + range.getA1Notation());
}
function checkStatusIsAssigned(e)
{
Logger.log("stg3");
var range = e.range;
if(range.getColumn() <= 12 &&
range.getLastColumn() >=12 )
{
var edited_row = range.getRow();
var status = SpreadsheetApp.getActiveSheet().getRange(edited_row,11).getValue();
if(status == 'Assigned')
{
return edited_row;
}
}
return 0;
}
function sendEmailOnassigned(e)
{
Logger.log("stg2");
var approved_row = checkStatusIsAssigned(e);
if(approved_row <= 0)
{
return;
}
Logger.log("stg4");
sendEmailByRow(approved_row);
}
function sendEmailByRow(row)
{
Logger.log("stg5");
var values = SpreadsheetApp.getActiveSheet().getRange(row,1,row,13).getValues();
var row_values = values[0];
var mail = composeAssignedEmail(row_values);
MailApp.sendEmail(Team_email,mail.subject,mail.message);
var Requester_email = composeRequesterEmail(row_values);
MailApp.sendEmail(Requester_email.email,Requester_email.subject,Requester_email.message);
}
function composeAssignedEmail(row_values)
{
Logger.log("stg6");
var Request_Number = row_values[1];
var email = row_values[2];
var Project_Name = row_values[4];
var Nature_Of_Work = row_values[5];
var Quantity = row_values[6];
var Estimated_Hours = row_values[7];
var Name = row_values[12];
var message = "Hello Requester, \n "+" \n The following Resource "+ Name ;
var subject = "Request_Number - " + Request_Number ;
return({message:message,subject:subject});
}
function composeRequesterEmail(row_values)
{
Logger.log("stg7");
var Request_Number = row_values[1];
var email = row_values[2] ;
var Project_Name = row_values[4];
var Nature_Of_Work = row_values[5];
var Quantity = row_values[6];
var Estimated_Hours = row_values[7];
var Name = row_values[12];
var message = "Hello Requester, \n "+" \n The following Resource "+ Name;
var subject = "Request_Number - " + Request_Number;
return({message:message,subject:subject, email:email });
}
Please tell me the error where is the mistake.
We can not use debug function to understand the mistake. because trigger is on edit.
Also when we use 'e' what are the information do we feed the function?
How to correct this?

Related

I execute my function, and it returns a function () { [native code] }

I execute my function, and it returns a function () { [native code] }
function Simpan() {
var Sheet = SpreadsheetApp.getActiveSpreadsheet();
var shtinput = Sheet.getSheetByName('Input Form');
var shtdb = Sheet.getSheetByName('Database');
var nomorinput = shtinput.getRange('D3').getValue();
var namaitem = shtinput.getRange('D5').getValue();
var jumlahitem = shtinput.getRange('D7').getValue;
var tgl = shtinput.getRange('D9').getValue;
var baris = shtdb.getRange('E1').getValue();
baris += 1;
var rangeisi = shtdb.getRange('A' + baris + ':D'+ baris);
rangeisi.setValues([[nomorinput,namaitem,jumlahitem,tgl]]);
}
It should show the input from the sheet
I see where is the problem, check the comments below:
function Simpan() {
var Sheet = SpreadsheetApp.getActiveSpreadsheet();
var shtinput = Sheet.getSheetByName('Input Form');
var shtdb = Sheet.getSheetByName('Database');
var nomorinput = shtinput.getRange('D3').getValue();
var namaitem = shtinput.getRange('D5').getValue();
var jumlahitem = shtinput.getRange('D7').getValue; // << you cannot call .getValue without following ()
var tgl = shtinput.getRange('D9').getValue; // << you cannot call .getValue without following ()
var baris = shtdb.getRange('E1').getValue();
baris += 1;
var rangeisi = shtdb.getRange('A' + baris + ':D'+ baris);
rangeisi.setValues([[nomorinput,namaitem,jumlahitem,tgl]]);
}
As I mentioned earlier,
when you call function (or method) in javascript, if you call them without (), it returns the definition of that function (or method) instead of executing them.
to make this code work as your expectation, you have to change it into:
function Simpan() {
var Sheet = SpreadsheetApp.getActiveSpreadsheet();
var shtinput = Sheet.getSheetByName('Input Form');
var shtdb = Sheet.getSheetByName('Database');
var nomorinput = shtinput.getRange('D3').getValue();
var namaitem = shtinput.getRange('D5').getValue();
var jumlahitem = shtinput.getRange('D7').getValue();
var tgl = shtinput.getRange('D9').getValue();
var baris = shtdb.getRange('E1').getValue();
baris += 1;
var rangeisi = shtdb.getRange('A' + baris + ':D'+ baris);
rangeisi.setValues([[nomorinput,namaitem,jumlahitem,tgl]]);
}

Events are not getting added in calendar

I have the name for event and end date (without start date) in Google Sheets.
Column B is the name of the event and column C is end date.
The script says execution successful but events are not getting added in Google Calendar.
I am the owner and have full rights/permission.
Here's the script:
function onOpen() {
var ui = SpreadsheetApp.getUi();
var menu = ui.createMenu('Sync to Calendar');
var item = menu.addItem('Commit', 'syncCalendar');
item.addToUi();
}
function calendar() {
var spreadsheet = SpreadsheetApp.getActiveSheet();
var eventCal = CalendarApp.getCalendarById("calendarid**");
var name = spreadsheet.getRange('B3:B250').getValue();
var start = new Date(spreadsheet.getRange('C3:C250').getValue()).getTime();
var end = new Date(spreadsheet.getRange('C3:C250').getValue()).getTime();
eventCal.createEvent(name,new Date(start),new Date(end));
Logger.log('Reminder is added to your calendar');
}
You have to make a loop as follows
const cal = '#################gmail.com'
function calendar() {
var spreadsheet = SpreadsheetApp.getActiveSheet();
var eventCal = CalendarApp.getCalendarById(cal);
var lastRow = spreadsheet.getLastRow()
var name = spreadsheet.getRange('B3:B' + lastRow).getValues().flat();
var start = spreadsheet.getRange('C3:C' + lastRow).getValues().flat();
var end = spreadsheet.getRange('C3:C' + lastRow).getValues().flat();
name.forEach((n, i) => {
try {
var id = eventCal.createEvent(n, new Date(start[i].getTime()), new Date(end[i].getTime())).getId();
console.log(id)
} catch (e) {
console.log(i + ' ' + e)
}
})
Logger.log('Reminder is added to your calendar');
}
flat()
forEach()
With the help of #Mike Steelson this script is working.
However, when you run the code again, it creates duplicates in the calendar.
Is there any way to avoid this?
const cal = 'yourcalendarid#group.calendar.google.com'
function calendar() {
var spreadsheet = SpreadsheetApp.getActiveSheet();
var eventCal = CalendarApp.getCalendarById(cal);
var lastRow = spreadsheet.getLastRow()
var name = spreadsheet.getRange('B3:B' + lastRow).getValues().flat();
var start = spreadsheet.getRange('C3:C' + lastRow).getValues().flat();
var end = spreadsheet.getRange('C3:C' + lastRow).getValues().flat();
name.forEach((n, i) => {
try {
var id = eventCal.createEvent(n, new Date(start[i].getTime()), new Date(end[i].getTime())).getId();
console.log(id)
} catch (e) {
console.log(i + ' ' + e)
}
})
Logger.log('Reminder is added to your calendar');
}

Email not sending or probably not being triggered on form submit Google Apps Scripts

Well we have this google form and the details are being added to google sheet with custom g apps scripts. When the details have been appended to the google sheet log, it should send email. If I run the sendmail() manually, it works but when I call it inside onFormSubmit(), it's not working. What could have gone wrong?
function onFormSubmit(e) {
var sheet = SpreadsheetApp.getActiveSpreadsheet();
var templateLink = sheet.getSheetByName("Template Link").getRange(1, 1).getValue();
var logSheet = sheet.getSheetByName("Log");
var formResponsesSheet = sheet.getSheetByName("Form Responses 1");
var formResponsesHeader = formResponsesSheet.getRange(1, 2, 1, formResponsesSheet.getLastColumn() -1).getValues();
var newFileName = e.namedValues['Name'][0] + "-" + e.namedValues['Date'][0];
var populatedDocsFolder = DriveApp.getFolderById("1yTSd7W0U4Gcsm6CIw8NtD022F-MA7CPx");
var templateDocID = DocumentApp.openByUrl(templateLink).getId();
var newDocID = DriveApp.getFileById(templateDocID).makeCopy(newFileName, populatedDocsFolder).getId();
var newDocLink = DriveApp.getFileById(newDocID).getUrl();
var newDoc = DocumentApp.openById(newDocID);
var newDocBody = newDoc.getBody();
for (i = 0; i < formResponsesHeader[0].length; i++) {
var thisHeader = formResponsesHeader[0][i];
var thisValue = e.namedValues[thisHeader][0];
newDocBody.replaceText("<<" + thisHeader + ">>", thisValue);
}
//Log
var name = e.namedValues['Name'][0];
var email = e.namedValues['Email'][0];
var date = e.namedValues['Date'][0];
logSheet.appendRow([name,email,date,newDocID]);
//Trigger
ScriptApp.newTrigger("sendEmail").timeBased().after(15000).create();
//sendEmail();
}
function sendEmail() {
var sheet = SpreadsheetApp.getActiveSpreadsheet();
var logSheet = sheet.getSheetByName("Log");
var logSheetData = logSheet.getDataRange().getDisplayValues();
var templateName = sheet.getSheetByName("Template Name").getRange(1, 1).getValue();
for (i = 1; i < logSheetData.length; i++) {
if (logSheetData[i][4] == "") {
//SEND EMAIL
var name = logSheetData[i][0];
var email = logSheetData[i][1];
var date = logSheetData[i][2];
var id = logSheetData[i][3];
var pdfName = templateName + "-" + name + "-" + date;
//PDF EMAIL
try{
var doc = DriveApp.getFileById(id);
var blob = doc.getBlob().getAs('application/pdf').setName(pdfName + ".pdf");
var subject = 'Document Created';
//GmailApp.sendEmail(email, subject, "This is just a test", {attachments: [blob]});
MailApp.sendEmail(email, subject, "", {attachments: [blob], name: pdfName});
}catch(err){
continue;
}
//Log Sheet Update
logSheet.getRange(i + 1, 5).setValue("Sent");
}
}
}
function onOpen() {
SpreadsheetApp.getUi().createMenu("Custom Menu")
.addItem("Build Form Submit Trigger", "formSubmitTrigger")
.addSeparator()
.addItem("Send Email", "sendEmail")
.addSeparator()
.addItem("Mismatch Check", "mismatchCheck")
.addToUi();
}
function formSubmitTrigger() {
var sheet = SpreadsheetApp.getActiveSpreadsheet();
ScriptApp.newTrigger("onFormSubmit").forSpreadsheet(sheet).onFormSubmit().create();
}
function mismatchCheck() {
var result = "";
var sheet = SpreadsheetApp.getActiveSpreadsheet();
var templateLink = sheet.getSheetByName("Template Link").getRange(1, 1).getValue();
var formResponsesSheet = sheet.getSheetByName("Form Responses 1");
var formResponsesHeader = formResponsesSheet.getRange(1, 2, 1, formResponsesSheet.getLastColumn() -1).getValues();
var docBody = DocumentApp.openByUrl(templateLink).getBody().getText();
var matches = docBody.match(/<</g); var noOfLessThanMatches = matches.length;
var matches = docBody.match(/>>/g); var noOfMoreThanMatches = matches.length;
var lessThan = docBody.search(/<</g);
var moreThan = docBody.search(/>>/g);
Logger.log([noOfLessThanMatches,noOfMoreThanMatches]);
result += "<b>Less Than Signs:</b> " + noOfLessThanMatches + "<br>";
result += "<b>More Than Signs:</b> " + noOfMoreThanMatches + "<br>";
result += "<br><b>Doc to Form Check</b><br>";
var newDocBody = docBody;
var reverseArray = [];
for (i = 0; i < noOfLessThanMatches; i++) {
var lessThan = newDocBody.search(/<</g);
var moreThan = newDocBody.search(/>>/g);
var subString = newDocBody.substring(lessThan + 2,moreThan);
Logger.log(subString);
var indexOf = formResponsesHeader[0].indexOf(subString);
if (indexOf > -1) {
result += subString + " - FOUND<br>";
} else {
result += subString + " - NOT FOUND<br>";
}
reverseArray.push(subString);
newDocBody = newDocBody.replace("<<" + subString + ">>","XX")
}
result += "<br><b>Form to Doc Check</b><br>";
for (z = 0; z < formResponsesHeader[0].length; z++) {
var thisString = formResponsesHeader[0][z];
var indexOf = reverseArray.indexOf(thisString);
if (indexOf > -1) {
result += thisString + " - FOUND<br>";
} else {
result += thisString + " - NOT FOUND<br>";
}
}
Logger.log(result);
var htmlOutput = HtmlService
.createHtmlOutput('<p>' + result + '</p>')
.setWidth(400)
.setHeight(500);
SpreadsheetApp.getUi().showModalDialog(htmlOutput, 'RESULT');
}
UPDATE: I have pasted the whole code instead above so you guys can see
You have to register onFormSubmit as the function that handles the form submit trigger. Have you registered the function "onFormSubmit" like this:
ScriptApp.newTrigger('onFormSubmit').forForm(form).onFormSubmit().create();
You might also want to check the registered triggers by clicking on Edit > Current project's trigger from your Apps Script project.
[Edit] Since the trigger is created properly, change the first the line of the trigger code from:
function onFormSubmit(e) {
var sheet = SpreadsheetApp.getActiveSpreadsheet();
to this:
function onFormSubmit(e) {
var sheet = SpreadsheetApp.openById(e.source.getDestinationId());

Google Script - return ContentService.createTextOutput?

I would like to display a count of the rows in the return ContentService.createTextOutput() has that been appended rather than just "Data Collected Saved". Hopefully this is possible?
function doPost(e) {
var data = eval(e.postData.contents) ;
var usr = data[0][0];
var ss = SpreadsheetApp.getActive();
var sh = ss.getSheetByName(usr) ;
var now = new Date()// Variable for date
if ( sh == null ) {
ss.insertSheet(usr);
var sh = ss.getSheetByName(usr) ;
var pos = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(usr);
SpreadsheetApp.setActiveSheet(pos);
var sheets = ss.getSheets();
ss.moveActiveSheet(sheets.length);
sh.appendRow(["User","Asset ID","Project"]);
}
for (var i=0;i<data.length;i++) {
sh.appendRow(data[i]);
}
return ContentService.createTextOutput("Data Collected Saved") ;
}
return ContentService.createTextOutput("Data Collected Saved " + data.length);
JS Strings

Stuck at G Suite Developer Quickstart for "check student attendance in Google Meet courses"

I would be very appreciative of any input. Thank you;
I'm using the G Suite Developer Quickstart for a Meet attendance script
https://developers.google.com/gsuite/add-ons/editors/sheets/quickstart/attendance
Unfortunately, upon using the provided code, and having made adjustments, I either always get "Absent" or "Present" for all students (regardless of whether they were present or not) depending on if I use "null" of "false" in an if statement for activities for applicationName 'meet'.
Here is the code I'm using as a superuser:
...
function onOpen() {
var ui = SpreadsheetApp.getUi();
ui.createMenu('Opciones SG')
.addItem("Importar Curso", 'importCourses')
.addItem('Verificar Asistencia', 'checkAll')
.addToUi();
}
function importCourses() {
var optionalArgs = {
teacherId: 'me',
pageSize: 5
};
var response = Classroom.Courses.list();
var courses = response.courses;
for (var i = 0; i < 1; i++) {
var courseName = courses[i].name;
var courseId = courses[i].id;
insertCourse(courseName, courseId)
}
}
function insertCourse(courseName, courseId) {
var spreadsheetName = courseName + "(" + courseId + ")"
var activeSpreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var yourNewSheet = activeSpreadsheet.getSheetByName(spreadsheetName);
if (yourNewSheet != null) {
return
}
yourNewSheet = activeSpreadsheet.insertSheet();
yourNewSheet.setName(spreadsheetName);
yourNewSheet.appendRow(['Nombre', 'Email', 'Asistencia'])
yourNewSheet.setFrozenRows(1)
var studentNames = getRoster(courseId)["studentNames"]
var studentEmails = getRoster(courseId)["studentEmails"]
for (var i = 0; i < studentNames.length; i++) {
yourNewSheet.appendRow([studentNames[i],studentEmails[i]])
}
yourNewSheet.autoResizeColumns(1, 2)
yourNewSheet.setFrozenColumns(2)
}
function getRoster(courseId) {
var studentNames = []
var studentEmails = []
var optionalArgs = {
pageSize: 100
};
var response = Classroom.Courses.Students.list(courseId, optionalArgs)
var students = response.students
for (var i = 0; i < 100; i++) {
try {
studentNames.push(students[i].profile.name.fullName)
studentEmails.push(students[i].profile.emailAddress)
} catch (err) {
return { "studentNames":studentNames, "studentEmails":studentEmails }
}
}
}
function checkAll() {
var ss = SpreadsheetApp.getActiveSheet();
var sheet = ss.getDataRange().getValues();
for (var i = 2; i < sheet.length * 100; i++){
var meetCode = getCleanCode(sheet[0][i])
// No Meet code given
if (meetCode == null) {
break;
}
else {
// check whether each student was present in Meet
checkMeet(meetCode, i+1);
}
}
}
function checkMeet(meetCode, index) {
// universal settings - static
var userKey = 'all';
var applicationName = 'meet';
var ss = SpreadsheetApp.getActiveSheet();
var sheet = ss.getDataRange().getValues();
for (var i = 0; i < sheet.length-1; i++) {
var emailAddress = sheet[i+1][1]
var optionalArgs = {
event_name: "call_ended",
filters: "identifier==" + emailAddress + ",meeting_code==" + meetCode
};
try {
var response = AdminReports.Activities.list(userKey, applicationName, optionalArgs);
var activities = response.items;
if (activities == false) {
markAbsent(ss,i+2,index)
}
else {
markPresent(ss,i+2,index)
}
} catch (err) {
continue
}
}
}
function getCleanCode(meetCode) {
try{
return meetCode.replace("/-/g","")
} catch (err) { return meetCode; }
}
function markAbsent(sheet, i, j) {
var cell = sheet.getRange(i, j);
cell.setValue("Absent");
}
function markPresent(sheet, i, j) {
var cell = sheet.getRange(i, j);
cell.setValue("Present");
}
...
For the correct functionality of the code, check for if (activities == null) or if (activities == undefined) - NOT if (activities == false)
If there are no response items (that is no items have been found for a given user and meeting code) - activities will be undefined, but not false.
if (activities == false) will never be fulfilled and if you use it - all participants will be marked as present
On the other hand, if activities == undefined for other reasons - for example because you introduced the wrong meet code (don't forget to replace 'Asistencia' through a valid meet code), all participants will be marked as absent
Note that the Reports API has some delay, so do not expect to retrieve participation data in live time.
If all participants are marked as absent - probably the data did not propagate yet, wait some time and try again.
Make sure you pass the correct meet code to the script. Your meet code should look something like xxx-xxxx-xxx.
The script needs to remove the - for correct functionality. For this please change in function getCleanCode(meetCode) the line return meetCode.replace("/-/g","") to return meetCode.replace(/-/g, "");
As for the question in your comment: here you can see all available Hangouts Meet Audit Activity Events that you can use for filtering instead of the meeting_code. Unfortunately the timestamp is not one of possible query parameters.
Here is the code we have been using for a few months now, no glitches:
function onOpen() {
var ui = SpreadsheetApp.getUi();
ui.createMenu('Asistencia')
.addItem('Asistencia', 'checkAll')
.addItem('*Crear*', 'createNewSheets')
.addToUi();
}
function createNewSheets() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
// Get the range of cells that store employee data.
var employeeDataRange = ss.getRangeByName("A:A");
var employeeObjects = employeeDataRange.getValues();
var template = ss.getSheetByName('Template');
for (var i=0; i < employeeObjects.length; i++) {
// Put the sheet you want to create in a variable
var sheet = ss.getSheetByName(employeeObjects[i]);
// Check if the sheet you want to create already exists. If so,
// log this and loop back. If not, create the new sheet.
if (sheet) {
Logger.log("Sheet " + employeeObjects[i] + "already exists");
} else {
template.copyTo(ss).setName(employeeObjects[i]);
}
}
return;
}
function importCourses() {
var optionalArgs = {
teacherId: 'me',
pageSize: 5
};
var response = Classroom.Courses.list(optionalArgs);
var courses = response.courses;
for (var i = 0; i < 2; i++) {
var courseName = courses[i].name;
var courseId = courses[i].id;
insertCourse(courseName, courseId)
}
}
function insertCourse(courseName, courseId) {
var spreadsheetName = courseName + "(" + courseId + ")"
var activeSpreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var yourNewSheet = activeSpreadsheet.getSheetByName(spreadsheetName);
if (yourNewSheet != null) {
return
}
yourNewSheet = activeSpreadsheet.insertSheet();
yourNewSheet.setName(spreadsheetName);
yourNewSheet.appendRow(['Nombre', 'Email', 'Asistencia'])
yourNewSheet.setFrozenRows(1)
var studentNames = getRoster(courseId)["studentNames"]
var studentEmails = getRoster(courseId)["studentEmails"]
for (var i = 0; i < studentNames.length; i++) {
yourNewSheet.appendRow([studentNames[i],studentEmails[i]])
}
yourNewSheet.autoResizeColumns(1, 2)
yourNewSheet.setFrozenColumns(2)
}
function getRoster(courseId) {
var studentNames = []
var studentEmails = []
var optionalArgs = {
pageSize: 100
};
var response = Classroom.Courses.Students.list(courseId, optionalArgs)
var students = response.students
for (var i = 0; i < 100; i++) {
try {
studentNames.push(students[i].profile.name.fullName)
studentEmails.push(students[i].profile.emailAddress)
} catch (err) {
return { "studentNames":studentNames, "studentEmails":studentEmails }
}
}
}
function checkAll() {
var ss = SpreadsheetApp.getActiveSheet();
var sheet = ss.getDataRange().getValues();
for (var i = 2; i < sheet.length * 100; i++){
var meetCode = getCleanCode(sheet[0][i])
// No Meet code given
if (meetCode == null) {
break;
}
else {
// check whether each student was present in Meet
checkMeet(meetCode, i+1);
}
}
}
function checkMeet(meetCode, index) {
// universal settings - static
var userKey = 'all';
var applicationName = 'meet';
var ss = SpreadsheetApp.getActiveSheet();
var sheet = ss.getDataRange().getValues();
//let today = new Date()
//var staringTime = new Date().toISOString();
// var DateValue = ss.getRange(1, 1).getValues();
for (var i = 0; i < sheet.length-1; i++) {
var emailAddress = sheet[i+1][1]
var optionalArgs = {
startTime: formatStartDate(),
event_name: "call_ended",
filters: "identifier==" + emailAddress + ",meeting_code==" + meetCode
};
try {
var response = AdminReports.Activities.list(userKey, applicationName, optionalArgs);
var activities = response.items;
if (activities == undefined) {
markAbsent(ss,i+2,index)
}
else {
markPresent(ss,i+2,index)
}
} catch (err) {
continue
}
}
}
function getCleanCode(meetCode) {
try{
return meetCode.replace(/-/g, "");
} catch (err) { return meetCode; }
}
function markAbsent(sheet, i, j) {
var cell = sheet.getRange(i, j);
cell.setValue("A");
}
function markPresent(sheet, i, j) {
var cell = sheet.getRange(i, j);
cell.setValue("");
}
function formatStartDate(){
let date = new Date();
const offset = date.getTimezoneOffset();
let offsetDate = new Date(date.getTime() - (offset*145*1000));
return offsetDate.toISOString();
}