n8n-nodes-binary-to-url 0.1.2 → 0.1.7

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 CHANGED
@@ -70,7 +70,7 @@ sudo systemctl restart n8n
70
70
  ```json
71
71
  {
72
72
  "fileKey": "1736567890123-abc123def456",
73
- "proxyUrl": "https://your-n8n.com/webhook/123/file/1736567890123-abc123def456",
73
+ "proxyUrl": "https://your-n8n.com/webhook/webhook-id/file?fileKey=1736567890123-abc123def456",
74
74
  "contentType": "image/jpeg",
75
75
  "fileSize": 245678
76
76
  }
@@ -0,0 +1,2 @@
1
+ import { BinaryToUrl } from './nodes/BinaryToUrl/BinaryToUrl.node';
2
+ export declare const nodeClasses: (typeof BinaryToUrl)[];
package/dist/index.js ADDED
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.nodeClasses = void 0;
4
+ const BinaryToUrl_node_1 = require("./nodes/BinaryToUrl/BinaryToUrl.node");
5
+ exports.nodeClasses = [BinaryToUrl_node_1.BinaryToUrl];
@@ -1,6 +1,18 @@
1
- import { INodeType, INodeTypeDescription, IExecuteFunctions, IWebhookFunctions, IWebhookResponseData, INodeExecutionData } from 'n8n-workflow';
1
+ import { INodeType, INodeTypeDescription, IExecuteFunctions, IWebhookFunctions, IWebhookResponseData, INodeExecutionData, IHookFunctions } from 'n8n-workflow';
2
+ interface IHookFunctionsExtended extends IHookFunctions {
3
+ addWebhookToDatabase?(webhookUrl: string, httpMethod: string, path: string, restartWebhook?: boolean): Promise<void>;
4
+ removeWebhookFromDatabase?(webhookUrl: string, httpMethod: string, path: string): Promise<void>;
5
+ }
2
6
  export declare class BinaryToUrl implements INodeType {
3
7
  description: INodeTypeDescription;
8
+ webhookMethods: {
9
+ default: {
10
+ checkExists(this: IHookFunctions): Promise<boolean>;
11
+ create(this: IHookFunctionsExtended): Promise<boolean>;
12
+ delete(this: IHookFunctionsExtended): Promise<boolean>;
13
+ };
14
+ };
4
15
  execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]>;
5
16
  webhook(this: IWebhookFunctions): Promise<IWebhookResponseData>;
6
17
  }
18
+ export {};
@@ -42,7 +42,7 @@ class BinaryToUrl {
42
42
  group: ['transform'],
43
43
  version: 1,
44
44
  subtitle: '={{$parameter["operation"]}}',
45
- description: 'Create temporary URLs for binary files within a workflow execution',
45
+ description: 'Store binary files in memory and retrieve them by key',
46
46
  defaults: {
47
47
  name: 'Binary to URL',
48
48
  },
@@ -53,7 +53,7 @@ class BinaryToUrl {
53
53
  name: 'default',
54
54
  httpMethod: 'GET',
55
55
  responseMode: 'onReceived',
56
- path: 'file/:fileKey',
56
+ path: 'file',
57
57
  isFullPath: false,
58
58
  },
59
59
  ],
@@ -67,7 +67,7 @@ class BinaryToUrl {
67
67
  {
68
68
  name: 'Upload',
69
69
  value: 'upload',
70
- description: 'Create temporary URL for binary file',
70
+ description: 'Store binary file in memory',
71
71
  action: 'Upload file',
72
72
  },
73
73
  {
@@ -92,7 +92,7 @@ class BinaryToUrl {
92
92
  description: 'Name of binary property containing the file to upload',
93
93
  },
94
94
  {
95
- displayName: 'URL Expiration Time (Seconds)',
95
+ displayName: 'TTL (Seconds)',
96
96
  name: 'ttl',
97
97
  type: 'number',
98
98
  displayOptions: {
@@ -101,8 +101,7 @@ class BinaryToUrl {
101
101
  },
102
102
  },
103
103
  default: 600,
104
- description: 'How long the URL remains valid (default: 600 seconds = 10 minutes)',
105
- hint: 'This is for temporary use within a workflow. For short-term sharing, use 300-3600 seconds. For workflow-internal use, 60-600 seconds is recommended.',
104
+ description: 'How long the file remains valid in memory (default: 600 seconds)',
106
105
  },
107
106
  {
108
107
  displayName: 'File Key',
@@ -114,11 +113,41 @@ class BinaryToUrl {
114
113
  },
115
114
  },
116
115
  default: '',
117
- description: 'Key of the file to delete from memory',
116
+ description: 'Key of the file to delete',
118
117
  },
119
118
  ],
120
119
  usableAsTool: true,
121
120
  };
121
+ this.webhookMethods = {
122
+ default: {
123
+ async checkExists() {
124
+ const webhookUrl = this.getNodeWebhookUrl('default');
125
+ return !!webhookUrl;
126
+ },
127
+ async create() {
128
+ const webhookUrl = this.getNodeWebhookUrl('default');
129
+ if (!webhookUrl) {
130
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Failed to get webhook URL');
131
+ }
132
+ // Try to register webhook in n8n's database if the method exists
133
+ if (this.addWebhookToDatabase) {
134
+ await this.addWebhookToDatabase(webhookUrl, 'GET', 'file', true);
135
+ }
136
+ return true;
137
+ },
138
+ async delete() {
139
+ const webhookUrl = this.getNodeWebhookUrl('default');
140
+ if (!webhookUrl) {
141
+ return true;
142
+ }
143
+ // Try to unregister webhook if the method exists
144
+ if (this.removeWebhookFromDatabase) {
145
+ await this.removeWebhookFromDatabase(webhookUrl, 'GET', 'file');
146
+ }
147
+ return true;
148
+ },
149
+ },
150
+ };
122
151
  }
123
152
  async execute() {
124
153
  const items = this.getInputData();
@@ -132,8 +161,8 @@ class BinaryToUrl {
132
161
  throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Unknown operation: ${operation}`);
