Using AND operator in Google Script - google-apps-script

I created a script to write the list of users in an OU to a spreadsheet and this works well. However now I wanted to script to write data for multiple OU's into the same spreadsheet but the '&&' operator does not seem to work. I tried using the OR '||" operator but that does not seem to work either. Any ideas?
function listAllUserRR() {
var sh = '1Or1yr9JtwsEvg97U1VjX4XNEZylxoVPwRzJXC6wZDKx';
var sheet = SpreadsheetApp.openById(sh);
var sheet1 = sheet.getSheetByName('Google Users');
var sheet1range = sheet.getRange("A:F")
sheet1range.clear()
var data = [];// array to store values
data.push(['Email' ,'Firstname', 'Lastname', 'OU', 'Suspended', 'LastLoginTime']);// store headers
var pageToken, page;
do {
page = AdminDirectory.Users.list({
customer: 'C00ont7ej',
query: "OrgUnitPath='/Brazil'" || "orgUnitPath='/Argentina'",
pageToken: pageToken
});
var users = page.users;
if (users) {
for (var i = 0; i < users.length; i++) {
var user = users[i];
data.push([user.primaryEmail, user.name.givenName, user.name.familyName, user.orgUnitPath, user.suspended, user.lastLoginTime, ]);//store in an array of arrays (one for each row)
}
} else {
Logger.log('No users found.');
}
pageToken = page.nextPageToken;
} while (pageToken);
sheet1.getRange(1,1,data.length,data[0].length).setValues(data);
var dated = sheet.getRange("P1")
dated.setValue(Utilities.formatDate(new Date(),Session.getScriptTimeZone(),'dd-MMM-yyy'));
}

This line is wrong:
query: "OrgUnitPath='/Brazil'" || "orgUnitPath='/Argentina'",
because you use a javascript operator between two strings. Javascript will do:
if the first string is not falsey (not 0, null, undefined, false or empty), it will return the first string. Or if not, it will return the second string. Example:
var query = "OrgUnitPath='/Brazil'" || "orgUnitPath='/Argentina'";
console.log(query);
// Prints: OrgUnitPath='/Brazil'
var query = "" || "orgUnitPath='/Argentina'";
console.log(query);
// Prints: orgUnitPath='/Argentina'
This is definately not what you want. You just want something like this:
var query = "OrgUnitPath='/Brazil' OR orgUnitPath='/Argentina'";
console.log(query);
// Prints: OrgUnitPath='/Brazil' OR orgUnitPath='/Argentina'
Also notice that you are using orgUnitPathand OrgUnitPath (both uppercase and lowercase o). I don't know if the query is case sensitive, but it is good to be consistent anyways...

I don't see any indication that the Directory API lets you specify multiple OUs when searching for users:
https://developers.google.com/admin-sdk/directory/v1/guides/search-users
Why not just split out the AdminDirectory lookup as a function that takes the OU name and the array and call it from a loop that passes each OU that you want and the array and then you can dump it all back into the spreadsheet.
function listAllUserRR() {
var ss = SpreadsheetApp.getActive();
var sheet = ss.insertSheet(Utilities.formatDate(new Date(),Session.getScriptTimeZone(),'dd-MMM-yyy_HH:mm'));
var data = [];// array to store values
data.push(['Email' ,'Firstname', 'Lastname', 'OU', 'Suspended', 'LastLoginTime']);// store headers
var orgUnitsArray = ["OrgUnitPath='/Brazil'", "orgUnitPath='/Argentina'"];
for (var i=0; i < orgUnitsArray.length; i++) {
getOrgUnitUsers(orgUnitsArray[i], data)
}
sheet.getRange(1,1,data.length,data[0].length).setValues(data);
}
function getOrgUnitUsers(orgUnit, userArray) {
var pageToken, page;
do {
page = AdminDirectory.Users.list({
customer: 'my_customer',
query: orgUnit,
pageToken: pageToken
});
var users = page.users;
if (users) {
for (var i = 0; i < users.length; i++) {
var user = users[i];
userArray.push([user.primaryEmail, user.name.givenName, user.name.familyName, user.orgUnitPath, user.suspended, user.lastLoginTime, ]);//store in an array of arrays (one for each row)
}
} else {
Logger.log('No users found.');
}
pageToken = page.nextPageToken;
} while (pageToken);
}

Related

Retrieve Mobile Device Report via Google Reports API via google scripts

