From 974f5f9f15bbd8c3cb96b8ffa3e1bfa8c9fd910f Mon Sep 17 00:00:00 2001 From: Ricardo Espinoza Date: Fri, 23 Oct 2020 03:15:11 -0400 Subject: [PATCH] :zap: Add GSuite group resource (#1048) --- .../GSuiteAdminOAuth2Api.credentials.ts | 1 + .../Google/GSuiteAdmin/GSuiteAdmin.node.ts | 128 ++++++- .../Google/GSuiteAdmin/GroupDescripion.ts | 332 ++++++++++++++++++ 3 files changed, 446 insertions(+), 15 deletions(-) create mode 100644 packages/nodes-base/nodes/Google/GSuiteAdmin/GroupDescripion.ts diff --git a/packages/nodes-base/credentials/GSuiteAdminOAuth2Api.credentials.ts b/packages/nodes-base/credentials/GSuiteAdminOAuth2Api.credentials.ts index 88c369c665..0271104a11 100644 --- a/packages/nodes-base/credentials/GSuiteAdminOAuth2Api.credentials.ts +++ b/packages/nodes-base/credentials/GSuiteAdminOAuth2Api.credentials.ts @@ -4,6 +4,7 @@ import { } from 'n8n-workflow'; const scopes = [ + 'https://www.googleapis.com/auth/admin.directory.group', 'https://www.googleapis.com/auth/admin.directory.user', 'https://www.googleapis.com/auth/admin.directory.domain.readonly', 'https://www.googleapis.com/auth/admin.directory.userschema.readonly', diff --git a/packages/nodes-base/nodes/Google/GSuiteAdmin/GSuiteAdmin.node.ts b/packages/nodes-base/nodes/Google/GSuiteAdmin/GSuiteAdmin.node.ts index e2631eb430..3a0ed1a8b6 100644 --- a/packages/nodes-base/nodes/Google/GSuiteAdmin/GSuiteAdmin.node.ts +++ b/packages/nodes-base/nodes/Google/GSuiteAdmin/GSuiteAdmin.node.ts @@ -21,6 +21,11 @@ import { userOperations, } from './UserDescription'; +import { + groupFields, + groupOperations, +} from './GroupDescripion'; + export class GSuiteAdmin implements INodeType { description: INodeTypeDescription = { displayName: 'G Suite Admin', @@ -48,6 +53,10 @@ export class GSuiteAdmin implements INodeType { name: 'resource', type: 'options', options: [ + { + name: 'Group', + value: 'group', + }, { name: 'User', value: 'user', @@ -56,6 +65,8 @@ export class GSuiteAdmin implements INodeType { default: 'user', description: 'The resource to operate on.', }, + ...groupOperations, + ...groupFields, ...userOperations, ...userFields, ], @@ -119,12 +130,112 @@ export class GSuiteAdmin implements INodeType { const resource = this.getNodeParameter('resource', 0) as string; const operation = this.getNodeParameter('operation', 0) as string; for (let i = 0; i < length; i++) { + if (resource === 'group') { + //https://developers.google.com/admin-sdk/directory/v1/reference/groups/insert + if (operation === 'create') { + const email = this.getNodeParameter('email', i) as string; + + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + + const body: IDataObject = { + email, + }; + + Object.assign(body, additionalFields); + + responseData = await googleApiRequest.call( + this, + 'POST', + `/directory/v1/groups`, + body, + ); + } + + //https://developers.google.com/admin-sdk/directory/v1/reference/groups/delete + if (operation === 'delete') { + const groupId = this.getNodeParameter('groupId', i) as string; + + responseData = await googleApiRequest.call( + this, + 'DELETE', + `/directory/v1/groups/${groupId}`, + {} + ); + + responseData = { success: true }; + } + + //https://developers.google.com/admin-sdk/directory/v1/reference/groups/get + if (operation === 'get') { + const groupId = this.getNodeParameter('groupId', i) as string; + + responseData = await googleApiRequest.call( + this, + 'GET', + `/directory/v1/groups/${groupId}`, + {}, + ); + } + + //https://developers.google.com/admin-sdk/directory/v1/reference/groups/list + if (operation === 'getAll') { + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + + const options = this.getNodeParameter('options', i) as IDataObject; + + Object.assign(qs, options); + + if (qs.customer === undefined) { + qs.customer = 'my_customer'; + } + + if (returnAll) { + responseData = await googleApiRequestAllItems.call( + this, + 'groups', + 'GET', + `/directory/v1/groups`, + {}, + qs + ); + + } else { + qs.maxResults = this.getNodeParameter('limit', i) as number; + + responseData = await googleApiRequest.call( + this, + 'GET', + `/directory/v1/groups`, + {}, + qs + ); + + responseData = responseData.groups; + } + } + + //https://developers.google.com/admin-sdk/directory/v1/reference/groups/update + if (operation === 'update') { + const groupId = this.getNodeParameter('groupId', i) as string; + + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + + const body: IDataObject = {}; + + Object.assign(body, updateFields); + + responseData = await googleApiRequest.call( + this, + 'PUT', + `/directory/v1/groups/${groupId}`, + body, + ); + } + } if (resource === 'user') { - //https://developers.google.com/admin-sdk/directory/v1/reference/users/insert if (operation === 'create') { - const domain = this.getNodeParameter('domain', i) as string; const firstName = this.getNodeParameter('firstName', i) as string; @@ -151,7 +262,6 @@ export class GSuiteAdmin implements INodeType { Object.assign(body, additionalFields); if (additionalFields.phoneUi) { - const phones = (additionalFields.phoneUi as IDataObject).phoneValues as IDataObject[]; body.phones = phones; @@ -160,7 +270,6 @@ export class GSuiteAdmin implements INodeType { } if (additionalFields.emailUi) { - const emails = (additionalFields.emailUi as IDataObject).emailValues as IDataObject[]; body.emails = emails; @@ -177,7 +286,6 @@ export class GSuiteAdmin implements INodeType { ); if (makeAdmin) { - await googleApiRequest.call( this, 'POST', @@ -191,7 +299,6 @@ export class GSuiteAdmin implements INodeType { //https://developers.google.com/admin-sdk/directory/v1/reference/users/delete if (operation === 'delete') { - const userId = this.getNodeParameter('userId', i) as string; responseData = await googleApiRequest.call( @@ -206,7 +313,6 @@ export class GSuiteAdmin implements INodeType { //https://developers.google.com/admin-sdk/directory/v1/reference/users/get if (operation === 'get') { - const userId = this.getNodeParameter('userId', i) as string; const projection = this.getNodeParameter('projection', i) as string; @@ -236,7 +342,6 @@ export class GSuiteAdmin implements INodeType { //https://developers.google.com/admin-sdk/directory/v1/reference/users/list if (operation === 'getAll') { - const returnAll = this.getNodeParameter('returnAll', i) as boolean; const projection = this.getNodeParameter('projection', i) as string; @@ -260,7 +365,6 @@ export class GSuiteAdmin implements INodeType { } if (returnAll) { - responseData = await googleApiRequestAllItems.call( this, 'users', @@ -271,7 +375,6 @@ export class GSuiteAdmin implements INodeType { ); } else { - qs.maxResults = this.getNodeParameter('limit', i) as number; responseData = await googleApiRequest.call( @@ -288,7 +391,6 @@ export class GSuiteAdmin implements INodeType { //https://developers.google.com/admin-sdk/directory/v1/reference/users/update if (operation === 'update') { - const userId = this.getNodeParameter('userId', i) as string; const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; @@ -315,7 +417,6 @@ export class GSuiteAdmin implements INodeType { } if (updateFields.phoneUi) { - const phones = (updateFields.phoneUi as IDataObject).phoneValues as IDataObject[]; body.phones = phones; @@ -325,7 +426,6 @@ export class GSuiteAdmin implements INodeType { } if (updateFields.emailUi) { - const emails = (updateFields.emailUi as IDataObject).emailValues as IDataObject[]; body.emails = emails; @@ -349,11 +449,9 @@ export class GSuiteAdmin implements INodeType { } if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); } else if (responseData !== undefined) { - returnData.push(responseData as IDataObject); } diff --git a/packages/nodes-base/nodes/Google/GSuiteAdmin/GroupDescripion.ts b/packages/nodes-base/nodes/Google/GSuiteAdmin/GroupDescripion.ts new file mode 100644 index 0000000000..91cf4caf2e --- /dev/null +++ b/packages/nodes-base/nodes/Google/GSuiteAdmin/GroupDescripion.ts @@ -0,0 +1,332 @@ +import { + INodeProperties, +} from 'n8n-workflow'; + +export const groupOperations = [ + { + displayName: 'Operation', + name: 'operation', + type: 'options', + displayOptions: { + show: { + resource: [ + 'group', + ], + }, + }, + options: [ + { + name: 'Create', + value: 'create', + description: 'Create a group', + }, + { + name: 'Delete', + value: 'delete', + description: 'Delete a group', + }, + { + name: 'Get', + value: 'get', + description: 'Get a group', + }, + { + name: 'Get All', + value: 'getAll', + description: 'Get all groups', + }, + { + name: 'Update', + value: 'update', + description: 'Update a group', + }, + ], + default: 'create', + description: 'The operation to perform.' + } +] as INodeProperties[]; + +export const groupFields = [ + /* -------------------------------------------------------------------------- */ + /* group:create */ + /* -------------------------------------------------------------------------- */ + { + displayName: 'Email', + name: 'email', + type: 'string', + required: true, + displayOptions: { + show: { + operation: [ + 'create', + ], + resource: [ + 'group', + ], + }, + }, + default: '', + description: `The group's email address. If your account has multiple domains, select the appropriate domain for the email address. The email must be unique`, + }, + { + displayName: 'Additional Fields', + name: 'additionalFields', + type: 'collection', + placeholder: 'Add Field', + default: {}, + displayOptions: { + show: { + operation: [ + 'create', + ], + resource: [ + 'group', + ], + }, + }, + options: [ + { + displayName: 'Description', + name: 'description', + type: 'string', + default: '', + description: `An extended description to help users determine the purpose of a group.
+ For example, you can include information about who should join the group,
+ the types of messages to send to the group, links to FAQs about the group, or related groups`, + }, + { + displayName: 'Name', + name: 'name', + type: 'string', + default: '', + description: `The group's display name`, + }, + ], + }, + /* -------------------------------------------------------------------------- */ + /* group:delete */ + /* -------------------------------------------------------------------------- */ + { + displayName: 'Group ID', + name: 'groupId', + type: 'string', + required: true, + displayOptions: { + show: { + operation: [ + 'delete', + ], + resource: [ + 'group', + ], + }, + }, + default: '', + description: `Identifies the group in the API request. The value can be the group's email address, group alias, or the unique group ID.` + }, + /* -------------------------------------------------------------------------- */ + /* group:get */ + /* -------------------------------------------------------------------------- */ + { + displayName: 'Group ID', + name: 'groupId', + type: 'string', + required: true, + displayOptions: { + show: { + operation: [ + 'get', + ], + resource: [ + 'group', + ], + }, + }, + default: '', + description: `Identifies the group in the API request. The value can be the group's email address, group alias, or the unique group ID.` + }, + /* -------------------------------------------------------------------------- */ + /* group:getAll */ + /* -------------------------------------------------------------------------- */ + { + displayName: 'Return All', + name: 'returnAll', + type: 'boolean', + displayOptions: { + show: { + operation: [ + 'getAll', + ], + resource: [ + 'group', + ], + }, + }, + default: false, + description: 'If all results should be returned or only up to a given limit.', + }, + { + displayName: 'Limit', + name: 'limit', + type: 'number', + displayOptions: { + show: { + operation: [ + 'getAll', + ], + resource: [ + 'group', + ], + returnAll: [ + false, + ], + }, + }, + typeOptions: { + minValue: 1, + maxValue: 500, + }, + default: 100, + description: 'How many results to return.', + }, + { + displayName: 'Options', + name: 'options', + type: 'collection', + placeholder: 'Add Option', + default: {}, + displayOptions: { + show: { + operation: [ + 'getAll', + ], + resource: [ + 'group', + ], + }, + }, + options: [ + { + displayName: 'Customer', + name: 'customer', + type: 'string', + default: '', + description: `The unique ID for the customer's G Suite account. In case of a multi-domain account, to fetch all groups for a customer, fill this field instead of domain`, + }, + { + displayName: 'Domain', + name: 'domain', + type: 'string', + default: '', + description: 'The domain name. Use this field to get fields from only one domain.', + }, + { + displayName: 'Order By', + name: 'orderBy', + type: 'options', + options: [ + { + name: 'Email', + value: 'email', + }, + ], + default: '', + description: 'Property to use for sorting results.', + }, + { + displayName: 'Query', + name: 'query', + type: 'string', + default: '', + description: `Query string search. Complete documentation is at`, + }, + { + displayName: 'Sort Order', + name: 'sortOrder', + type: 'options', + options: [ + { + name: 'Ascending', + value: 'ASCENDING', + }, + { + name: 'Descending', + value: 'DESCENDING', + }, + ], + default: '', + description: 'Whether to return results in ascending or descending order', + }, + { + displayName: 'User ID', + name: 'userId', + type: 'string', + default: '', + description: `Email or immutable ID of the user if only those groups are to be listed, the given user is a member of. If it's an ID, it should match with the ID of the user object.`, + }, + ], + }, + /* -------------------------------------------------------------------------- */ + /* group:update */ + /* -------------------------------------------------------------------------- */ + { + displayName: 'Group ID', + name: 'groupId', + type: 'string', + required: true, + displayOptions: { + show: { + operation: [ + 'update', + ], + resource: [ + 'group', + ], + }, + }, + default: '', + description: `Identifies the group in the API request. The value can be the group's email address, group alias, or the unique group ID.`, + }, + { + displayName: 'Update Fields', + name: 'updateFields', + type: 'collection', + placeholder: 'Add Field', + default: {}, + displayOptions: { + show: { + operation: [ + 'update', + ], + resource: [ + 'group', + ], + }, + }, + options: [ + { + displayName: 'Description', + name: 'description', + type: 'string', + default: '', + description: `An extended description to help users determine the purpose of a group.
+ For example, you can include information about who should join the group,
+ the types of messages to send to the group, links to FAQs about the group, or related groups`, + }, + { + displayName: 'Email', + name: 'email', + type: 'string', + default: '', + description: `The group's email address. If your account has multiple domains, select the appropriate domain for the email address. The email must be unique.`, + }, + { + displayName: 'Name', + name: 'name', + type: 'string', + default: '', + description: `The group's display name`, + }, + ], + }, +] as INodeProperties[];