n8n-nodes-signal-cli-rest-api 0.2.2 → 0.3.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.
@@ -1,9 +1,11 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Signal = void 0;
4
+ const n8n_workflow_1 = require("n8n-workflow");
4
5
  const messages_1 = require("./messages");
5
6
  const groups_1 = require("./groups");
6
7
  const contacts_1 = require("./contacts");
8
+ const attachments_1 = require("./attachments");
7
9
  class Signal {
8
10
  constructor() {
9
11
  this.description = {
@@ -56,6 +58,24 @@ class Signal {
56
58
  description: 'Remove a reaction from a message',
57
59
  action: 'Remove a reaction',
58
60
  },
61
+ {
62
+ name: 'Attachments: List Attachments',
63
+ value: 'listAttachments',
64
+ description: 'List attachments for the account',
65
+ action: 'List attachments',
66
+ },
67
+ {
68
+ name: 'Attachments: Download Attachment',
69
+ value: 'downloadAttachment',
70
+ description: 'Download an attachment as binary file',
71
+ action: 'Download attachment',
72
+ },
73
+ {
74
+ name: 'Attachments: Remove Attachment',
75
+ value: 'removeAttachment',
76
+ description: 'Remove an attachment',
77
+ action: 'Remove attachment',
78
+ },
59
79
  {
60
80
  name: 'Contacts: Get Contacts',
61
81
  value: 'getContacts',
@@ -174,46 +194,16 @@ class Signal {
174
194
  allowCustom: true,
175
195
  },
176
196
  options: [
177
- {
178
- name: 'Thumbs Up',
179
- value: '👍',
180
- },
181
- {
182
- name: 'Heart',
183
- value: '❤️',
184
- },
185
- {
186
- name: 'Smile',
187
- value: '😄',
188
- },
189
- {
190
- name: 'Sad',
191
- value: '😢',
192
- },
193
- {
194
- name: 'Angry',
195
- value: '😣',
196
- },
197
- {
198
- name: 'Star',
199
- value: '⭐',
200
- },
201
- {
202
- name: 'Fire',
203
- value: '🔥',
204
- },
205
- {
206
- name: 'Plus',
207
- value: '➕',
208
- },
209
- {
210
- name: 'Minus',
211
- value: '➖',
212
- },
213
- {
214
- name: 'Handshake',
215
- value: '🤝',
216
- },
197
+ { name: 'Thumbs Up', value: '👍' },
198
+ { name: 'Heart', value: '❤️' },
199
+ { name: 'Smile', value: '😄' },
200
+ { name: 'Sad', value: '😢' },
201
+ { name: 'Angry', value: '😣' },
202
+ { name: 'Star', value: '⭐' },
203
+ { name: 'Fire', value: '🔥' },
204
+ { name: 'Plus', value: '➕' },
205
+ { name: 'Minus', value: '➖' },
206
+ { name: 'Handshake', value: '🤝' },
217
207
  ],
218
208
  displayOptions: {
219
209
  show: {
@@ -248,6 +238,20 @@ class Signal {
248
238
  },
249
239
  },
250
240
  },
241
+ {
242
+ displayName: 'Attachment ID',
243
+ name: 'attachmentId',
244
+ type: 'string',
245
+ default: '',
246
+ placeholder: 'attachment_id_from_trigger.png',
247
+ description: 'ID of the attachment to download or remove',
248
+ required: true,
249
+ displayOptions: {
250
+ show: {
251
+ operation: ['downloadAttachment', 'removeAttachment'],
252
+ },
253
+ },
254
+ },
251
255
  {
252
256
  displayName: 'Timeout (seconds)',
253
257
  name: 'timeout',
@@ -256,7 +260,7 @@ class Signal {
256
260
  description: 'Request timeout in seconds (set higher for Get Groups, e.g., 300)',
257
261
  displayOptions: {
258
262
  show: {
259
- operation: ['sendMessage', 'sendAttachment', 'sendReaction', 'removeReaction', 'getContacts', 'getGroups', 'createGroup', 'updateGroup'],
263
+ operation: ['sendMessage', 'sendAttachment', 'sendReaction', 'removeReaction', 'getContacts', 'getGroups', 'createGroup', 'updateGroup', 'listAttachments', 'downloadAttachment', 'removeAttachment'],
260
264
  },
261
265
  },
262
266
  typeOptions: {
@@ -276,6 +280,7 @@ class Signal {
276
280
  const apiUrl = credentials.apiUrl;
277
281
  const apiToken = credentials.apiToken;
278
282
  const phoneNumber = credentials.phoneNumber;
283
+ this.logger.debug(`Signal: Starting execute for operation ${operation}, items length: ${items.length}`);
279
284
  for (let i = 0; i < items.length; i++) {
280
285
  const timeout = this.getNodeParameter('timeout', i, operation === 'getGroups' ? 300 : 60) * 1000;
281
286
  const params = {
@@ -288,29 +293,38 @@ class Signal {
288
293
  emoji: this.getNodeParameter('emoji', i, ''),
289
294
  targetAuthor: this.getNodeParameter('targetAuthor', i, ''),
290
295
  targetSentTimestamp: this.getNodeParameter('targetSentTimestamp', i, 0),
296
+ attachmentId: this.getNodeParameter('attachmentId', i, ''),
291
297
  timeout,
292
298
  apiUrl,
293
299
  apiToken,
294
300
  phoneNumber,
295
301
  };
296
302
  try {
303
+ let result;
297
304
  if (['sendMessage', 'sendAttachment', 'sendReaction', 'removeReaction'].includes(operation)) {
298
- const result = await messages_1.executeMessagesOperation.call(this, operation, i, params);
299
- returnData.push(result);
305
+ result = await messages_1.executeMessagesOperation.call(this, operation, i, params);
306
+ }
307
+ else if (['listAttachments', 'downloadAttachment', 'removeAttachment'].includes(operation)) {
308
+ result = await attachments_1.executeAttachmentsOperation.call(this, operation, i, params);
300
309
  }
301
310
  else if (['getGroups', 'createGroup', 'updateGroup'].includes(operation)) {
302
- const result = await groups_1.executeGroupsOperation.call(this, operation, i, params);
303
- returnData.push(result);
311
+ result = await groups_1.executeGroupsOperation.call(this, operation, i, params);
304
312
  }
305
313
  else if (operation === 'getContacts') {
306
- const result = await contacts_1.executeContactsOperation.call(this, operation, i, params);
307
- returnData.push(result);
314
+ result = await contacts_1.executeContactsOperation.call(this, operation, i, params);
315
+ }
316
+ else {
317
+ throw new n8n_workflow_1.NodeApiError(this.getNode(), { message: 'Unknown operation' });
308
318
  }
319
+ this.logger.info(`Signal: Operation ${operation} result for item ${i}: ${JSON.stringify(result.json || result.binary, null, 2)}`);
320
+ returnData.push(result);
309
321
  }
310
322
  catch (error) {
323
+ this.logger.error(`Signal: Error in operation ${operation} for item ${i}`, { error });
311
324
  throw error;
312
325
  }
313
326
  }
327
+ this.logger.debug(`Signal: Returning data length: ${returnData.length}`);
314
328
  return [returnData];
315
329
  }
316
330
  }
@@ -35,25 +35,25 @@ class SignalTrigger {
35
35
  },
36
36
  },
37
37
  {
38
- displayName: 'Only With Text',
39
- name: 'onlyWithText',
38
+ displayName: 'Ignore Messages',
39
+ name: 'ignoreMessages',
40
40
  type: 'boolean',
41
- default: true,
42
- description: 'Retrieve only messages with text content',
41
+ default: false,
42
+ description: 'Enable to ignore messages with text content',
43
43
  },
44
44
  {
45
- displayName: 'Only With Attachments',
46
- name: 'onlyWithAttachments',
45
+ displayName: 'Ignore Attachments',
46
+ name: 'ignoreAttachments',
47
47
  type: 'boolean',
48
48
  default: false,
49
- description: 'Retrieve only messages with attachments',
49
+ description: 'Enable to ignore messages with attachments',
50
50
  },
51
51
  {
52
- displayName: 'Only With Reactions',
53
- name: 'onlyWithReactions',
52
+ displayName: 'Ignore Reactions',
53
+ name: 'ignoreReactions',
54
54
  type: 'boolean',
55
55
  default: false,
56
- description: 'Retrieve only messages with reactions',
56
+ description: 'Enable to ignore messages with reactions',
57
57
  },
58
58
  ],
59
59
  };
@@ -64,21 +64,25 @@ class SignalTrigger {
64
64
  const apiToken = credentials.apiToken;
65
65
  const phoneNumber = credentials.phoneNumber;
66
66
  const reconnectDelay = this.getNodeParameter('reconnectDelay', 0) * 1000;
67
- const onlyWithText = this.getNodeParameter('onlyWithText', 0);
68
- const onlyWithAttachments = this.getNodeParameter('onlyWithAttachments', 0);
69
- const onlyWithReactions = this.getNodeParameter('onlyWithReactions', 0);
67
+ const ignoreMessages = this.getNodeParameter('ignoreMessages', 0);
68
+ const ignoreAttachments = this.getNodeParameter('ignoreAttachments', 0);
69
+ const ignoreReactions = this.getNodeParameter('ignoreReactions', 0);
70
70
  const wsUrl = `${apiUrl.replace('http', 'ws')}/v1/receive/${phoneNumber}`;
71
+ this.logger.debug(`SignalTrigger: Attempting to connect to WS URL: ${wsUrl}`);
71
72
  const processedMessages = new Set();
72
73
  const maxMessages = 1000;
73
74
  const connectWebSocket = () => {
74
75
  const ws = new ws_1.WebSocket(wsUrl, {
75
76
  headers: apiToken ? { Authorization: `Bearer ${apiToken}` } : {},
76
77
  });
78
+ ws.on('open', () => {
79
+ this.logger.debug(`SignalTrigger: Successfully connected to ${wsUrl}`);
80
+ });
77
81
  ws.on('message', (data) => {
78
82
  var _a, _b, _c, _d, _e;
79
83
  try {
80
84
  const message = JSON.parse(data.toString());
81
- this.logger.debug(`SignalTrigger: Received message: ${JSON.stringify(message, null, 2)}`);
85
+ this.logger.debug(`SignalTrigger: Received raw message: ${JSON.stringify(message, null, 2)}`);
82
86
  const timestamp = ((_a = message.envelope) === null || _a === void 0 ? void 0 : _a.timestamp) || 0;
83
87
  if (processedMessages.has(timestamp)) {
84
88
  this.logger.debug(`SignalTrigger: Skipping duplicate message with timestamp ${timestamp}`);
@@ -97,6 +101,7 @@ class SignalTrigger {
97
101
  timestamp: timestamp,
98
102
  account: message.account || '',
99
103
  };
104
+ this.logger.debug(`SignalTrigger: Processed message content: ${JSON.stringify(processedMessage, null, 2)}`);
100
105
  // Ігнорувати події без вмісту
101
106
  if (!processedMessage.messageText &&
102
107
  processedMessage.attachments.length === 0 &&
@@ -104,11 +109,11 @@ class SignalTrigger {
104
109
  this.logger.debug(`SignalTrigger: Skipping empty message with timestamp ${timestamp}`);
105
110
  return;
106
111
  }
107
- // Фільтрація за параметрами
108
- if ((onlyWithText && !processedMessage.messageText) ||
109
- (onlyWithAttachments && processedMessage.attachments.length === 0) ||
110
- (onlyWithReactions && processedMessage.reactions.length === 0)) {
111
- this.logger.debug(`SignalTrigger: Skipping filtered message with timestamp ${timestamp}`);
112
+ // Фільтрація: ігнорувати, якщо увімкнено ignore і відповідний вміст присутній
113
+ if ((ignoreMessages && processedMessage.messageText) ||
114
+ (ignoreAttachments && processedMessage.attachments.length > 0) ||
115
+ (ignoreReactions && processedMessage.reactions.length > 0)) {
116
+ this.logger.debug(`SignalTrigger: Ignoring message with timestamp ${timestamp} due to filter`);
112
117
  return;
113
118
  }
114
119
  const returnData = {
@@ -134,7 +139,7 @@ class SignalTrigger {
134
139
  const ws = connectWebSocket();
135
140
  return new Promise((resolve, reject) => {
136
141
  ws.on('open', () => {
137
- this.logger.debug(`SignalTrigger: Connected to ${wsUrl}`);
142
+ this.logger.debug(`SignalTrigger: Initial connection to ${wsUrl}`);
138
143
  resolve({
139
144
  closeFunction: async () => {
140
145
  ws.close();
@@ -0,0 +1,10 @@
1
+ import { IExecuteFunctions, INodeExecutionData } from 'n8n-workflow';
2
+ interface OperationParams {
3
+ attachmentId?: string;
4
+ timeout: number;
5
+ apiUrl: string;
6
+ apiToken: string;
7
+ phoneNumber: string;
8
+ }
9
+ export declare function executeAttachmentsOperation(this: IExecuteFunctions, operation: string, itemIndex: number, params: OperationParams): Promise<INodeExecutionData>;
10
+ export {};
@@ -0,0 +1,152 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.executeAttachmentsOperation = void 0;
7
+ const n8n_workflow_1 = require("n8n-workflow");
8
+ const axios_1 = __importDefault(require("axios"));
9
+ async function executeAttachmentsOperation(operation, itemIndex, params) {
10
+ var _a, _b, _c, _d, _e;
11
+ const { attachmentId, timeout, apiUrl, apiToken, phoneNumber } = params;
12
+ const axiosConfig = {
13
+ headers: apiToken ? { Authorization: `Bearer ${apiToken}` } : {},
14
+ timeout,
15
+ responseType: operation === 'downloadAttachment' ? 'arraybuffer' : 'json',
16
+ };
17
+ const retryRequest = async (request, retries = 2, delay = 5000) => {
18
+ for (let attempt = 1; attempt <= retries; attempt++) {
19
+ try {
20
+ return await request();
21
+ }
22
+ catch (error) {
23
+ if (attempt === retries)
24
+ throw error;
25
+ await new Promise(resolve => setTimeout(resolve, delay));
26
+ }
27
+ }
28
+ };
29
+ try {
30
+ if (operation === 'listAttachments') {
31
+ const response = await retryRequest(() => axios_1.default.get(`${apiUrl}/v1/attachments/${phoneNumber}`, axiosConfig));
32
+ return { json: response.data, pairedItem: { item: itemIndex } };
33
+ }
34
+ else if (operation === 'downloadAttachment') {
35
+ if (!attachmentId) {
36
+ throw new n8n_workflow_1.NodeApiError(this.getNode(), { message: 'Attachment ID is required' });
37
+ }
38
+ const endpoint = `${apiUrl}/v1/attachments/${attachmentId}`;
39
+ this.logger.debug(`Attachments: Downloading from endpoint: ${endpoint}`);
40
+ const response = await retryRequest(() => axios_1.default.get(endpoint, axiosConfig));
41
+ this.logger.debug(`Attachments: Download response size: ${response.data.byteLength}, content-type: ${response.headers['content-type']}`);
42
+ if (!response.data || response.data.byteLength === 0) {
43
+ this.logger.warn(`Attachments: Empty response data for attachment ${attachmentId}`);
44
+ return { json: { status: 'Empty attachment' }, pairedItem: { item: itemIndex } };
45
+ }
46
+ const contentType = response.headers['content-type'] || 'application/octet-stream';
47
+ const contentDisposition = response.headers['content-disposition'] || '';
48
+ const fileName = ((_a = contentDisposition.match(/filename="(.+)"/)) === null || _a === void 0 ? void 0 : _a[1]) || `attachment_${attachmentId}`;
49
+ const fileExtension = fileName.split('.').pop() || '';
50
+ // Конвертуємо ArrayBuffer в Buffer для n8n
51
+ const buffer = Buffer.from(response.data);
52
+ this.logger.debug(`Attachments: Created buffer of size: ${buffer.length}`);
53
+ // Збираємо всі доступні headers
54
+ const allHeaders = response.headers || {};
55
+ // Визначаємо тип файлу
56
+ const isImage = contentType.startsWith('image/');
57
+ const isVideo = contentType.startsWith('video/');
58
+ const isAudio = contentType.startsWith('audio/');
59
+ const isDocument = contentType.includes('pdf') || contentType.includes('document') || contentType.includes('text');
60
+ // Форматуємо розмір файлу
61
+ const formatFileSize = (bytes) => {
62
+ if (bytes === 0)
63
+ return '0 Bytes';
64
+ const k = 1024;
65
+ const sizes = ['Bytes', 'KB', 'MB', 'GB'];
66
+ const i = Math.floor(Math.log(bytes) / Math.log(k));
67
+ return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
68
+ };
69
+ return {
70
+ json: {
71
+ // Основна інформація про файл
72
+ attachmentId,
73
+ fileName,
74
+ fileExtension,
75
+ mimeType: contentType,
76
+ // Розмір файлу
77
+ sizeBytes: buffer.length,
78
+ sizeFormatted: formatFileSize(buffer.length),
79
+ // Тип файлу
80
+ fileType: {
81
+ isImage,
82
+ isVideo,
83
+ isAudio,
84
+ isDocument,
85
+ category: isImage ? 'Image' : isVideo ? 'Video' : isAudio ? 'Audio' : isDocument ? 'Document' : 'Other'
86
+ },
87
+ // HTTP headers від API
88
+ headers: Object.keys(allHeaders).reduce((acc, key) => {
89
+ const value = allHeaders[key];
90
+ if (value !== null && value !== undefined && value !== '') {
91
+ acc[key] = value;
92
+ }
93
+ return acc;
94
+ }, {}),
95
+ // Додаткова інформація
96
+ downloadInfo: {
97
+ endpoint,
98
+ downloadedAt: new Date().toISOString(),
99
+ contentDisposition: contentDisposition || null,
100
+ hasValidContent: buffer.length > 0,
101
+ isEmpty: buffer.length === 0
102
+ },
103
+ // Статус завантаження
104
+ status: buffer.length > 0 ? 'downloaded_successfully' : 'empty_attachment'
105
+ },
106
+ binary: {
107
+ attachment: {
108
+ data: buffer.toString('base64'),
109
+ mimeType: contentType,
110
+ fileName: fileName,
111
+ fileExtension,
112
+ // Додаткові метадані для binary даних
113
+ fileSize: buffer.length,
114
+ id: attachmentId,
115
+ directory: `/attachments/${phoneNumber}`,
116
+ // Додаткові поля які можуть бути корисними
117
+ encoding: 'base64',
118
+ originalName: fileName,
119
+ downloadedFrom: endpoint,
120
+ downloadedAt: new Date().toISOString(),
121
+ // Якщо є content-disposition, додаємо його
122
+ ...(contentDisposition && { contentDisposition }),
123
+ // Категорія файлу для зручності
124
+ category: isImage ? 'image' : isVideo ? 'video' : isAudio ? 'audio' : isDocument ? 'document' : 'other',
125
+ // MD5 хеш для ідентифікації (опціонально)
126
+ ...(buffer.length > 0 && {
127
+ checksum: require('crypto').createHash('md5').update(buffer).digest('hex')
128
+ })
129
+ }
130
+ },
131
+ pairedItem: { item: itemIndex }
132
+ };
133
+ }
134
+ else if (operation === 'removeAttachment') {
135
+ if (!attachmentId) {
136
+ throw new n8n_workflow_1.NodeApiError(this.getNode(), { message: 'Attachment ID is required' });
137
+ }
138
+ const response = await retryRequest(() => axios_1.default.delete(`${apiUrl}/v1/attachments/${attachmentId}`, axiosConfig));
139
+ return { json: response.data || { status: 'Attachment removed' }, pairedItem: { item: itemIndex } };
140
+ }
141
+ throw new n8n_workflow_1.NodeApiError(this.getNode(), { message: 'Unknown operation' });
142
+ }
143
+ catch (error) {
144
+ const axiosError = error;
145
+ throw new n8n_workflow_1.NodeApiError(this.getNode(), {
146
+ message: axiosError.message,
147
+ description: (((_c = (_b = axiosError.response) === null || _b === void 0 ? void 0 : _b.data) === null || _c === void 0 ? void 0 : _c.error) || axiosError.message),
148
+ httpCode: ((_e = (_d = axiosError.response) === null || _d === void 0 ? void 0 : _d.status) === null || _e === void 0 ? void 0 : _e.toString()) || 'unknown',
149
+ }, { itemIndex });
150
+ }
151
+ }
152
+ exports.executeAttachmentsOperation = executeAttachmentsOperation;
@@ -32,7 +32,7 @@ async function executeMessagesOperation(operation, itemIndex, params) {
32
32
  number: phoneNumber,
33
33
  recipients: [recipient],
34
34
  }, axiosConfig));
35
- return { json: response.data, pairedItem: { item: itemIndex } };
35
+ return { json: response.data || { status: 'Message sent' }, pairedItem: { item: itemIndex } };
36
36
  }
37
37
  else if (operation === 'sendAttachment') {
38
38
  const response = await retryRequest(() => axios_1.default.post(`${apiUrl}/v1/send`, {
@@ -41,7 +41,7 @@ async function executeMessagesOperation(operation, itemIndex, params) {
41
41
  recipients: [recipient],
42
42
  attachments: [attachmentUrl],
43
43
  }, axiosConfig));
44
- return { json: response.data, pairedItem: { item: itemIndex } };
44
+ return { json: response.data || { status: 'Attachment sent' }, pairedItem: { item: itemIndex } };
45
45
  }
46
46
  else if (operation === 'sendReaction') {
47
47
  const response = await retryRequest(() => axios_1.default.post(`${apiUrl}/v1/reactions/${phoneNumber}`, {
@@ -50,7 +50,7 @@ async function executeMessagesOperation(operation, itemIndex, params) {
50
50
  target_author: targetAuthor,
51
51
  timestamp: targetSentTimestamp,
52
52
  }, axiosConfig));
53
- return { json: response.data, pairedItem: { item: itemIndex } };
53
+ return { json: response.data || { status: 'Reaction sent' }, pairedItem: { item: itemIndex } };
54
54
  }
55
55
  else if (operation === 'removeReaction') {
56
56
  const response = await retryRequest(() => axios_1.default.delete(`${apiUrl}/v1/reactions/${phoneNumber}`, {
@@ -0,0 +1,10 @@
1
+ import { IExecuteFunctions, INodeExecutionData } from 'n8n-workflow';
2
+ interface MessageHistoryParams {
3
+ timeout: number;
4
+ fullHistory: boolean;
5
+ apiUrl: string;
6
+ apiToken: string;
7
+ phoneNumber: string;
8
+ }
9
+ export declare function getMessageHistory(this: IExecuteFunctions, params: MessageHistoryParams): Promise<INodeExecutionData[]>;
10
+ export {};
@@ -0,0 +1,58 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.getMessageHistory = void 0;
7
+ const n8n_workflow_1 = require("n8n-workflow");
8
+ const axios_1 = __importDefault(require("axios"));
9
+ async function getMessageHistory(params) {
10
+ var _a, _b, _c, _d;
11
+ const { timeout, fullHistory, apiUrl, apiToken, phoneNumber } = params;
12
+ const axiosConfig = {
13
+ headers: apiToken ? { Authorization: `Bearer ${apiToken}` } : {},
14
+ timeout,
15
+ };
16
+ const retryRequest = async (request, retries = 2, delay = 5000) => {
17
+ for (let attempt = 1; attempt <= retries; attempt++) {
18
+ try {
19
+ return await request();
20
+ }
21
+ catch (error) {
22
+ if (attempt === retries)
23
+ throw error;
24
+ await new Promise(resolve => setTimeout(resolve, delay));
25
+ }
26
+ }
27
+ };
28
+ try {
29
+ const url = fullHistory
30
+ ? `${apiUrl}/v1/receive/${phoneNumber}`
31
+ : `${apiUrl}/v1/receive/${phoneNumber}?timeout=${timeout / 1000}`;
32
+ const response = await retryRequest(() => axios_1.default.get(url, axiosConfig));
33
+ const messages = Array.isArray(response.data) ? response.data : [];
34
+ return messages.map((message, index) => {
35
+ var _a, _b, _c, _d, _e, _f, _g, _h;
36
+ return ({
37
+ json: {
38
+ messageText: ((_b = (_a = message.envelope) === null || _a === void 0 ? void 0 : _a.dataMessage) === null || _b === void 0 ? void 0 : _b.message) || '',
39
+ attachments: ((_d = (_c = message.envelope) === null || _c === void 0 ? void 0 : _c.dataMessage) === null || _d === void 0 ? void 0 : _d.attachments) || [],
40
+ reactions: ((_f = (_e = message.envelope) === null || _e === void 0 ? void 0 : _e.dataMessage) === null || _f === void 0 ? void 0 : _f.reactions) || [],
41
+ sourceNumber: ((_g = message.envelope) === null || _g === void 0 ? void 0 : _g.sourceNumber) || '',
42
+ timestamp: ((_h = message.envelope) === null || _h === void 0 ? void 0 : _h.timestamp) || 0,
43
+ account: message.account || '',
44
+ },
45
+ pairedItem: { item: index },
46
+ });
47
+ });
48
+ }
49
+ catch (error) {
50
+ const axiosError = error;
51
+ throw new n8n_workflow_1.NodeApiError(this.getNode(), {
52
+ message: axiosError.message,
53
+ description: (((_b = (_a = axiosError.response) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.error) || axiosError.message),
54
+ httpCode: ((_d = (_c = axiosError.response) === null || _c === void 0 ? void 0 : _c.status) === null || _d === void 0 ? void 0 : _d.toString()) || 'unknown',
55
+ });
56
+ }
57
+ }
58
+ exports.getMessageHistory = getMessageHistory;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "n8n-nodes-signal-cli-rest-api",
3
- "version": "0.2.2",
3
+ "version": "0.3.0",
4
4
  "description": "Signal Node for n8n using signal-cli-rest-api",
5
5
  "repository": {
6
6
  "type": "git",