Inviting guests to a "Quick Add" Google Calendar event - google-apps-script

I am trying to improve the functionality of the "Quick Add" feature in Google Calendar. Quick Add is the feature that is normally accessed by going to Google Calendar and clicking the down arrow next to the red "Create" button (see image: http://s2.postimg.org/95zxshivt/calendar_screenshot.png).
The functionality I am trying to achieve is to allow the user to invite guests to the newly created Calendar event using keywords in what they type in the Quick Add box. For example, if the user uses the Quick Add box to add an event by entering the text Eat pizza tomorrow at 3pm with michelle#gmail.com and john#gmail.com, Google Calendar adds a new event with the title Eat pizza with michelle#gmail.com and john#gmail.com at 3pm the next day, like it is supposed to. I want to go a step further by having Google also send out two Calendar invites to the newly created event: one for michelle#gmail.com and the other to john#gmail.com.
I appreciate your advice on this topic. I am trying to understand what the best approach is:
Use a trigger with Google Apps Script to catch when the user has added a Calendar event. The trigger will access the title of the event, pick out any e-mail addresses present in the title, and send an invitation to the newly created event to each of those e-mail addresses.
Use a Chrome extension to have the user enter the string that they normally would type into the Quick Add box by clicking on the extension's icon in the Chrome browser. The extension would pick the e-mail addresses out of what the user types in, use createEventFromDescription(description) on the user's input to create the event, and then send an invitation to the newly created event to each of those e-mail addresses.
Please let me know what you think. I would greatly appreciate your ideas.
Lucy

As you probably know, there is not trigger source linked to the creation of an event from the Calendar Ui.
You have indeed 2 possibilities :
encode the event using a dedicated Ui (a chrome extension or a standalone webapp) that would take care of sending the invitations but that would probably not meet the initial requirement you described as "expanding the capabilities os the quickAdd features"
Find a way to detect an event creation and automatically send invitations from its content.
This last possibility is perfectly doable using a timer trigger that monitors your calendar and detects any new event (by comparing a list stored somewhere to the actual calendar content).
I have made such an app for a different purpose and it works nicely but there are a few difficulties you should be aware of.
When storing the events in scriptProperties (it's probably the best place to go) you have a limited amount of storage size available so you must know how much event you will be able to handle.
Any change in an event like adding a detail or rectifying a typo will re-trigger the invitation process and send the invitation again. Although this can probably be avoided but it would be quite complex.
When the script runs right after an event end, the comparison detects an change because one event is missing (from the script pov) so it could send a mail to cancel the event (if you had chosen to implement that functionality of course but I guess it's a "must have"). It might be a bit tricky to handle that situation... (compare event end time to actual time when the trigger fires the script, could be a matter of milliseconds ;-).
Apart from these difficulties, the general idea is as follow :
create a timer trigger to run every hour or so
store every event in this calendar in script Properties (or eventually in a spreadsheet) starting from the present date and ending in a few days (not too far ahead because it wouldn't make sense to send invites for an event happening next year)
compare the list with the calendar content
grab every "new" events and extract email address from the description (using regex for example or string manipulation)
send the invitations (that's the easy part)
This workflow works but it might be a bit fragile in the comparison and in the email detection.
EDIT
Since this was an interesting subject (IMHO) and that I thought I could use efficiently (now that I switched to english in my calendar UI ;-D) I wrote a code to achieve it...
I embedded the code in a spreadsheet to simplify the processsing and the storage of the events in the many calendars I own.
This spreadsheet is viewable here and if you make a copy of it you'll be able to run the code.
I setup a timer trigger that runs the autoCheckAllCal function every hour and it seems to work without any issue.
Tell me what you think.
The full code is reproduced below, it gets data from the calendar, checks if the event has guests and if not it checks the title for any valid email address (one or more) and sends the invitations automatically.
I used a regex to extract emails from the title string (this regex was borrowed from an answer on SO since I'm not good enough at this !)
note : setup an onOpen trigger for myOnOpen (because of global var declaration using SS service)
// update the ID below to your copy ID and run the Callist() function to get the calendars ID on first sheet.
//set up an onOpen trigger for the myOnOpen function
var ss = SpreadsheetApp.openById('1xDOaoSl3HbkS95cj8Jl-82rdiui7G0sFz96PIO6iVF4');// this spreadsheet
var calNamesSheet = ss.getSheetByName('calNames');
var calList = calNamesSheet.getDataRange().getValues();
function MyOnOpen() {
var menuEntries = [ {name: "Lauch autoTest", functionName: "autoCheckAllCals"},
{name: "delete created sheets", functionName: "delsheets"}
];
ss.addMenu("Tracking utilities",menuEntries);//
}
function autoCheckAllCals(){
var today = new Date(); // now
var startDate = new Date(today.setHours(0,0,0,0));// today # 0 AM
var endDate = new Date(new Date(startDate).setDate(startDate.getDate()+7)); // adjust time frame to read here = 7 days
for(var nn=0;nn<calList.length;nn++){
var logArray = new Array();
logArray.push(['Calendar + Title','Description','Start','End','Location','Creators','Date Created','Duration','Guests']);
var calName = calList[nn][0];
var calId = calList[nn][1];
var Calendar = CalendarApp.getCalendarById(calId);
var events = Calendar.getEvents(startDate , endDate);
if (events[0]) {
for (var i = 0; i < events.length; i++) {
var row = new Array();
row.push(calName +' : '+events[i].getTitle());
row.push(events[i].getDescription());
row.push(Utilities.formatDate(events[i].getStartTime(), Session.getScriptTimeZone(), "MMM-dd-yy")+' # ' +Utilities.formatDate(events[i].getStartTime(), Session.getScriptTimeZone(), "HH:mm"));
row.push(Utilities.formatDate(events[i].getEndTime(), Session.getScriptTimeZone(), "MMM-dd-yy")+' # ' +Utilities.formatDate(events[i].getEndTime(), Session.getScriptTimeZone(), "HH:mm"));
row.push(events[i].getLocation());
row.push(events[i].getCreators().join());
row.push('on '+Utilities.formatDate(events[i].getLastUpdated(), Session.getScriptTimeZone(), "MMM-dd-yyyy"));
row.push(((events[i].getEndTime() - events[i].getStartTime()) / 3600000)+' hours');//duration
var inviteList = checkInvites(events[i]);
if (inviteList.length==0){ // if guests were found in checkInvites() then don't read it from event since checkInvites() added them to the cal but this event is not yet updated
var list = events[i].getGuestList();
for(n=0;n<list.length;++n){inviteList.push(list[n].getEmail())};
}else{
for(var n in inviteList){
events[i].addGuest(inviteList[n]);
}
}
row.push(inviteList.join(', '));
logArray.push(row);
}
}
// Logger.log(logArray);
if(logArray.length==0){continue};
try{
var sheetToWrite = ss.insertSheet(calName,ss.getNumSheets());// create sheet if doesn't exist
}catch(err){
var sheetToWrite = ss.getSheetByName(calName);// else open it
}
sheetToWrite.getRange(1,1,logArray.length,logArray[0].length).setValues(logArray).setHorizontalAlignment('left'); // enhance formating
sheetToWrite.getRange(1,1,1,logArray[0].length).setBackground('#EEA').setBorder(true,true,true,true,true,true).setHorizontalAlignment('left').setFontSize(12);
for(var w in logArray[0]){
sheetToWrite.setColumnWidth(Number(w)+1,180);
}
}
}
function checkInvites(event){
var email = []
var title = event.getTitle();
if(title.indexOf('#')==-1){return email};
email = title.match(/([\w-\.]+)#((?:[\w]+\.)+)([a-zA-Z]{2,4})/g);
Logger.log('email var = '+email);
return email;
}
function delsheets(){
var numbofsheet = ss.getNumSheets();// check how many sheets in the spreadsheet
for (var pa=numbofsheet-1;pa>0;pa--){
ss.setActiveSheet(ss.getSheets()[pa]);
if(ss.getSheets()[pa].getSheetName()!='calNames'){
ss.deleteActiveSheet(); // delete sheets begining with the last one
Utilities.sleep(400);
}
}
SpreadsheetApp.flush();
}
// This small function is to get the list of calendar names & Ids that you have access to, please edit the calNames sheet to keep only the ones you want to monitor (without empty rows).
function Callist(){
calNamesSheet.getDataRange().clearContent();
var list = new Array();
var store = new Array();
list = CalendarApp.getAllCalendars()
for (n=0;n<list.length;++n){
var name = list[n].getName() ;
var id = list[n].getId() ;
store.push( [name,id])
}
calNamesSheet.getRange(1,1,store.length,store[0].length).setValues(store);
}
// Serge insas - 08-2014

Related

Alternative to using triggers to automatically send email for each calendar event created

I am trying to automate certain parts of my workflow for scheduling clients with Google Calendar. I've successfully managed to capture new/edited/deleted events in Google Apps Script using a trigger which detects changes and Calendar.event.list to sync those changes with a spreadsheet.
I create a new row, or edit an existing one, in my spreadsheet of all the clients. What I desire to do is three days before the appointment with the client, automatically generate a custom email with all of their details, to send them as a reminder regarding the appointment.
My plan was every time a new row was created in the Spreadsheet (when a new Calendar event was created), was to make a new email trigger. That trigger would execute code to create an email, with all of the clients info.
function createEmailTrigger(event) {
var today = new Date();
today.setHours(0,0,0,0); // Don't care about time
// Create Email Trigger three days before
const sendDaysBefore = 3;
var daysBefore = new Date(event.start);
daysBefore.setDate(daysBefore.getDate() - sendDaysBefore);
var trigger = ScriptApp.newTrigger('sendEmail')
.timeBased()
.at(daysBefore)
.create();
associateEventWithTrigger(trigger.getUniqueId(), event);
return trigger.getUniqueId();
}
associateEventWithTrigger connects the trigger id with the Calendar event. sendEmail would then create a new email with all of the client's info, which came from the Calendar event. When the trigger is executed, it deletes the trigger since it won't be used again.
All of this was working fine, as I was testing one Calendar event at a time. However, once I decided to sync all of this year's Calendar events, the script very quickly threw this error:
Exception: This script has too many triggers. Triggers must be deleted from the script before more can be added.
Apparently you can only have 20 triggers per user/script. This is very inconvenient, as I was expecting to create hundreds of triggers.
Therefore, I need to rethink how to go about doing this. Any suggestions? I appreciate it.
Proposed workaround
This script is designed to be run on a time-driven trigger that runs daily.
function sendReminderEmails() {
let file = SpreadsheetApp.getActive();
let sheet = file.getSheetByName("Sheet1");
let range = sheet.getDataRange();
let values = range.getValues();
// removing headers
values.shift()
values.forEach(row => {
let name = row[0]
let email = row[1]
let date = row[2]
// Date object representing time now
let now = new Date();
// helper variables
let second = 1000;
let minute = second * 60;
let hour = minute * 60;
let day = hour * 24;
// gets time to appointment in milliseconds
let timeToApp = date.getTime() - now.getTime()
if (timeToApp > 2 * day && timeToApp < 3 * day) {
MailApp.sendEmail(
email,
"Remember Your Appointment",
"Hello " + name + ",\nYou have an appointment coming up soon."
)
}
})
}
This is based on a sample spreadsheet like this:
So you would need to adapt it to your particular format.
Script walkthrough
It is based on the date object.
If your dates are stored as formatted dates in your spreadsheet, when you getValues, Apps Script will automatically pass them as Date object. Alternatively you can cast them as Date objects in Apps Script if needed.
The script starts off by getting all the values in the target sheet.
It initialized a new Date object that represents the time now.
It then goes through each row of the target sheet and gets a value for how long until the appointment.
If the value is between 2 days and 3 days, then an email is sent.
I Think you could make an script to search events every day , events that are 3 days ahead , select then and send email. So it will be just one script that will be triggeres every day, using the date trigger mode.

Creating calendar event in sheets using Google App Script and want to add attendees

I'm trying to create calendar events in sheets using Google App Script (I'm very new to this). The sheet contains details of the event (date, time, event title, and guest list) as well as the calendar ID (this is a training calendar). I want to make it simple for the end-user to fill in the information on the sheet, click 'schedule now' and the script run and send the events out to all email addresses mentioned in the guest list.
Here is an example of the sheet:
Here is a copy of the code (I found this on the Google Developer website and tried to adapt it to add guests but haven't been able to get it working and really not sure where to go with this. Ideally, I'd like the guest list to come from the sheet and not be written into the code as an option.
function scheduleTraining() {
var spreadsheet = SpreadsheetApp.getActiveSheet();
var calendarId = spreadsheet.getRange("C3").getValue();
var eventCal = CalendarApp.getCalendarById(calendarId);
Logger.log(eventCal)
var signups = spreadsheet.getRange("A5:C20").getValues();
for (x=0; x<signups.length; x++) {
var shift = signups[x];
var startTime = shift[0]
var endTime = shift[1]
var title = shift[2]
eventCal.createEvent(title, startTime, endTime, {
location: 'remote',
description: 'snacks provided',
})
}
}
function onOpen(e) {
SpreadsheetApp.getUi()
.createMenu('Schedule Training')
.addItem('Schedule Now', 'scheduleTraining')
.addToUi();
}
If anyone can help with this or has any ideas on how to do this better, I'm all ears!
Thanks!
Issues:
The dates in your spreadsheet file are strings/texts. You can verify that if you do =isDate(A7). If the latter returns FALSE then you don't have a valid date object. If you see the official documentation you need to pass date objects and not date texts.
Another remark I have is that your range is "A5:C20" but you should start from A7. Row 5 and 6 don't contain the information required, according to your screenshot.
Question based on your comment:
how I can include inviting the guests when it's run
Again according to the documentation, you can add guests using the advanced parameters options and in particular guests:
eventCal.createEvent(title, startTime, endTime, {
location: 'remote',
description: 'snacks provided',
guests: 'test1#gmail.com,test2#gmail.com'
})
guests is a type of string that contains a comma-separated list of email addresses
that should be added as guests.

How do I get my google calendar event's ID into the right format for the Calendar API to read in my script?

I'm trying to write a script that will do both: 1) update an existing event's dates and title on my Google calendar, based on the dates provided in my sheet AND 2) send the updated dates by email to the event's guests (so the event on their calendars is updated).
I was able to successfully update my event's dates and title using CalendarApp.getEventById(eventId). However, I'd really like the event notifications to resend to each guest when the dates of the event have updated. This doesn't seem possible to do using CalendarApp (if it's possible, please tell me how!). After struggling with this in this question, I'm now trying to use Calendar.Events.patch to both update the event and send the update to all the event's guests.
The problem I keep encountering is that the eventId, as logged in my sheet by my createEvent script, is in a format ending in "#google.com." This format is read just fine by CalendarApp, but cannot be read by Calendar.Events.patch. I've tried encoding it to base64, since that seeems to be the format looked for by Calendar.Events.patch, but I think I'm still missing something.
When I run the code below, the error returns "API call to calendar.events.get failed with error: Not Found."
function updateEvent(calendarId, eventId, email) {
var vSS = SpreadsheetApp.getActiveSpreadsheet();
var vS = vSS.getActiveSheet();
var eventId = vS.getRange("R2").getValue(); //R2 is the cell where my eventId is logged
//My attempt to encode my eventId to base64
var base64data = eventId;
var encoded = Utilities.base64Encode(base64data,Utilities.Charset.UTF_8);
var vEventName = vS.getRange("M3").getValue();
var newstartTime = vS.getRange("M5").getValue();
var newendTime = vS.getRange("M6").getValue();
var event = Calendar.Events.get('example#gmail.com', encoded);
if(event.attendees) {
event.attendees.push({
email: email
});
} else {
event.attendees = new Array({email: email});
}
event = Calendar.Events.patch(vEventName, encoded, {
start: newstartTime,
end: newendTime,
sendUpdates: "all"});
}
I suspect the encoded eventId is off a few characters or something, since that seems to be the case when I run the #google.com eventId through this encoding tool. I just don't know enough to fix it.
Please understand that I'm extremely new to writing scripts and I've already been struggling with this issue for well over a week. I think I learned a lot after the last question I posted, since now I have a better understanding of my exact problem, but I still don't know the fix. I'm trying to teach myself how to do this by reading the questions on this website, reading Google's information (which I unfortunately largely don't understand), and watching YouTube videos. If I'm asking too much of the script, please let me know.
You want to retrieve an event using event ID.
You want to update an event and send an email to users.
You want to modify the event name, start and end time of the event.
eventId is 1c0tqtn56c1tdo1i0fus66f53g#google.com which is a text value.
vEventName is Ethiopia Limu which is a text value.
newstartTime is 6/10/2019 which is a date object.
newendTime is 7/30/2019 which is a date object.
If my understanding is correct, how about this modification?
Modification points:
In your script, it seems that the scripts for retrieving the event and updating the event are different. So in this modification, there were separated.
You can see the event at the log, when the script is run.
The event is updated.
About the event ID, you can use 1c0tqtn56c1tdo1i0fus66f53g of 1c0tqtn56c1tdo1i0fus66f53g#google.com as the event ID.
When these are reflected to your script, it becomes as follows.
Modified script:
function updateEvent(calendarId, eventId, email) {
var vSS = SpreadsheetApp.getActiveSpreadsheet();
var vS = vSS.getActiveSheet();
var eventId = vS.getRange("R2").getValue();
var vEventName = vS.getRange("M3").getValue();
var newstartTime = vS.getRange("M5").getValue();
var newendTime = vS.getRange("M6").getValue();
var eid = eventId.split("#")[0]; // Added
// Retrieve event
var event = Calendar.Events.get(calendarId, eid);
if(event.attendees) {
event.attendees.push({
email: email
});
} else {
event.attendees = new Array({email: email});
}
Logger.log(event)
// Update event
var resource = {
start: {dateTime: newstartTime.toISOString()},
end: {dateTime: newendTime.toISOString()},
summary: vEventName,
};
Calendar.Events.patch(resource, calendarId, eid, {sendUpdates: "all"})
}
Note:
If an error related to date and time occurs when the event is updated, please confirm whether newstartTime and newendTime are the date object, respectively.
Reference:
Events: patch

Google Script to Submit Form to Calendar Event

School teacher using my personal Google account to create forms and publish calendars to my class web site.
Trying to make it fast and easy as possible for kids (with no access to Google Apps) to schedule make up tests using this form.
A quick and dirty victory would be to have their form submission added to my calendar as an all-day event with the details in the description field. I could then review and edit the event to the specific time requested (I have only certain time options offered on the form as a drop-down selection item.)
A beautiful and elegant solution would be to have the script write the event on the day and time indicated on the drop-down, but I think that would require sorcery....
The form writes its responses to the spreadsheet fine and email notification works too, but can't get the calendar event creation to happen.
Will keep trying to find/learn the necessary code but would greatly appreciate a kick in the right direction.
Cheers,
Here is a "sorcery gift" since you're a teacher (so am I) and not a programmer (neither am I) that hopefully does exactly what you need.
EDIT : I added the submission date/time in description
function createCalEvent(e) {
Logger.log(e);
// this will return something like this :
/*
{values=[11/9/2014 22:30:00, serge, test descr, 11/7/2014, Before school | 7:30],
namedValues={Your Full Name=[serge], Work to Make Up=[test descr], Date You Will Make Up Assignment=[11/7/2014],
Makeup Time=[Before school | 7:30], Timestamp=[11/9/2014 22:30:00]}, range=Range, source=Spreadsheet, authMode=FULL}
*/
var cal = CalendarApp.getCalendarById("h22nevo15tm0nojb6ul4hu7ft8#group.calendar.google.com");// replace with the right calendar ID, this one is for test (and is public)
var name = e.namedValues["Your Full Name"][0];
var descr = e.namedValues["Work to Make Up"][0];
var submitTime = e.namedValues["Timestamp"][0];
var date = e.namedValues["Date You Will Make Up Assignment"][0].split('/');
var time = e.namedValues["Makeup Time"][0].split('|')[1].split(':');
Logger.log(name+' '+descr+' '+date+' '+time); // this will return serge test descr 11,7,2014 7,30
var startTime = new Date(date[2],date[0]-1,date[1]);
startTime.setHours(time[0],time[1],0,0);
endTime = new Date(startTime.getTime()+3600000); //assuming event is 1 hour long
Logger.log('start='+startTime+' end='+endTime);
cal.createEvent('name = '+name, startTime, endTime, {'description':descr+' (subimitted on '+submitTime+')'});
}
You will have to set up a trigger (on form submit) to trigger that function when a form is submitted.
IMPORTANT NOTE : don't try this code from the script editor without sending a form, it won't work !!! (e will be undefined, obviously)

addEditors to Document from formSubmit

I'm Working on creating script that will perform the actions described below. so far, I've managed to get the first two parts to function, but am now stuck on getting anything more to work. I've reviewed several response forums and tried the suggestions, but no success.
Desired script flow:
form submitted from spreadsheet form
completes fields:
Timestamp
Username (email collected on submission)
Student
Grade
Intervention Plan
Core Reading/Math
Team (email list)
1 script runs onFormSubmit that then creates a copy of a template document, renames that new copy to the e.value "student" submitted in form,
2 then replaces selected text strings within the document with values submitted in the form.
3 Add editors to new document and sends notification with desired instructions
4 creates event (one week from submission date) event details include instructions and link to shared document for team members to complete with their input, sends event invitation to email list.
Here is the working script so far.
function formSubmitValues(e) {
var timeStamp = e.values[0];
var userEmail = e.values[1];
var student = e.values[2];
var grade = e.values[3];
var conern = e.values[4];
var readingCore = e.values[5];
var mathCore = e.values[6];
var interventions = e.values[7];
var team = e.values[8].toString(); // "just to be sure"..Henrique says add .toString this allowed the replaceText part to work
//Makes copy of template document and renames
var tempID = ("1Rq0pDAnuGNfL6W3GB0ZuLeWM2uYzHpKzoyxoXlwjtgE") // use document ID from Template Document
var copyId = DocsList
.getFileById(tempID)
.makeCopy(student + " Initial Referral") // names new copy as student's name
.getId();
// trying to add editors to new document using email list generated in form submit value of "team"
DocsList.getFileById(copyId).addEditors([team]);
// replaces text within template with selected fields from formSubmitValues
var doc = DocumentApp.openById(copyId)
var body = doc.getActiveSection();
body.replaceText("%STUDENT%", student);
body.replaceText("%DATE%", timeStamp);
body.replaceText("%TEACHER%", userEmail);
body.replaceText("%TEAM%", team);
return doc;
}
REPORTED ISSUE RESPONSE: Here is what they said: "The function takes an array or strings, like: DocsList.getFileById(copyId).addEditors(['parent#domain.com', 'parent2#domain.com']);
I tried entering emails directly into script like this and things worked.
So my problem is not the 'addEditors method, but lies in getting the form submitted emails to be passed correctly. Any suggestions on how I would do this?
I have tried what I believe to be all combinations of using .toString(), or not, and using .Split(',').
RE-DEFINE PROBLEM : So it is an issue of how the emails are passed from the e.values form submit.
Here is where I'm at:
When I type emails into script directly: .addEditors(['parent#domain.com', 'email2#domain.net', 'email3#gmail.com']) it works, (I did have to move the addEditors method in the script to go right after the .makeCopy instead of at the end.)
This is what the Execution Transcript shows:
File.addEditors([[parent#domain.com, email2#domain.net]]) and it runs the rest of the script. note: One part I don't understand is the single quotes i.e. 'email' They must be typed in the script, but don't show up on Transcript when run. I've tried putting them around emails in the form, but it makes them show in Transcript and still doesn't run anyway.
So this is what script looks like now:
var tempID = ("1Rq0pDAnuGNfL6W3GB0ZuLeWM2uYzHpKzoyxoXlwjtgE") // use document ID from Template Document
var copyId = DocsList
.getFileById(tempID)
.makeCopy(student + " - TestingCopy") // names new copy as student's name + text
.addEditors([team.split(',')])
.getId();
But when I use the var team with or without .split(',') it does not work. But in the Transcript it shows:
File.addEditors([[rreynolds#domain.net, parent#domain.com]])
which looks identical as to what shows when it does work, but that is the last thing shown in Transcript and editors are not added to document and the script does not finish.
I'm obviously not understanding something here. Is there a way I could get the emails in the team e.values to be treated in a way that the addEditors method is requiring? In the spreadsheet cell they appear as a CSV. i.e rreynolds#domain.net, parent#domain.com
Do they have to be read one at a time, or something?
I'm learning a lot, and appreciate all your help. I am sorry for the confusion with all the comments, but am not sure of the correct way to address issues in this forum. For example: should I go back and edit my original script to show the current version, or add it someplace else? I'm trying to keep the conversation flowing, so that it is easier for others to follow - Thanks rob
please let me give a last (hopefully) clear answer : (thanks for sharing the spreadsheet, this is far more easy to work on ;-)
here is your code fully working.
I have created some intermediate variables to show how it works.
function formSubmitEditors(e) {
// defines spreadsheet form events on submit of form. This function formSubmitEditors is triggered on formSubmit
var timeStamp = e.values[0];
var fileName = e.values[1];
var team = e.values[2].replace(/, /g,"|"); // remove unwanted spaces and commas replace by | for visibility ;-)
Logger.log(team);// contains | as separators
var teamArray = team.split('|');
Logger.log(teamArray.length+' : '+teamArray);// check that it is an array of x elements
//Makes copy of template document and renames
var tempID = '1Rq0pDAnuGNfL6W3GB0ZuLeWM2uYzHpKzoyxoXlwjtgE' // use document ID from Template Document
var copyId = DocsList
.getFileById(tempID)
.makeCopy(fileName + " - TestingCopy") // names new copy as student's name + text
.getId(); //
var file = DocsList.getFileById(copyId).addEditors(teamArray);
// replaces merged-text values within template with selected fields from formSubmitValues
var doc = DocumentApp.openById(copyId)
var body = doc.getActiveSection();
body.replaceText("%FILE%", fileName);// you wrote %FILENAME% in place of %FILE%
body.replaceText("%DATE%", timeStamp);
body.replaceText("%TEAM%", team);// it will be shown with | as separators, if you don't like it replace team by teamArray.toString() to get commas again.
}
EDIT : I removed the toString() for team event, not necessary since e.parameters are already strings.
EDIT2 : to be complete and do what you needed in the initial question you could replace the end of the code with this one that creates the Cal event on next week and sends invites with link to the doc.
var file = DocsList.getFileById(copyId).addEditors(editorsArray);
var fileurl = file.getUrl();
Logger.log(fileurl)
// replaces merged-text values within template with selected fields from formSubmitValues
var doc = DocumentApp.openById(copyId)
var body = doc.getActiveSection();
body.replaceText("%FILE%", fileName);
body.replaceText("%DATE%", timeStamp);
body.replaceText("%MAILS%", editors);
var Cal = CalendarApp.getCalendarsByName('testencodage')[0];// replace with your calendar name you want to use
var newEvent = Cal.createAllDayEvent('Fill the questionnary', new Date(new Date(newtimeStamp).getTime()+7*24*3600*1000), { guests : e.values[2] , sendInvites : true , description :"Don't forget to fill this document "+fileurl})
}
I'd suggest a couple of things
Add a few Logger.log statements in your code to print out debug information.
Add a try ... catch block around the entire section of code and print out the exception. See if you are getting any exception.
Last, use the Execution transcript window to see where your script stopped, if it did.
There are 2 ways to add an editor by email : addEditors([emailAddresses]) and addEditor(emailAddress)
The first has an "s" and needs an array of email adress strings, the second takes a single string as argument. You should use the second or add [brackets] to the email string in your code.
concerning you comment // need to figure out where/how to: .addEditors(email1,email2,etc);
// is this done from DocsList or DocumentApp class?
addEditor() and addEditors() belong to the file class, a member of DocsList class , you can add user(s) using user(s) objects or user(s) email(s) as explained in the doc.
It could be used like this DocFile.addEditors([email1,email2])
EDIT : A lot of comments on this post, sorry about that, it has become quite uneasy to read... I tested these addEditors feature with spreadsheet and it works as expected, using simple array for multiple user emails and string for single email. The document service seems to have a problem with the addEditor() method and it should be reported to the issue tracker.
REPORTED I've reported issue #1512 - Rocketrob