Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SIGNL4 Node: Attachment Support #1356

Merged
merged 6 commits into from
Jan 31, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 13 additions & 6 deletions packages/nodes-base/nodes/Signl4/GenericFunctions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,26 +9,33 @@ import {
import {
OptionsWithUri,
} from 'request';

/**
* Make an API request to SIGNL4
*
* @param {IHookFunctions | IExecuteFunctions} this
* @param {object} message
* @param {string} method
* @param {string} contentType
* @param {string} body
* @param {object} query
* @param {string} teamSecret
* @param {object} options
* @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 = {
headers: {
'Accept': '*/*',
'Content-Type': contentType
},
method,
body,
qs: query,
uri: uri || ``,
json: true,
uri: "https://connect.signl4.com/webhook/" + teamSecret,
json: false,
};

if (!Object.keys(body).length) {
Expand All @@ -40,7 +47,7 @@ export async function SIGNL4ApiRequest(this: IExecuteFunctions, method: string,
options = Object.assign({}, options, option);

try {
return await this.helpers.request!(options);
return JSON.parse(await this.helpers.request!(options));
} catch (error) {

if (error.response && error.response.body && error.response.body.details) {
Expand Down
4 changes: 2 additions & 2 deletions packages/nodes-base/nodes/Signl4/Signl4.node.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"node": "n8n-nodes-base.signl4",
"nodeVersion": "1.0",
"codexVersion": "1.0",
"nodeVersion": "1.1",
"codexVersion": "1.1",
"categories": [
"Communication",
"Development"
Expand Down
103 changes: 71 additions & 32 deletions packages/nodes-base/nodes/Signl4/Signl4.node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -265,36 +265,71 @@ export class Signl4 implements INodeType {
if (operation === 'send') {
const message = this.getNodeParameter('message', i) as string;
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) {
data['X-S4-AlertingScenario'] = additionalFields.alertingScenario as string;
}
if (additionalFields.externalId) {
data['X-S4-ExternalID'] = additionalFields.externalId as string;
// Title
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.filtering) {
data['X-S4-Filtering'] = (additionalFields.filtering as boolean).toString();

// X-S4-Service
if (additionalFields.service) {
data += "------Boundary-cc2050af-c42f-4cda-a0c3-ede7eaa89513\r\n";
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) {
const locationUi = (additionalFields.locationFieldsUi as IDataObject).locationFieldsValues as IDataObject;
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 += "------Boundary-cc2050af-c42f-4cda-a0c3-ede7eaa89513\r\n";
data += "Content-Disposition: form-data; name=\"X-S4-AlertingScenario\"\r\n\r\n";
data += additionalFields.alertingScenario as string + "\r\n";
}
data['X-S4-Status'] = 'new';
if (additionalFields.title) {
data['title'] = additionalFields.title as string;

// 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";
}

const attachments = additionalFields.attachmentsUi as IDataObject;
// 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;
if (attachments) {
if (attachments.attachmentsBinary && items[i].binary) {

Expand All @@ -304,38 +339,39 @@ export class Signl4 implements INodeType {

if (binaryProperty) {

const supportedFileExtension = ['png', 'jpg', 'txt'];
const supportedFileExtension = ['png', 'jpg', 'bmp', 'gif', 'mp3', 'wav'];

if (!supportedFileExtension.includes(binaryProperty.fileExtension as string)) {

throw new Error(`Invalid extension, just ${supportedFileExtension.join(',')} are supported}`);
}

data['file'] = {
value: Buffer.from(binaryProperty.data, BINARY_ENCODING),
options: {
filename: binaryProperty.fileName,
contentType: binaryProperty.mimeType,
},
};
data += "------Boundary-cc2050af-c42f-4cda-a0c3-ede7eaa89513\r\n";
data += "Content-Disposition: form-data; name=\"" + binaryProperty.fileName + "\"; filename=\"" + binaryProperty.fileName + "\"\r\n";
data += "Content-Type: " + binaryProperty.mimeType + "\r\n";
data += "Content-Transfer-Encoding: base64\r\n\r\n";

data += Buffer.from(binaryProperty.data, 'base64').toString('base64') + "\r\n";

} else {
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 endpoint = `https://connect.signl4.com/webhook/${credentials?.teamSecret}`;
const teamSecret = credentials?.teamSecret as string;

responseData = await SIGNL4ApiRequest.call(
this,
'POST',
'',
'multipart/form-data; boundary=----Boundary-cc2050af-c42f-4cda-a0c3-ede7eaa89513',
data,
{},
endpoint,
teamSecret,
{},
);
}
Expand All @@ -347,18 +383,21 @@ export class Signl4 implements INodeType {
data['X-S4-ExternalID'] = this.getNodeParameter('externalId', i) as string;

data['X-S4-Status'] = 'resolved';

// Source system
data['X-S4-SourceSystem'] = 'n8n';

const credentials = this.getCredentials('signl4Api');

const endpoint = `https://connect.signl4.com/webhook/${credentials?.teamSecret}`;
const teamSecret = credentials?.teamSecret as string;

responseData = await SIGNL4ApiRequest.call(
this,
'POST',
'',
data,
'application/json',
JSON.stringify(data),
{},
endpoint,
teamSecret,
{},
);
}
Expand Down