n8n/packages/nodes-base/nodes/Rocketchat/Rocketchat.node.ts
Omar Ajoue d6239d5bfb
Add full continue-on-fail support to all nodes (#1996)
* Update Compression node

* Update Crypto node

* Update DateTime node

* Update EditImage node

* Update EmailSend node

* Update ExecuteWorkflow node

* Update FTP node

* Update Function node

* Update FunctionItem node

* Update ExecuteCommand node

* Update OpenWeatherMap node

* Update ReadBinaryFile node

* Update ReadPdf node

* Update RssFeedRead node & add URL validation

* Update SpreadsheetFile node

* Update Switch node

* Update WriteBinaryFile node

* Update Xml node

* Update ActiveCampaign node

* Update Airtable node

* Update ApiTemplateIo node

* Update Asana node

* Update AwsLambda node

* Update AwsSns node

* Update AwsComprehend node

* Update AwsRekognition node

* Update AwsS3 node

* Fix Error item

* Update AwsSes node

* Update AwsSqs node

* Update Amqp node

* Update Bitly node

* Update Box node

* Update Brandfetch node

* Update CircleCi node

* Update Clearbit node

* Update ClickUp node

* Update Cockpit node

* Update CoinGecko node

* Update Contentful node

* Update ConvertKit node

* Update Cortex node

* Update CustomerIo node

* Update DeepL node

* Update Demio node

* Update Disqus node

* Update Drift node

* Update Dropbox node

* Update GetResponse node

* Refactor & Update Ghost node

* Update Github node

* Update Gitlab node

* Update GoogleAnalytics node

* Update GoogleBooks node

* Update GoogleCalendar node

* Update GoogleDrive node

* Update Gmail node

* Update GoogleSheets node

* Update GoogleSlides node

* Update GoogleTasks node

* Update Gotify node

* Update GraphQL node

* Update HackerNews node

* Update Harvest node

* Update HtmlExtract node

* Update Hubspot node

* Update Hunter node

* Update Intercom node

* Update Kafka node

* Refactor & update Line node

* Update LinkedIn node

* Update Mailchimp node

* Update Mandrill node

* Update Matrix node

* Update Mautic node

* Update Medium node

* Update MessageBird node

* Update Mindee node

* Update Mocean node

* Update MondayCom node

* Update MicrosoftExcel node

* Update MicrosoftOneDrive node

* Update MicrosoftOutlook node

* Update Affinity node

* Update Chargebee node

* Update Discourse node

* Update Freshdesk node

* Update YouTube node

* Update InvoiceNinja node

* Update MailerLite node

* Update Mailgun node

* Update Mailjet node

* Update Mattermost node

* Update Nasa node

* Update NextCloud node

* Update OpenThesaurus node

* Update Orbit node

* Update PagerDuty node

* Update PayPal node

* Update Peekalink node

* Update Phantombuster node

* Update PostHog node

* Update ProfitWell node

* Refactor & Update Pushbullet node

* Update QuickBooks node

* Update Raindrop node

* Update Reddit node

* Update Rocketchat node

* Update S3 node

* Update Salesforce node

* Update SendGrid node

* Update SentryIo node

* Update Shopify node

* Update Signl4 node

* Update Slack node

* Update Spontit node

* Update Spotify node

* Update Storyblok node

* Refactor & Update Strapi node

* Refactor & Update Strava node

* Update Taiga node

* Refactor & update Tapfiliate node

* Update Telegram node

* Update TheHive node

* Update Todoist node

* Update TravisCi node

* Update Trello node

* Update Twilio node

* Update Twist node

* Update Twitter node

* Update Uplead node

* Update UProc node

* Update Vero node

* Update Webflow node

* Update Wekan node

* Update Wordpress node

* Update Xero node

* Update Yourls node

* Update Zendesk node

* Update ZohoCrm node

* Refactor & Update Zoom node

* Update Zulip node

* Update Clockify node

* Update MongoDb node

* Update MySql node

* Update MicrosoftTeams node

* Update Stackby node

* Refactor Discourse node

* Support corner-case in Github node update

* Support corner-case in Gitlab node update

* Refactor & Update GoogleContacts node

* Refactor Mindee node

* Update Coda node

* Lint fixes

* Update Beeminder node

* Update Google Firebase RealtimeDatabase node

* Update HelpScout node

* Update Mailcheck node

* Update Paddle node

* Update Pipedrive node

* Update Pushover node

* Update Segment node

* Refactor & Update Vonage node

* Added new conditions to warnings on execute batch cmd

* Added keep only properties flag

* Fixed code for keep only props

* Added dependencies for image editing

Co-authored-by: dali <servfrdali@yahoo.fr>
2021-07-20 08:58:54 +02:00

518 lines
14 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import {
IExecuteFunctions,
} from 'n8n-core';
import {
IDataObject,
INodeExecutionData,
INodeType,
INodeTypeDescription,
} from 'n8n-workflow';
import {
rocketchatApiRequest,
validateJSON
} from './GenericFunctions';
interface IField {
short?: boolean;
title?: string;
value?: string;
}
interface IAttachment {
color?: string;
text?: string;
ts?: string;
title?: string;
thumb_url?: string;
message_link?: string;
collapsed?: boolean;
author_name?: string;
author_link?: string;
author_icon?: string;
title_link?: string;
title_link_download?: boolean;
image_url?: string;
audio_url?: string;
video_url?: string;
fields?: IField[];
}
interface IPostMessageBody {
channel: string;
text?: string;
alias?: string;
emoji?: string;
avatar?: string;
attachments?: IAttachment[];
}
export class Rocketchat implements INodeType {
description: INodeTypeDescription = {
displayName: 'RocketChat',
name: 'rocketchat',
icon: 'file:rocketchat.svg',
group: ['output'],
version: 1,
subtitle: '={{$parameter["resource"] + ": " + $parameter["operation"]}}',
description: 'Consume RocketChat API',
defaults: {
name: 'RocketChat',
color: '#c02428',
},
inputs: ['main'],
outputs: ['main'],
credentials: [
{
name: 'rocketchatApi',
required: true,
},
],
properties: [
{
displayName: 'Resource',
name: 'resource',
type: 'options',
options: [
{
name: 'Chat',
value: 'chat',
},
],
default: 'chat',
description: 'The resource to operate on.',
},
{
displayName: 'Operation',
name: 'operation',
type: 'options',
displayOptions: {
show: {
resource: [
'chat',
],
},
},
options: [
{
name: 'Post Message',
value: 'postMessage',
description: 'Post a message to a channel or a direct message',
},
],
default: 'postMessage',
description: 'The operation to perform.',
},
{
displayName: 'Channel',
name: 'channel',
type: 'string',
required: true,
displayOptions: {
show: {
resource: [
'chat',
],
operation: [
'postMessage',
],
},
},
default: '',
description: 'The channel name with the prefix in front of it.',
},
{
displayName: 'Text',
name: 'text',
type: 'string',
displayOptions: {
show: {
resource: [
'chat',
],
operation: [
'postMessage',
],
},
},
default: '',
description: 'The text of the message to send, is optional because of attachments.',
},
{
displayName: 'JSON Parameters',
name: 'jsonParameters',
type: 'boolean',
default: false,
description: '',
displayOptions: {
show: {
resource: [
'chat',
],
operation: [
'postMessage',
],
},
},
},
{
displayName: 'Options',
name: 'options',
type: 'collection',
placeholder: 'Add Option',
default: {},
displayOptions: {
show: {
resource: [
'chat',
],
operation: [
'postMessage',
],
},
},
options: [
{
displayName: 'Alias',
name: 'alias',
type: 'string',
default: '',
description: 'This will cause the messages name to appear as the given alias, but your username will still display.',
},
{
displayName: 'Avatar',
name: 'avatar',
type: 'string',
default: '',
description: 'If provided, this will make the avatar use the provided image url.',
},
{
displayName: 'Emoji',
name: 'emoji',
type: 'string',
default: '',
description: 'This will cause the messages name to appear as the given alias, but your username will still display.',
},
],
},
{
displayName: 'Attachments',
name: 'attachments',
type: 'collection',
default: {},
placeholder: 'Add Attachment Item',
typeOptions: {
multipleValues: true,
multipleValueButtonText: 'Add Attachment',
},
displayOptions: {
show: {
resource: [
'chat',
],
operation: [
'postMessage',
],
jsonParameters: [
false,
],
},
},
options: [
{
displayName: 'Color',
name: 'color',
type: 'color',
default: '#ff0000',
description: 'The color you want the order on the left side to be, any value background-css supports.',
},
{
displayName: 'Text',
name: 'text',
type: 'string',
default: '',
description: 'The text to display for this attachment, it is different than the messages text.',
},
{
displayName: 'Timestamp',
name: 'ts',
type: 'dateTime',
default: '',
description: 'Displays the time next to the text portion.',
},
{
displayName: 'Thumb URL',
name: 'thumbUrl',
type: 'string',
default: '',
description: 'An image that displays to the left of the text, looks better when this is relatively small.',
},
{
displayName: 'Message Link',
name: 'messageLink',
type: 'string',
default: '',
description: 'Only applicable if the timestamp is provided, as it makes the time clickable to this link.',
},
{
displayName: 'Collapsed',
name: 'collapsed',
type: 'boolean',
default: false,
description: 'Causes the image, audio, and video sections to be hiding when collapsed is true.',
},
{
displayName: 'Author Name',
name: 'authorName',
type: 'string',
default: '',
description: 'Name of the author.',
},
{
displayName: 'Author Link',
name: 'authorLink',
type: 'string',
default: '',
description: 'Providing this makes the author name clickable and points to this link.',
},
{
displayName: 'Author Icon',
name: 'authorIcon',
type: 'string',
default: '',
placeholder: 'https://site.com/img.png',
description: 'Displays a tiny icon to the left of the Authors name.',
},
{
displayName: 'Title',
name: 'title',
type: 'string',
default: '',
description: 'Title to display for this attachment, displays under the author.',
},
{
displayName: 'Title Link',
name: 'titleLink',
type: 'string',
default: '',
description: 'Providing this makes the title clickable, pointing to this link.',
},
{
displayName: 'Title Link Download',
name: 'titleLinkDownload',
type: 'boolean',
default: false,
description: 'When this is true, a download icon appears and clicking this saves the link to file.',
},
{
displayName: 'Image URL',
name: 'imageUrl',
type: 'string',
default: '',
description: 'The image to display, will be “big” and easy to see.',
},
{
displayName: 'Audio URL',
name: 'audioUrl',
type: 'string',
default: '',
placeholder: 'https://site.com/aud.mp3',
description: 'Audio file to play, only supports what html audio does.',
},
{
displayName: 'video URL',
name: 'videoUrl',
type: 'string',
default: '',
placeholder: 'https://site.com/vid.mp4',
description: 'Video file to play, only supports what html video does.',
},
{
displayName: 'Fields',
name: 'fields',
type: 'fixedCollection',
placeholder: 'Add Field Item',
typeOptions: {
multipleValues: true,
},
default: '',
options: [
{
name: 'fieldsValues',
displayName: 'Fields',
values: [
{
displayName: 'Short',
name: 'short',
type: 'boolean',
default: false,
description: 'Whether this field should be a short field.',
},
{
displayName: 'Title',
name: 'title',
type: 'string',
default: '',
description: 'The title of this field.',
},
{
displayName: 'Value',
name: 'value',
type: 'string',
default: '',
description: 'The value of this field, displayed underneath the title value.',
},
],
},
],
},
],
},
{
displayName: 'Attachments',
name: 'attachmentsJson',
type: 'json',
typeOptions: {
alwaysOpenEditWindow: true,
},
displayOptions: {
show: {
resource: [
'chat',
],
operation: [
'postMessage',
],
jsonParameters: [
true,
],
},
},
default: '',
required: false,
description: '',
},
],
};
async execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {
const items = this.getInputData();
const length = (items.length as unknown) as number;
let responseData;
const returnData: IDataObject[] = [];
const resource = this.getNodeParameter('resource', 0) as string;
const operation = this.getNodeParameter('operation', 0) as string;
for (let i = 0; i < length; i++) {
try {
if (resource === 'chat') {
//https://rocket.chat/docs/developer-guides/rest-api/chat/postmessage
if (operation === 'postMessage') {
const channel = this.getNodeParameter('channel', i) as string;
const text = this.getNodeParameter('text', i) as string;
const options = this.getNodeParameter('options', i) as IDataObject;
const jsonActive = this.getNodeParameter('jsonParameters', i) as boolean;
const body: IPostMessageBody = {
channel,
text,
};
if (options.alias) {
body.alias = options.alias as string;
}
if (options.avatar) {
body.avatar = options.avatar as string;
}
if (options.emoji) {
body.emoji = options.emoji as string;
}
if (!jsonActive) {
const optionsAttachments = this.getNodeParameter('attachments', i) as IDataObject[];
if (optionsAttachments.length > 0) {
const attachments: IAttachment[] = [];
for (let i = 0; i < optionsAttachments.length; i++) {
const attachment: IAttachment = {};
for (const option of Object.keys(optionsAttachments[i])) {
if (option === 'color') {
attachment.color = optionsAttachments[i][option] as string;
} else if (option === 'text') {
attachment.text = optionsAttachments[i][option] as string;
} else if (option === 'ts') {
attachment.ts = optionsAttachments[i][option] as string;
} else if (option === 'messageLinks') {
attachment.message_link = optionsAttachments[i][option] as string;
} else if (option === 'thumbUrl') {
attachment.thumb_url = optionsAttachments[i][option] as string;
} else if (option === 'collapsed') {
attachment.collapsed = optionsAttachments[i][option] as boolean;
} else if (option === 'authorName') {
attachment.author_name = optionsAttachments[i][option] as string;
} else if (option === 'authorLink') {
attachment.author_link = optionsAttachments[i][option] as string;
} else if (option === 'authorIcon') {
attachment.author_icon = optionsAttachments[i][option] as string;
} else if (option === 'title') {
attachment.title = optionsAttachments[i][option] as string;
} else if (option === 'titleLink') {
attachment.title_link = optionsAttachments[i][option] as string;
} else if (option === 'titleLinkDownload') {
attachment.title_link_download = optionsAttachments[i][option] as boolean;
} else if (option === 'imageUrl') {
attachment.image_url = optionsAttachments[i][option] as string;
} else if (option === 'audioUrl') {
attachment.audio_url = optionsAttachments[i][option] as string;
} else if (option === 'videoUrl') {
attachment.video_url = optionsAttachments[i][option] as string;
} else if (option === 'fields') {
const fieldsValues = (optionsAttachments[i][option] as IDataObject).fieldsValues as IDataObject[];
if (fieldsValues.length > 0) {
const fields: IField[] = [];
for (let i = 0; i < fieldsValues.length; i++) {
const field: IField = {};
for (const key of Object.keys(fieldsValues[i])) {
if (key === 'short') {
field.short = fieldsValues[i][key] as boolean;
} else if (key === 'title') {
field.title = fieldsValues[i][key] as string;
} else if (key === 'value') {
field.value = fieldsValues[i][key] as string;
}
}
fields.push(field);
attachment.fields = fields;
}
}
}
}
attachments.push(attachment);
}
body.attachments = attachments;
}
} else {
body.attachments = validateJSON(this.getNodeParameter('attachmentsJson', i) as string);
}
responseData = await rocketchatApiRequest.call(this, '/chat', 'POST', 'postMessage', body);
}
}
if (Array.isArray(responseData)) {
returnData.push.apply(returnData, responseData as IDataObject[]);
} else if (responseData !== undefined) {
returnData.push(responseData as IDataObject);
}
} catch (error) {
if (this.continueOnFail()) {
returnData.push({ error: error.message });
continue;
}
throw error;
}
}
return [this.helpers.returnJsonArray(returnData)];
}
}