n8n-nodes-onedesk 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,72 @@
1
+ # n8n-nodes-onedesk
2
+
3
+ An [n8n](https://n8n.io) community node for **OneDesk**. Start workflows from
4
+ OneDesk ticket activity (new tickets, replies, tag changes, and more) via
5
+ OneDesk's outbound webhooks.
6
+
7
+ This is a **trigger-only** node (OneDesk → n8n).
8
+
9
+ ## What's included
10
+
11
+ - **OneDesk API credential** — an API key + base URL, sent as the `X-API-KEY`
12
+ header. Tested against `GET /api/integrations/me`.
13
+ - **OneDesk Trigger node** — pick an event; when the workflow is activated the node
14
+ registers an outbound webhook with OneDesk (and removes it on deactivation). The
15
+ event payload becomes the node's output.
16
+
17
+ ### Events
18
+
19
+ `ticket.created`, `ticket.updated`, `ticket.tags.updated`, `ticket.spam.updated`,
20
+ `ticket.note.created`, `conversation.created`, `contact.updated`, `contact.deleted`,
21
+ `automation.triggered`.
22
+
23
+ Keep `src/events.ts` in sync with the backend's
24
+ `apps/back-end/src/outbound-webhooks/webhook-events.ts`.
25
+
26
+ ## Backend endpoints it uses
27
+
28
+ | n8n piece | OneDesk endpoint |
29
+ | --- | --- |
30
+ | Credential test | `GET /api/integrations/me` |
31
+ | Trigger activate (`create`) | `POST /api/hooks/subscriptions` (with `via: "n8n"`) |
32
+ | Trigger deactivate (`delete`) | `DELETE /api/hooks/subscriptions/:id` |
33
+ | Event delivery | OneDesk POSTs to the node's webhook URL |
34
+
35
+ ## Develop
36
+
37
+ ```bash
38
+ npm install
39
+ npm run build # tsc → dist/ (+ copies the icon)
40
+ ```
41
+
42
+ ### Test locally against a self-hosted n8n
43
+
44
+ ```bash
45
+ # in this package
46
+ npm run build
47
+ npm link
48
+
49
+ # in your n8n custom dir (~/.n8n/custom, create it if missing)
50
+ npm link n8n-nodes-onedesk
51
+
52
+ # start n8n; the OneDesk Trigger node + OneDesk API credential appear
53
+ npx n8n
54
+ ```
55
+
56
+ Point the credential's **Base URL** at your OneDesk API (ngrok for local dev, or
57
+ production). Add the OneDesk Trigger node, pick an event, and activate the workflow —
58
+ a subscription appears on OneDesk's **Settings → Integrations → n8n** page.
59
+
60
+ ## Publish
61
+
62
+ ```bash
63
+ npm run build
64
+ npm publish # publishes n8n-nodes-onedesk to npm
65
+ ```
66
+
67
+ Users then install it via n8n **Settings → Community Nodes → Install**
68
+ (`n8n-nodes-onedesk`), or `npm install n8n-nodes-onedesk` in a self-hosted setup.
69
+
70
+ > Verifying deliveries: each webhook request is signed with an
71
+ > `X-OneDesk-Signature` header (HMAC-SHA256 of the body with the subscription
72
+ > secret). Self-hosted receivers can verify it; see the OneDesk docs.
@@ -0,0 +1,9 @@
1
+ import { IAuthenticateGeneric, ICredentialTestRequest, ICredentialType, INodeProperties } from 'n8n-workflow';
2
+ export declare class OneDeskApi implements ICredentialType {
3
+ name: string;
4
+ displayName: string;
5
+ documentationUrl: string;
6
+ properties: INodeProperties[];
7
+ authenticate: IAuthenticateGeneric;
8
+ test: ICredentialTestRequest;
9
+ }
@@ -0,0 +1,47 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.OneDeskApi = void 0;
4
+ class OneDeskApi {
5
+ constructor() {
6
+ this.name = 'oneDeskApi';
7
+ this.displayName = 'OneDesk API';
8
+ this.documentationUrl = 'https://onedesk.so/docs/appIntegration';
9
+ this.properties = [
10
+ {
11
+ displayName: 'API Key',
12
+ name: 'apiKey',
13
+ type: 'string',
14
+ typeOptions: { password: true },
15
+ default: '',
16
+ required: true,
17
+ description: 'Generate one in OneDesk under Settings → Integrations → API keys',
18
+ },
19
+ {
20
+ displayName: 'Base URL',
21
+ name: 'baseUrl',
22
+ type: 'string',
23
+ default: 'https://server.onedesk.so',
24
+ required: true,
25
+ description: 'The OneDesk API base URL (no trailing slash, no /api suffix)',
26
+ },
27
+ ];
28
+ // OneDesk's ApiKeyGuard reads the key from the X-API-KEY header.
29
+ this.authenticate = {
30
+ type: 'generic',
31
+ properties: {
32
+ headers: {
33
+ 'X-API-KEY': '={{$credentials.apiKey}}',
34
+ },
35
+ },
36
+ };
37
+ // The "Test" button in the credential dialog hits /integrations/me.
38
+ this.test = {
39
+ request: {
40
+ baseURL: '={{$credentials.baseUrl}}',
41
+ url: '/api/integrations/me',
42
+ method: 'GET',
43
+ },
44
+ };
45
+ }
46
+ }
47
+ exports.OneDeskApi = OneDeskApi;
@@ -0,0 +1,5 @@
1
+ export declare const ONEDESK_EVENTS: {
2
+ name: string;
3
+ value: string;
4
+ description: string;
5
+ }[];
package/dist/events.js ADDED
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ONEDESK_EVENTS = void 0;
4
+ // Mirror of the backend's WEBHOOK_EVENTS
5
+ // (apps/back-end/src/outbound-webhooks/webhook-events.ts). Keep in sync — each
6
+ // entry becomes an option in the OneDesk Trigger node's event dropdown.
7
+ exports.ONEDESK_EVENTS = [
8
+ { name: 'New Ticket', value: 'ticket.created', description: 'A new ticket is created' },
9
+ { name: 'Ticket Updated', value: 'ticket.updated', description: 'A ticket is updated (assignment, status, etc.)' },
10
+ { name: 'Ticket Tags Updated', value: 'ticket.tags.updated', description: "A ticket's tags change" },
11
+ { name: 'Ticket Spam Status Updated', value: 'ticket.spam.updated', description: 'A ticket is marked as (or unmarked from) spam' },
12
+ { name: 'New Ticket Note', value: 'ticket.note.created', description: 'A public note is added to a ticket' },
13
+ { name: 'New Conversation Message', value: 'conversation.created', description: 'A new reply/message is added to a ticket' },
14
+ { name: 'Contact Updated', value: 'contact.updated', description: 'A contact is updated' },
15
+ { name: 'Contact Deleted', value: 'contact.deleted', description: 'A contact is deleted' },
16
+ { name: 'Automation Triggered', value: 'automation.triggered', description: "An automation's Trigger Integration action fires" },
17
+ ];
@@ -0,0 +1,12 @@
1
+ import { IHookFunctions, INodeType, INodeTypeDescription, IWebhookFunctions, IWebhookResponseData } from 'n8n-workflow';
2
+ export declare class OneDeskTrigger implements INodeType {
3
+ description: INodeTypeDescription;
4
+ webhookMethods: {
5
+ default: {
6
+ checkExists(this: IHookFunctions): Promise<boolean>;
7
+ create(this: IHookFunctions): Promise<boolean>;
8
+ delete(this: IHookFunctions): Promise<boolean>;
9
+ };
10
+ };
11
+ webhook(this: IWebhookFunctions): Promise<IWebhookResponseData>;
12
+ }
@@ -0,0 +1,108 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.OneDeskTrigger = void 0;
4
+ const MAIN_OUTPUT = 'main';
5
+ const events_1 = require("../../events");
6
+ class OneDeskTrigger {
7
+ constructor() {
8
+ this.description = {
9
+ displayName: 'OneDesk Trigger',
10
+ name: 'oneDeskTrigger',
11
+ icon: 'file:onedesk.svg',
12
+ group: ['trigger'],
13
+ version: 1,
14
+ subtitle: '={{$parameter["event"]}}',
15
+ description: 'Starts a workflow when a OneDesk event happens',
16
+ defaults: {
17
+ name: 'OneDesk Trigger',
18
+ },
19
+ // No input connections — it is a trigger.
20
+ inputs: [],
21
+ outputs: [MAIN_OUTPUT],
22
+ credentials: [
23
+ {
24
+ name: 'oneDeskApi',
25
+ required: true,
26
+ },
27
+ ],
28
+ webhooks: [
29
+ {
30
+ name: 'default',
31
+ httpMethod: 'POST',
32
+ responseMode: 'onReceived',
33
+ path: 'webhook',
34
+ },
35
+ ],
36
+ properties: [
37
+ {
38
+ displayName: 'Event',
39
+ name: 'event',
40
+ type: 'options',
41
+ required: true,
42
+ default: 'ticket.created',
43
+ description: 'The OneDesk event that triggers the workflow',
44
+ options: events_1.ONEDESK_EVENTS.map((e) => ({
45
+ name: e.name,
46
+ value: e.value,
47
+ description: e.description,
48
+ })),
49
+ },
50
+ ],
51
+ };
52
+ this.webhookMethods = {
53
+ default: {
54
+ async checkExists() {
55
+ const webhookData = this.getWorkflowStaticData('node');
56
+ return Boolean(webhookData.subscriptionId);
57
+ },
58
+ async create() {
59
+ const webhookUrl = this.getNodeWebhookUrl('default');
60
+ const event = this.getNodeParameter('event');
61
+ const workflowName = this.getWorkflow().name;
62
+ const response = (await this.helpers.httpRequestWithAuthentication.call(this, 'oneDeskApi', {
63
+ method: 'POST',
64
+ baseURL: '={{$credentials.baseUrl}}',
65
+ url: '/api/hooks/subscriptions',
66
+ body: {
67
+ event,
68
+ targetUrl: webhookUrl,
69
+ label: workflowName,
70
+ via: 'n8n',
71
+ },
72
+ json: true,
73
+ }));
74
+ if (response.id === undefined) {
75
+ return false;
76
+ }
77
+ this.getWorkflowStaticData('node').subscriptionId = response.id;
78
+ return true;
79
+ },
80
+ async delete() {
81
+ const webhookData = this.getWorkflowStaticData('node');
82
+ if (!webhookData.subscriptionId) {
83
+ return true;
84
+ }
85
+ try {
86
+ await this.helpers.httpRequestWithAuthentication.call(this, 'oneDeskApi', {
87
+ method: 'DELETE',
88
+ baseURL: '={{$credentials.baseUrl}}',
89
+ url: `/api/hooks/subscriptions/${webhookData.subscriptionId}`,
90
+ });
91
+ }
92
+ catch {
93
+ // If OneDesk already removed it, treat as success.
94
+ }
95
+ delete webhookData.subscriptionId;
96
+ return true;
97
+ },
98
+ },
99
+ };
100
+ }
101
+ async webhook() {
102
+ const body = this.getBodyData();
103
+ return {
104
+ workflowData: [this.helpers.returnJsonArray(body)],
105
+ };
106
+ }
107
+ }
108
+ exports.OneDeskTrigger = OneDeskTrigger;
@@ -0,0 +1,4 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24">
2
+ <rect width="24" height="24" rx="5" fill="#0969da"/>
3
+ <path d="M12 5.5a6.5 6.5 0 1 0 0 13 6.5 6.5 0 0 0 0-13Zm0 3a3.5 3.5 0 1 1 0 7 3.5 3.5 0 0 1 0-7Z" fill="#fff"/>
4
+ </svg>
package/package.json ADDED
@@ -0,0 +1,41 @@
1
+ {
2
+ "name": "n8n-nodes-onedesk",
3
+ "version": "1.0.0",
4
+ "description": "n8n community node for OneDesk — trigger workflows from ticket activity.",
5
+ "keywords": [
6
+ "n8n-community-node-package",
7
+ "onedesk",
8
+ "support",
9
+ "helpdesk"
10
+ ],
11
+ "license": "MIT",
12
+ "main": "index.js",
13
+ "scripts": {
14
+ "build": "tsc && npm run copy-icons",
15
+ "copy-icons": "node -e \"const fs=require('fs'),p=require('path');const src='src/nodes/OneDesk/onedesk.svg',dst='dist/nodes/OneDesk/onedesk.svg';fs.mkdirSync(p.dirname(dst),{recursive:true});fs.copyFileSync(src,dst)\"",
16
+ "dev": "tsc --watch",
17
+ "lint": "tsc --noEmit"
18
+ },
19
+ "files": [
20
+ "dist"
21
+ ],
22
+ "n8n": {
23
+ "n8nNodesApiVersion": 1,
24
+ "credentials": [
25
+ "dist/credentials/OneDeskApi.credentials.js"
26
+ ],
27
+ "nodes": [
28
+ "dist/nodes/OneDesk/OneDeskTrigger.node.js"
29
+ ]
30
+ },
31
+ "engines": {
32
+ "node": ">=18"
33
+ },
34
+ "peerDependencies": {
35
+ "n8n-workflow": "*"
36
+ },
37
+ "devDependencies": {
38
+ "n8n-workflow": "^1.55.0",
39
+ "typescript": "^5.4.0"
40
+ }
41
+ }