n8n-nodes-bgos 0.3.0 → 0.3.1

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.
@@ -117,7 +117,7 @@ class BGOSAction {
117
117
  callbackSuccess: Boolean(this.getNodeParameter('callbackSuccess', i, true)),
118
118
  callbackError: String(this.getNodeParameter('callbackError', i, '') ?? ''),
119
119
  };
120
- const result = await (0, eventHandler_1.handleEventByType)(eventType, eventData, nodeParams);
120
+ const result = await eventHandler_1.handleEventByType.call(this, eventType, eventData, nodeParams);
121
121
  returnData.push({
122
122
  json: {
123
123
  ...items[i].json,
@@ -1 +1,2 @@
1
- export declare function sendMessageToAgent(webhookUrl: string, userId: string, messageData: Record<string, unknown>): Promise<unknown>;
1
+ import type { IExecuteFunctions } from 'n8n-workflow';
2
+ export declare function sendMessageToAgent(this: IExecuteFunctions, webhookUrl: string, userId: string, messageData: Record<string, unknown>): Promise<unknown>;
@@ -1,66 +1,38 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
6
3
  exports.sendMessageToAgent = sendMessageToAgent;
7
- const form_data_1 = __importDefault(require("form-data"));
8
- const node_fetch_1 = __importDefault(require("node-fetch"));
9
- const rateLimiter_1 = require("./rateLimiter");
10
- const http_status_codes_1 = require("http-status-codes");
11
4
  async function sendMessageToAgent(webhookUrl, userId, messageData) {
12
5
  const url = `${webhookUrl}/${userId}`;
13
- const formData = new form_data_1.default();
14
6
  const msg = messageData.message;
15
- if (messageData.chat_id)
16
- formData.append('chatId', String(messageData.chat_id));
17
- if (msg?.chatId)
18
- formData.append('chatId', String(msg.chatId));
19
- formData.append('sender', msg?.sender ?? 'user');
20
- formData.append('sentDate', msg?.sentDate ?? new Date().toISOString());
21
- if (messageData.text)
22
- formData.append('text', String(messageData.text));
23
- if (msg?.text)
24
- formData.append('text', String(msg.text));
25
- formData.append('isAudio', String(msg?.isAudio ?? false));
26
- formData.append('hasAttachment', String(msg?.hasAttachment ?? false));
27
- formData.append('duration', String(msg?.duration ?? 0));
28
- formData.append('isMixedAttachments', String(msg?.isMixedAttachments ?? false));
7
+ const payload = {};
8
+ const chatId = messageData.chat_id ?? msg?.chatId;
9
+ if (chatId != null)
10
+ payload.chatId = String(chatId);
11
+ payload.sender = msg?.sender ?? 'user';
12
+ payload.sentDate = msg?.sentDate ?? new Date().toISOString();
13
+ const text = (messageData.text ?? msg?.text);
14
+ if (text != null)
15
+ payload.text = text;
16
+ payload.isAudio = Boolean(msg?.isAudio ?? false);
17
+ payload.hasAttachment = Boolean(msg?.hasAttachment ?? false);
18
+ payload.duration = Number(msg?.duration ?? 0);
19
+ payload.isMixedAttachments = Boolean(msg?.isMixedAttachments ?? false);
29
20
  if (msg?.audioFileName) {
30
- formData.append('audioFileName', String(msg.audioFileName));
21
+ payload.audioFileName = String(msg.audioFileName);
31
22
  if (msg.audioData)
32
- formData.append('audioData', String(msg.audioData));
23
+ payload.audioData = String(msg.audioData);
33
24
  if (msg.audioMimeType)
34
- formData.append('audioMimeType', String(msg.audioMimeType));
25
+ payload.audioMimeType = String(msg.audioMimeType);
35
26
  }
36
- if (msg?.files && Array.isArray(msg.files))
37
- formData.append('files', JSON.stringify(msg.files));
38
- const response = await (0, rateLimiter_1.rateLimitedRequest)(async () => {
39
- const res = await (0, node_fetch_1.default)(url, {
40
- method: 'POST',
41
- body: formData,
42
- headers: { 'User-Agent': 'n8n-BGOS-Action/1.0' },
43
- });
44
- if (res.status === http_status_codes_1.StatusCodes.TOO_MANY_REQUESTS) {
45
- const retryAfter = res.headers.get('retry-after');
46
- const delay = retryAfter ? parseInt(retryAfter, 10) * 1000 : 1000;
47
- throw Object.assign(new Error(`Rate limit exceeded. Retry after ${delay}ms`), { response: res, status: http_status_codes_1.StatusCodes.TOO_MANY_REQUESTS });
48
- }
49
- return res;
50
- });
51
- if (!response.ok && response.status !== http_status_codes_1.StatusCodes.TOO_MANY_REQUESTS) {
52
- throw new Error(`HTTP error! status: ${response.status} - ${response.statusText}`);
53
- }
54
- const contentType = response.headers.get('content-type');
55
- const isAudioResponse = contentType && (contentType.includes('audio/') || contentType.includes('application/octet-stream') || contentType.includes('binary'));
56
- if (isAudioResponse) {
57
- const arrayBuffer = await response.arrayBuffer();
58
- const base64Audio = Buffer.from(arrayBuffer).toString('base64');
59
- return { type: 'audio', data: base64Audio, contentType, audioFileName: `audio_response_${Date.now()}.mp3` };
27
+ if (msg?.files && Array.isArray(msg.files)) {
28
+ payload.files = msg.files;
60
29
  }
61
- const responseText = await response.text();
62
- if (!responseText) {
63
- return { id: '-1', chat_id: messageData.chat_id ?? msg?.chatId, sender: 'assistant', sent_date: new Date().toISOString(), text: 'Empty response from server', is_audio: false, has_attachment: false };
64
- }
65
- return JSON.parse(responseText);
30
+ const response = await this.helpers.httpRequest({
31
+ method: 'POST',
32
+ url,
33
+ headers: { 'User-Agent': 'n8n-BGOS-Action/1.0' },
34
+ body: payload,
35
+ json: true,
36
+ });
37
+ return response;
66
38
  }
@@ -1,3 +1,4 @@
1
+ import type { IExecuteFunctions } from 'n8n-workflow';
1
2
  type NodeParams = {
2
3
  operation: string;
3
4
  webhookUrl?: string;
@@ -8,5 +9,5 @@ type NodeParams = {
8
9
  callbackError?: string;
9
10
  [key: string]: unknown;
10
11
  };
11
- export declare function handleEventByType(eventType: string, eventData: Record<string, unknown>, nodeParams: NodeParams): Promise<unknown>;
12
+ export declare function handleEventByType(this: IExecuteFunctions, eventType: string, eventData: Record<string, unknown>, nodeParams: NodeParams): Promise<unknown>;
12
13
  export {};
@@ -27,7 +27,7 @@ async function handleEventByType(eventType, eventData, nodeParams) {
27
27
  const webhookUrl = (nodeParams.webhookUrl ?? assistant?.webhookUrl ?? assistant?.webhook);
28
28
  if (!webhookUrl)
29
29
  throw new Error('Webhook URL is required.');
30
- return await (0, agentWebhook_1.sendMessageToAgent)(webhookUrl, userId, eventData);
30
+ return await agentWebhook_1.sendMessageToAgent.call(this, webhookUrl, userId, eventData);
31
31
  }
32
32
  case 'reportCallbackResult': {
33
33
  const apiOptions = getApiOptions(nodeParams);
@@ -38,7 +38,13 @@ async function handleEventByType(eventType, eventData, nodeParams) {
38
38
  const error = (nodeParams.callbackError ?? eventData.error);
39
39
  if (!messageId || !optionId || !userId)
40
40
  throw new Error('message_id, option_id and user_id are required for reportCallbackResult. Use data from button_clicked event.');
41
- return await (0, techWebhook_1.reportCallbackResult)(apiOptions, { messageId: String(messageId), optionId: String(optionId), userId, success, error });
41
+ return await techWebhook_1.reportCallbackResult.call(this, apiOptions, {
42
+ messageId: String(messageId),
43
+ optionId: String(optionId),
44
+ userId,
45
+ success,
46
+ error,
47
+ });
42
48
  }
43
49
  case 'sendMessageBackend':
44
50
  case 'sendVoiceMessageBackend':
@@ -51,7 +57,7 @@ async function handleEventByType(eventType, eventData, nodeParams) {
51
57
  const text = eventData.text ?? message?.text ?? null;
52
58
  if (!assistantId || !chatId)
53
59
  throw new Error('assistantId and chatId are required for send-message operations.');
54
- return await (0, techWebhook_1.sendMessageToBackend)(apiOptions, {
60
+ return await techWebhook_1.sendMessageToBackend.call(this, apiOptions, {
55
61
  assistantId: assistantId,
56
62
  chatId: chatId,
57
63
  sender: (eventData.sender ?? message?.sender ?? 'assistant'),
@@ -78,7 +84,7 @@ async function handleEventByType(eventType, eventData, nodeParams) {
78
84
  if (!assistant)
79
85
  throw new Error('Assistant data is required for createAssistant operation.');
80
86
  const { id: _id, userId: _u, ...assistantData } = assistant;
81
- return await (0, techWebhook_1.createAssistant)(getApiOptions(nodeParams), userId, assistantData);
87
+ return await techWebhook_1.createAssistant.call(this, getApiOptions(nodeParams), userId, assistantData);
82
88
  }
83
89
  case 'updateAssistant': {
84
90
  const userId = (nodeParams.userId ?? eventData.user_id ?? eventData.userId);
@@ -90,7 +96,7 @@ async function handleEventByType(eventType, eventData, nodeParams) {
90
96
  if (!assistantId)
91
97
  throw new Error('Assistant ID is required for updateAssistant operation.');
92
98
  const { id: _id, userId: _u, ...assistantData } = assistant;
93
- return await (0, techWebhook_1.updateAssistant)(getApiOptions(nodeParams), userId, String(assistantId), assistantData);
99
+ return await techWebhook_1.updateAssistant.call(this, getApiOptions(nodeParams), userId, String(assistantId), assistantData);
94
100
  }
95
101
  case 'deleteAssistant': {
96
102
  const userId = (nodeParams.userId ?? eventData.user_id ?? eventData.userId);
@@ -99,7 +105,7 @@ async function handleEventByType(eventType, eventData, nodeParams) {
99
105
  const assistantId = eventData.assistant_id ?? assistant?.id;
100
106
  if (!assistantId)
101
107
  throw new Error('Assistant ID is required for deleteAssistant operation.');
102
- return await (0, techWebhook_1.deleteAssistant)(getApiOptions(nodeParams), userId, String(assistantId));
108
+ return await techWebhook_1.deleteAssistant.call(this, getApiOptions(nodeParams), userId, String(assistantId));
103
109
  }
104
110
  case 'renameChat': {
105
111
  const userId = (nodeParams.userId ?? eventData.user_id ?? eventData.userId);
@@ -111,7 +117,7 @@ async function handleEventByType(eventType, eventData, nodeParams) {
111
117
  const newName = eventData.new_name ?? chat?.title;
112
118
  if (!chatId || !newName)
113
119
  throw new Error('Chat ID and new name are required for renameChat operation.');
114
- return await (0, techWebhook_1.renameChat)(getApiOptions(nodeParams), userId, String(chatId), String(newName));
120
+ return await techWebhook_1.renameChat.call(this, getApiOptions(nodeParams), userId, String(chatId), String(newName));
115
121
  }
116
122
  case 'deleteChat': {
117
123
  const userId = (nodeParams.userId ?? eventData.user_id ?? eventData.userId);
@@ -120,7 +126,7 @@ async function handleEventByType(eventType, eventData, nodeParams) {
120
126
  const chatId = eventData.chat_id ?? chat?.id;
121
127
  if (!chatId)
122
128
  throw new Error('Chat ID is required for deleteChat operation.');
123
- return await (0, techWebhook_1.deleteChat)(getApiOptions(nodeParams), userId, String(chatId));
129
+ return await techWebhook_1.deleteChat.call(this, getApiOptions(nodeParams), userId, String(chatId));
124
130
  }
125
131
  case 'saveChatHistory': {
126
132
  const userId = (nodeParams.userId ?? eventData.user_id ?? eventData.userId);
@@ -129,7 +135,7 @@ async function handleEventByType(eventType, eventData, nodeParams) {
129
135
  if (!eventData.message && !eventData.messages)
130
136
  throw new Error('Message or messages data is required for saveChatHistory operation.');
131
137
  const messages = (eventData.messages ?? [eventData.message]);
132
- return await (0, techWebhook_1.saveChatHistory)(getApiOptions(nodeParams), userId, messages);
138
+ return await techWebhook_1.saveChatHistory.call(this, getApiOptions(nodeParams), userId, messages);
133
139
  }
134
140
  default:
135
141
  throw new Error(`Unsupported operation: ${operation}`);
@@ -1,2 +1,2 @@
1
- export declare function retryWithBackoff<T>(fn: () => Promise<T>, maxRetries?: number, retryCount?: number): Promise<T>;
1
+ export declare function retryWithBackoff<T>(fn: () => Promise<T>): Promise<T>;
2
2
  export declare function rateLimitedRequest<T>(fn: () => Promise<T>): Promise<T>;
@@ -1,37 +1,12 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
6
3
  exports.retryWithBackoff = retryWithBackoff;
7
4
  exports.rateLimitedRequest = rateLimitedRequest;
8
- const bottleneck_1 = __importDefault(require("bottleneck"));
9
- const http_status_codes_1 = require("http-status-codes");
10
- const limiter = new bottleneck_1.default({
11
- reservoir: 30,
12
- reservoirRefreshAmount: 30,
13
- reservoirRefreshInterval: 1000,
14
- maxConcurrent: 1,
15
- minTime: 1000 / 30,
16
- });
17
- async function retryWithBackoff(fn, maxRetries = 5, retryCount = 0) {
18
- try {
19
- return await fn();
20
- }
21
- catch (error) {
22
- const err = error;
23
- const status = err?.response?.status ?? err?.status;
24
- const isRateLimitError = status === http_status_codes_1.StatusCodes.TOO_MANY_REQUESTS ||
25
- (err?.message && String(err.message).includes(String(http_status_codes_1.StatusCodes.TOO_MANY_REQUESTS)));
26
- if (isRateLimitError && retryCount < maxRetries) {
27
- const retryAfter = err?.response?.headers?.get?.('retry-after');
28
- const delay = retryAfter ? parseInt(retryAfter, 10) * 1000 : Math.min(1000 * 2 ** retryCount, 32000);
29
- await new Promise((resolve) => setTimeout(resolve, delay));
30
- return retryWithBackoff(fn, maxRetries, retryCount + 1);
31
- }
32
- throw error;
33
- }
5
+ async function retryWithBackoff(fn) {
6
+ // For verified community nodes, external dependencies and timers like setTimeout
7
+ // are restricted. Keep this helper as a simple pass-through.
8
+ return fn();
34
9
  }
35
10
  async function rateLimitedRequest(fn) {
36
- return limiter.schedule(() => retryWithBackoff(fn));
11
+ return retryWithBackoff(fn);
37
12
  }
@@ -1,20 +1,21 @@
1
+ import type { IExecuteFunctions } from 'n8n-workflow';
1
2
  export interface BgosApiOptions {
2
3
  baseUrl: string;
3
4
  apiKey?: string;
4
5
  }
5
- export declare function createAssistant(options: BgosApiOptions, userId: string, assistantData: Record<string, unknown>): Promise<unknown>;
6
- export declare function updateAssistant(options: BgosApiOptions, userId: string, assistantId: string | number, assistantData: Record<string, unknown>): Promise<unknown>;
7
- export declare function deleteAssistant(options: BgosApiOptions, _userId: string, assistantId: string | number): Promise<{
6
+ export declare function createAssistant(this: IExecuteFunctions, options: BgosApiOptions, userId: string, assistantData: Record<string, unknown>): Promise<unknown>;
7
+ export declare function updateAssistant(this: IExecuteFunctions, options: BgosApiOptions, userId: string, assistantId: string | number, assistantData: Record<string, unknown>): Promise<unknown>;
8
+ export declare function deleteAssistant(this: IExecuteFunctions, options: BgosApiOptions, _userId: string, assistantId: string | number): Promise<{
8
9
  success: boolean;
9
10
  }>;
10
- export declare function renameChat(options: BgosApiOptions, userId: string, chatId: string | number, newTitle: string): Promise<{
11
+ export declare function renameChat(this: IExecuteFunctions, options: BgosApiOptions, userId: string, chatId: string | number, newTitle: string): Promise<{
11
12
  success: boolean;
12
13
  }>;
13
- export declare function deleteChat(options: BgosApiOptions, _userId: string, chatId: string | number): Promise<{
14
+ export declare function deleteChat(this: IExecuteFunctions, options: BgosApiOptions, _userId: string, chatId: string | number): Promise<{
14
15
  success: boolean;
15
16
  }>;
16
- export declare function saveChatHistory(options: BgosApiOptions, _userId: string, messages: unknown[]): Promise<unknown>;
17
- export declare function sendMessageToBackend(options: BgosApiOptions, payload: {
17
+ export declare function saveChatHistory(this: IExecuteFunctions, options: BgosApiOptions, _userId: string, messages: unknown[]): Promise<unknown>;
18
+ export declare function sendMessageToBackend(this: IExecuteFunctions, options: BgosApiOptions, payload: {
18
19
  assistantId: string | number;
19
20
  chatId: string | number;
20
21
  sender?: string;
@@ -32,7 +33,7 @@ export declare function sendMessageToBackend(options: BgosApiOptions, payload: {
32
33
  isMixedAttachments?: boolean | null;
33
34
  [key: string]: unknown;
34
35
  }): Promise<unknown>;
35
- export declare function reportCallbackResult(options: BgosApiOptions, payload: {
36
+ export declare function reportCallbackResult(this: IExecuteFunctions, options: BgosApiOptions, payload: {
36
37
  messageId: number | string;
37
38
  optionId: number | string;
38
39
  userId: string;
@@ -1,7 +1,4 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
6
3
  exports.createAssistant = createAssistant;
7
4
  exports.updateAssistant = updateAssistant;
@@ -11,10 +8,6 @@ exports.deleteChat = deleteChat;
11
8
  exports.saveChatHistory = saveChatHistory;
12
9
  exports.sendMessageToBackend = sendMessageToBackend;
13
10
  exports.reportCallbackResult = reportCallbackResult;
14
- /**
15
- * HTTP calls to BGOS backend REST API (api/v1/assistants, chats, messages).
16
- */
17
- const node_fetch_1 = __importDefault(require("node-fetch"));
18
11
  function buildHeaders(apiKey) {
19
12
  const headers = { 'Content-Type': 'application/json', Accept: 'application/json' };
20
13
  if (apiKey)
@@ -23,49 +16,53 @@ function buildHeaders(apiKey) {
23
16
  }
24
17
  async function createAssistant(options, userId, assistantData) {
25
18
  const url = `${options.baseUrl.replace(/\/$/, '')}/api/v1/assistants`;
26
- const response = await (0, node_fetch_1.default)(url, {
19
+ return this.helpers.httpRequest({
27
20
  method: 'POST',
21
+ url,
28
22
  headers: buildHeaders(options.apiKey),
29
- body: JSON.stringify({ userId, ...assistantData }),
23
+ body: { userId, ...assistantData },
24
+ json: true,
30
25
  });
31
- if (!response.ok)
32
- throw new Error(`Failed to create assistant: ${response.status} ${response.statusText} - ${await response.text()}`);
33
- return response.json();
34
26
  }
35
27
  async function updateAssistant(options, userId, assistantId, assistantData) {
36
28
  const url = `${options.baseUrl.replace(/\/$/, '')}/api/v1/assistants/${assistantId}`;
37
- const response = await (0, node_fetch_1.default)(url, {
29
+ return this.helpers.httpRequest({
38
30
  method: 'PATCH',
31
+ url,
39
32
  headers: buildHeaders(options.apiKey),
40
- body: JSON.stringify({ userId, ...assistantData }),
33
+ body: { userId, ...assistantData },
34
+ json: true,
41
35
  });
42
- if (!response.ok)
43
- throw new Error(`Failed to update assistant: ${response.status} ${response.statusText} - ${await response.text()}`);
44
- return response.json();
45
36
  }
46
37
  async function deleteAssistant(options, _userId, assistantId) {
47
38
  const url = `${options.baseUrl.replace(/\/$/, '')}/api/v1/assistants/${assistantId}`;
48
- const response = await (0, node_fetch_1.default)(url, { method: 'DELETE', headers: buildHeaders(options.apiKey) });
49
- if (!response.ok)
50
- throw new Error(`Failed to delete assistant: ${response.status} ${response.statusText} - ${await response.text()}`);
39
+ await this.helpers.httpRequest({
40
+ method: 'DELETE',
41
+ url,
42
+ headers: buildHeaders(options.apiKey),
43
+ json: false,
44
+ });
51
45
  return { success: true };
52
46
  }
53
47
  async function renameChat(options, userId, chatId, newTitle) {
54
48
  const url = `${options.baseUrl.replace(/\/$/, '')}/api/v1/chats/${chatId}/title`;
55
- const response = await (0, node_fetch_1.default)(url, {
49
+ await this.helpers.httpRequest({
56
50
  method: 'PATCH',
51
+ url,
57
52
  headers: buildHeaders(options.apiKey),
58
- body: JSON.stringify({ userId, title: newTitle }),
53
+ body: { userId, title: newTitle },
54
+ json: true,
59
55
  });
60
- if (!response.ok)
61
- throw new Error(`Failed to rename chat: ${response.status} ${response.statusText} - ${await response.text()}`);
62
56
  return { success: true };
63
57
  }
64
58
  async function deleteChat(options, _userId, chatId) {
65
59
  const url = `${options.baseUrl.replace(/\/$/, '')}/api/v1/chats/${chatId}`;
66
- const response = await (0, node_fetch_1.default)(url, { method: 'DELETE', headers: buildHeaders(options.apiKey) });
67
- if (!response.ok)
68
- throw new Error(`Failed to delete chat: ${response.status} ${response.statusText} - ${await response.text()}`);
60
+ await this.helpers.httpRequest({
61
+ method: 'DELETE',
62
+ url,
63
+ headers: buildHeaders(options.apiKey),
64
+ json: false,
65
+ });
69
66
  return { success: true };
70
67
  }
71
68
  async function saveChatHistory(options, _userId, messages) {
@@ -76,14 +73,13 @@ async function saveChatHistory(options, _userId, messages) {
76
73
  text: (m.text ?? m.message?.text ?? ''),
77
74
  sentDate: (m.sentDate ?? m.sent_date ?? m.message?.sentDate ?? m.timestamp ?? new Date().toISOString()),
78
75
  }));
79
- const response = await (0, node_fetch_1.default)(url, {
76
+ return this.helpers.httpRequest({
80
77
  method: 'POST',
78
+ url,
81
79
  headers: buildHeaders(options.apiKey),
82
- body: JSON.stringify(dtos),
80
+ body: dtos,
81
+ json: true,
83
82
  });
84
- if (!response.ok)
85
- throw new Error(`Failed to save chat history: ${response.status} ${response.statusText} - ${await response.text()}`);
86
- return response.json();
87
83
  }
88
84
  async function sendMessageToBackend(options, payload) {
89
85
  const url = `${options.baseUrl.replace(/\/$/, '')}/api/v1/send-message`;
@@ -105,29 +101,28 @@ async function sendMessageToBackend(options, payload) {
105
101
  options: payload.options ?? [],
106
102
  files: payload.files ?? [],
107
103
  };
108
- const response = await (0, node_fetch_1.default)(url, {
104
+ return this.helpers.httpRequest({
109
105
  method: 'POST',
106
+ url,
110
107
  headers: buildHeaders(options.apiKey),
111
- body: JSON.stringify(body),
108
+ body,
109
+ json: true,
112
110
  });
113
- if (!response.ok)
114
- throw new Error(`Failed to send message to BGOS backend: ${response.status} ${response.statusText} - ${await response.text()}`);
115
- return response.json();
116
111
  }
117
112
  async function reportCallbackResult(options, payload) {
118
113
  const url = `${options.baseUrl.replace(/\/$/, '')}/api/v1/messages/callback-result`;
119
- const response = await (0, node_fetch_1.default)(url, {
114
+ const body = {
115
+ messageId: Number(payload.messageId),
116
+ optionId: Number(payload.optionId),
117
+ userId: payload.userId,
118
+ success: payload.success,
119
+ error: payload.error,
120
+ };
121
+ return this.helpers.httpRequest({
120
122
  method: 'POST',
123
+ url,
121
124
  headers: buildHeaders(options.apiKey),
122
- body: JSON.stringify({
123
- messageId: Number(payload.messageId),
124
- optionId: Number(payload.optionId),
125
- userId: payload.userId,
126
- success: payload.success,
127
- error: payload.error,
128
- }),
125
+ body,
126
+ json: true,
129
127
  });
130
- if (!response.ok)
131
- throw new Error(`Failed to report callback result: ${response.status} ${response.statusText} - ${await response.text()}`);
132
- return response.json();
133
128
  }
@@ -1,11 +1,7 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
6
3
  exports.BgosTrigger = void 0;
7
4
  const n8n_workflow_1 = require("n8n-workflow");
8
- const node_fetch_1 = __importDefault(require("node-fetch"));
9
5
  const stubs_1 = require("./stubs");
10
6
  class BgosTrigger {
11
7
  description = {
@@ -95,15 +91,13 @@ class BgosTrigger {
95
91
  const url = `${String(baseUrl).replace(/\/$/, '')}/api/v1/webhooks`;
96
92
  const webhookUrl = this.getNodeWebhookUrl('default');
97
93
  const updates = this.getNodeParameter('updates', 0);
98
- const response = await (0, node_fetch_1.default)(url, {
94
+ const data = (await this.helpers.httpRequest({
99
95
  method: 'POST',
96
+ url,
100
97
  headers: { 'Content-Type': 'application/json', 'X-API-Key': apiKey },
101
- body: JSON.stringify({ webhookUrl, eventTypes: updates?.length ? updates : ['*'] }),
102
- });
103
- if (!response.ok) {
104
- throw new Error(`Failed to register BGOS webhook: ${response.status} ${response.statusText} - ${await response.text()}`);
105
- }
106
- const data = (await response.json());
98
+ body: { webhookUrl, eventTypes: updates?.length ? updates : ['*'] },
99
+ json: true,
100
+ }));
107
101
  if (data?.id != null) {
108
102
  const staticData = this.getWorkflowStaticData('node');
109
103
  staticData.webhookSubscriptionId = String(data.id);
@@ -120,18 +114,15 @@ class BgosTrigger {
120
114
  return true;
121
115
  const url = `${String(baseUrl).replace(/\/$/, '')}/api/v1/webhooks/${subscriptionId}`;
122
116
  try {
123
- const response = await (0, node_fetch_1.default)(url, {
117
+ await this.helpers.httpRequest({
124
118
  method: 'DELETE',
119
+ url,
125
120
  headers: { 'Content-Type': 'application/json', 'X-API-Key': apiKey },
121
+ json: false,
126
122
  });
127
- if (!response.ok) {
128
- // eslint-disable-next-line no-console
129
- console.error(`Failed to delete BGOS webhook ${subscriptionId}: ${response.status} ${response.statusText}`);
130
- }
131
123
  }
132
124
  catch (error) {
133
- // eslint-disable-next-line no-console
134
- console.error(`Error deleting BGOS webhook ${subscriptionId}:`, error);
125
+ // Best-effort cleanup; ignore errors when deleting remote webhook
135
126
  }
136
127
  delete staticData.webhookSubscriptionId;
137
128
  return true;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "n8n-nodes-bgos",
3
- "version": "0.3.0",
3
+ "version": "0.3.1",
4
4
  "description": "n8n community nodes for BGOS (Brand Growth OS) - AI assistant chat platform",
5
5
  "keywords": [
6
6
  "n8n-community-node-package",
@@ -41,12 +41,7 @@
41
41
  "dist/nodes/BGOSAction/BGOSAction.node.js"
42
42
  ]
43
43
  },
44
- "dependencies": {
45
- "bottleneck": "^2.19.5",
46
- "form-data": "^4.0.0",
47
- "http-status-codes": "^2.3.0",
48
- "node-fetch": "^3.3.2"
49
- },
44
+ "dependencies": {},
50
45
  "devDependencies": {
51
46
  "@types/node": "^20.0.0",
52
47
  "@typescript-eslint/parser": "~7.18.0",