I am trying to retrieve the mobile device report but I keep getting this error: "API call to directory.mobiledevices.list failed with error: Bad Request".
I think the issue is the customerId. What should I use to retrieve all mobile devices info? I have tried using "all" and also defining the domain name but no luck.
Must appreciated for your time and input! TIA!
function mobileReport() {
var spreadsheet = SpreadsheetApp.getActive();
var sheet = spreadsheet.getSheetByName('SHEETNAME');
sheet.clear();
// Append the headers.
var headers = ['Full Name','Email','Device Id','Model','Type','Status','Last Sync'];
sheet.appendRow(headers).setFrozenRows(1);
var rows = [];
var pageToken;
var count = 0;
do {
var page = AdminDirectory.Mobiledevices.list({
orderBy: 'email',
maxResults: 500,
pageToken: pageToken
});
var users = page.mobiledevices;
if (users) {
for (var i = 0; i < users.length; i++) {
var user = users[i];
rows.push([user.name,user.email,user.deviceId,user.model,user.type,user.status,user.lastSync]);
}
// Append the results.
sheet.getRange(2, 1, rows.length,headers.length).setValues(rows);
}
else {
Logger.log('No users found.');
}
pageToken = page.nextPageToken;
} while (pageToken);
}
Modification points:
When I saw the official document, it seems that at the method of "Method: mobiledevices.list" in Directory API, customerId is required to be used as follows.
customerId: The unique ID for the customer's Google Workspace account. As an account administrator, you can also use the my_customer alias to represent your account's customerId. The customerId is also returned as part of the Users resource.
But in your script, this is not used. By this, the arguments for AdminDirectory.Mobiledevices.list are not correct. I think that this is the reason of your issue of "Bad Request".
The maximum value of maxResults is 100.
It seems that the email of Enum of orderBy is EMAIL. Ref
In your script, setValues is used in the loop and the same range is used. In this case, the values are overwritten by every loop.
When above points are reflected to your script, it becomes as follows.
Modified script:
Please modify your script as follows.
From:
var rows = [];
var pageToken;
var count = 0;
do {
var page = AdminDirectory.Mobiledevices.list({
orderBy: 'email',
maxResults: 500,
pageToken: pageToken
});
var users = page.mobiledevices;
if (users) {
for (var i = 0; i < users.length; i++) {
var user = users[i];
rows.push([user.name,user.email,user.deviceId,user.model,user.type,user.status,user.lastSync]);
}
// Append the results.
sheet.getRange(2, 1, rows.length,headers.length).setValues(rows);
}
else {
Logger.log('No users found.');
}
pageToken = page.nextPageToken;
} while (pageToken);
To:
var customerId = "###"; // <--- Please set customerId.
var rows = [];
var pageToken;
var count = 0; // It seems that this variable is not used in the script.
do {
var page = AdminDirectory.Mobiledevices.list(customerId, {
orderBy: 'EMAIL',
maxResults: 100,
pageToken: pageToken
});
var users = page.mobiledevices;
if (users.length > 0) {
for (var i = 0; i < users.length; i++) {
var user = users[i];
rows.push([user.name, user.email, user.deviceId, user.model, user.type, user.status, user.lastSync]);
}
} else {
Logger.log('No users found.');
}
pageToken = page.nextPageToken;
} while (pageToken);
if (rows.length > 0) {
sheet.getRange(2, 1, rows.length, headers.length).setValues(rows);
}
Note:
In this modified script, it supposes that you can retrieve the values using AdminDirectory.Mobiledevices.list. Please be careful this.
Reference:
Method: mobiledevices.list

Get User Names based from their email id using Google App Script

