SIGNL4: Attachment Support

Attachment support added to SIGNL4.
This commit is contained in:
rons4 2021-01-19 13:25:21 +01:00
parent 9911348166
commit 06282ff7de
3 changed files with 82 additions and 38 deletions

View file

@ -9,6 +9,10 @@ import {
import { import {
OptionsWithUri, OptionsWithUri,
} from 'request'; } from 'request';
const https = require('https')
//import * as https from 'https';
/** /**
* Make an API request to SIGNL4 * Make an API request to SIGNL4
@ -18,17 +22,18 @@ import {
* @returns {Promise<any>} * @returns {Promise<any>}
*/ */
export async function SIGNL4ApiRequest(this: IExecuteFunctions, method: string, resource: string, body: any = {}, query: IDataObject = {}, uri?: string, option: IDataObject = {}): Promise<any> { // tslint:disable-line:no-any export async function SIGNL4ApiRequest(this: IExecuteFunctions, method: string, contentType: string, body: string, query: IDataObject = {}, teamSecret?: string, option: IDataObject = {}): Promise<any> { // tslint:disable-line:no-any
let options: OptionsWithUri = { let options: OptionsWithUri = {
headers: { headers: {
'Accept': '*/*', 'Accept': '*/*',
'Content-Type': contentType
}, },
method, method,
body, body,
qs: query, qs: query,
uri: uri || ``, uri: "https://connect.signl4.com/webhook/" + teamSecret,
json: true, json: false,
}; };
if (!Object.keys(body).length) { if (!Object.keys(body).length) {

View file

@ -1,7 +1,7 @@
{ {
"node": "n8n-nodes-base.signl4", "node": "n8n-nodes-base.signl4",
"nodeVersion": "1.0", "nodeVersion": "1.1",
"codexVersion": "1.0", "codexVersion": "1.1",
"categories": [ "categories": [
"Communication", "Communication",
"Development" "Development"

View file

@ -265,36 +265,71 @@ export class Signl4 implements INodeType {
if (operation === 'send') { if (operation === 'send') {
const message = this.getNodeParameter('message', i) as string; const message = this.getNodeParameter('message', i) as string;
const additionalFields = this.getNodeParameter('additionalFields',i) as IDataObject; const additionalFields = this.getNodeParameter('additionalFields',i) as IDataObject;
let data = "";
const data: IDataObject = { // Message
message, data += "------Boundary-cc2050af-c42f-4cda-a0c3-ede7eaa89513\r\n";
}; data += "Content-Disposition: form-data; name=\"message\"\r\n\r\n";
data += message + "\r\n";
if (additionalFields.alertingScenario) { // Title
data['X-S4-AlertingScenario'] = additionalFields.alertingScenario as string; if (additionalFields.title) {
data += "------Boundary-cc2050af-c42f-4cda-a0c3-ede7eaa89513\r\n";
data += "Content-Disposition: form-data; name=\"title\"\r\n\r\n";
data += additionalFields.title as string + "\r\n";
} }
if (additionalFields.externalId) {
data['X-S4-ExternalID'] = additionalFields.externalId as string; // X-S4-Service
} if (additionalFields.service) {
if (additionalFields.filtering) { data += "------Boundary-cc2050af-c42f-4cda-a0c3-ede7eaa89513\r\n";
data['X-S4-Filtering'] = (additionalFields.filtering as boolean).toString(); data += "Content-Disposition: form-data; name=\"X-S4-Service\"\r\n\r\n";
data += additionalFields.service as string + "\r\n";
} }
// X-S4-Location
if (additionalFields.locationFieldsUi) { if (additionalFields.locationFieldsUi) {
const locationUi = (additionalFields.locationFieldsUi as IDataObject).locationFieldsValues as IDataObject; const locationUi = (additionalFields.locationFieldsUi as IDataObject).locationFieldsValues as IDataObject;
if (locationUi) { if (locationUi) {
data['X-S4-Location'] = `${locationUi.latitude},${locationUi.longitude}`; data += "------Boundary-cc2050af-c42f-4cda-a0c3-ede7eaa89513\r\n";
data += "Content-Disposition: form-data; name=\"X-S4-Location\"\r\n\r\n";
data += `${locationUi.latitude},${locationUi.longitude}` + "\r\n";
} }
} }
if (additionalFields.service) {
data['X-S4-Service'] = additionalFields.service as string; // X-S4-AlertingScenario
} if (additionalFields.alertingScenario) {
data['X-S4-Status'] = 'new'; data += "------Boundary-cc2050af-c42f-4cda-a0c3-ede7eaa89513\r\n";
if (additionalFields.title) { data += "Content-Disposition: form-data; name=\"X-S4-AlertingScenario\"\r\n\r\n";
data['title'] = additionalFields.title as string; data += additionalFields.alertingScenario as string + "\r\n";
} }
// X-S4-Filtering
if (additionalFields.filtering) {
data += "------Boundary-cc2050af-c42f-4cda-a0c3-ede7eaa89513\r\n";
data += "Content-Disposition: form-data; name=\"X-S4-Filtering\"\r\n\r\n";
data += (additionalFields.filtering as boolean).toString() + "\r\n";
}
// X-S4-ExternalID
if (additionalFields.externalId) {
data += "------Boundary-cc2050af-c42f-4cda-a0c3-ede7eaa89513\r\n";
data += "Content-Disposition: form-data; name=\"X-S4-ExternalID\"\r\n\r\n";
data += additionalFields.externalId as string + "\r\n";
}
// Status
data += "------Boundary-cc2050af-c42f-4cda-a0c3-ede7eaa89513\r\n";
data += "Content-Disposition: form-data; name=\"X-S4-Status\"\r\n\r\n";
data += "new\r\n";
// Source System
data += "------Boundary-cc2050af-c42f-4cda-a0c3-ede7eaa89513\r\n";
data += "Content-Disposition: form-data; name=\"X-S4-SourceSystem\"\r\n\r\n";
data += "n8n\r\n";
// Attachments
const attachments = additionalFields.attachmentsUi as IDataObject; const attachments = additionalFields.attachmentsUi as IDataObject;
if (attachments) { if (attachments) {
if (attachments.attachmentsBinary && items[i].binary) { if (attachments.attachmentsBinary && items[i].binary) {
@ -304,38 +339,39 @@ export class Signl4 implements INodeType {
if (binaryProperty) { if (binaryProperty) {
const supportedFileExtension = ['png', 'jpg', 'txt']; const supportedFileExtension = ['png', 'jpg', 'bmp', 'gif', 'mp3', 'wav'];
if (!supportedFileExtension.includes(binaryProperty.fileExtension as string)) { if (!supportedFileExtension.includes(binaryProperty.fileExtension as string)) {
throw new Error(`Invalid extension, just ${supportedFileExtension.join(',')} are supported}`); throw new Error(`Invalid extension, just ${supportedFileExtension.join(',')} are supported}`);
} }
data['file'] = { data += "------Boundary-cc2050af-c42f-4cda-a0c3-ede7eaa89513\r\n";
value: Buffer.from(binaryProperty.data, BINARY_ENCODING), data += "Content-Disposition: form-data; name=\"" + binaryProperty.fileName + "\"; filename=\"" + binaryProperty.fileName + "\"\r\n";
options: { data += "Content-Type: " + binaryProperty.mimeType + "\r\n";
filename: binaryProperty.fileName, data += "Content-Transfer-Encoding: base64\r\n\r\n";
contentType: binaryProperty.mimeType,
}, data += Buffer.from(binaryProperty.data, 'base64').toString('base64') + "\r\n";
};
} else { } else {
throw new Error(`Binary property ${propertyName} does not exist on input`); throw new Error(`Binary property ${propertyName} does not exist on input`);
} }
} }
} }
data += "------Boundary-cc2050af-c42f-4cda-a0c3-ede7eaa89513--\r\n";
const credentials = this.getCredentials('signl4Api'); const credentials = this.getCredentials('signl4Api');
const endpoint = `https://connect.signl4.com/webhook/${credentials?.teamSecret}`; const teamSecret = credentials?.teamSecret as string;
responseData = await SIGNL4ApiRequest.call( responseData = await SIGNL4ApiRequest.call(
this, this,
'POST', 'POST',
'', 'multipart/form-data; boundary=----Boundary-cc2050af-c42f-4cda-a0c3-ede7eaa89513',
data, data,
{}, {},
endpoint, teamSecret,
{}, {},
); );
} }
@ -347,18 +383,21 @@ export class Signl4 implements INodeType {
data['X-S4-ExternalID'] = this.getNodeParameter('externalId', i) as string; data['X-S4-ExternalID'] = this.getNodeParameter('externalId', i) as string;
data['X-S4-Status'] = 'resolved'; data['X-S4-Status'] = 'resolved';
// Source system
data['X-S4-SourceSystem'] = 'n8n';
const credentials = this.getCredentials('signl4Api'); const credentials = this.getCredentials('signl4Api');
const endpoint = `https://connect.signl4.com/webhook/${credentials?.teamSecret}`; const teamSecret = credentials?.teamSecret as string;
responseData = await SIGNL4ApiRequest.call( responseData = await SIGNL4ApiRequest.call(
this, this,
'POST', 'POST',
'', 'application/json',
data, JSON.stringify(data),
{}, {},
endpoint, teamSecret,
{}, {},
); );
} }