n8n-nodes-signauf 0.1.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.
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SignaufApi = void 0;
|
|
4
|
+
class SignaufApi {
|
|
5
|
+
constructor() {
|
|
6
|
+
this.name = 'signaufApi';
|
|
7
|
+
this.displayName = 'Signauf API';
|
|
8
|
+
this.documentationUrl = 'https://signauf.com/dashboard/docs';
|
|
9
|
+
this.properties = [
|
|
10
|
+
{
|
|
11
|
+
displayName: 'API Key',
|
|
12
|
+
name: 'apiKey',
|
|
13
|
+
type: 'string',
|
|
14
|
+
typeOptions: { password: true },
|
|
15
|
+
default: '',
|
|
16
|
+
required: true,
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
displayName: 'Base URL',
|
|
20
|
+
name: 'baseUrl',
|
|
21
|
+
type: 'string',
|
|
22
|
+
default: 'https://signauf.com',
|
|
23
|
+
description: 'Override only if you are self-hosting Signauf',
|
|
24
|
+
},
|
|
25
|
+
];
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
exports.SignaufApi = SignaufApi;
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Signauf = void 0;
|
|
4
|
+
const n8n_workflow_1 = require("n8n-workflow");
|
|
5
|
+
class Signauf {
|
|
6
|
+
constructor() {
|
|
7
|
+
this.description = {
|
|
8
|
+
displayName: 'Signauf',
|
|
9
|
+
name: 'signauf',
|
|
10
|
+
icon: 'file:signauf.svg',
|
|
11
|
+
group: ['transform'],
|
|
12
|
+
version: 1,
|
|
13
|
+
description: 'Submit an approval request and pause until a human approves or denies it',
|
|
14
|
+
defaults: { name: 'Signauf' },
|
|
15
|
+
inputs: ['main'],
|
|
16
|
+
outputs: ['main'],
|
|
17
|
+
credentials: [
|
|
18
|
+
{
|
|
19
|
+
name: 'signaufApi',
|
|
20
|
+
required: true,
|
|
21
|
+
},
|
|
22
|
+
],
|
|
23
|
+
properties: [
|
|
24
|
+
{
|
|
25
|
+
displayName: 'Operation',
|
|
26
|
+
name: 'operation',
|
|
27
|
+
type: 'options',
|
|
28
|
+
noDataExpression: true,
|
|
29
|
+
options: [
|
|
30
|
+
{
|
|
31
|
+
name: 'Submit for Approval',
|
|
32
|
+
value: 'submitForApproval',
|
|
33
|
+
description: 'Submit a request and wait for a human decision',
|
|
34
|
+
action: 'Submit a request and wait for a human decision',
|
|
35
|
+
},
|
|
36
|
+
],
|
|
37
|
+
default: 'submitForApproval',
|
|
38
|
+
},
|
|
39
|
+
// Submit for Approval fields
|
|
40
|
+
{
|
|
41
|
+
displayName: 'Form ID',
|
|
42
|
+
name: 'templateId',
|
|
43
|
+
type: 'string',
|
|
44
|
+
required: true,
|
|
45
|
+
default: '',
|
|
46
|
+
description: 'The ID of the Signauf form to route this request through. Find it in your Signauf dashboard under Forms.',
|
|
47
|
+
displayOptions: { show: { operation: ['submitForApproval'] } },
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
displayName: 'Payload',
|
|
51
|
+
name: 'payload',
|
|
52
|
+
type: 'json',
|
|
53
|
+
required: true,
|
|
54
|
+
default: '{}',
|
|
55
|
+
description: 'JSON object containing the request data. Keys must match the field paths defined in the form.',
|
|
56
|
+
displayOptions: { show: { operation: ['submitForApproval'] } },
|
|
57
|
+
},
|
|
58
|
+
],
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
async execute() {
|
|
62
|
+
var _a;
|
|
63
|
+
const credentials = await this.getCredentials('signaufApi');
|
|
64
|
+
const baseUrl = credentials.baseUrl.replace(/\/$/, '');
|
|
65
|
+
const apiKey = credentials.apiKey;
|
|
66
|
+
const items = this.getInputData();
|
|
67
|
+
const returnData = [];
|
|
68
|
+
for (let i = 0; i < items.length; i++) {
|
|
69
|
+
const templateId = this.getNodeParameter('templateId', i);
|
|
70
|
+
const payloadRaw = this.getNodeParameter('payload', i);
|
|
71
|
+
let payload;
|
|
72
|
+
try {
|
|
73
|
+
payload = typeof payloadRaw === 'string' ? JSON.parse(payloadRaw) : payloadRaw;
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Payload must be valid JSON', { itemIndex: i });
|
|
77
|
+
}
|
|
78
|
+
// Grab n8n's resume URL for this execution — Signauf will POST here on decision
|
|
79
|
+
const resumeUrl = this.evaluateExpression('{{ $execution.resumeUrl }}', i);
|
|
80
|
+
if (!resumeUrl) {
|
|
81
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Could not get execution resume URL. Make sure your n8n instance has a webhook base URL configured.', { itemIndex: i });
|
|
82
|
+
}
|
|
83
|
+
const response = await this.helpers.httpRequest({
|
|
84
|
+
method: 'POST',
|
|
85
|
+
url: `${baseUrl}/api/v1/requests`,
|
|
86
|
+
headers: {
|
|
87
|
+
Authorization: `Bearer ${apiKey}`,
|
|
88
|
+
'Content-Type': 'application/json',
|
|
89
|
+
},
|
|
90
|
+
body: {
|
|
91
|
+
templateId,
|
|
92
|
+
payload,
|
|
93
|
+
callbackUrl: resumeUrl,
|
|
94
|
+
},
|
|
95
|
+
json: true,
|
|
96
|
+
});
|
|
97
|
+
returnData.push({
|
|
98
|
+
json: (_a = response.data) !== null && _a !== void 0 ? _a : response,
|
|
99
|
+
pairedItem: { item: i },
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
// Pause this execution — resumes automatically when Signauf POSTs to the callbackUrl
|
|
103
|
+
// The resumed execution receives the decision payload (status, comment, requestId, etc.)
|
|
104
|
+
await this.putExecutionToWait(new Date(Date.now() + 365 * 24 * 60 * 60 * 1000));
|
|
105
|
+
return [returnData];
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
exports.Signauf = Signauf;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 60 60" fill="none">
|
|
2
|
+
<line x1="18" y1="56" x2="18" y2="26" stroke="#4f46e5" stroke-width="7" stroke-linecap="square"/>
|
|
3
|
+
<polygon points="18,6 3,30 33,30" fill="#4f46e5"/>
|
|
4
|
+
<line x1="42" y1="56" x2="42" y2="26" stroke="#4f46e5" stroke-width="7" stroke-linecap="square" opacity="0.35"/>
|
|
5
|
+
<polygon points="42,6 27,30 57,30" fill="#4f46e5" opacity="0.35"/>
|
|
6
|
+
</svg>
|
package/package.json
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "n8n-nodes-signauf",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "n8n community node for Signauf — submit approval requests and wait for human decisions",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"n8n-community-node-package",
|
|
7
|
+
"signauf",
|
|
8
|
+
"approval",
|
|
9
|
+
"workflow",
|
|
10
|
+
"human-in-the-loop"
|
|
11
|
+
],
|
|
12
|
+
"license": "MIT",
|
|
13
|
+
"homepage": "https://signauf.com",
|
|
14
|
+
"author": {
|
|
15
|
+
"name": "Signauf",
|
|
16
|
+
"email": "support@signauf.com"
|
|
17
|
+
},
|
|
18
|
+
"repository": {
|
|
19
|
+
"type": "git",
|
|
20
|
+
"url": "https://github.com/kam-itnn/n8n-nodes-signauf"
|
|
21
|
+
},
|
|
22
|
+
"main": "index.js",
|
|
23
|
+
"scripts": {
|
|
24
|
+
"build": "tsc && node -e \"require('fs').copyFileSync('src/nodes/Signauf/signauf.svg','dist/nodes/Signauf/signauf.svg')\"",
|
|
25
|
+
"dev": "tsc --watch"
|
|
26
|
+
},
|
|
27
|
+
"files": [
|
|
28
|
+
"dist"
|
|
29
|
+
],
|
|
30
|
+
"n8n": {
|
|
31
|
+
"n8nNodesApiVersion": 1,
|
|
32
|
+
"credentials": [
|
|
33
|
+
"dist/credentials/SignaufApi.credentials.js"
|
|
34
|
+
],
|
|
35
|
+
"nodes": [
|
|
36
|
+
"dist/nodes/Signauf/Signauf.node.js"
|
|
37
|
+
]
|
|
38
|
+
},
|
|
39
|
+
"devDependencies": {
|
|
40
|
+
"@types/node": "^20.0.0",
|
|
41
|
+
"typescript": "^5.0.0"
|
|
42
|
+
},
|
|
43
|
+
"peerDependencies": {
|
|
44
|
+
"n8n-workflow": "^2.16.0"
|
|
45
|
+
}
|
|
46
|
+
}
|