133
162
  }
134
163
  async webhook() {
135
- const req = this.getRequestObject();
136
- const fileKey = req.params.fileKey;
164
+ const query = this.getQueryData();
165
+ const fileKey = query.fileKey;
137
166
  const workflow = this.getWorkflow();
138
167
  const workflowId = workflow.id;
139
168
  if (!fileKey) {
@@ -211,10 +240,17 @@ async function handleUpload(context, items) {
211
240
  }
212
241
  const workflow = context.getWorkflow();
213
242
  const workflowId = workflow.id;
243
+ const node = context.getNode();
214
244
  const baseUrl = context.getInstanceBaseUrl();
215
- // Remove trailing slash and ensure clean URL
216
- const cleanBaseUrl = baseUrl.replace(/\/+$/, '');
217
- const webhookUrl = `${cleanBaseUrl}/webhook/${workflowId}/file/:fileKey`;
245
+ // Use n8n's getNodeWebhookUrl helper to build the correct webhook URL
246
+ // The webhook path is 'file' with fileKey as query parameter
247
+ const webhookUrlBase = (0, n8n_workflow_1.getNodeWebhookUrl)(baseUrl, workflowId, node, 'file', false);
248
+ // Validate that the webhook URL was generated successfully
249
+ if (!webhookUrlBase) {
250
+ throw new n8n_workflow_1.NodeOperationError(context.getNode(), 'Failed to generate webhook URL. Please check your n8n configuration.');
251
+ }
252
+ // URL template with query parameter
253
+ const webhookUrlTemplate = `${webhookUrlBase}?fileKey=:fileKey`;
218
254
  const returnData = [];
219
255
  for (const item of items) {
220
256
  const binaryData = item.binary?.[binaryPropertyName];
@@ -245,7 +281,7 @@ async function handleUpload(context, items) {
245
281
  throw new n8n_workflow_1.NodeOperationError(context.getNode(), `File size exceeds maximum limit of ${MAX_FILE_SIZE / 1024 / 1024}MB`);
246
282
  }
247
283
  const result = await MemoryStorage_js_1.MemoryStorage.upload(workflowId, buffer, contentType, ttl * 1000);
248
- const proxyUrl = webhookUrl.replace(':fileKey', result.fileKey);
284
+ const proxyUrl = webhookUrlTemplate.replace(':fileKey', result.fileKey);
249
285
  context.logger.info(`File uploaded: ${result.fileKey}, size: ${fileSize}, contentType: ${contentType}, TTL: ${ttl}s`);
250
286
  returnData.push({
251
287
  json: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "n8n-nodes-binary-to-url",
3
- "version": "0.1.2",
3
+ "version": "0.1.7",
4
4
  "description": "n8n community node for creating temporary URLs for binary files within workflow execution",
5
5
  "keywords": [
6
6
  "n8n-community-node-package",
@@ -53,7 +53,11 @@
53
53
  "typescript": "5.9.2"
54
54
  },
55
55
  "peerDependencies": {
56
- "n8n-workflow": "*"
56
+ "n8n-workflow": ">=1.0.0"
57
+ },
58
+ "engines": {
59
+ "node": ">=18.10.0",
60
+ "n8n": ">=2.0.0"
57
61
  },
58
62
  "publishConfig": {
59
63
  "registry": "https://registry.npmjs.org"