🚚 Directorize and alphabetize nodes (#2445)

* 🚚 Directorize nodes

*  Alphabetize nodes and credentials

* 🔥 Remove unused node

* 🔥 Remove unused codex

* 🔥 Remove duplicate cred file references

* 🐛 Fix node file paths

* 🔥 Remove duplicate node reference
This commit is contained in:
Iván Ovejero
2021-11-17 17:30:14 +01:00
committed by GitHub
parent 0022c7eb09
commit 766f74c782
95 changed files with 109 additions and 472 deletions

View File

@@ -0,0 +1,138 @@
{
"node": "n8n-nodes-base.cron",
"nodeVersion": "1.0",
"codexVersion": "1.0",
"details": "The Cron node uses Cron under the hood - a time-based job scheduler in Unix-like computer operating systems. Use this node when you want to trigger workflows periodically, especially in more complex scenarios like \"every Tuesday at 9 am\" or \"Weekdays\".",
"categories": [
"Core Nodes"
],
"resources": {
"primaryDocumentation": [
{
"url": "https://docs.n8n.io/nodes/n8n-nodes-base.cron/"
}
],
"generic": [
{
"label": "2021 Goals: Level Up Your Vocabulary With Vonage and n8n",
"icon": "🎯",
"url": "https://n8n.io/blog/2021-goals-level-up-your-vocabulary-with-vonage-and-n8n/"
},
{
"label": "Love at first sight: Ricardos n8n journey",
"icon": "❤️",
"url": "https://n8n.io/blog/love-at-first-sight-ricardos-n8n-journey/"
},
{
"label": "2021: The Year to Automate the New You with n8n",
"icon": "☀️",
"url": "https://n8n.io/blog/2021-the-year-to-automate-the-new-you-with-n8n/"
},
{
"label": "Why business process automation with n8n can change your daily life",
"icon": "🧬",
"url": "https://n8n.io/blog/why-business-process-automation-with-n8n-can-change-your-daily-life/"
},
{
"label": "Why I chose n8n over Zapier in 2020",
"icon": "😍",
"url": "https://n8n.io/blog/why-i-chose-n8n-over-zapier-in-2020/"
},
{
"label": "How to host virtual coffee breaks with n8n",
"icon": "☕️",
"url": "https://n8n.io/blog/how-to-host-virtual-coffee-breaks-with-n8n/"
},
{
"label": "Automatically pulling and visualizing data with n8n",
"icon": "📈",
"url": "https://n8n.io/blog/automatically-pulling-and-visualizing-data-with-n8n/"
},
{
"label": "Database Monitoring and Alerting with n8n",
"icon": "📡",
"url": "https://n8n.io/blog/database-monitoring-and-alerting-with-n8n/"
},
{
"label": "Automate your data processing pipeline in 9 steps",
"icon": "⚙️",
"url": "https://n8n.io/blog/automate-your-data-processing-pipeline-in-9-steps-with-n8n/"
},
{
"label": "5 tasks you can automate with the new Notion API ",
"icon": "⚡️",
"url": "https://n8n.io/blog/5-tasks-you-can-automate-with-notion-api/"
},
{
"label": "Celebrating World Poetry Day with a daily poem in Telegram",
"icon": "📜",
"url": "https://n8n.io/blog/world-poetry-day-workflow/"
},
{
"label": "15 Google apps you can combine and automate to increase productivity",
"icon": "💡",
"url": "https://n8n.io/blog/automate-google-apps-for-productivity/"
},
{
"label": "Automate Designs with Bannerbear and n8n",
"icon": "🎨",
"url": "https://n8n.io/blog/automate-designs-with-bannerbear-and-n8n/"
},
{
"label": "Tracking Time Spent in Meetings With Google Calendar, Twilio, and n8n",
"icon": "🗓",
"url": "https://n8n.io/blog/tracking-time-spent-in-meetings-with-google-calendar-twilio-and-n8n/"
},
{
"label": "Creating Error Workflows in n8n",
"icon": "🌪",
"url": "https://n8n.io/blog/creating-error-workflows-in-n8n/"
},
{
"label": "Using Automation to Boost Productivity in the Workplace",
"icon": "💪",
"url": "https://n8n.io/blog/using-automation-to-boost-productivity-in-the-workplace/"
},
{
"label": "Why this Product Manager loves workflow automation with n8n",
"icon": "🧠",
"url": "https://n8n.io/blog/why-this-product-manager-loves-workflow-automation-with-n8n/"
},
{
"label": "Sending Automated Congratulations with Google Sheets, Twilio, and n8n ",
"icon": "🙌",
"url": "https://n8n.io/blog/sending-automated-congratulations-with-google-sheets-twilio-and-n8n/"
},
{
"label": "A low-code bitcoin ticker built with QuestDB and n8n.io",
"icon": "📈",
"url": "https://n8n.io/blog/a-low-code-bitcoin-ticker-built-with-questdb-and-n8n-io/"
},
{
"label": "Benefits of automation and n8n: An interview with HubSpot's Hugh Durkin",
"icon": "🎖",
"url": "https://n8n.io/blog/benefits-of-automation-and-n8n-an-interview-with-hubspots-hugh-durkin/"
},
{
"label": "Creating scheduled text affirmations with n8n",
"icon": "🤟",
"url": "https://n8n.io/blog/creating-scheduled-text-affirmations-with-n8n/"
},
{
"label": "How Goomer automated their operations with over 200 n8n workflows",
"icon": "🛵",
"url": "https://n8n.io/blog/how-goomer-automated-their-operations-with-over-200-n8n-workflows/"
}
]
},
"alias": [
"Time",
"Scheduler",
"Polling"
],
"subcategories": {
"Core Nodes": [
"Flow"
]
}
}

View File

@@ -0,0 +1,344 @@
import { ITriggerFunctions } from 'n8n-core';
import {
INodeType,
INodeTypeDescription,
ITriggerResponse,
} from 'n8n-workflow';
import { CronJob } from 'cron';
interface TriggerTime {
mode: string;
hour: number;
minute: number;
dayOfMonth: number;
weekeday: number;
[key: string]: string | number;
}
export class Cron implements INodeType {
description: INodeTypeDescription = {
displayName: 'Cron',
name: 'cron',
icon: 'fa:calendar',
group: ['trigger'],
version: 1,
description: 'Triggers the workflow at a specific time',
defaults: {
name: 'Cron',
color: '#00FF00',
},
inputs: [],
outputs: ['main'],
properties: [
{
displayName: 'Trigger Times',
name: 'triggerTimes',
type: 'fixedCollection',
typeOptions: {
multipleValues: true,
multipleValueButtonText: 'Add Time',
},
default: {},
description: 'Triggers for the workflow',
placeholder: 'Add Cron Time',
options: [
{
name: 'item',
displayName: 'Item',
values: [
{
displayName: 'Mode',
name: 'mode',
type: 'options',
options: [
{
name: 'Every Minute',
value: 'everyMinute',
},
{
name: 'Every Hour',
value: 'everyHour',
},
{
name: 'Every Day',
value: 'everyDay',
},
{
name: 'Every Week',
value: 'everyWeek',
},
{
name: 'Every Month',
value: 'everyMonth',
},
{
name: 'Every X',
value: 'everyX',
},
{
name: 'Custom',
value: 'custom',
},
],
default: 'everyDay',
description: 'How often to trigger.',
},
{
displayName: 'Hour',
name: 'hour',
type: 'number',
typeOptions: {
minValue: 0,
maxValue: 23,
},
displayOptions: {
hide: {
mode: [
'custom',
'everyHour',
'everyMinute',
'everyX',
],
},
},
default: 14,
description: 'The hour of the day to trigger (24h format).',
},
{
displayName: 'Minute',
name: 'minute',
type: 'number',
typeOptions: {
minValue: 0,
maxValue: 59,
},
displayOptions: {
hide: {
mode: [
'custom',
'everyMinute',
'everyX',
],
},
},
default: 0,
description: 'The minute of the day to trigger.',
},
{
displayName: 'Day of Month',
name: 'dayOfMonth',
type: 'number',
displayOptions: {
show: {
mode: [
'everyMonth',
],
},
},
typeOptions: {
minValue: 1,
maxValue: 31,
},
default: 1,
description: 'The day of the month to trigger.',
},
{
displayName: 'Weekday',
name: 'weekday',
type: 'options',
displayOptions: {
show: {
mode: [
'everyWeek',
],
},
},
options: [
{
name: 'Monday',
value: '1',
},
{
name: 'Tuesday',
value: '2',
},
{
name: 'Wednesday',
value: '3',
},
{
name: 'Thursday',
value: '4',
},
{
name: 'Friday',
value: '5',
},
{
name: 'Saturday',
value: '6',
},
{
name: 'Sunday',
value: '0',
},
],
default: '1',
description: 'The weekday to trigger.',
},
{
displayName: 'Cron Expression',
name: 'cronExpression',
type: 'string',
displayOptions: {
show: {
mode: [
'custom',
],
},
},
default: '* * * * * *',
description: 'Use custom cron expression. Values and ranges as follows:<ul><li>Seconds: 0-59</li><li>Minutes: 0 - 59</li><li>Hours: 0 - 23</li><li>Day of Month: 1 - 31</li><li>Months: 0 - 11 (Jan - Dec)</li><li>Day of Week: 0 - 6 (Sun - Sat)</li></ul>',
},
{
displayName: 'Value',
name: 'value',
type: 'number',
typeOptions: {
minValue: 0,
maxValue: 1000,
},
displayOptions: {
show: {
mode: [
'everyX',
],
},
},
default: 2,
description: 'All how many X minutes/hours it should trigger.',
},
{
displayName: 'Unit',
name: 'unit',
type: 'options',
displayOptions: {
show: {
mode: [
'everyX',
],
},
},
options: [
{
name: 'Minutes',
value: 'minutes',
},
{
name: 'Hours',
value: 'hours',
},
],
default: 'hours',
description: 'If it should trigger all X minutes or hours.',
},
],
},
],
},
],
};
async trigger(this: ITriggerFunctions): Promise<ITriggerResponse> {
const triggerTimes = this.getNodeParameter('triggerTimes') as unknown as {
item: TriggerTime[];
};
// Define the order the cron-time-parameter appear
const parameterOrder = [
'second', // 0 - 59
'minute', // 0 - 59
'hour', // 0 - 23
'dayOfMonth', // 1 - 31
'month', // 0 - 11(Jan - Dec)
'weekday', // 0 - 6(Sun - Sat)
];
// Get all the trigger times
const cronTimes: string[] = [];
let cronTime: string[];
let parameterName: string;
if (triggerTimes.item !== undefined) {
for (const item of triggerTimes.item) {
cronTime = [];
if (item.mode === 'custom') {
cronTimes.push(item.cronExpression as string);
continue;
}
if (item.mode === 'everyMinute') {
cronTimes.push(`${Math.floor(Math.random() * 60).toString()} * * * * *`);
continue;
}
if (item.mode === 'everyX') {
if (item.unit === 'minutes') {
cronTimes.push(`${Math.floor(Math.random() * 60).toString()} */${item.value} * * * *`);
} else if (item.unit === 'hours') {
cronTimes.push(`${Math.floor(Math.random() * 60).toString()} 0 */${item.value} * * *`);
}
continue;
}
for (parameterName of parameterOrder) {
if (item[parameterName] !== undefined) {
// Value is set so use it
cronTime.push(item[parameterName] as string);
} else if (parameterName === 'second') {
// For seconds we use by default a random one to make sure to
// balance the load a little bit over time
cronTime.push(Math.floor(Math.random() * 60).toString());
} else {
// For all others set "any"
cronTime.push('*');
}
}
cronTimes.push(cronTime.join(' '));
}
}
// The trigger function to execute when the cron-time got reached
// or when manually triggered
const executeTrigger = () => {
this.emit([this.helpers.returnJsonArray([{}])]);
};
const timezone = this.getTimezone();
// Start the cron-jobs
const cronJobs: CronJob[] = [];
for (const cronTime of cronTimes) {
cronJobs.push(new CronJob(cronTime, executeTrigger, undefined, true, timezone));
}
// Stop the cron-jobs
async function closeFunction() {
for (const cronJob of cronJobs) {
cronJob.stop();
}
}
async function manualTriggerFunction() {
executeTrigger();
}
return {
closeFunction,
manualTriggerFunction,
};
}
}