pull:初次提交

This commit is contained in:
Yep_Q
2025-09-08 04:48:28 +08:00
parent 5c0619656d
commit f64f498365
11751 changed files with 1953723 additions and 0 deletions

View File

@@ -0,0 +1,42 @@
import type {
IDataObject,
IExecuteFunctions,
IHookFunctions,
IHttpRequestMethods,
ILoadOptionsFunctions,
IPollFunctions,
IRequestOptions,
ITriggerFunctions,
JsonObject,
} from 'n8n-workflow';
import { NodeApiError } from 'n8n-workflow';
export async function togglApiRequest(
this:
| ITriggerFunctions
| IPollFunctions
| IHookFunctions
| IExecuteFunctions
| ILoadOptionsFunctions,
method: IHttpRequestMethods,
resource: string,
body: IDataObject = {},
query?: IDataObject,
uri?: string,
) {
const options: IRequestOptions = {
method,
qs: query,
uri: uri || `https://api.track.toggl.com/api/v9/me${resource}`,
body,
json: true,
};
if (Object.keys(options.body as IDataObject).length === 0) {
delete options.body;
}
try {
return await this.helpers.requestWithAuthentication.call(this, 'togglApi', options);
} catch (error) {
throw new NodeApiError(this.getNode(), error as JsonObject);
}
}

View File

@@ -0,0 +1,18 @@
{
"node": "n8n-nodes-base.togglTrigger",
"nodeVersion": "1.0",
"codexVersion": "1.0",
"categories": ["Productivity", "Utility"],
"resources": {
"credentialDocumentation": [
{
"url": "https://docs.n8n.io/integrations/builtin/credentials/toggl/"
}
],
"primaryDocumentation": [
{
"url": "https://docs.n8n.io/integrations/builtin/trigger-nodes/n8n-nodes-base.toggltrigger/"
}
]
}
}

View File

@@ -0,0 +1,81 @@
import { DateTime } from 'luxon';
import moment from 'moment-timezone';
import type {
IPollFunctions,
IDataObject,
INodeExecutionData,
INodeType,
INodeTypeDescription,
JsonObject,
} from 'n8n-workflow';
import { NodeApiError, NodeConnectionTypes, NodeOperationError } from 'n8n-workflow';
import { togglApiRequest } from './GenericFunctions';
export class TogglTrigger implements INodeType {
description: INodeTypeDescription = {
displayName: 'Toggl Trigger',
name: 'togglTrigger',
// eslint-disable-next-line n8n-nodes-base/node-class-description-icon-not-svg
icon: 'file:toggl.png',
group: ['trigger'],
version: 1,
description: 'Starts the workflow when Toggl events occur',
defaults: {
name: 'Toggl Trigger',
},
credentials: [
{
name: 'togglApi',
required: true,
},
],
polling: true,
inputs: [],
outputs: [NodeConnectionTypes.Main],
properties: [
{
displayName: 'Event',
name: 'event',
type: 'options',
options: [
{
name: 'New Time Entry',
value: 'newTimeEntry',
},
],
required: true,
default: 'newTimeEntry',
},
],
};
async poll(this: IPollFunctions): Promise<INodeExecutionData[][] | null> {
const webhookData = this.getWorkflowStaticData('node');
const event = this.getNodeParameter('event') as string;
let endpoint: string;
if (event === 'newTimeEntry') {
endpoint = '/time_entries';
} else {
throw new NodeOperationError(this.getNode(), `The defined event "${event}" is not supported`);
}
const qs: IDataObject = {};
let timeEntries = [];
qs.start_date = webhookData.lastTimeChecked ?? DateTime.now().toISODate();
qs.end_date = moment().format();
try {
timeEntries = await togglApiRequest.call(this, 'GET', endpoint, {}, qs);
webhookData.lastTimeChecked = qs.end_date;
} catch (error) {
throw new NodeApiError(this.getNode(), error as JsonObject);
}
if (Array.isArray(timeEntries) && timeEntries.length !== 0) {
return [this.helpers.returnJsonArray(timeEntries)];
}
return null;
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB