diff --git a/packages/nodes-base/nodes/Wise/Wise.node.ts b/packages/nodes-base/nodes/Wise/Wise.node.ts index 44a9e478488a5..85862a8730a3d 100644 --- a/packages/nodes-base/nodes/Wise/Wise.node.ts +++ b/packages/nodes-base/nodes/Wise/Wise.node.ts @@ -15,6 +15,8 @@ import { v4 as uuid } from 'uuid'; import { accountFields, accountOperations, + activityFields, + activityOperations, exchangeRateFields, exchangeRateOperations, profileFields, @@ -67,6 +69,10 @@ export class Wise implements INodeType { name: 'Account', value: 'account', }, + { + name: 'Activity', + value: 'activity', + }, { name: 'Exchange Rate', value: 'exchangeRate', @@ -92,6 +98,8 @@ export class Wise implements INodeType { }, ...accountOperations, ...accountFields, + ...activityOperations, + ...activityFields, ...exchangeRateOperations, ...exchangeRateFields, ...profileOperations, @@ -261,6 +269,92 @@ export class Wise implements INodeType { binaryOutput = true; } } + } else if (resource === 'activity') { + // ********************************************************************* + // activity + // ********************************************************************* + + if (operation === 'getAll') { + // ---------------------------------- + // activity: getAll + // ---------------------------------- + + // https://docs.wise.com/api-docs/api-reference/activity + + const profileId = this.getNodeParameter('profileId', i); + const returnAll = this.getNodeParameter('returnAll', i); + const filters = this.getNodeParameter('filters', i) as IDataObject; + + const qs: IDataObject = {}; + + if (filters.since) { + qs.since = moment + .tz(filters.since as string, timezone) + .utc() + .format(); + } + + if (returnAll) { + const allActivities: IDataObject[] = []; + let cursor: string | null = null; + + do { + qs.size = 100; + if (cursor) { + qs.cursor = cursor; + } + + const response = (await wiseApiRequest.call( + this, + 'GET', + `v1/profiles/${profileId}/activities`, + {}, + qs, + )) as { activities: IDataObject[]; cursor: string | null }; + + let activities = response.activities || []; + + if (filters.status) { + activities = activities.filter((a: IDataObject) => a.status === filters.status); + } + + allActivities.push(...activities); + cursor = response.cursor; + } while (cursor); + + responseData = allActivities; + } else { + const limit = this.getNodeParameter('limit', i) as number; + const matchingActivities: IDataObject[] = []; + let cursor: string | null = null; + + do { + qs.size = 100; + if (cursor) { + qs.cursor = cursor; + } + + const response = (await wiseApiRequest.call( + this, + 'GET', + `v1/profiles/${profileId}/activities`, + {}, + qs, + )) as { activities: IDataObject[]; cursor: string | null }; + + let activities = response.activities || []; + + if (filters.status) { + activities = activities.filter((a: IDataObject) => a.status === filters.status); + } + + matchingActivities.push(...activities); + cursor = response.cursor; + } while (cursor && matchingActivities.length < limit); + + responseData = matchingActivities.slice(0, limit); + } + } } else if (resource === 'exchangeRate') { // ********************************************************************* // exchangeRate diff --git a/packages/nodes-base/nodes/Wise/descriptions/ActivityDescription.ts b/packages/nodes-base/nodes/Wise/descriptions/ActivityDescription.ts new file mode 100644 index 0000000000000..0632decfe47a6 --- /dev/null +++ b/packages/nodes-base/nodes/Wise/descriptions/ActivityDescription.ts @@ -0,0 +1,121 @@ +import type { INodeProperties } from 'n8n-workflow'; + +export const activityOperations: INodeProperties[] = [ + { + displayName: 'Operation', + name: 'operation', + type: 'options', + noDataExpression: true, + default: 'getAll', + options: [ + { + name: 'Get Many', + value: 'getAll', + action: 'Get many activities', + }, + ], + displayOptions: { + show: { + resource: ['activity'], + }, + }, + }, +]; + +export const activityFields: INodeProperties[] = [ + // ---------------------------------- + // activity: getAll + // ---------------------------------- + { + displayName: 'Profile Name or ID', + name: 'profileId', + type: 'options', + required: true, + default: [], + typeOptions: { + loadOptionsMethod: 'getProfiles', + }, + description: + 'ID of the user profile to retrieve activities for. Choose from the list, or specify an ID using an expression.', + displayOptions: { + show: { + resource: ['activity'], + operation: ['getAll'], + }, + }, + }, + { + displayName: 'Return All', + name: 'returnAll', + type: 'boolean', + default: false, + description: 'Whether to return all results or only up to a given limit', + displayOptions: { + show: { + resource: ['activity'], + operation: ['getAll'], + }, + }, + }, + { + displayName: 'Limit', + name: 'limit', + type: 'number', + default: 50, + description: 'Max number of results to return', + typeOptions: { + minValue: 1, + maxValue: 100, + }, + displayOptions: { + show: { + resource: ['activity'], + operation: ['getAll'], + returnAll: [false], + }, + }, + }, + { + displayName: 'Filters', + name: 'filters', + type: 'collection', + placeholder: 'Add Filter', + default: {}, + displayOptions: { + show: { + resource: ['activity'], + operation: ['getAll'], + }, + }, + options: [ + { + displayName: 'Since', + name: 'since', + type: 'dateTime', + default: '', + description: 'Only return activities created after this date', + }, + { + displayName: 'Status', + name: 'status', + type: 'options', + default: '', + description: 'Filter by activity status', + options: [ + { + name: 'All', + value: '', + }, + { + name: 'Completed', + value: 'COMPLETED', + }, + { + name: 'Pending', + value: 'PENDING', + }, + ], + }, + ], + }, +]; diff --git a/packages/nodes-base/nodes/Wise/descriptions/index.ts b/packages/nodes-base/nodes/Wise/descriptions/index.ts index 0e6fc503950b2..1093992ec5630 100644 --- a/packages/nodes-base/nodes/Wise/descriptions/index.ts +++ b/packages/nodes-base/nodes/Wise/descriptions/index.ts @@ -1,4 +1,5 @@ export * from './AccountDescription'; +export * from './ActivityDescription'; export * from './ExchangeRateDescription'; export * from './ProfileDescription'; export * from './QuoteDescription';