From 8081a9e91b52612b7a2eb6e911495613b18ee0a4 Mon Sep 17 00:00:00 2001 From: d3no Date: Tue, 25 Jan 2022 20:04:42 +0800 Subject: [PATCH 1/4] add dlr url column add dlr url(delivery report URl) column. Allow user set the endpoint to receive the report --- .../nodes-base/nodes/Mocean/Mocean.node.ts | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/packages/nodes-base/nodes/Mocean/Mocean.node.ts b/packages/nodes-base/nodes/Mocean/Mocean.node.ts index 959610c9eb72b..2cc0abbf9bef9 100644 --- a/packages/nodes-base/nodes/Mocean/Mocean.node.ts +++ b/packages/nodes-base/nodes/Mocean/Mocean.node.ts @@ -171,6 +171,26 @@ export class Mocean implements INodeType { }, description: 'The message to send', }, + + { + displayName: 'Delivery Report URL', + name: 'dlr-url', + type: 'string', + default: '', + placeholder: '', + required: false, + displayOptions: { + show: { + operation: [ + 'send', + ], + resource: [ + 'sms', + ], + }, + }, + description: 'The message to send', + }, ], }; @@ -185,6 +205,7 @@ export class Mocean implements INodeType { let requesetMethod: string; let resource: string; let text: string; + let dlrUrl: string; let dataKey: string; // For Post let body: IDataObject; @@ -198,6 +219,7 @@ export class Mocean implements INodeType { resource = this.getNodeParameter('resource', itemIndex, '') as string; operation = this.getNodeParameter('operation',itemIndex,'') as string; text = this.getNodeParameter('message', itemIndex, '') as string; + dlrUrl = this.getNodeParameter('dlr-url',itemIndex, '') as string; requesetMethod = 'POST'; body['mocean-from'] = this.getNodeParameter('from', itemIndex, '') as string; body['mocean-to'] = this.getNodeParameter('to', itemIndex, '') as string; @@ -218,6 +240,10 @@ export class Mocean implements INodeType { } else if(resource === 'sms') { dataKey = 'messages'; body['mocean-text'] = text; + if (dlrUrl !== '') { + body['mocean-dlr-url'] = dlrUrl; + body['mocean-dlr-mask'] = '1'; + } endpoint = '/rest/2/sms'; } else { throw new NodeOperationError(this.getNode(), `Unknown resource ${resource}`); From 3173197ad2251bf5988402b60866dc5028b69dc6 Mon Sep 17 00:00:00 2001 From: d3no Date: Wed, 16 Feb 2022 16:24:06 +0800 Subject: [PATCH 2/4] update update delivery report url description --- packages/nodes-base/nodes/Mocean/Mocean.node.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/nodes-base/nodes/Mocean/Mocean.node.ts b/packages/nodes-base/nodes/Mocean/Mocean.node.ts index 2cc0abbf9bef9..6fbc53f6b9c60 100644 --- a/packages/nodes-base/nodes/Mocean/Mocean.node.ts +++ b/packages/nodes-base/nodes/Mocean/Mocean.node.ts @@ -189,7 +189,7 @@ export class Mocean implements INodeType { ], }, }, - description: 'The message to send', + description: 'Delivery report URL', }, ], From 274b692c75618991b037c6d6186ba69826b8f3f9 Mon Sep 17 00:00:00 2001 From: Michael Kret Date: Wed, 30 Mar 2022 13:34:40 +0300 Subject: [PATCH 3/4] :zap: fixed nodelinter issues, added credential test, replaced icon --- .../nodes/Mocean/GenericFunctions.ts | 4 +- .../nodes-base/nodes/Mocean/Mocean.node.ts | 55 ++++++++++++++++-- packages/nodes-base/nodes/Mocean/mocean.png | Bin 669 -> 0 bytes packages/nodes-base/nodes/Mocean/mocean.svg | 24 ++++++++ 4 files changed, 75 insertions(+), 8 deletions(-) delete mode 100644 packages/nodes-base/nodes/Mocean/mocean.png create mode 100644 packages/nodes-base/nodes/Mocean/mocean.svg diff --git a/packages/nodes-base/nodes/Mocean/GenericFunctions.ts b/packages/nodes-base/nodes/Mocean/GenericFunctions.ts index 3951df2deed51..52849300ae7b7 100644 --- a/packages/nodes-base/nodes/Mocean/GenericFunctions.ts +++ b/packages/nodes-base/nodes/Mocean/GenericFunctions.ts @@ -4,7 +4,7 @@ import { } from 'n8n-core'; import { - IDataObject, NodeApiError, NodeOperationError, + IDataObject, JsonObject, NodeApiError, NodeOperationError, } from 'n8n-workflow'; /** @@ -47,6 +47,6 @@ export async function moceanApiRequest(this: IHookFunctions | IExecuteFunctions, try { return await this.helpers.request(options); } catch (error) { - throw new NodeApiError(this.getNode(), error); + throw new NodeApiError(this.getNode(), (error as JsonObject)); } } diff --git a/packages/nodes-base/nodes/Mocean/Mocean.node.ts b/packages/nodes-base/nodes/Mocean/Mocean.node.ts index 6fbc53f6b9c60..f808c612bc192 100644 --- a/packages/nodes-base/nodes/Mocean/Mocean.node.ts +++ b/packages/nodes-base/nodes/Mocean/Mocean.node.ts @@ -1,11 +1,16 @@ import { IExecuteFunctions } from 'n8n-core'; import { + ICredentialsDecrypted, + ICredentialTestFunctions, IDataObject, + INodeCredentialTestResult, INodeExecutionData, INodeType, INodeTypeDescription, + JsonObject, NodeOperationError, } from 'n8n-workflow'; +import { OptionsWithUri } from 'request'; import {moceanApiRequest} from './GenericFunctions'; @@ -14,7 +19,8 @@ export class Mocean implements INodeType { description: INodeTypeDescription = { displayName: 'Mocean', name: 'mocean', - icon: 'file:mocean.png', + subtitle: `={{$parameter["operation"] + ": " + $parameter["resource"]}}`, + icon: 'file:mocean.svg', group: ['transform'], version: 1, description: 'Send SMS and voice messages via Mocean', @@ -27,6 +33,7 @@ export class Mocean implements INodeType { { name: 'moceanApi', required: true, + testedBy: 'moceanApiTest', }, ], properties: [ @@ -36,6 +43,7 @@ export class Mocean implements INodeType { displayName: 'Resource', name: 'resource', type: 'options', + noDataExpression: true, options:[ { name: 'SMS', @@ -52,6 +60,7 @@ export class Mocean implements INodeType { displayName: 'Operation', name: 'operation', type: 'options', + noDataExpression: true, displayOptions: { show: { resource: [ @@ -68,7 +77,7 @@ export class Mocean implements INodeType { }, ], default: 'send', - description: 'The operation to perform.', + description: 'Operation to perform', }, { displayName: 'From', @@ -88,7 +97,7 @@ export class Mocean implements INodeType { ], }, }, - description: 'The number to which to send the message', + description: 'Number to which to send the message', }, { @@ -109,7 +118,7 @@ export class Mocean implements INodeType { ], }, }, - description: 'The number from which to send the message', + description: 'Number from which to send the message', }, { @@ -169,7 +178,7 @@ export class Mocean implements INodeType { ], }, }, - description: 'The message to send', + description: 'Message to send', }, { @@ -192,7 +201,41 @@ export class Mocean implements INodeType { description: 'Delivery report URL', }, ], + }; + + methods = { + credentialTest: { + async moceanApiTest(this: ICredentialTestFunctions, credential: ICredentialsDecrypted): Promise { + const credentials = credential.data; + + const body: IDataObject = {}; + body['mocean-api-key'] = credentials!['mocean-api-key']; + body['mocean-api-secret'] = credentials!['mocean-api-secret']; + body['mocean-to'] = '6012356789'; + body['mocean-resp-format'] = 'JSON'; + + const options = { + method: 'POST', + form: body, + qs: {}, + uri: `https://rest.moceanapi.com/rest/2/nl`, + json: true, + }; + try { + await this.helpers.request!(options); + } catch (error) { + return { + status: 'Error', + message: `Connection details not valid: ${(error as JsonObject).message}`, + }; + } + return { + status: 'OK', + message: 'Authentication successful!', + }; + }, + }, }; @@ -262,7 +305,7 @@ export class Mocean implements INodeType { } } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + returnData.push({ error: (error as JsonObject).message }); continue; } throw error; diff --git a/packages/nodes-base/nodes/Mocean/mocean.png b/packages/nodes-base/nodes/Mocean/mocean.png deleted file mode 100644 index f660c71e0a0f226599a928dd8d4eaac3f5871533..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 669 zcmV;O0%HA%P)hSn{p3q{8 z#+kF*Q-HxGU9lcmt`bkG`uzR)`TXzm`O4SqkF3{cj>t%Ny*zHYF=n;9&E~ku<&>}4 zPJF;Ya=QKg{@Ua6)Zg#U+wH~F>cG(Gp10hBqSA7g%r0cKDq*wW==86|;)jA`y^ijw0004`Nkl9!xpZ_;Q};f zDJ46qu39~iW9+M&^XNAC5k2>Sq4I8tkDN?YHXCA}Ma7&Yv{~oOKbruwk7GIRqc;*8 z2JR^65%3{LtC!gsP>?O*ZP@kt{mnMBlVUI^`Z9vEQb|lc-ed37HMSjqe9(WxRqWcH@u1SwG@8T^3l~SxJfPC1pz=Kb)x?$!?sSq^ zPfli9+~T%syqmY#KQXsH7(V)>tt*-0PrHe zHEw~*nEsB~K&@7*)xN0T#P1wvws5Li00000NkvXXu0mjf D0<%bt diff --git a/packages/nodes-base/nodes/Mocean/mocean.svg b/packages/nodes-base/nodes/Mocean/mocean.svg new file mode 100644 index 0000000000000..ed5d0de24ef70 --- /dev/null +++ b/packages/nodes-base/nodes/Mocean/mocean.svg @@ -0,0 +1,24 @@ + + + + +Created by potrace 1.16, written by Peter Selinger 2001-2019 + + + + + From 92b724b402095c73e6e554cfebe06e8714b81595 Mon Sep 17 00:00:00 2001 From: ricardo Date: Wed, 30 Mar 2022 12:24:23 -0400 Subject: [PATCH 4/4] :zap: Improvements --- .../nodes-base/nodes/Mocean/Mocean.node.ts | 63 ++++++++++--------- 1 file changed, 34 insertions(+), 29 deletions(-) diff --git a/packages/nodes-base/nodes/Mocean/Mocean.node.ts b/packages/nodes-base/nodes/Mocean/Mocean.node.ts index f808c612bc192..06009320e5b20 100644 --- a/packages/nodes-base/nodes/Mocean/Mocean.node.ts +++ b/packages/nodes-base/nodes/Mocean/Mocean.node.ts @@ -1,4 +1,7 @@ -import { IExecuteFunctions } from 'n8n-core'; +import { + IExecuteFunctions, +} from 'n8n-core'; + import { ICredentialsDecrypted, ICredentialTestFunctions, @@ -10,10 +13,10 @@ import { JsonObject, NodeOperationError, } from 'n8n-workflow'; -import { OptionsWithUri } from 'request'; - -import {moceanApiRequest} from './GenericFunctions'; +import { + moceanApiRequest, +} from './GenericFunctions'; export class Mocean implements INodeType { description: INodeTypeDescription = { @@ -44,7 +47,7 @@ export class Mocean implements INodeType { name: 'resource', type: 'options', noDataExpression: true, - options:[ + options: [ { name: 'SMS', value: 'sms', @@ -125,7 +128,7 @@ export class Mocean implements INodeType { displayName: 'Language', name: 'language', type: 'options', - options:[ + options: [ { name: 'Chinese Mandarin (China)', value: 'cmn-CN', @@ -180,14 +183,11 @@ export class Mocean implements INodeType { }, description: 'Message to send', }, - { - displayName: 'Delivery Report URL', - name: 'dlr-url', - type: 'string', - default: '', - placeholder: '', - required: false, + displayName: 'Options', + name: 'options', + type: 'collection', + placeholder: 'Add Field', displayOptions: { show: { operation: [ @@ -198,7 +198,17 @@ export class Mocean implements INodeType { ], }, }, - description: 'Delivery report URL', + default: {}, + options: [ + { + displayName: 'Delivery Report URL', + name: 'dlrUrl', + type: 'string', + default: '', + placeholder: '', + description: 'Delivery report URL', + }, + ], }, ], }; @@ -207,21 +217,16 @@ export class Mocean implements INodeType { credentialTest: { async moceanApiTest(this: ICredentialTestFunctions, credential: ICredentialsDecrypted): Promise { const credentials = credential.data; - - const body: IDataObject = {}; - body['mocean-api-key'] = credentials!['mocean-api-key']; - body['mocean-api-secret'] = credentials!['mocean-api-secret']; - body['mocean-to'] = '6012356789'; - body['mocean-resp-format'] = 'JSON'; + const query: IDataObject = {}; + query['mocean-api-key'] = credentials!['mocean-api-key']; + query['mocean-api-secret'] = credentials!['mocean-api-secret']; const options = { - method: 'POST', - form: body, - qs: {}, - uri: `https://rest.moceanapi.com/rest/2/nl`, + method: 'GET', + qs: query, + uri: `https://rest.moceanapi.com/rest/2/account/balance`, json: true, }; - try { await this.helpers.request!(options); } catch (error) { @@ -260,9 +265,8 @@ export class Mocean implements INodeType { qs = {}; try { resource = this.getNodeParameter('resource', itemIndex, '') as string; - operation = this.getNodeParameter('operation',itemIndex,'') as string; + operation = this.getNodeParameter('operation', itemIndex, '') as string; text = this.getNodeParameter('message', itemIndex, '') as string; - dlrUrl = this.getNodeParameter('dlr-url',itemIndex, '') as string; requesetMethod = 'POST'; body['mocean-from'] = this.getNodeParameter('from', itemIndex, '') as string; body['mocean-to'] = this.getNodeParameter('to', itemIndex, '') as string; @@ -280,7 +284,8 @@ export class Mocean implements INodeType { dataKey = 'voice'; body['mocean-command'] = JSON.stringify(command); endpoint = '/rest/2/voice/dial'; - } else if(resource === 'sms') { + } else if (resource === 'sms') { + dlrUrl = this.getNodeParameter('options.dlrUrl', itemIndex, '') as string; dataKey = 'messages'; body['mocean-text'] = text; if (dlrUrl !== '') { @@ -293,7 +298,7 @@ export class Mocean implements INodeType { } if (operation === 'send') { - const responseData = await moceanApiRequest.call(this,requesetMethod,endpoint,body,qs); + const responseData = await moceanApiRequest.call(this, requesetMethod, endpoint, body, qs); for (const item of responseData[dataKey] as IDataObject[]) { item.type = resource;