Skip to content
This repository was archived by the owner on Dec 7, 2023. It is now read-only.

Commit c072cf3

Browse files
committed
updated group-membership solution
1 parent 653fbae commit c072cf3

File tree

6 files changed

+217
-149
lines changed

6 files changed

+217
-149
lines changed

group-membership/.eslintrc.json

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"extends": "../configs/appsscript.eslintrc.json"
3+
}

group-membership/README.md

+90-67
Original file line numberDiff line numberDiff line change
@@ -1,85 +1,108 @@
11
---
2-
title: Give external users access to resources
3-
description: Scale access to external vendors and customers via a Google Sheet
4-
and a Google Group.
5-
labels: Apps Script, Sheets, Groups for Business
6-
material_icon: assignment turned in
2+
title: Scale access to external vendors and partners
3+
description: Share documents, events, and communications with users outside
4+
your domain
5+
labels: Sheets, Groups for Business, Apps Script
6+
material_icon: group_work
77
create_time: 2019-08-30
8-
update_time: 2019-09-17
8+
update_time: 2019-12-27
99
---
10-
1110
Contributed by Tech and Eco, follow me on
1211
[Twitter](https://twitter.com/TechandEco)!
1312

14-
You may manage multiple Google Groups for your organization and wish to
15-
streamline this process, especially if you have to manually send an email upon
16-
granting users membership. The following Google Spreadsheet contains a script
17-
that helps add the email address of a user to a G Suite Google Group,
18-
and then sends them an email confirming they have been added.
13+
Use a Google Group to work cross-functionally with vendors, partners,
14+
customers, and volunteers outside of your domain, and scale access
15+
to work assignments and leverage security controls. You can add an external
16+
user's Google email (this can be their own G Suite account, a G Suite user
17+
account you created for them within your domain, or a free Gmail account) to
18+
your G Suite Google group (not available for consumer Google Groups) via a
19+
Google Sheet to manage users in bulk and keep track of the onboarding history.
20+
21+
Top 6 benefits of this solution:
22+
23+
1. Adds a new external user to a G Suite Google Group you create
24+
(example: [email protected]) once, and it allows users to open all
25+
resources that are shared with that group moving forward (calendar, files,
26+
training site, dashboards (built on DataStudio), etc.
27+
28+
1. When adding one or more users to your Google Group, users can receive a
29+
welcome email with the links they can access. Creating a Google Site is
30+
optional but recommended to centralize information in a
31+
beautiful website interface.
32+
33+
1. The template of the welcome email is composed in a Google Doc. You
34+
can use seperate Google Docs for different recipients to customize
35+
messaging.
36+
37+
1. Capture the email addresses of users in your Sheet, and add them in bulk to
38+
the desired Google Groups at a later time by changing the column "Allowed"
39+
to "yes" for each row of users.
40+
41+
1. You or members of your team, can add users to different Google Groups as
42+
long as the person who made a copy of this sheet has
43+
_manager_ or _owner_ rights in each of those Google Groups.
44+
45+
1. Removing a user from a Group (via the Google Group's interface) will revoke
46+
their access to all resources. You can also limit documents to be available
47+
to that group for a
48+
[specific period of time](https://support.google.com/docs/answer/2494893?co=GENIE.Platform%3DDesktop&hl=en).
49+
50+
![Users are added to a Google Group via a Google Sheet](https://cdn.jsdelivr.net/gh/gsuitedevs/solutions@master/group-membership/demo.gif)
1951

2052
## Technology highlights
2153

22-
* Using the `onEdit` _simple trigger_ in a Google Sheet, you can grant access
23-
to multiple resources from a spreadsheet.
24-
To learn more [click here](https://developers.google.com/apps-script/guides/triggers/#onedite)
25-
* Manage group members using the
26-
[Admin Directory](https://developers.google.com/admin-sdk/directory/v1/guides/manage-group-members)
27-
* A _Google Document_ is used as the email's _template_.
54+
- Install a trigger with a click so the script is setup to run everytime the
55+
Sheet is edited. To learn more visit
56+
[this page](https://developers.google.com/apps-script/guides/triggers/installable))
57+
- Add members to a _Google Group for Business_ using the
58+
[Admin Directory API](https://developers.google.com/apps-script/advanced/admin-sdk-directory)
2859

2960
## Try it
3061

31-
1. Make a [copy of this Google Spreadsheet](https://docs.google.com/spreadsheets/d/1kNuOc_evfqbu8dVJIA5N4r27d_Ubnr915eln4cbq2cU/copy) from your G Suite account.
32-
1. From your spreadsheet, click on **Tools > Script Editor**. This will bring
33-
you to the _Apps Script editor_.
34-
1. Ensure the **Admin Directory API** is enabled via
35-
**Resources > Advanced Google Services**.
36-
1. Now run the script by clicking the **Select function** drop down > choose **"installTrigger."** Then click the Run button (►). This will create a
37-
trigger for your sheet automatically.
62+
1. Make a [copy of this Google Spreadsheet](https://docs.google.com/spreadsheets/d/1KJKc2DcCr2bHLCq5Judvvwuen3k3ifFY8wtQWKfHDXU/copy) from your _G Suite_ account.
63+
64+
1. Enter for testing purposes a _Gmail address you own_ and a Google Group you
65+
have _rights to manage_ its membership.
3866

39-
> _Caution_: If you run this script _more than once_, it will generate
40-
> _multiple triggers_ causing duplicate emails. Ensure you run the script
41-
> once and that there aren't multiple triggers on the triggers page.
42-
> You can visit the triggers page by clicking the _trigger icon_ (which
43-
> looks like a clock from the script's page.
67+
> _Note_: The membership status will be populated by the words
68+
**Newly added** if the
69+
> user was added to the group, or **Already added** if it recognizes the user
70+
> is already a member of that group.
71+
72+
1. Enter “yes” in the “Allowed” column.
73+
1. Let’s visit the code now by clicking on **Tools > Script Editor**.
74+
1. Ensure the _Admin Directory API_ is enabled via
75+
**Resources > Advanced Google Services**.
76+
1. Create a trigger by clicking the clock-like icon and choosing the
77+
“onEditInstallableTrigger” function from the drop-down to run the event on
78+
“onOpen”
79+
1. Return to the script page and _run the script_ by clicking the
80+
**"Select function"** drop down >
81+
choose **"onEditInstallableTrigger."** Then click the Run button (►).
82+
This will create a trigger for your sheet automatically.
4483

4584
1. When prompted, click the **Review permissions** and click **Allow** so the
46-
script can email on your behalf.
47-
48-
> _Important_: If you get the warning **This app isn't verified**, continue
49-
> with the verification process by clicking **Advanced** and then scroll
50-
> down and click the grey text at the bottom that says
51-
> **Go to (Copy this external-access to a Google Group via onEdit Sheet**
52-
53-
1. After granting permissions, return to your spreadsheet and _type an email
54-
address_ in the `Email` column and the _group address_ in the `Google Group`
55-
column, and the word `yes` in the `Allowed` column.
56-
57-
> _Note_: if you do not populate the column `allowed` with the word `yes`,
58-
> the script is instructed to _not run_. This is helpful if you wish to
59-
> capture requests to join a group in the sheet but not add them the users
60-
> yet until you populate the **allowed** column.
61-
62-
1. To _test_, enter _your own email_ and a Google Group that you already
63-
are a member of and have _manager rights_ to adding members in order to
64-
receive the confirmation email.
65-
66-
## Optionally customize your email template
67-
68-
1. _[optional]_ You can modify the font, color, and images of your email
69-
template by [making a copy of this doc](https://docs.google.com/document/d/1-ajkkIP8gUWqMcnpXhkqwlM_2Y18USLdJ-pFZdDEZ70/copy). Then copy its
70-
URL address and replace the one listed in the vairable `addedToGroupDocId`
71-
in the sheet's script.
72-
73-
> _Note_: `{{EMAIL}}` and `{{GOOGLE_GROUP}}` are placeholders in your
74-
> template that insert the values from the Google Sheet. In order for
75-
> external users to receive the template's format, the Google doc's
76-
> permissions must be set to **Viewable by anyone with this link**; and at
77-
> least **Viewable by anyone in your organization** to share with anyone
78-
> in your domain.
79-
80-
1. _[optional]_ To modify the _subject line_ of the confirmation email, enter
81-
the desired message in the variable `addedToGroupSubject` in the sheet's
82-
script.
85+
script can email on your behalf.
86+
87+
> _Note_: If you get a warning that **This app isn't verified** continue
88+
> with the verification process by clicking **Advanced** and then scroll
89+
> down and click the grey text at the bottom that begins with **Go to...**
90+
91+
1. Check your inbox and Google Group’s interface under it’s _members_ section.
92+
93+
## _[optional]_ Customize your messaging
94+
95+
- If you wish to change the subject lines of your emails, replace
96+
the text in the “Email subject” column.
97+
98+
- If you wish to change the email template that is sent out, replace the URL
99+
in the “Email template” column with your preferred Google Doc. If you wish
100+
to include any of the column values in the template, enter them as such in
101+
the template {{Column_name}} like this: _Welcome, we have added your
102+
{{Email}} to this {{Google_Group}} in order give you access to the following
103+
resources..._
104+
> _Note_: If you encounter any issues with the welcome email, change the
105+
> permission levels of the Google Doc templates to more open settings.
83106
84107
## Next steps
85108

group-membership/demo.gif

997 KB
Loading

group-membership/src/Code.js

+103
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
/**
2+
* Trigger that runs on edit after being installed via the interface.
3+
*
4+
* @param {Object} e - onEdit trigger event.
5+
*/
6+
function onEditInstallableTrigger(e) {
7+
// Get the headers, row range and values from the active sheet.
8+
var sheet = SpreadsheetApp.getActiveSheet();
9+
var headers = sheet.getDataRange().offset(0, 0, 1).getValues()[0];
10+
var range = sheet.getRange(e.range.getRow(), 1, 1, headers.length);
11+
var row = range.getValues()[0];
12+
13+
// Convert the row Array into an entries Object using the headers for the
14+
// field names.
15+
var entries = headers.reduce(function(result, columnName, i) {
16+
result[columnName] = row[i];
17+
return result;
18+
}, {});
19+
20+
// Update the entries Object with the status returned by addToGroup().
21+
try {
22+
entries['Status'] = addToGroup(
23+
entries['Email'],
24+
entries['Google Group'],
25+
entries['Allowed'],
26+
entries['Email template doc URL'],
27+
entries['Email subject']
28+
);
29+
} catch (e) {
30+
// If there's an error, report that as the status.
31+
entries['Status'] = e;
32+
}
33+
34+
// Convert the updated entries Object into a row Array.
35+
var rowToWrite = headers.map(function(columnName) {
36+
return entries[columnName];
37+
});
38+
39+
// setValues() receives a 2D array, so we create an array with the row
40+
// contents.
41+
range.setValues([rowToWrite]);
42+
}
43+
44+
45+
/**
46+
* Trigger that runs on edit after being installed via the interface.
47+
*
48+
* @param {string} userEmail - email of user to add to the group.
49+
* @param {string} groupEmail - address of Google Group to add user to.
50+
* @param {string} allowed - 'yes' flag to add user to group.
51+
* @param {string} emailTemplateDocUrl - Google Doc URL that serves as template
52+
* of the welcome email sent to a user added to the group.
53+
* @param {string} emailSubject - subject of welcome email sent to user added to group.
54+
* @return {string} - status if email was sent to a user added in the sheet.
55+
*/
56+
function addToGroup(userEmail, groupEmail, allowed, emailTemplateDocUrl, emailSubject) {
57+
if (allowed.toLowerCase() != 'yes') {
58+
return 'Not sent';
59+
}
60+
61+
// If the group does not contain the user's email, add it and send an email.
62+
var group = GroupsApp.getGroupByEmail(groupEmail);
63+
if (!group.hasUser(userEmail)) {
64+
// User is not part of the group, add user to the group.
65+
var member = {email: userEmail, role: 'MEMBER'};
66+
AdminDirectory.Members.insert(member, groupEmail);
67+
68+
// Send a confirmation email that the member was now added.
69+
var docId = DocumentApp.openByUrl(emailTemplateDocUrl).getId();
70+
var emailBody = docToHtml(docId);
71+
72+
// Replace the template variables like {{VARIABLE}} with real values.
73+
emailBody = emailBody.replace('{{EMAIL}}', userEmail);
74+
emailBody = emailBody.replace('{{GOOGLE_GROUP}}', groupEmail);
75+
76+
MailApp.sendEmail({
77+
to: userEmail,
78+
subject: emailSubject,
79+
htmlBody: emailBody,
80+
});
81+
82+
// Set the status to the current date.
83+
return new Date();
84+
}
85+
return 'Already in group';
86+
}
87+
88+
/**
89+
* Fetches a Google Doc as an HTML string.
90+
*
91+
* @param {string} docId - The ID of a Google Doc to fetch content from.
92+
* @return {string} The Google Doc rendered as an HTML string.
93+
*/
94+
function docToHtml(docId) {
95+
var url = 'https://docs.google.com/feeds/download/documents/export/Export?id=' +
96+
docId + '&exportFormat=html';
97+
var param = {
98+
method: 'get',
99+
headers: {'Authorization': 'Bearer ' + ScriptApp.getOAuthToken()},
100+
muteHttpExceptions: true,
101+
};
102+
return UrlFetchApp.fetch(url, param).getContentText();
103+
}

group-membership/src/appsscript.json

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{
2+
"timeZone": "America/Los_Angeles",
3+
"dependencies": {
4+
"enabledAdvancedServices": [{
5+
"userSymbol": "AdminDirectory",
6+
"serviceId": "admin",
7+
"version": "directory_v1"
8+
}]
9+
},
10+
"exceptionLogging": "STACKDRIVER",
11+
"oauthScopes": [
12+
"https://www.googleapis.com/auth/admin.directory.group.member",
13+
"https://www.googleapis.com/auth/documents",
14+
"https://www.googleapis.com/auth/drive.readonly",
15+
"https://www.googleapis.com/auth/groups",
16+
"https://www.googleapis.com/auth/script.external_request",
17+
"https://www.googleapis.com/auth/script.scriptapp",
18+
"https://www.googleapis.com/auth/script.send_mail",
19+
"https://www.googleapis.com/auth/spreadsheets.currentonly"
20+
]
21+
}

group-membership/src/group-membership.js

-82
This file was deleted.

0 commit comments

Comments
 (0)