n8n-nodes-chat2crm 0.1.8 → 0.1.10
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
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# Структура проекта
|
|
2
|
+
|
|
3
|
+
## Основные директории
|
|
4
|
+
|
|
5
|
+
- **nodes/**
|
|
6
|
+
- `Chat2CrmSend/` — Нода для отправки сообщений
|
|
7
|
+
- `Chat2CrmSend.node.ts` — Основной файл ноды
|
|
8
|
+
- `chat2crm.svg` — Иконка ноды
|
|
9
|
+
- `Chat2CrmTrigger/` — Триггерная нода для прослушивания стримов
|
|
10
|
+
- `Chat2CrmTrigger.node.ts` — Основной файл ноды
|
|
11
|
+
- `chat2crm.svg` — Иконка ноды
|
|
12
|
+
- `Infra/` — Инфраструктурные модули
|
|
13
|
+
- `RedisConnection.ts` — Подключение к Redis
|
|
14
|
+
- `StreamConfig.ts` — Конфигурация потоков Redis
|
|
15
|
+
|
|
16
|
+
- **credentials/**
|
|
17
|
+
- `Chat2CrmRedisApi.credentials.ts` — Credentials для Redis API
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
## Конфигурационные файлы
|
|
21
|
+
|
|
22
|
+
- `index.js` — Точка входа модуля (экспорт узлов и credentials)
|
|
23
|
+
- `package.json`
|
|
24
|
+
- `package-lock.json`
|
|
25
|
+
- `tsconfig.json`
|
|
26
|
+
- `gulpfile.js`
|
|
27
|
+
- `.eslintrc.js`
|
|
28
|
+
- `.gitignore`
|
|
29
|
+
- `.n8nignore`
|
|
30
|
+
|
|
31
|
+
## Документация
|
|
32
|
+
|
|
33
|
+
- `README.md` — Документация проекта
|
|
34
|
+
- `QUICKSTART.md` — Руководство по быстрому старту
|
|
@@ -43,9 +43,8 @@ class Chat2CrmSend {
|
|
|
43
43
|
displayName: 'Message Data',
|
|
44
44
|
name: 'messageData',
|
|
45
45
|
type: 'json',
|
|
46
|
-
required: true,
|
|
47
46
|
default: '{}',
|
|
48
|
-
description: 'Message data to send to Redis stream (JSON object)',
|
|
47
|
+
description: 'Message data to send to Redis stream (JSON object). If not provided, will use data from input item (from trigger).',
|
|
49
48
|
},
|
|
50
49
|
{
|
|
51
50
|
displayName: 'Message ID',
|
|
@@ -261,34 +260,46 @@ class Chat2CrmSend {
|
|
|
261
260
|
}
|
|
262
261
|
// Обрабатываем каждый элемент входных данных
|
|
263
262
|
for (let itemIndex = 0; itemIndex < items.length; itemIndex++) {
|
|
264
|
-
const
|
|
265
|
-
|
|
263
|
+
const item = items[itemIndex];
|
|
264
|
+
const inputJson = item.json;
|
|
265
|
+
// Определяем данные для отправки: приоритет - data из входного элемента, затем commandList, затем параметр messageData
|
|
266
266
|
let messageData = {};
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
267
|
+
if (inputJson.data && typeof inputJson.data === 'object') {
|
|
268
|
+
// Используем data из входного элемента (из триггера)
|
|
269
|
+
messageData = inputJson.data;
|
|
270
|
+
}
|
|
271
|
+
else if (inputJson.commandList && typeof inputJson.commandList === 'object') {
|
|
272
|
+
// Используем commandList из входного элемента (из триггера)
|
|
273
|
+
messageData = inputJson.commandList;
|
|
274
|
+
}
|
|
275
|
+
else {
|
|
276
|
+
// Используем параметр messageData из настроек ноды
|
|
277
|
+
const messageDataParam = this.getNodeParameter('messageData', itemIndex);
|
|
278
|
+
try {
|
|
279
|
+
if (typeof messageDataParam === 'string') {
|
|
280
|
+
// Если это строка, пытаемся распарсить JSON
|
|
281
|
+
if (messageDataParam.trim() === '') {
|
|
282
|
+
messageData = {};
|
|
283
|
+
}
|
|
284
|
+
else {
|
|
285
|
+
messageData = JSON.parse(messageDataParam);
|
|
286
|
+
}
|
|
272
287
|
}
|
|
273
|
-
else {
|
|
274
|
-
|
|
288
|
+
else if (typeof messageDataParam === 'object' && messageDataParam !== null) {
|
|
289
|
+
// Если это уже объект, используем его напрямую
|
|
290
|
+
messageData = messageDataParam;
|
|
275
291
|
}
|
|
276
292
|
}
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
messageData = messageDataParam;
|
|
280
|
-
}
|
|
281
|
-
else {
|
|
282
|
-
throw new n8n_workflow_1.ApplicationError('messageData must be a JSON object or string', { level: 'error' });
|
|
293
|
+
catch (error) {
|
|
294
|
+
throw new n8n_workflow_1.ApplicationError(`Invalid JSON in messageData: ${error.message}`, { level: 'error' });
|
|
283
295
|
}
|
|
284
296
|
}
|
|
285
|
-
catch (error) {
|
|
286
|
-
throw new n8n_workflow_1.ApplicationError(`Invalid JSON in messageData: ${error.message}`, { level: 'error' });
|
|
287
|
-
}
|
|
288
297
|
// Проверяем, что messageData не пустой
|
|
289
298
|
if (Object.keys(messageData).length === 0) {
|
|
290
|
-
throw new n8n_workflow_1.ApplicationError('messageData cannot be empty', { level: 'error' });
|
|
299
|
+
throw new n8n_workflow_1.ApplicationError('messageData cannot be empty. Provide data in input item or in messageData parameter', { level: 'error' });
|
|
291
300
|
}
|
|
301
|
+
// Определяем messageId: приоритет - из входного элемента, затем из параметра
|
|
302
|
+
const finalMessageId = inputJson.messageId || messageId || '*';
|
|
292
303
|
// Отправляем сообщение в каждый выбранный stream
|
|
293
304
|
const sent = [];
|
|
294
305
|
const errors = [];
|
|
@@ -312,7 +323,7 @@ class Chat2CrmSend {
|
|
|
312
323
|
}
|
|
313
324
|
}
|
|
314
325
|
// Отправляем сообщение в stream
|
|
315
|
-
const id = await redis.xadd(stream,
|
|
326
|
+
const id = await redis.xadd(stream, finalMessageId, ...fields);
|
|
316
327
|
if (!id) {
|
|
317
328
|
throw new n8n_workflow_1.ApplicationError('Failed to add message to stream: XADD returned null', { level: 'error' });
|
|
318
329
|
}
|
|
@@ -166,15 +166,17 @@ async function createRedisConnection(credentials, db = 0) {
|
|
|
166
166
|
console.log(`[Redis Connection] Direct connection to Redis at ${redisHost}:${redisPort}`);
|
|
167
167
|
}
|
|
168
168
|
// Создаем подключение к Redis
|
|
169
|
-
|
|
169
|
+
// ВАЖНО: Используем переданный параметр db, а НЕ credentials.db
|
|
170
|
+
const selectedDb = db; // Явно используем переданный параметр
|
|
171
|
+
console.log(`[Redis Connection] Connecting to Redis: ${redisHost}:${redisPort}, DB: ${selectedDb}`);
|
|
170
172
|
const redis = new ioredis_1.default({
|
|
171
173
|
host: redisHost,
|
|
172
174
|
port: redisPort,
|
|
173
|
-
db: db
|
|
175
|
+
db: selectedDb, // Явно используем переданный параметр db
|
|
174
176
|
password: credentials.password,
|
|
175
177
|
enableReadyCheck: true,
|
|
176
178
|
maxRetriesPerRequest: 3,
|
|
177
|
-
connectTimeout: 10000,
|
|
179
|
+
connectTimeout: 10000,
|
|
178
180
|
retryStrategy: (times) => {
|
|
179
181
|
const delay = Math.min(times * 50, 2000);
|
|
180
182
|
return delay;
|
|
@@ -182,16 +184,24 @@ async function createRedisConnection(credentials, db = 0) {
|
|
|
182
184
|
});
|
|
183
185
|
// Добавляем обработчики событий для диагностики
|
|
184
186
|
redis.on('connect', () => {
|
|
185
|
-
console.log(`[Redis Connection] Connected to Redis at ${redisHost}:${redisPort}, DB ${
|
|
187
|
+
console.log(`[Redis Connection] Connected to Redis at ${redisHost}:${redisPort}, DB ${selectedDb}`);
|
|
186
188
|
});
|
|
187
|
-
redis.on('ready', () => {
|
|
188
|
-
console.log(`[Redis Connection] Redis ready at ${redisHost}:${redisPort}, DB ${
|
|
189
|
+
redis.on('ready', async () => {
|
|
190
|
+
console.log(`[Redis Connection] Redis ready at ${redisHost}:${redisPort}, DB ${selectedDb}`);
|
|
191
|
+
// Явно выбираем базу данных после готовности подключения
|
|
192
|
+
try {
|
|
193
|
+
await redis.select(selectedDb);
|
|
194
|
+
console.log(`[Redis Connection] Explicitly selected DB ${selectedDb}`);
|
|
195
|
+
}
|
|
196
|
+
catch (error) {
|
|
197
|
+
console.error(`[Redis Connection] Failed to select DB ${selectedDb}:`, error.message);
|
|
198
|
+
}
|
|
189
199
|
});
|
|
190
200
|
redis.on('error', (err) => {
|
|
191
|
-
console.error(`[Redis Connection] Redis error on ${redisHost}:${redisPort}, DB ${
|
|
201
|
+
console.error(`[Redis Connection] Redis error on ${redisHost}:${redisPort}, DB ${selectedDb}:`, err.message);
|
|
192
202
|
});
|
|
193
203
|
redis.on('close', () => {
|
|
194
|
-
console.log(`[Redis Connection] Redis connection closed: ${redisHost}:${redisPort}, DB ${
|
|
204
|
+
console.log(`[Redis Connection] Redis connection closed: ${redisHost}:${redisPort}, DB ${selectedDb}`);
|
|
195
205
|
});
|
|
196
206
|
return redis;
|
|
197
207
|
}
|