I have a project to send mail to multiple users, I have written script to send multiple users an Email using App script, but to make the mail more personalized, I want to start mail as "Hi Abhishek Mehta"
Using AdminDirectory.Users.get(userKey, {fields:'name'}) I am able to fetch the name of the users, but not sure how to list them in the sheet.
In normal words, I have 50 Email ids and want to fetch full name of the Email id and want to write it in a Google sheet using Google App Script.
Request help from the community.
name of getUser() returns an object, you'll need to access that object to get the first and surname of the user.
The following script will get all the users in your domain (provided you have admin access) sorted by email and list them in a sheet named Users
function listAllUsers() {
var ss = SpreadsheetApp.getActiveSheet();
var pageToken,
page;
var userInfo = []
do {
page = AdminDirectory.Users.list({
domain: '---------',
orderBy: 'email',
maxResults: 500,
pageToken: pageToken
});
var users = page.users;
if (users) {
for (var i = 0; i < users.length; i++) {
var user = users[i];
try {
userInfo.push([user.primaryEmail, user.name.givenName, user.name.familyName]);
} catch (e) {
userInfo.push([user.primaryEmail, "", ""]);
}
}
} else {
Logger.log('No users found.');
}
pageToken = page.nextPageToken;
} while (pageToken);
var sheet = ss.getSheetByName('Users')
sheet.getRange(2, 1, userInfo.length, userInfo[0].length).setValues(userInfo);
}
To get the names of a list of users you can use the following script. It assumes that the usernames (email addresses) are listed in column A starting in row 2 and without breaks.
There are 3 values in the name object
.givenName is the users first name.
.familyName is the users surname
.fullName is the first name and surname separated by a space
function usersNames() {
var ss = SpreadsheetApp.getActiveSheet();
var data = ss.getRange('A2:A').getValues();
var userNames = [];
for (var i = 0; i < data.length; i++) {
if (data[i][0]) {
var names = AdminDirectory.Users.get(data[i][0]).name
userNames.push([names.givenName, names.familyName]);
} else {
break;
}
}
ss.getRange(2, 2, userNames.length, 2).setValues(userNames)
}
Here is the script for the same.
File id = Example in Bold Letters (https://docs.google.com/spreadsheets/d/1JeNKU366pzsdH-Pg9EsjKENLO0orqunduoOGJJMnKjM4/edit#gid=63023734)
File Name = Name of the sheet under the main spreadsheet, like sheet1 or sheet2
`function getUserName() {
var ss = SpreadsheetApp.openById("File ID");
var sheet = ss.getSheetByName("File Name")
var values = sheet.getDataRange().getValues()
var fileArray = [["User Name"]]
for(i=1; i <values.length; i++)
{
var userKey = values[i][2] // '2' = Cloumn C
try{
var status = "No Name Found"
var status = AdminDirectory.Users.get(userKey, {fields:'name'})
var fullname = status.name.fullName
Logger.log(fullname)
if (status != "No Name Found"){
status = fullname
}
}
catch (e) {
Logger.log(e.message)
var status = e.message
}
fileArray.push([status])
}
var range = sheet.getRange(1, 4, fileArray.length, 1).setValues(fileArray)
}`

How to get all groups for a user in Google App Script?

Is there any way to get all groups for a user? My code which is not working properly is below;
var pageToken = null;
var filter= {userKey: "abc#gmail.com"}; //this is a member's email address
do {
var result = AdminDirectory.Groups.list(filter);
filter.pageToken = result.pageToken;
if(result.groups) {
groups = groups.concat(result.groups.map(function(group) {
return {
name: group.name
};
}));
}
}
while(result.pageToken);
for(i = 0; i < groups.length; i++) {
console.log(groups[i].name);
}
It returns empty groups array.
The code is simpler than that, no need to use token.
The returned value is an array of objects with several properties (see JSON)
It goes like this
function myFunction() {
var user = AdminDirectory.Groups.list({userKey:"userEmail#xxx.yyy"});
var groupMembership = [];
var userGroupProperties = user.groups;
Logger.log(JSON.stringify(userGroupProperties));
for(var n=0 ; n<userGroupProperties.length ; n++){
groupMembership.push(userGroupProperties[n].name)
}
Logger.log('groupMembership = '+groupMembership);
}

List more than 30 students in a class in Google Classroom API query

At this moment, I have a script that works correctly to list students of a class in Google Classroom, but it does NOT list ALL of the students, only the first 30. I need it to list ALL of the students, no matter how many there are. What I have now is the following:
function listStudents() {
var s = SpreadsheetApp.getActiveSpreadsheet();
var sh = s.getSheetByName('CLASS');
var r = sh.getDataRange();
var n = r.getNumRows();
var d = r.getValues();
for (x = 0; x < n; x++) {
var i = d[x][0];
if(i == ''){ continue; } else if (i == 'D') {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sh = ss.getSheetByName('LISTSTUDENTS');
var tea = Classroom.Courses.Students.list(d[x][8]);
var t = tea.students;
var arr = [];
try {
for (i = 0; i < t.length; i++) {
var c = t[i];
var ids = c.profile;
var em = ids.emailAddress;
arr.push([em]);
}
}
catch (e) { continue; }
sh.getRange(d[x][14], d[x][15], arr.length, arr[0].length).setValues(arr);
}
}
}
You receive only 30 students in the query because you are only accessing the first page of results. Almost every "advanced service" functions in a similar manner with regards to collections, in that they return a variable number of items in the call (usually up to a size that can be specified in the query, but there are limits). This is to ensure timely service availability for everyone who uses it.
For example, consider Bob (from Accounting). This style of request pagination means he can't request a single response with 20,000 items, during which the service is slower for everyone else. He can, however, request the next 100 items, 200 times. While Bob is consuming those 100 items from his most recent query, others are able to use the service without disruption.
To set this up, you want to use a code loop that is guaranteed to execute at least once, and uses the nextPageToken that is included in the response to the call to .list() to control the loop. In Javascript / Google Apps Script, this can be a do .. while loop:
// Runs once, then again until nextPageToken is missing in the response.
const roster = [],
// The optional arguments pageToken and pageSize can be independently omitted or included.
// In general, 'pageToken' is essentially required for large collections.
options = {pageSize: /* reasonable number */};
do {
// Get the next page of students for this course.
var search = Classroom.Courses.Students.list(courseId, options);
// Add this page's students to the local collection of students.
// (Could do something else with them now, too.)
if (search.students)
Array.prototype.push.apply(roster, search.students);
// Update the page for the request
options.pageToken = search.nextPageToken;
} while (options.pageToken);
Logger.log("There are %s students in class # %s", roster.length, courseId);
for those who struggle with this, here's the code
function listStudent() {
var pageSizeValue = 300; /*** change with numbers that you want*/
var nextPageToken = '';
var courseID = 1234; /*** change with numbers that you want*/
var ownerArray = [];
do {
var optionalArgs = {
pageSize: pageSizeValue,
pageToken: nextPageToken
};
var cls = Classroom.Courses.Students.list(courseID, optionalArgs);
var nextPageToken = cls.nextPageToken;
const ssData = cls.students.map(c => {
return [c.profile.id,c.profile.name.fullName,c.profile.emailAddress]
});
Array.prototype.push.apply(ownerArray, ssData);
} while (nextPageToken);
const ss = SpreadsheetApp.openById("1234"); // <<< UPDATE THIS
const sheet = ss.getSheetByName("Sheet1"); // <<< UPDATE THIS
sheet.getRange(2,1,ownerArray.length,ownerArray[0].length).setValues(ownerArray); // <<< UPDATE THIS
}
I modified the getRoster function in the example provided by Google (https://developers.google.com/apps-script/add-ons/editors/sheets/quickstart/attendance) as follows, and it worked for me.
function getRoster(courseId) {
var studentNames = []
var studentEmails = []
var nextPageToken = ''
do {
var optionalArgs = {
pageSize: 30,
pageToken: nextPageToken
};
var response = Classroom.Courses.Students.list(courseId, optionalArgs)
var students = response.students
nextPageToken = response.nextPageToken
for (var i = 0; i <= students.length; i++) {
try {
studentNames.push(students[i].profile.name.fullName)
studentEmails.push(students[i].profile.emailAddress)
} catch (err) {
}
}
} while (nextPageToken);
return { "studentNames":studentNames, "studentEmails":studentEmails }
}

Exceeded maximum execution time in Google Apps Script to retrieve users name and email address from email domain

I have this code. I set a time trigger to retrieve every employee's names, email address from the email domain, assign a primary key to it and write it on spreadsheet. I did that for attendance system. But when the execution time is greater than 5 minutes, I can't retrieve the whole employees name and email address from the email domain.
What can I do?
Please help.
Thank you!
function primarykeyrecord(){
var lastval;
var sheet=getData();
var data = sheet.getDataRange().getValues();
lastval=data[data.length-1][0];
if(lastval !== "primarykeyvalue"){
lastval=lastval+1;
}
else {
lastval=1;
}
// Logger.log( lastval);
return lastval;
}
// list all the user from the domain
function listAllUsers() {
var pageToken, page;
var today =methodtimenow();
do {
page = AdminDirectory.Users.list({
domain: '',
//orderBy: 'givenName',
maxResults: 300,
pageToken: pageToken
});
users = page.users;
userslength=users.length; // the number of user from the email domain
if (users) {
for (var i = 0; i < users.length; i++) {
var user = users[i];
var sheet = getData();
var lastval=primarykeyrecord();
var range = sheet.getRange(sheet.getLastRow()+1, 1, 1, 4);
var values = [[lastval,today,user.primaryEmail,user.name.fullName ]];
range.setValues(values);
}
} else {
Logger.log('No users found.');
}
pageToken = page.nextPageToken;
} while (pageToken);
//Logger.log(values);
}
The reason your script is timing out is, you are recursively calling setValues() and getValue(). Both are resource intensive process and should be used sparingly as possible, use batch updating instead.
The below code gets all the user data in values array and adds the array in one go at the end.
function listAllUsers() {
var pageToken, page;
var today =methodtimenow();
var lastval=primarykeyrecord(); //Access the last value once and then keep adding one
var values = [] //Create empty array
do {
page = AdminDirectory.Users.list({
domain: '',
//orderBy: 'givenName',
maxResults: 300,
pageToken: pageToken
});
users = page.users;
userslength=users.length; // the number of user from the email domain
if (users) {
// And all the user data to values array
for (var i = 0; i < users.length; i++) {
var user = users[i];
var temp = [lastval,today,user.primaryEmail,user.name.fullName ];
values.push(temp)
lastval++; //Increase key value by one
}
} else {
Logger.log('No users found.');
}
pageToken = page.nextPageToken;
} while (pageToken);
var sheet = getData();
var lastRow = sheet.getLastRow()
var range = sheet.getRange(lastRow+1, 1, values.length, 4);
range.setValues(values);
//Logger.log(values);
}
Hope that helps!