Add Line-Node (#1137)

*  Line-Node

*  Improvements
This commit is contained in:
Ricardo Espinoza 2020-11-10 13:08:48 -05:00 committed by GitHub
parent 2d74ebb9ab
commit 1ce19de200
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 419 additions and 0 deletions

View file

@ -0,0 +1,47 @@
import {
ICredentialType,
NodePropertyTypes,
} from 'n8n-workflow';
export class LineNotifyOAuth2Api implements ICredentialType {
name = 'lineNotifyOAuth2Api';
extends = [
'oAuth2Api',
];
displayName = 'Line Notify OAuth2 API';
properties = [
{
displayName: 'Authorization URL',
name: 'authUrl',
type: 'hidden' as NodePropertyTypes,
default: 'https://notify-bot.line.me/oauth/authorize',
required: true,
},
{
displayName: 'Access Token URL',
name: 'accessTokenUrl',
type: 'hidden' as NodePropertyTypes,
default: 'https://notify-bot.line.me/oauth/token',
required: true,
},
{
displayName: 'Scope',
name: 'scope',
type: 'hidden' as NodePropertyTypes,
default: 'notify',
required: true,
},
{
displayName: 'Auth URI Query Parameters',
name: 'authQueryParameters',
type: 'hidden' as NodePropertyTypes,
default: '',
},
{
displayName: 'Authentication',
name: 'authentication',
type: 'hidden' as NodePropertyTypes,
default: 'body',
},
];
}

View file

@ -0,0 +1,50 @@
import {
OptionsWithUri,
} from 'request';
import {
IExecuteFunctions,
IExecuteSingleFunctions,
IHookFunctions,
ILoadOptionsFunctions,
} from 'n8n-core';
import {
IDataObject,
} from 'n8n-workflow';
export async function lineApiRequest(this: IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions | IHookFunctions, method: string, resource: string, body: any = {}, qs: IDataObject = {}, uri?: string, option: IDataObject = {}): Promise<any> { // tslint:disable-line:no-any
let options: OptionsWithUri = {
headers: {
'Content-Type': 'application/json',
},
method,
body,
qs,
uri: uri || ``,
json: true,
};
options = Object.assign({}, options, option);
try {
if (Object.keys(body).length === 0) {
delete options.body;
}
//@ts-ignore
return await this.helpers.requestOAuth2.call(this, 'lineNotifyOAuth2Api', options, { tokenType: 'Bearer' });
} catch (error) {
let errorMessage;
if (error.response && error.response.body && error.response.body.message) {
errorMessage = error.response.body.message;
throw new Error(`Line error response [${error.statusCode}]: ${errorMessage}`);
}
throw error;
}
}

View file

@ -0,0 +1,144 @@
import {
BINARY_ENCODING,
IExecuteFunctions,
} from 'n8n-core';
import {
IBinaryKeyData,
IDataObject,
INodeExecutionData,
INodeType,
INodeTypeDescription,
} from 'n8n-workflow';
import {
lineApiRequest,
} from './GenericFunctions';
import {
notificationFields,
notificationOperations,
} from './NotificationDescription';
export class Line implements INodeType {
description: INodeTypeDescription = {
displayName: 'Line',
name: 'line',
icon: 'file:line.png',
group: ['input'],
version: 1,
subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}',
description: 'Consume Line API.',
defaults: {
name: 'Line',
color: '#00b900',
},
inputs: ['main'],
outputs: ['main'],
credentials: [
{
name: 'lineNotifyOAuth2Api',
required: true,
displayOptions: {
show: {
resource: [
'notification',
],
},
},
},
],
properties: [
{
displayName: 'Resource',
name: 'resource',
type: 'options',
options: [
{
name: 'Notification',
value: 'notification',
},
],
default: 'notification',
description: 'The resource to operate on.',
},
...notificationOperations,
...notificationFields,
],
};
async execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {
const items = this.getInputData();
const returnData: IDataObject[] = [];
const length = (items.length as unknown) as number;
const qs: IDataObject = {};
let responseData;
const resource = this.getNodeParameter('resource', 0) as string;
const operation = this.getNodeParameter('operation', 0) as string;
for (let i = 0; i < length; i++) {
if (resource === 'notification') {
//https://notify-bot.line.me/doc/en/
if (operation === 'send') {
const message = this.getNodeParameter('message', i) as string;
const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject;
const body: IDataObject = {
message,
};
Object.assign(body, additionalFields);
if (body.hasOwnProperty('notificationDisabled')) {
body.notificationDisabled = (body.notificationDisabled) ? 'true' : 'false';
}
if (body.stickerUi) {
const sticker = (body.stickerUi as IDataObject).stickerValue as IDataObject;
if (sticker) {
body.stickerId = sticker.stickerId;
body.stickerPackageId = sticker.stickerPackageId;
}
delete body.stickerUi;
}
if (body.imageUi) {
const image = (body.imageUi as IDataObject).imageValue as IDataObject;
if (image && image.binaryData === true) {
if (items[i].binary === undefined) {
throw new Error('No binary data exists on item!');
}
//@ts-ignore
if (items[i].binary[image.binaryProperty] === undefined) {
throw new Error(`No binary data property "${image.binaryProperty}" does not exists on item!`);
}
const binaryData = (items[i].binary as IBinaryKeyData)[image.binaryProperty as string];
body.imageFile = {
value: Buffer.from(binaryData.data, BINARY_ENCODING),
options: {
filename: binaryData.fileName,
},
};
} else {
body.imageFullsize = image.imageFullsize;
body.imageThumbnail = image.imageThumbnail;
}
delete body.imageUi;
}
responseData = await lineApiRequest.call(this, 'POST', '', {}, {}, 'https://notify-api.line.me/api/notify', { formData: body });
}
}
}
if (Array.isArray(responseData)) {
returnData.push.apply(returnData, responseData as IDataObject[]);
} else if (responseData !== undefined) {
returnData.push(responseData as IDataObject);
}
return [this.helpers.returnJsonArray(returnData)];
}
}

