-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit f58b7b0
Showing
4 changed files
with
230 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
![Google Group Directory Unlister](https://raw.githubusercontent.com/xd1936/googlegroupdirectoryunlister/master/img/screenshot.png) | ||
|
||
# Google Group Directory Unlister | ||
|
||
### Basics | ||
|
||
[Google Groups for Gsuite](https://support.google.com/a/topic/25838) is a product that allows admins to create mailing lists for their domain. It is different than the public-facing [Google Groups](https://groups.google.com/) forums. When an admin makes a new Google Group for their domain, by default, the email address for that group is available in their domain's directory. That means that every user in the domain has the group's email address autocomplete when they type in the "To:" field in Gmail. There is no way to change that setting unless you do it programatically via the [Admin Group Settings API](https://developers.google.com/admin-sdk/groups-settings/v1/reference/groups). | ||
|
||
In order to make our Admin's lives easier, I created this script. It simply grabs all of the groups on your domain and lets you toggle whether they are or are not included in the directory. | ||
|
||
### Setup | ||
|
||
`Note: This project must be initially created by a domain administrator account` | ||
|
||
1. Log in as a domain administrator and create a [new Google Apps Script project](https://script.google.com/) in Google Drive. | ||
2. Copy and paste the code from [`code.gs`](https://raw.githubusercontent.com/xd1936/googlegroupdirectoryunlister/master/code.gs) into `code.gs` in the Apps Script project | ||
3. Create a new html file with **File** → **New** → **Html file**, name it `index.html`, and copy the code from [`index.html`](https://raw.githubusercontent.com/xd1936/googlegroupdirectoryunlister/master/index.html) into it. | ||
4. Go into **Resources** → **Advanced Google services...**, and turn on the **Admin Directory API** and **Groups Settings API**. Also follow the *Developer Console* link on this same screen and enable access to the **Admin SDK** and **Groups Settings API** for this project ([more information](https://developers.google.com/apps-script/guides/services/advanced)). | ||
5. Go into the `code.gs` file and change the `domain` variable on line 3 to be your domain. | ||
6. Go into **Publish** → **Deploy as web app...**. Choose the level of access that you want to have on the panel (Under **Who has access to the app:**), and click **Deploy**. | ||
|
||
You're done! Navigate to that web app URL to see your groups and modify each one's setting. | ||
|
||
### Updating | ||
|
||
When updates are released here on Github, simply copy and paste the newer [`code.gs`](https://raw.githubusercontent.com/xd1936/googlegroupdirectoryunlister/master/code.gs) and [`index.html`](https://raw.githubusercontent.com/xd1936/googlegroupdirectoryunlister/master/index.html) files to your project, and go to **Publish** → **Deploy as web app...**. Increment the version number (Pick "New" under the **Project Version** dropdown) and click **Deploy**. You should be good to go! | ||
|
||
- - - | ||
|
||
Feel free to take a look at the source and adapt as you please. I would love to see some pull requests for improvements to the Javascript. | ||
|
||
This source is licensed as follows: | ||
|
||
[![Creative Commons License](https://i.creativecommons.org/l/by-sa/4.0/88x31.png)](http://creativecommons.org/licenses/by-sa/4.0/) | ||
|
||
<span xmlns:dct="http://purl.org/dc/terms/" property="dct:title">Google Group Directory Unlister</span> is licensed under a [Creative Commons Attribution-ShareAlike 4.0 International License](http://creativecommons.org/licenses/by-sa/4.0/). | ||
|
||
- - - | ||
|
||
[![Buy Me A Coffee](https://www.buymeacoffee.com/assets/img/custom_images/white_img.png)](https://buymeacoff.ee/leoherzog) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
// | ||
// | ||
var domain = "yourdomain.com"; | ||
// | ||
// | ||
|
||
function doGet() { | ||
return HtmlService.createHtmlOutputFromFile('index.html').setTitle("Google Group Directory Unlister"); | ||
} | ||
|
||
function test_() { | ||
//var groups = getAllGroups(); | ||
//Logger.log(JSON.stringify(groups)); | ||
|
||
//Logger.log(showGroupInDirectory("[email protected]", false)); | ||
//Logger.log(getGroupDirectoryStatus("[email protected]")); | ||
} | ||
|
||
// https://developers.google.com/apps-script/advanced/admin-sdk-directory#list_all_groups | ||
function getAllGroups() { | ||
var allGroups = []; | ||
var pageToken, page; | ||
do { | ||
page = AdminDirectory.Groups.list({ | ||
"domain": domain, | ||
"pageToken": pageToken | ||
}); | ||
var groups = page.groups; | ||
if (groups) { | ||
for (var i in groups) { | ||
allGroups = allGroups.concat(groups[i]); | ||
} | ||
} else { | ||
throw 'No groups found.'; | ||
} | ||
pageToken = page.nextPageToken; | ||
} while (pageToken); | ||
return allGroups; | ||
} | ||
|
||
function showGroupInDirectory(groupId, showInDirectory) { | ||
|
||
var re = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; | ||
if (!groupId || typeof groupId != "string" || !re.test(groupId.toLowerCase())) { | ||
throw "Please call this function with a Google Group ID"; | ||
} | ||
if (showInDirectory == null) { | ||
showInDirectory = "true"; | ||
} | ||
showInDirectory = showInDirectory.toString(); | ||
if (showInDirectory != "true" && showInDirectory != "false") { | ||
throw "Please call this function with a boolean. Do you want this group to show in the directory or not?"; | ||
} | ||
|
||
// okay. we now have a valid email address for the group id, and if we do or don't want it to be in the directory. | ||
// get the group object | ||
var group = AdminGroupsSettings.Groups.get(groupId); | ||
// update it's "included in the list" property | ||
group.includeInGlobalAddressList = showInDirectory; | ||
// then patch the group with it's new setting | ||
AdminGroupsSettings.Groups.patch(group, groupId); | ||
|
||
return group; | ||
|
||
} | ||
|
||
function getGroupSettings(groupId) { | ||
var re = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; | ||
if (!groupId || typeof groupId != "string" || !re.test(groupId.toLowerCase())) { | ||
throw "Please call this function with a Google Group ID"; | ||
} | ||
return AdminGroupsSettings.Groups.get(groupId); | ||
} |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
<!DOCTYPE html> | ||
<html> | ||
<head> | ||
<base target="_top"> | ||
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> | ||
<script src="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0/js/bootstrap.min.js"></script> | ||
<script src="//use.fontawesome.com/releases/v5.0.8/js/all.js"></script> | ||
<link href="//cdnjs.cloudflare.com/ajax/libs/bootswatch/4.0.0/materia/bootstrap.min.css" rel="stylesheet" /> | ||
<style>body{padding-top:40px}</style> | ||
</head> | ||
<body> | ||
<div class="container"> | ||
<div class="row"> | ||
<div class="col-auto mr-auto"> | ||
<h1><i class="fas fa-users"></i> Google Group Directory Listings</h1> | ||
</div> | ||
<div class="col-auto"> | ||
<button type="button" id="refresh" class="btn btn-primary btn-lg"><i class="fas fa-sync"></i></button> | ||
</div> | ||
</div> | ||
<div id="content" class="row"> | ||
</div> | ||
</div> | ||
<script> | ||
$(document).ready(function() { | ||
getGroups(); | ||
}); | ||
|
||
$('#refresh').click(function() { | ||
if (!$('#refresh').hasClass('disabled')) { | ||
getGroups(); | ||
} | ||
}); | ||
|
||
function getGroups() { | ||
$('#refresh').addClass('disabled').html('<i class="fas fa-spin fa-sync"></i>'); | ||
google.script.run.withSuccessHandler(updateCards).withFailureHandler(handleError).getAllGroups(); | ||
} | ||
|
||
function updateCards(groups) { | ||
|
||
console.log("Updating all groups..."); | ||
|
||
var content = ""; | ||
for (var i in groups) { | ||
var id = sanitizeForId(groups[i].email); | ||
content += '<div class="col-4">'; | ||
content += '<div id="' + id + '" class="card border-light mb-3">'; | ||
content += '<div class="card-header">' + groups[i].email + ' <small>(' + groups[i].directMembersCount + ')</small></div>'; | ||
content += '<div class="card-body">'; | ||
content += '<h4 class="card-title">' + groups[i].name + '</h4>'; | ||
content += '<p id="' + id + '-status" class="card-text"><button id="' + id + '-button" type="button" class="btn btn-sm btn-secondary disabled">Loading...</button></p>'; | ||
content += '</div>'; | ||
content += '</div>'; | ||
content += '</div>'; | ||
} | ||
$('#content').empty().html(content); | ||
|
||
console.log("Updated all groups! Updating statuses for each card..."); | ||
|
||
for (var i in groups) { | ||
getCardStatus(groups[i].email); | ||
} | ||
|
||
$('#refresh').removeClass('disabled').html('<i class="fas fa-sync"></i>'); | ||
|
||
} | ||
|
||
function handleError(error) { | ||
alert(error); | ||
} | ||
|
||
function getCardStatus(groupId) { | ||
google.script.run.withSuccessHandler(updateCardStatus).withFailureHandler(handleError).getGroupSettings(groupId); | ||
} | ||
|
||
function updateCardStatus(settings) { | ||
|
||
console.log("Updating Card for " + settings.email + "..."); | ||
|
||
var id = sanitizeForId(settings.email); | ||
var card = $('#' + id); | ||
var status = $('#' + id + '-status'); | ||
|
||
card.removeClass("border-light border-success border-danger border-warning"); | ||
if (settings.includeInGlobalAddressList == "true") { | ||
card.addClass("border-success"); | ||
status.html('<button id="' + id + '-button" onclick="unlist(\'' + settings.email + '\')" type="button" class="btn btn-sm btn-success"><i class="fas fa-minus"></i> Unlist from Directory</button>'); | ||
} else if (settings.includeInGlobalAddressList == "false") { | ||
card.addClass("border-danger"); | ||
status.html('<button id="' + id + '-button" onclick="relist(\'' + settings.email + '\')" type="button" class="btn btn-sm btn-danger"><i class="fas fa-plus"></i> Relist to Directory</button>'); | ||
} else { | ||
card.addClass("border-warning"); | ||
status.html('<button id="' + id + '-button" type="button" class="btn btn-sm btn-warning disabled">Error</button>'); | ||
} | ||
|
||
} | ||
|
||
function unlist(groupId) { | ||
console.log("Unlisting " + groupId + "..."); | ||
$("#" + sanitizeForId(groupId) + '-button').addClass("disabled").prop('onclick', null).off('click'); | ||
google.script.run.withSuccessHandler(updateCardStatus).withFailureHandler(handleError).showGroupInDirectory(groupId, "false"); | ||
} | ||
|
||
function relist(groupId) { | ||
console.log("Relisting " + groupId + "..."); | ||
$("#" + sanitizeForId(groupId) + '-button').addClass("disabled").prop('onclick', null).off('click'); | ||
google.script.run.withSuccessHandler(updateCardStatus).withFailureHandler(handleError).showGroupInDirectory(groupId, "true"); | ||
} | ||
|
||
function sanitizeForId(email) { | ||
return email.replace(/@|\./g, ""); | ||
} | ||
</script> | ||
|
||
</body> | ||
</html> |