diff --git a/packages/nodes-base/credentials/Sms77.credentials.ts b/packages/nodes-base/credentials/Sms77.credentials.ts new file mode 100644 index 0000000000..f098297dff --- /dev/null +++ b/packages/nodes-base/credentials/Sms77.credentials.ts @@ -0,0 +1,17 @@ +import { + ICredentialType, + NodePropertyTypes, +} from 'n8n-workflow'; + +export class Sms77 implements ICredentialType { + name = 'Sms77'; + displayName = 'Sms77'; + properties = [ + { + displayName: 'API Key', + name: 'apiKey', + type: 'string' as NodePropertyTypes, + default: '', + }, + ]; +} diff --git a/packages/nodes-base/nodes/Sms77/GenericFunctions.ts b/packages/nodes-base/nodes/Sms77/GenericFunctions.ts new file mode 100644 index 0000000000..68e9fb281b --- /dev/null +++ b/packages/nodes-base/nodes/Sms77/GenericFunctions.ts @@ -0,0 +1,47 @@ +import {IExecuteFunctions, IHookFunctions,} from 'n8n-core'; +import {IDataObject,} from 'n8n-workflow'; + +/** + * Make an API request to MSG91 + * + * @param {IHookFunctions | IExecuteFunctions} this + * @param {string} method + * @param {string} endpoint + * @param {object} form + * @param {object | undefined} qs + * @returns {Promise} + */ +export async function sms77ApiRequest(this: IHookFunctions | IExecuteFunctions, method: string, endpoint: string, form: IDataObject, qs?: IDataObject): Promise { // tslint:disable-line:no-any + const setPayload = (o?: IDataObject) => { + if (!o) { + o = {}; + } + + o.p = credentials!.apiKey as string; + o.json = 1; + o.sendwith = 'n8n'; + + return o; + }; + + const credentials = this.getCredentials('Sms77'); + if (credentials === undefined) { + throw new Error('No credentials got returned!'); + } + + 'GET' === method ? qs = setPayload(qs) : form = setPayload(form); + + const res = await this.helpers.request({ + form, + json: true, + method, + qs, + uri: `https://gateway.sms77.io/api/${endpoint}`, + }); + + if ('100' !== res.success) { + throw new Error('Invalid sms77 credentials or API error!'); + } + + return res; +} diff --git a/packages/nodes-base/nodes/Sms77/Sms77.node.ts b/packages/nodes-base/nodes/Sms77/Sms77.node.ts new file mode 100644 index 0000000000..c483253d42 --- /dev/null +++ b/packages/nodes-base/nodes/Sms77/Sms77.node.ts @@ -0,0 +1,144 @@ +import {IExecuteFunctions,} from 'n8n-core'; +import {IDataObject, INodeExecutionData, INodeType, INodeTypeDescription,} from 'n8n-workflow'; +import {sms77ApiRequest} from './GenericFunctions'; + +export class Sms77 implements INodeType { + description: INodeTypeDescription = { + displayName: 'Sms77', + name: 'sms77', + icon: 'file:sms77.png', + group: ['transform'], + version: 1, + subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}', + description: 'Send SMS', + defaults: { + name: 'Sms77', + color: '#18D46A', + }, + inputs: ['main'], + outputs: ['main'], + credentials: [ + { + name: 'Sms77', + required: true, + } + ], + properties: [ + { + displayName: 'Resource', + name: 'resource', + type: 'options', + options: [ + { + name: 'SMS', + value: 'sms', + }, + ], + default: 'sms', + description: 'The resource to operate on.', + }, + { + displayName: 'Operation', + name: 'operation', + type: 'options', + displayOptions: { + show: { + resource: [ + 'sms', + ], + }, + }, + options: [ + { + name: 'Send', + value: 'send', + description: 'Send SMS', + }, + ], + default: 'send', + description: 'The operation to perform.', + }, + { + displayName: 'From', + name: 'from', + type: 'string', + default: '', + placeholder: '+4901234567890', + required: false, + displayOptions: { + show: { + operation: [ + 'send', + ], + resource: [ + 'sms', + ], + }, + }, + description: 'The number from which to send the message.', + }, + { + displayName: 'To', + name: 'to', + type: 'string', + default: '', + placeholder: '+49876543210', + required: true, + displayOptions: { + show: { + operation: [ + 'send', + ], + resource: [ + 'sms', + ], + }, + }, + description: 'The number, with coutry code, to which to send the message.', + }, + { + displayName: 'Message', + name: 'message', + type: 'string', + default: '', + required: true, + displayOptions: { + show: { + operation: [ + 'send', + ], + resource: [ + 'sms', + ], + }, + }, + description: 'The message to send', + }, + ], + }; + + async execute(this: IExecuteFunctions): Promise { + const returnData: IDataObject[] = []; + + for (let i = 0; i < this.getInputData().length; i++) { + const resource = this.getNodeParameter('resource', i); + if ('sms' !== resource) { + throw new Error(`The resource "${resource}" is not known!`); + } + + const operation = this.getNodeParameter('operation', i); + if ('send' !== operation) { + throw new Error(`The operation "${operation}" is not known!`); + } + + returnData.push({ + requestId: await sms77ApiRequest.call(this, 'POST', 'sms', {}, { + from: this.getNodeParameter('from', i), + to: this.getNodeParameter('to', i), + text: this.getNodeParameter('message', i), + } as IDataObject) + }); + } + return [this.helpers.returnJsonArray(returnData)]; + } +} diff --git a/packages/nodes-base/nodes/Sms77/sms77.png b/packages/nodes-base/nodes/Sms77/sms77.png new file mode 100644 index 0000000000..9ee5756efe Binary files /dev/null and b/packages/nodes-base/nodes/Sms77/sms77.png differ diff --git a/packages/nodes-base/package.json b/packages/nodes-base/package.json index cb48917d6c..82e0c02223 100644 --- a/packages/nodes-base/package.json +++ b/packages/nodes-base/package.json @@ -92,6 +92,7 @@ "dist/credentials/RundeckApi.credentials.js", "dist/credentials/ShopifyApi.credentials.js", "dist/credentials/SlackApi.credentials.js", + "dist/credentials/Sms77.credentials.js", "dist/credentials/Smtp.credentials.js", "dist/credentials/StripeApi.credentials.js", "dist/credentials/SalesmateApi.credentials.js",