View file

@ -0,0 +1,176 @@
import {
INodeProperties,
} from 'n8n-workflow';
export const notificationOperations = [
{
displayName: 'Operation',
name: 'operation',
type: 'options',
displayOptions: {
show: {
resource: [
'notification',
],
},
},
options: [
{
name: 'Send',
value: 'send',
description: 'Sends notifications to users or groups',
},
],
default: 'send',
description: 'The operation to perform.',
},
] as INodeProperties[];
export const notificationFields = [
/* -------------------------------------------------------------------------- */
/* notification:send */
/* -------------------------------------------------------------------------- */
{
displayName: 'Message',
name: 'message',
required: true,
type: 'string',
displayOptions: {
show: {
operation: [
'send',
],
resource: [
'notification',
],
},
},
default: '',
},
{
displayName: 'Additional Fields',
name: 'additionalFields',
type: 'collection',
placeholder: 'Add Field',
default: {},
displayOptions: {
show: {
operation: [
'send',
],
resource: [
'notification',
],
},
},
options: [
{
displayName: 'Image',
name: 'imageUi',
placeholder: 'Add Image',
type: 'fixedCollection',
typeOptions: {
multipleValues: false,
},
default: {},
options: [
{
name: 'imageValue',
displayName: 'image',
values: [
{
displayName: 'Binary Data',
name: 'binaryData',
type: 'boolean',
default: false,
},
{
displayName: 'Image Full Size',
name: 'imageFullsize',
type: 'string',
default: '',
displayOptions: {
show: {
binaryData: [
false,
],
},
},
description: 'HTTP/HTTPS URL. Maximum size of 2048×2048px JPEG',
},
{
displayName: 'Image Thumbnail',
name: 'imageThumbnail',
type: 'string',
displayOptions: {
show: {
binaryData: [
false,
],
},
},
default: '',
description: 'HTTP/HTTPS URL. Maximum size of 240×240px JPEG',
},
{
displayName: 'Binary Property',
name: 'binaryProperty',
type: 'string',
displayOptions: {
show: {
binaryData: [
true,
],
},
},
default: 'data',
description: `Name of the property that holds the binary data.<br>`,
},
],
},
],
},
{
displayName: 'Notification Disabled',
name: 'notificationDisabled',
type: 'boolean',
default: false,
description: `true: The user doesn't receive a push notification when the message is sent.<br>
false: The user receives a push notification when the message is sent`,
},
{
displayName: 'Sticker',
name: 'stickerUi',
placeholder: 'Add Sticker',
type: 'fixedCollection',
typeOptions: {
multipleValues: false,
},
default: {},
options: [
{
name: 'stickerValue',
displayName: 'Sticker',
values: [
{
displayName: 'Sticker ID',
name: 'stickerId',
type: 'number',
default: '',
description: 'Sticker ID',
},
{
displayName: 'Sticker Package ID',
name: 'stickerPackageId',
type: 'number',
default: '',
description: 'Package ID',
},
],
},
],
},
],
},
] as INodeProperties[];

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

View file

@ -107,6 +107,7 @@
"dist/credentials/JotFormApi.credentials.js",
"dist/credentials/Kafka.credentials.js",
"dist/credentials/KeapOAuth2Api.credentials.js",
"dist/credentials/LineNotifyOAuth2Api.credentials.js",
"dist/credentials/LinkedInOAuth2Api.credentials.js",
"dist/credentials/MailerLiteApi.credentials.js",
"dist/credentials/MailchimpApi.credentials.js",
@ -315,6 +316,7 @@
"dist/nodes/Kafka/Kafka.node.js",
"dist/nodes/Keap/Keap.node.js",
"dist/nodes/Keap/KeapTrigger.node.js",
"dist/nodes/Line/Line.node.js",
"dist/nodes/LinkedIn/LinkedIn.node.js",
"dist/nodes/MailerLite/MailerLite.node.js",
"dist/nodes/MailerLite/MailerLiteTrigger.node.js",