Google Apps Script, G Suite Admins, Google Calendar, Calendar API, AdminDirectory, GroupsApp
Note! This approach no longer force subscribes users to a Calendar. The new approach can be found here. [update 06 Apr 2022]
It appears that the approach below no longer force-subscribes users in a Group to a calendar. Google Made this change in March of 2020, some 7 months after the post was written.
There is also a note in the Sharing Calendars chapter of the Calendar API information stating:
Note: Sharing a calendar with a user no longer automatically inserts the calendar into their CalendarList. If the user should be able to see and interact with the shared calendar, you will also need to call the CalendarList: insert() method.
While this explanation is no doubt helpful for general use, using the insert()
method in CalendarList
requires that the script be run by the user that needs to be shared.
One hint to a workaround can be found in the update notes referring to the ability to invite guests using domain-wide authority using a service account.
This is a pretty gnarly process to set up and write about and has taken some time to write about and test, but you can now find the tutorial here:
https://yagisanatode.com/2022/04/05/how-to-force-subscribe-a-user-in-your-domain-to-a-google-calendar-in-google-apps-script/
Having said all that, the script below does still contain some interesting use cases for using the Admin SDK service and Advanced Calendar API service in Google Apps Script, so I will leave it up until I can publish a solution.
The script below can now be modified to to extract the users in a group and then use a Service Account on each user to force subscribe them using the code in the tutorial link above.
Big thanks to Jeremy for bringing this to my attention and apologies, I could not find a quick fix.
~ Yagi 06 April 2022
Note! This article is for G Suite users and admins. You won’t be able to apply the same code to Consumer accounts.
Google Groups in G Suite can be a really convenient and clean way to share users to drive folders and file locations, email users and set up Google+ community locations. However, I have come across some issues with sharing Google Calendar to Google Groups.
When you assign a Google Group email to a Google Calendar it sends out an email inviting the users in the group to accept the calendar into their list of shared calendars. The user must then accept the invitation before the calendar is added to their Google Calendar list of shared calendars…calendar.
The users receive an email message like this:
Hello Goat_GroupAlpha,
We are writing to let you know that Billy.Goat@yagisanatode.com has given you access to view events on the Google Calendar called “Test”.
Click this link to add the calendar.
– The Google Calendar Team
The Problem
In a large organisation, not all users in a group will add the calendar using the link. This might be okay but if the calendar is important or the user, as is often the case, simply just forgot to add it, then there will be emails to you the admin in the future asking you why they don’t have the calendar that everyone else has and has now missed some important event…sigh.
Another issue is that when a new user is added to a group when the group has already been added to a calendar, then that user will not receive an email invitation to the calendar and won’t be able to see the calendar.
Almost a Solution
When users are added individually to a calendar, the calendar is added automagically to their Google Calendar profile and placed in the Other calendars section of their calendar dashboard. An accompanying slightly different email is sent:
Hello sid@yagisanatode.com,
We are writing to let you know that Bill.Goat@yagisanatode.com has given you access to view events on the Google Calendar called “Test”.
We have automatically added this calendar to your Google Calendar account. You can hide or completely remove this calendar at any time.
– The Google Calendar Team
View Your Calendar.
This is optimal. It adds the calendar for the user and the user doesn’t have to do anything.
The problem is that we don’t want to waste time adding hundreds of users to multiple calendars by hand and have to manage them when we need to add new users or remove old users when they have left a group.
The Solution
To solve this problem we use Google Apps Script to get all the emails addresses of the members in a G Suite group, compare that against all the current members in the Calendar and add anyone who is missing.
We will use two Advance Google Services:
In your Google Apps Script Editor, you will need to go to Resources > Advanced Google Services and activate these services.
If you are not an administrator for your organisation, that’s cool too. I’ll explain how you might be able to achieve the same thing by replacing the Admin SDK Directory Service with the GroupsApp service in the bonus material at the end.
The Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 |
/*################################################################### * Forces calendar subscription to users from an assigned group with * with the same domain. * Adds the selected calendars to users in a group and provides email * notification to the user. * * Uses Advanced Google Services: * - Calendar - Advanced Calendar Service * - AdminDirectory - Admin SDK Directory Service * * NOTE: User can hide and unsubscribe anytime. For G Suite Domain accounts only */ function addCalendarToGroupMembers(){ var calendarId = 'yagisanatode.com_m4fu4078qg5ot8bo46o4hgbvc@group.calendar.google.com' var groupEmail = 'Goat_GroupAlpha@yagisanatode.com'; //Crosscheck group users against calendar and get list of users from group to add. var userEmails = getMissingEmailsFromGroup(groupEmail, calendarId); for (var user in userEmails){ var resource = { 'scope': { 'type': 'user', 'value': userEmails[user] }, 'role': 'reader' }; try{ Calendar.Acl.insert(resource, calendarId); } catch(e){ Logger.log("addGroupToCalendar: Email or Calendar ID error: "+ e) }; }; var calendarName =Calendar.Calendars.get(calendarId).summary; Logger.log( userEmails.length + " email from group "+ groupEmail + " was added to: " + calendarName); }; /*################################################################### * Compares the emails in the group against the calendar and returns any group emails that are not in * the calendar. * * Executed from: * - addCalendarToGroupMembers * * @param{string} group email ID address * @param{string} calendar email ID address * * @return{array} emails from the selected group that need to be added to the calendar. */ function getMissingEmailsFromGroup(groupID, calendarID){ var groupEmails = getUserEmailsInGroup(groupID); var calendarEmails = getUserEmailsInCalendar(calendarID); for(var cldE in calendarEmails){ for(var grpE in groupEmails){ if(groupEmails[grpE] == calendarEmails[cldE]){ groupEmails.splice(grpE,1); }; } }; return groupEmails; }; /*################################################################### * Gets a list of users emails from the selected group * * Uses AdminDirector SDK - Advanced Google Service * * Executed from: * - getMissingEmailsFromGroup * * @param{array} group email ID address * * @return{array} emails in a selected group. */ function getUserEmailsInGroup(groupID){ try{ var groupMembers = AdminDirectory.Members.list(groupID); var groupMemberEmails = groupMembers.members.map(function(user){ return user.email }); } catch(e){ Logger.log("getUserEmailsInGroup: No Group ID with this name: "+ e); } return groupMemberEmails }; /*################################################################### * Gets a list of users emails from the selected group * * Executed from: * - getMissingEmailsFromGroup * * @param{array} calendar email ID address * * @return{array} emails in a selected calendar. */ function getUserEmailsInCalendar(calendarID){ try{ //Gets object list of all rules for specific calendar. var calendarList = Calendar.Acl.list(calendarID); //Gets the items in the list. [{role:reader,scope:{type:domain}},...] var users = calendarList.items // List of all users who don't have the scope.type: domain var emails = users .filter(function(users){ return users.scope.type !=='domain'; }) .map(function(users){ return users.scope.value; }); } catch(e){ Logger.log("getUserEmailsInGroup: No Calendar ID with this name: "+ e); } return emails; }; |
The two main external variables for this program are the:
calendarId
groupEmail
I have stored them in the main run function addCalendarToGroupMembers()
but you could equally make them global variables or draw this data from something like a Google Sheet, a form or a web-app.
calendarId
As the name suggests, the calendar ID is the specific ID of the calendar. To find it, go to the calendar in your Google Calendar dashboard – in our case, this is the Test calendar – got down the left side-bar until you find one of your calendars you want to use. If you hover over it three ellipses will appear to the right of the calendar. Click on them and a window will appear. Click the option Settings and sharing.
On the left side-bar again under our Test calendar, there will be a list of options. We are going to click > Integrate calendar. The first option here will be the Calendar Id.
groupEmail
Fortunately, the Group email is also the Id of your group. I’m pretty certain you can figure out how to get that one on your one.
Next, let’s dive into what the functions do:
addCalendarToGroupMembers()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
function addCalendarToGroupMembers(){ var calendarId = 'yagisanatode.com_m4fu4078qg5ot8bo46o4hgbvc@group.calendar.google.com' var groupEmail = 'Goat_GroupAlpha@yagisanatode.com'; //Crosscheck group users against calendar and get list of users from group to add. var userEmails = getMissingEmailsFromGroup(groupEmail, calendarId); for (var user in userEmails){ var resource = { 'scope': { 'type': 'user', 'value': userEmails[user] }, 'role': 'reader' }; try{ Calendar.Acl.insert(resource, calendarId); } catch(e){ Logger.log("addGroupToCalendar: Email or Calendar ID error: "+ e) }; }; var calendarName =Calendar.Calendars.get(calendarId).summary; Logger.log( userEmails.length + " email from group "+ groupEmail + " was added to: " + calendarName); }; |
As we mentioned above, this is the main run function for this code.
Once we added our external variables, our first task is to compare all the members of the calendar against all the members in our selected group.
We could simply re-add all the members of the group to the calendar, but we really don’t want to spam our users and we want to also improve our runtime.
Line 6, takes the groupEmail
and calendarId
variables and sends it to our getMissingEmailsFromGroup()
function. It then returns a list of users in the group who have not been added to the calendar.
Line 9 then loops through all the users in the remaining userEmails
.
Next, we get to work with the Advanced Calendar Service.
Let’s jump down to row 19 to see what we are using.
From the Calendar service, we are going to use the Access Control List (Acl) method. This method contains all the rules for managing the settings of the calendar. For our purpose, it also contains the names of all added members into the calendar and their associated permissions.
As you can see on line 19 we will be inserting new users into our Acl. Acl.insert
take two parameters:
- The resources we want to add.
- The calendar ID.
Each Acl element contains a list of item objects. Each of these are basically the calendar rules for each member or resource. For us to add a new member to the calendar we need to add a new resource, provide it with a role, which in our case is, reader, then the scope for that resource. We want to make the user scope ‘user’ and the value of the scope will be the new member’s email.
You can see how we’ve added the new member details to lines 11-17.
We’ll encompass this in a try and catch statement just in case we get some bad emails or something.
Finally, we will use the Calendar.Calendars.get method to grab a summary (title) of the calendar. Then, we will log it out with a total count of users added to the calendar. You could change this around to an alert, toast on a Google Sheet or even an update back to a web app.
getMissingEmailsFromGroup(groupID, calendarID)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
/*################################################################### * Compares the emails in the group against the calendar and returns any group emails that are not in * the calendar. * * Executed from: * - addCalendarToGroupMembers * * @param{string} group email ID address * @param{string} calendar email ID address * * @return{array} emails from the selected group that need to be added to the calendar. */ function getMissingEmailsFromGroup(groupID, calendarID){ var groupEmails = getUserEmailsInGroup(groupID); var calendarEmails = getUserEmailsInCalendar(calendarID); for(var cldE in calendarEmails){ for(var grpE in groupEmails){ if(groupEmails[grpE] == calendarEmails[cldE]){ groupEmails.splice(grpE,1); }; } }; return groupEmails; }; |
This function is called from the main addCalendarToGroupMembers()
function. Its job is to compare the calendar member emails against the group emails and if there is a match, remove it from the group email list.
On lines 16 and 17 you can see that it calls two other functions to get the email lists from the calendar and group respectively.
Line 19 and 20 then begin the nested loops that go through each array of emails.
Line 22 then compares the two arrays and if there is a match, line 23 removes or splices out that email from the groupEmails
array.
Finally, the function returns the remaining emails from the group to the main function addCalendarToGroupMembers()
.
getUserEmailsInGroup(groupID)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
/*################################################################### * Gets a list of users emails from the selected group * * Uses AdminDirector SDK - Advanced Google Service * * Executed from: * - getMissingEmailsFromGroup * * @param{array} group email ID address * * @return{array} emails in a selected group. */ function getUserEmailsInGroup(groupID){ try{ var groupMembers = AdminDirectory.Members.list(groupID); var groupMemberEmails = groupMembers.members.map(function(user){ return user.email }); } catch(e){ Logger.log("getUserEmailsInGroup: No Group ID with this name: "+ e); } return groupMemberEmails }; |
In this function we use the Admin SDK Google Advanced Service to grab the member emails of a group. It then returns the list of emails back to getMissingEmailsFromGroup(groupID, calendarID)
function.
To do this we use the Members method of the AdminDirectory retrieving a list of members and their details. This will retrieve data like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
{ kind:admin#directory#members, members:[ { role:MEMBER, kind:admin#directory#member, etag:"6SvioVgjoij499P0Qg/slkj_krjj9i-3h9fs", id:12321516189189889, type:USER, email:nanny@yagisanatode.com, status:ACTIVE }, { role:MEMBER, kind:admin#directory#member, etag:"6SvioVgzHpCuKx0aOweB485P0Qg/W3F4lWsPyqcFEeCNK6wj19zeVsc", id:354599818687881876, type:USER, email:sid@yagisanatode.com, status:ACTIVE } ], etag:"X1p6oVgB4zHpCuKx0aOweLR85Svg/IE0YxdyBE0iPQL9kEXPjvbABs4" } |
All we need out of this is the user’s email address. To access this we first need to get to the members object array. From there we can use map to grab each email address. Briefly, map allow you to neatly take specific details of each item set in a loop and even modify it before returning the details as a new array.
Finally, we return our list of member’s emails.
getUserEmailsInCalendar(calendarID)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
/*################################################################### * Gets a list of users emails from the selected group * * Uses Calenar - Advanced Google Service * * Executed from: * - getMissingEmailsFromGroup * * @param{array} calendar email ID address * * @return{array} emails in a selected calendar. */ function getUserEmailsInCalendar(calendarID){ try{ //Gets object list of all rules for specific calendar. var calendarList = Calendar.Acl.list(calendarID); //Gets the items in the list. [{role:reader,scope:{type:domain}},...] var users = calendarList.items // List of all users who don't have the scope.type: domain var emails = users .filter(function(users){ return users.scope.type !=='domain'; }) .map(function(users){ return users.scope.value; }); } catch(e){ Logger.log("getUserEmailsInGroup: No Calendar ID with this name: "+ e); } return emails; }; |
This function is called from the getMissingEmailsFromGroup(groupID, calendarID)
function. It uses the Calendar Advanced Services Acl again. It returns a list of member emails from the calendar.
Line 19 grabs the Access Control List…erh...list from the calendar. This is the list of all the rules and permissions added to the calendar. It looks a little something like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
{ kind:calendar#acl, nextSyncToken:0221651681689415165, etag:"p33s80gf7ikoqr3sf", items: [ { role:owner, kind:calendar#aclRule, scope: { type:user, value:yagisanatode.com_klksjdfosdi8987fs79sd8s97fjh8@group.calendar.google.com }, etag:"00000000000000000000", id:user:yagisanatode.com_klksjdfosdi8987fs79sd8s97fjh8@group.calendar.google.com }, { role:reader, kind:calendar#aclRule, scope: { type:user, value:billy@yagisanatode.com }, etag:"001651566816561959747", id:user:billy@yagisanatode.com }, { role:reader, kind:calendar#aclRule, scope: { type:user, value:sid@yagisanatode.com }, etag:"002555555520178855100", id:user:sid@yagisanatode.com }, { role:reader, kind:calendar#aclRule, scope: { type:domain, value:yagisanatode.com }, etag:"000328823444021200100", id:domain:yagisanatode.com }, { role:owner, kind:calendar#aclRule, scope:{ type:user, value:Billy.Goat@yagisanatode.com }, etag:"002325897891254654459", id:user:Billy.Goat@yagisanatode.com } ] } |
As you can see all our member data is in the items array. So on line 22, we create the variable users to directly reference that array.
We can then remove one of the extraneous items that have a scope type of domain. We will do this by using filter on lines 26 and 27.
We don’t want all the other data for each member of the calendar. We only want the emails. To achieve this we then chained a map method to our filter that will iterate through each user item and only store the email (Lines 29-30).
All of the emails collected from the filter and map chain are stored in the emails variable on line 25. These are then returned back to the getMissingEmailsFromGroup(groupID, calendarID)
function.
Bonus Code
While the above is really all you need to add new users to calendars, below are a few more tools for adding and removing users from calendars with Google Apps Script.
Remove All Users From a Calendar
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
/*################################################################### *Clear Calendar * * Clears the emails address of all users in calendar who don't have edit * permissions. * * @param{string} calendar ID * */ function clearCalendar(calendarID){ //Gets object list of all rules for specific calendar. var calendarList = Calendar.Acl.list(calendarID); //Gets the items in the list. [{role:reader,scope:{type:domain}},...] var users = calendarList.items // List of all users with the role: reader who don't have the scope.type: domain var emails = users .filter(function(reader){ return reader.role === 'reader' && reader.scope.type !=='domain'; }) .map(function(reader){ return reader.id; }); //remove email ids for(var id in emails){ try{ Calendar.Acl.remove(calendarID,emails[id]); } catch(e){ Logger.log("Clear Calendar: Bad email or calendar ID: "+e) }; }; }; |
This function removes all the users from a calendar who have the ‘reader’ role, which is essentially anyone who cannot make changes to the calendar.
Get Group Member Emails For Non-Admins
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
/*################################################################### * Gets all email addresses from an assigned group. * * Must be a member of the group. * * @param{string} group email address * * @return{array} emails from group. */ function getGroupEmail(email){ var group = GroupsApp.getGroupByEmail(email); var users = group.getUsers(); return users; }; |
If you don’t have G Suite Admin privileges in your organisations. You might be able to use swap out the getUserEmailsInGroup(groupID)
function with this one. The only provision here is that you must be a member of the group.
Force Calendar Subscriptions for Users not in a Group
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
/* ################## Force Calendar Subscription ###################### * * Forces calendar subscription to users for users with * with the same domain. * Adds the selected calendars to users in a list and provides an email * notification to the user. * * NOTE: User can hide and unsubscribe anytime. For G Suite Domain accounts only */ function addCalendar() { var calendarIds = [ 'yagisanatode.com_m4fu4078qg5ot8bo46o4hgbvc@group.calendar.google.com' ]; var userEmail = [ ''Goat_GroupAlpha@yagisanatode.com'' ]; for (var id in calendarIds) { for (var user in userEmail){ var resource = { 'scope': { 'type': 'user', 'value': userEmail[user] }, 'role': 'reader' }; Calendar.Acl.insert(resource, calendarIds[id]); }; }; }; |
This function simply forces calendar subscription for users who are not in a group. You can add multiple users and multiple calendars.
It is just like going into your calendar settings and manually adding users.
Conclusion
For me, I have found this pretty useful. It has significantly reduced complaints from users in groups who forgot to manually add a pertinent calendar ensuring they have the information that they need. It has also helped to ensure that new members of the group are added to the calendar and it will be ready for them to see.
To make things convenient, I added a bunch of buttons to a Google Sheet that lists all the groups from my domain and all the calendars I have edit access to. I can manually update a calendar with a group or set a twice-yearly time trigger to update group members on a calendar.
I hope you find the code useful for your own projects.
Need help with Google Workspace development?
My team of experts can help you with all of your needs, from custom app development to integrations and security. We have a proven track record of success in helping businesses of all sizes get the most out of Google Workspace.
Schedule a free consultation today to discuss your needs and get started or learn more about our services here.
Changelog
24 Feb 2022 – Discovered from commenter Jeffery, that the force subscribe no longer works due to changes Google-side. Wrote an update note to head the tutorial.
06 Mar 2022 – Wrote a tutorial on how to force subscribe a user to a Calendar in Google Apps Script using a Service Account and Domain Wide Delegation of Authority. Updated the header with links to this tutorial and suggestions on how to modifity the current tutorial.
Hi! thank you for that code…
I tried to apply it, but I’m getting a slightly different result from what you wrote here
my users gets the email with the link to click… and calendar not showing automagically on the web interface
did anything change in google management? or am I missing something? any clue?
thanks
Hi Daniele,
I don’t think anything has changed. Are you using a GSuite (Google Workspace) or Google for Education account, or a normal consumer account?
~Yagi
Hi Yashi, thank you for your reply
G Suite for Education, admin account
tried again, checked twice – and more and more 🙂
same result: email invitation with link to click on, calendar not shown among Other calendars section of the users unless they click on the email link
Hi Daniele,
I’m not sure what is going on there. I ran a sample on a Google Workspace account and it seems okay. You wouldn’t think the G of Ed would be any different. Maybe sharing with student accounts might produce this over paid teacher/admin accounts but that doesn’t really make sense either.
Hi Yashi, thank you for investigating.
I also don’t think it’s a teacher/student sharing related problem: I tested it with admin-to-teacher invitation
I never heard of such differences between Workspace and GSfEdu, too.
If you’ve tested it again and it works, this make me think that the different behavior could be related to some kind of settings in my admin console. I’ll give a deeper look into the question. If any idea or solution, I’ll give you a feedback.
Thank you again.
Hey folks. I just stumbled upon this (THANK YOU) and noticed the line of code I needed to add was this between lines 32 and 33:
Calendar.CalendarList.insert(resource);
That did the trick. The Calendar.Acl.insert adds the permissions. The Calendar.CalendarList adds it to the list.
Thanks again! If anyone ever figures out how to add a non-Google calendar via scripting (like a feed how you would use BY URL), let me know!
How would I reverse the script to remove the calendar permissions for users who are removed from the group?
Hi shsmithm,
You could get the list of users in the updated group and then remove them with the removeGuest() method.
Give it a go, and if you get stuck, you are welcome to share your code here.
~Yagi
Hey there! Thanks for this excellent tutorial! Just wanted to give you a heads up that this may be outdated––when I individually invite users to a calendar (manually) they aren’t automatically added. The email they receive looks very similar to the one you posted above but instead says “After adding this calendar to your other calendars, you can hide or completely remove it whenever you want.” and includes a link to add the calendar. Am I sharing the calendar incorrectly? I’m doing it from the calendar’s settings page on calendar.google.com.
Thanks again for the great information!
Hi Josh,
Thanks for the heads up. Are you working in a paid Google Workspace Domain account or a consumer account?
~Yagi
Great work! I’m working with the coding framework you shared in “Force Calendar Subscriptions for Users not in a Group”. What if I simply want to set the visibility of a list of calendars to anyone in my domain. Essentially, ticking that box in the share settings that says “Make available for [your domain]”. I can get all of the Calendar Ids I want to work with into an array, but I’m stuck on how to proceed in changing their visibility. I thought maybe changing the scope type to domain would have solved that, but no dice. Do you have any code snippets that solve for that? It seems like it should be something simple, but I haven’t been able to figure it out yet. Thanks.
Wow thanks for the prompt reply haha. I am definitely doing this from a paid Workspace account. I actually have a couple and I believe I tried this from a legacy business starter license and a different account with a legacy business standard license.
Stumbled across this, love your work.
How can I add multiple groups for this?
Hi Jeremy,
Thanks.
Your could change the
groupEmail
string togroupEmails
array with your list of group emails.Add a new variable, call it say,
allEmails
.Next, loop through each group email in your array of
groupEmails
runninggetMissingEmailsFromGroup(the currently iterated group email, calendarId);
pushing your emails to theallEmails
group.Once done, replace
userEmails
on line 19 with your newallEmails
loop and you should be good to go.Feel free to paste your code if you get stuck and I can guide you.
~Yagi