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 +72 -0
- package/dist/credentials/OneDeskApi.credentials.d.ts +9 -0
- package/dist/credentials/OneDeskApi.credentials.js +47 -0
- package/dist/events.d.ts +5 -0
- package/dist/events.js +17 -0
- package/dist/nodes/OneDesk/OneDeskTrigger.node.d.ts +12 -0
- package/dist/nodes/OneDesk/OneDeskTrigger.node.js +108 -0
- package/dist/nodes/OneDesk/onedesk.svg +4 -0
- package/package.json +41 -0
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;
|
package/dist/events.d.ts
ADDED
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;
|
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
|
+
}
|