@peopl-health/nexus 2.4.7 → 2.4.8

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.
Files changed (45) hide show
  1. package/examples/assistants/DoctorScheduleAssistant.js +3 -2
  2. package/lib/adapters/BaileysProvider.js +5 -4
  3. package/lib/adapters/TwilioProvider.js +20 -19
  4. package/lib/assistants/BaseAssistant.js +7 -6
  5. package/lib/config/awsConfig.js +14 -12
  6. package/lib/config/llmConfig.js +3 -2
  7. package/lib/config/mongoAuthConfig.js +5 -5
  8. package/lib/controllers/assistantController.js +12 -11
  9. package/lib/controllers/bugReportController.js +6 -5
  10. package/lib/controllers/conversationController.js +72 -71
  11. package/lib/controllers/interactionController.js +7 -6
  12. package/lib/controllers/mediaController.js +15 -13
  13. package/lib/controllers/messageController.js +7 -6
  14. package/lib/controllers/patientController.js +2 -1
  15. package/lib/controllers/qualityMessageController.js +5 -4
  16. package/lib/controllers/templateController.js +11 -9
  17. package/lib/controllers/uploadController.js +3 -1
  18. package/lib/core/NexusMessaging.js +18 -18
  19. package/lib/helpers/assistantHelper.js +8 -9
  20. package/lib/helpers/baileysHelper.js +4 -3
  21. package/lib/helpers/filesHelper.js +9 -8
  22. package/lib/helpers/llmsHelper.js +5 -4
  23. package/lib/helpers/mediaHelper.js +3 -2
  24. package/lib/helpers/messageHelper.js +12 -11
  25. package/lib/helpers/processHelper.js +1 -1
  26. package/lib/helpers/qrHelper.js +2 -1
  27. package/lib/helpers/twilioMediaProcessor.js +19 -29
  28. package/lib/helpers/whatsappHelper.js +3 -2
  29. package/lib/index.js +11 -14
  30. package/lib/interactive/index.js +11 -11
  31. package/lib/middleware/requestId.js +9 -14
  32. package/lib/models/messageModel.js +5 -4
  33. package/lib/providers/OpenAIAssistantsProvider.js +10 -9
  34. package/lib/providers/OpenAIResponsesProvider.js +18 -17
  35. package/lib/providers/OpenAIResponsesProviderTools.js +3 -5
  36. package/lib/providers/createProvider.js +2 -1
  37. package/lib/services/airtableService.js +6 -5
  38. package/lib/services/assistantService.js +20 -20
  39. package/lib/services/conversationService.js +16 -16
  40. package/lib/services/preprocessingHooks.js +3 -1
  41. package/lib/storage/MongoStorage.js +14 -14
  42. package/lib/utils/errorHandler.js +3 -1
  43. package/lib/utils/logger.js +35 -3
  44. package/lib/utils/sanitizer.js +0 -6
  45. package/package.json +1 -1
@@ -1,4 +1,5 @@
1
1
  const { BaseAssistant } = require('../../lib/assistants/BaseAssistant');
2
+ const { logger } = require('../../lib/utils/logger');
2
3
 
3
4
  class DoctorScheduleAssistant extends BaseAssistant {
4
5
  constructor(thread) {
@@ -38,7 +39,7 @@ class DoctorScheduleAssistant extends BaseAssistant {
38
39
  }
39
40
  },
40
41
  handler: async (payload = {}) => {
41
- console.log('[DoctorScheduleAssistant] storePatientAppointment', payload);
42
+ logger.info('[DoctorScheduleAssistant] storePatientAppointment', payload);
42
43
 
43
44
  if (!payload.contact_number || !payload.appointment_type) {
44
45
  return JSON.stringify({
@@ -58,7 +59,7 @@ class DoctorScheduleAssistant extends BaseAssistant {
58
59
  notes: payload.notes || null
59
60
  };
60
61
 
61
- console.log('[DoctorScheduleAssistant] Appointment captured', appointment);
62
+ logger.info('[DoctorScheduleAssistant] Appointment captured', appointment);
62
63
 
63
64
  return JSON.stringify({ success: true, appointment });
64
65
  }
@@ -1,4 +1,5 @@
1
1
  const { MessageProvider } = require('../core/MessageProvider');
2
+ const { logger } = require('../utils/logger');
2
3
 
3
4
  /**
4
5
  * Baileys WhatsApp messaging provider
@@ -155,7 +156,7 @@ class BaileysProvider extends MessageProvider {
155
156
  ? __nexusSend
156
157
  : async (payload) => await this.sendMessage(payload);
157
158
 
158
- console.log('[BaileysProvider] Scheduled message created', {
159
+ logger.info('[BaileysProvider] Scheduled message created', {
159
160
  code: scheduledMessage.code,
160
161
  delay,
161
162
  hasMedia: Boolean(scheduledMessage.fileUrl)
@@ -165,15 +166,15 @@ class BaileysProvider extends MessageProvider {
165
166
  try {
166
167
  const payload = { ...scheduledMessage };
167
168
  delete payload.__nexusSend;
168
- console.log('[BaileysProvider] Timer fired', {
169
+ logger.info('[BaileysProvider] Timer fired', {
169
170
  code: payload.to || payload.code,
170
171
  hasMessage: Boolean(payload.message || payload.body),
171
172
  hasMedia: Boolean(payload.fileUrl)
172
173
  });
173
174
  await sender(payload);
174
- console.log('Scheduled message sent successfully');
175
+ logger.info('Scheduled message sent successfully');
175
176
  } catch (error) {
176
- console.error(`Scheduled message failed: ${error.message}`);
177
+ logger.error(`Scheduled message failed: ${error.message}`);
177
178
  }
178
179
  }, delay);
179
180
 
@@ -5,6 +5,7 @@ const { uploadMediaToS3, getFileExtension } = require('../helpers/mediaHelper');
5
5
  const { sanitizeMediaFilename } = require('../utils/sanitizer');
6
6
  const { generatePresignedUrl } = require('../config/awsConfig');
7
7
  const { validateMedia, getMediaType } = require('../utils/mediaValidator');
8
+ const { logger } = require('../utils/logger');
8
9
  const { v4: uuidv4 } = require('uuid');
9
10
 
10
11
  /**
@@ -90,7 +91,7 @@ class TwilioProvider extends MessageProvider {
90
91
  delete messageParams.body;
91
92
  }
92
93
  if (mediaPrep.uploaded) {
93
- console.log('[TwilioProvider] Outbound media uploaded to S3', {
94
+ logger.info('[TwilioProvider] Outbound media uploaded to S3', {
94
95
  code: formattedCode,
95
96
  bucket: mediaPrep.bucketName,
96
97
  key: mediaPrep.key
@@ -103,7 +104,7 @@ class TwilioProvider extends MessageProvider {
103
104
  throw new Error('Message must have body, media URL, or content SID');
104
105
  }
105
106
 
106
- console.log('[TwilioProvider] Sending message', messageParams);
107
+ logger.info('[TwilioProvider] Sending message', messageParams);
107
108
 
108
109
  try {
109
110
  const result = await this.twilioClient.messages.create(messageParams);
@@ -119,9 +120,9 @@ class TwilioProvider extends MessageProvider {
119
120
  fromMe: true,
120
121
  processed: false
121
122
  });
122
- console.log('[TwilioProvider] Message persisted successfully', { messageId: result.sid });
123
+ logger.info('[TwilioProvider] Message persisted successfully', { messageId: result.sid });
123
124
  } catch (storageError) {
124
- console.error('TwilioProvider storage failed:', storageError);
125
+ logger.error('TwilioProvider storage failed:', storageError);
125
126
  }
126
127
  }
127
128
  return {
@@ -143,7 +144,7 @@ class TwilioProvider extends MessageProvider {
143
144
  ? __nexusSend
144
145
  : async (payload) => await this.sendMessage(payload);
145
146
 
146
- console.log('[TwilioProvider] Scheduled message created', {
147
+ logger.info('[TwilioProvider] Scheduled message created', {
147
148
  code: scheduledMessage.code,
148
149
  delay,
149
150
  hasContentSid: Boolean(scheduledMessage.contentSid)
@@ -178,7 +179,7 @@ class TwilioProvider extends MessageProvider {
178
179
  })();
179
180
 
180
181
  if (!ScheduledMessageModel) {
181
- console.warn('[TwilioProvider] Scheduled message model unavailable for status update');
182
+ logger.warn('[TwilioProvider] Scheduled message model unavailable for status update');
182
183
  return;
183
184
  }
184
185
 
@@ -190,7 +191,7 @@ class TwilioProvider extends MessageProvider {
190
191
  })();
191
192
 
192
193
  if (!query) {
193
- console.warn('[TwilioProvider] Scheduled message status update skipped: no identifier', {
194
+ logger.warn('[TwilioProvider] Scheduled message status update skipped: no identifier', {
194
195
  hasId: Boolean(scheduledMessage._id),
195
196
  messageId,
196
197
  existingWaId: scheduledMessage.wa_id
@@ -204,7 +205,7 @@ class TwilioProvider extends MessageProvider {
204
205
  $push: { statusHistory: statusEntry }
205
206
  });
206
207
  } catch (statusErr) {
207
- console.warn('[TwilioProvider] Failed to update scheduled message status', statusErr?.message || statusErr);
208
+ logger.warn('[TwilioProvider] Failed to update scheduled message status', statusErr?.message || statusErr);
208
209
  }
209
210
  };
210
211
 
@@ -218,7 +219,7 @@ class TwilioProvider extends MessageProvider {
218
219
  if (payload.message && !payload.body) {
219
220
  payload.body = payload.message;
220
221
  }
221
- console.log('[TwilioProvider] Timer fired', {
222
+ logger.info('[TwilioProvider] Timer fired', {
222
223
  code: payload.code,
223
224
  hasMessage: Boolean(payload.message || payload.body),
224
225
  hasMedia: Boolean(payload.fileUrl)
@@ -228,7 +229,7 @@ class TwilioProvider extends MessageProvider {
228
229
  await updateStatus('sent', messageId);
229
230
  } catch (error) {
230
231
  await updateStatus('failed', null, error);
231
- console.error(`Scheduled message failed: ${error.message}`);
232
+ logger.error(`Scheduled message failed: ${error.message}`);
232
233
  }
233
234
  }, delay);
234
235
 
@@ -248,7 +249,7 @@ class TwilioProvider extends MessageProvider {
248
249
  }
249
250
 
250
251
  if (!bucketName) {
251
- console.warn('[TwilioProvider] AWS_S3_BUCKET_NAME not configured. Skipping media upload for outbound message.');
252
+ logger.warn('[TwilioProvider] AWS_S3_BUCKET_NAME not configured. Skipping media upload for outbound message.');
252
253
  return { mediaUrl: fileUrl, uploaded: false };
253
254
  }
254
255
 
@@ -283,7 +284,7 @@ class TwilioProvider extends MessageProvider {
283
284
  const mediaType = validation.valid ? validation.mediaType : (declaredType || getMediaType(contentType));
284
285
 
285
286
  if (!validation.valid) {
286
- console.warn('[TwilioProvider] Outbound media validation warning', {
287
+ logger.warn('[TwilioProvider] Outbound media validation warning', {
287
288
  code: formattedCode,
288
289
  message: validation.message
289
290
  });
@@ -332,7 +333,7 @@ class TwilioProvider extends MessageProvider {
332
333
  key
333
334
  };
334
335
  } catch (error) {
335
- console.error('[TwilioProvider] Failed to upload outbound media to S3. Using original URL.', {
336
+ logger.error('[TwilioProvider] Failed to upload outbound media to S3. Using original URL.', {
336
337
  code: formattedCode,
337
338
  error: error?.message || error
338
339
  });
@@ -395,7 +396,7 @@ class TwilioProvider extends MessageProvider {
395
396
  const template = await this.getTemplate(contentSid);
396
397
 
397
398
  if (!template || !template.types) {
398
- console.warn('[TwilioProvider] Template not found or has no types:', contentSid);
399
+ logger.warn('[TwilioProvider] Template not found or has no types:', contentSid);
399
400
  return null;
400
401
  }
401
402
 
@@ -403,7 +404,7 @@ class TwilioProvider extends MessageProvider {
403
404
  let textContent = this.extractTextFromTemplate(template);
404
405
 
405
406
  if (!textContent) {
406
- console.warn('[TwilioProvider] No text content found in template:', contentSid);
407
+ logger.warn('[TwilioProvider] No text content found in template:', contentSid);
407
408
  return null;
408
409
  }
409
410
 
@@ -414,7 +415,7 @@ class TwilioProvider extends MessageProvider {
414
415
 
415
416
  return textContent.trim();
416
417
  } catch (error) {
417
- console.error('[TwilioProvider] Error rendering template:', error.message);
418
+ logger.error('[TwilioProvider] Error rendering template:', error.message);
418
419
  return null;
419
420
  }
420
421
  }
@@ -541,7 +542,7 @@ class TwilioProvider extends MessageProvider {
541
542
 
542
543
  return rendered.trim();
543
544
  } catch (error) {
544
- console.warn('[TwilioProvider] Error rendering template variables:', error.message);
545
+ logger.warn('[TwilioProvider] Error rendering template variables:', error.message);
545
546
  return templateBody; // Return original template if rendering fails
546
547
  }
547
548
  }
@@ -598,7 +599,7 @@ class TwilioProvider extends MessageProvider {
598
599
  }
599
600
  }
600
601
  } catch (approvalError) {
601
- console.warn('Approval request fetch failed:', approvalError?.message || approvalError);
602
+ logger.warn('Approval request fetch failed:', approvalError?.message || approvalError);
602
603
  }
603
604
 
604
605
  return {
@@ -606,7 +607,7 @@ class TwilioProvider extends MessageProvider {
606
607
  approvalRequest: processedApprovalRequest
607
608
  };
608
609
  } catch (error) {
609
- console.error('Error checking approval status:', error);
610
+ logger.error('Error checking approval status:', error);
610
611
  throw error;
611
612
  }
612
613
  }
@@ -3,6 +3,7 @@ const { Thread } = require('../models/threadModel');
3
3
  const { Message } = require('../models/messageModel');
4
4
  const { formatMessage } = require('../helpers/messageHelper');
5
5
  const { createProvider } = require('../providers/createProvider');
6
+ const { logger } = require('../utils/logger');
6
7
 
7
8
  const DEFAULT_MAX_HISTORICAL_MESSAGES = parseInt(process.env.MAX_HISTORICAL_MESSAGES || '50', 10);
8
9
 
@@ -38,7 +39,7 @@ class BaseAssistant {
38
39
  }
39
40
  } catch (err) {
40
41
  if (process.env.NODE_ENV !== 'production') {
41
- console.warn('[BaseAssistant] Failed to initialise OpenAIProvider from client:', err?.message || err);
42
+ logger.warn('[BaseAssistant] Failed to initialise OpenAIProvider from client:', err?.message || err);
42
43
  }
43
44
  }
44
45
  }
@@ -53,7 +54,7 @@ class BaseAssistant {
53
54
  }
54
55
 
55
56
  if (this.assistantId) {
56
- console.log(`Assistant ${this.assistantId} initialized.`);
57
+ logger.info(`Assistant ${this.assistantId} initialized.`);
57
58
  }
58
59
  }
59
60
 
@@ -75,7 +76,7 @@ class BaseAssistant {
75
76
  llmConfig.setOpenAIProvider(provider);
76
77
  }
77
78
  } catch (error) {
78
- console.warn('[BaseAssistant] Failed to bootstrap provider:', error?.message || error);
79
+ logger.warn('[BaseAssistant] Failed to bootstrap provider:', error?.message || error);
79
80
  }
80
81
  }
81
82
  }
@@ -215,11 +216,11 @@ class BaseAssistant {
215
216
  })
216
217
  .filter(message => message !== null);
217
218
 
218
- console.log(`[buildInitialMessages] Built ${formattedMessages.length} initial messages for ${code}`);
219
+ logger.info(`[buildInitialMessages] Built ${formattedMessages.length} initial messages for ${code}`);
219
220
 
220
221
  return formattedMessages;
221
222
  } catch (error) {
222
- console.error('[buildInitialMessages] Error fetching messages:', error);
223
+ logger.error('[buildInitialMessages] Error fetching messages:', error);
223
224
  return [];
224
225
  }
225
226
  }
@@ -235,7 +236,7 @@ class BaseAssistant {
235
236
  }
236
237
 
237
238
  if (this.assistantId) {
238
- console.log(`Assistant ${this.assistantId} closed`);
239
+ logger.info(`Assistant ${this.assistantId} closed`);
239
240
  }
240
241
 
241
242
  return `Assistant ${this.assistantId || ''} successfully closed.`.trim();
@@ -1,3 +1,5 @@
1
+ const { logger } = require('../utils/logger');
2
+
1
3
  const AWS = require('aws-sdk');
2
4
  const fs = require('fs');
3
5
  const path = require('path');
@@ -26,16 +28,16 @@ async function uploadBufferToS3(buffer, bucketName, key, contentType, isWhatsApp
26
28
 
27
29
  try {
28
30
  const data = await s3.upload(params).promise();
29
- console.log(`File uploaded successfully at ${data.Location}`);
31
+ logger.info(`File uploaded successfully at ${data.Location}`);
30
32
  return data.Location;
31
33
  } catch (error) {
32
- console.error(`Error uploading file: ${error.message}`);
34
+ logger.error(`Error uploading file: ${error.message}`);
33
35
  throw error;
34
36
  }
35
37
  }
36
38
 
37
39
  async function downloadFileFromS3(bucketName, key, downloadPath) {
38
- console.log(`[S3] Attempting to download file from S3 - Bucket: ${bucketName}, Key: ${key}`);
40
+ logger.info(`[S3] Attempting to download file from S3 - Bucket: ${bucketName}, Key: ${key}`);
39
41
 
40
42
  const headParams = {
41
43
  Bucket: bucketName,
@@ -44,11 +46,11 @@ async function downloadFileFromS3(bucketName, key, downloadPath) {
44
46
 
45
47
  try {
46
48
  await s3.headObject(headParams).promise();
47
- console.log(`[S3] Key exists in bucket: ${key}`);
49
+ logger.info(`[S3] Key exists in bucket: ${key}`);
48
50
  } catch (headErr) {
49
- console.error(`[S3] Object check failed - Key: ${key}, Error: ${headErr.code} - ${headErr.message}`);
51
+ logger.error(`[S3] Object check failed - Key: ${key}, Error: ${headErr.code} - ${headErr.message}`);
50
52
  if (headErr.code === 'NotFound') {
51
- console.log(`[S3] Key does not exist in bucket: ${key}`);
53
+ logger.info(`[S3] Key does not exist in bucket: ${key}`);
52
54
  }
53
55
  throw headErr;
54
56
  }
@@ -59,21 +61,21 @@ async function downloadFileFromS3(bucketName, key, downloadPath) {
59
61
  };
60
62
 
61
63
  try {
62
- console.log(`[S3] Downloading file data - Key: ${key}`);
64
+ logger.info(`[S3] Downloading file data - Key: ${key}`);
63
65
  const data = await s3.getObject(params).promise();
64
- console.log(`[S3] Successfully retrieved file - Key: ${key}, ContentType: ${data.ContentType}, Size: ${data.ContentLength} bytes`);
66
+ logger.info(`[S3] Successfully retrieved file - Key: ${key}, ContentType: ${data.ContentType}, Size: ${data.ContentLength} bytes`);
65
67
 
66
68
  if (downloadPath) {
67
69
  const directory = path.dirname(downloadPath);
68
70
  fs.mkdirSync(directory, { recursive: true });
69
71
  fs.writeFileSync(downloadPath, data.Body);
70
- console.log(`[S3] File saved to disk at: ${downloadPath}`);
72
+ logger.info(`[S3] File saved to disk at: ${downloadPath}`);
71
73
  return;
72
74
  }
73
75
 
74
76
  return data;
75
77
  } catch (error) {
76
- console.error(`[S3] Error downloading file - Key: ${key}, Error: ${error.code} - ${error.message}`);
78
+ logger.error(`[S3] Error downloading file - Key: ${key}, Error: ${error.code} - ${error.message}`);
77
79
  throw error;
78
80
  }
79
81
  }
@@ -87,10 +89,10 @@ async function generatePresignedUrl(bucketName, key, expiration = 3000) {
87
89
 
88
90
  try {
89
91
  const url = await s3.getSignedUrlPromise('getObject', params);
90
- console.log(`Presigned URL generated: ${url}`);
92
+ logger.info(`Presigned URL generated: ${url}`);
91
93
  return url;
92
94
  } catch (error) {
93
- console.error(`Error generating presigned URL: ${error.message}`);
95
+ logger.error(`Error generating presigned URL: ${error.message}`);
94
96
  throw error;
95
97
  }
96
98
  }
@@ -1,4 +1,5 @@
1
1
  const runtimeConfig = require('./runtimeConfig');
2
+ const { logger } = require('../utils/logger');
2
3
  const { createProvider } = require('../providers/createProvider');
3
4
 
4
5
  let anthropicClient = null;
@@ -61,9 +62,9 @@ const resolveAnthropicClient = () => {
61
62
  try {
62
63
  const { Anthropic } = require('@anthropic-ai/sdk');
63
64
  anthropicClient = new Anthropic({ apiKey });
64
- console.log('[llmConfig] Anthropic client initialised');
65
+ logger.info('[llmConfig] Anthropic client initialised');
65
66
  } catch (error) {
66
- console.warn('[llmConfig] Failed to initialise Anthropic client. Install @anthropic-ai/sdk if you plan to use vision features.', error?.message || error);
67
+ logger.warn('[llmConfig] Failed to initialise Anthropic client. Install @anthropic-ai/sdk if you plan to use vision features.', error?.message || error);
67
68
  anthropicClient = null;
68
69
  }
69
70
 
@@ -1,14 +1,14 @@
1
1
  const { MongoClient } = require('mongodb');
2
-
3
2
  const { proto, Curve, signedKeyPair, generateRegistrationId } = require('baileys');
4
3
  const { randomBytes } = require('crypto');
4
+ const { logger } = require('../utils/logger');
5
5
 
6
6
  async function connectToMongo(mongoClient) {
7
7
  try {
8
8
  await mongoClient.connect();
9
- console.log('Connected to Mongo database successfully.');
9
+ logger.info('Connected to Mongo database successfully.');
10
10
  } catch (err) {
11
- console.error('Error connecting to Mongo database:', err.message);
11
+ logger.error('Error connecting to Mongo database:', err.message);
12
12
  throw err;
13
13
  }
14
14
  }
@@ -87,7 +87,7 @@ async function useMongoDBAuthState(uri, dbName, sessionId) {
87
87
  const data = JSON.stringify(await collection.findOne({ _id: `${sessionId}-${key}` }));
88
88
  return JSON.parse(data, BufferJSON.reviver);
89
89
  } catch (err) {
90
- console.log(err);
90
+ logger.error(err);
91
91
  return null;
92
92
  }
93
93
  };
@@ -96,7 +96,7 @@ async function useMongoDBAuthState(uri, dbName, sessionId) {
96
96
  try {
97
97
  await collection.deleteOne({ _id: `${sessionId}-${key}` });
98
98
  } catch (err) {
99
- console.log(err);
99
+ logger.error(err);
100
100
  }
101
101
  };
102
102
 
@@ -6,6 +6,7 @@ const { getRecordByFilter } = require('../services/airtableService');
6
6
  const { createAssistant, addMsgAssistant, addInsAssistant } = require('../services/assistantService');
7
7
  const { getThreadInfo, switchAssistant } = require('../services/assistantService');
8
8
  const { sendMessage } = require('../core/NexusMessaging');
9
+ const { logger } = require('../utils/logger');
9
10
 
10
11
 
11
12
  const activeAssistantController = async (req, res) => {
@@ -15,7 +16,7 @@ const activeAssistantController = async (req, res) => {
15
16
  await Thread.updateOne({ code }, { $set: { active: !!active } });
16
17
  return res.status(200).send({ message: 'Active assistant' });
17
18
  } catch (error) {
18
- console.log(error);
19
+ logger.error(error);
19
20
  return res.status(500).send({ message: 'Failed to active assistant', error });
20
21
  }
21
22
  };
@@ -31,7 +32,7 @@ const addInsAssistantController = async (req, res) => {
31
32
  if (ans) await sendMessage({code, body: ans, fileType: 'text'});
32
33
  return res.status(200).send({ message: 'Add instruction to the assistant' });
33
34
  } catch (error) {
34
- console.log(error);
35
+ logger.error(error);
35
36
  res.status(500).send({ message: 'Failed to add instruction to assistant', error });
36
37
  }
37
38
  };
@@ -44,7 +45,7 @@ const addMsgAssistantController = async (req, res) => {
44
45
  if (ans) await sendMessage({code, body: ans, fileType: 'text'});
45
46
  return res.status(200).send({ message: 'Add message to the assistant' });
46
47
  } catch (error) {
47
- console.log(error);
48
+ logger.error(error);
48
49
  res.status(500).send({ message: 'Failed to add message assistant', error });
49
50
  }
50
51
  };
@@ -58,18 +59,18 @@ const createAssistantController = async (req, res) => {
58
59
  messages = Array.isArray(messages) ? messages : [];
59
60
 
60
61
  try {
61
- console.log('[createAssistantController] codes', codes);
62
+ logger.info('[createAssistantController] codes', codes);
62
63
  for (const code of codes) {
63
64
  await createAssistant(code, assistant_id, [...instrucciones, ...messages], force);
64
- console.log('[createAssistantController] messages', messages);
65
+ logger.info('[createAssistantController] messages', messages);
65
66
  for (const message of messages) {
66
- console.log('[createAssistantController] message', message);
67
+ logger.info('[createAssistantController] message', message);
67
68
  await sendMessage({code, body: message, fileType: 'text'});
68
69
  }
69
70
  }
70
71
  res.status(200).send({ message: 'Create the assistant' });
71
72
  } catch (error) {
72
- console.log(error);
73
+ logger.error(error);
73
74
  res.status(500).send({ message: 'Failed to create assistant', error });
74
75
  }
75
76
  };
@@ -81,7 +82,7 @@ const getInfoAssistantController = async (req, res) => {
81
82
  let threadInfo = await getThreadInfo(code);
82
83
  return res.status(200).send({ message: 'Send assistant info' , threadInfo});
83
84
  } catch (error) {
84
- console.log(error);
85
+ logger.error(error);
85
86
  res.status(500).send({ message: 'Failed to receive assistant info', error });
86
87
  }
87
88
  };
@@ -96,7 +97,7 @@ const listAssistantController = async (req, res) => {
96
97
  const assistants = await getRecordByFilter(Config_ID, tableName, `status="${airtableStatus}"`);
97
98
  return res.status(200).send({ message: 'List assistants' , assistants});
98
99
  } catch (error) {
99
- console.log(error);
100
+ logger.error(error);
100
101
  res.status(500).send({ message: 'Failed to list assistants', error });
101
102
  }
102
103
  };
@@ -108,7 +109,7 @@ const switchAssistantController = async (req, res) => {
108
109
  await switchAssistant(code, assistant_id);
109
110
  return res.status(200).send({ message: 'Switch assistant' });
110
111
  } catch (error) {
111
- console.log(error);
112
+ logger.error(error);
112
113
  res.status(500).send({ message: 'Failed to switch assistant', error });
113
114
  }
114
115
  };
@@ -120,7 +121,7 @@ const stopAssistantController = async (req, res) => {
120
121
  await Thread.updateOne({ code }, { $set: { stopped: !!stop } });
121
122
  return res.status(200).send({ message: 'Stop assistant' });
122
123
  } catch (error) {
123
- console.log(error);
124
+ logger.error(error);
124
125
  return res.status(500).send({ message: 'Failed to stop assistant', error });
125
126
  }
126
127
  };
@@ -1,6 +1,7 @@
1
1
  const { Message } = require('../models/messageModel');
2
2
  const { addRecord, getRecordByFilter } = require('../services/airtableService');
3
3
  const { Logging_ID } = require('../config/airtableConfig');
4
+ const { logger } = require('../utils/logger');
4
5
 
5
6
  async function logBugReportToAirtable(reporter, whatsapp_id, description, severity, messageIds = []) {
6
7
  try {
@@ -21,7 +22,7 @@ async function logBugReportToAirtable(reporter, whatsapp_id, description, severi
21
22
  patientId = patientRecords[0].record_logging_id;
22
23
  }
23
24
  } catch (err) {
24
- console.warn('Could not find patient in estado_general:', err.message);
25
+ logger.warn('Could not find patient in estado_general:', err.message);
25
26
  }
26
27
 
27
28
  const airtableData = {
@@ -33,9 +34,9 @@ async function logBugReportToAirtable(reporter, whatsapp_id, description, severi
33
34
  };
34
35
 
35
36
  await addRecord(Logging_ID, 'bug_reports', airtableData);
36
- console.log('Bug report logged to Airtable successfully');
37
+ logger.info('Bug report logged to Airtable successfully');
37
38
  } catch (error) {
38
- console.error('Error logging bug report to Airtable:', error);
39
+ logger.error('Error logging bug report to Airtable:', error);
39
40
  }
40
41
  }
41
42
 
@@ -50,12 +51,12 @@ const reportBugController = async (req, res) => {
50
51
  }
51
52
 
52
53
  logBugReportToAirtable(reporter, whatsapp_id, description, severity, messages).catch(err =>
53
- console.error('Background bug report logging failed:', err)
54
+ logger.error('Background bug report logging failed:', err)
54
55
  );
55
56
 
56
57
  res.status(201).json({ success: true, message: 'Bug report submitted successfully' });
57
58
  } catch (error) {
58
- console.error('Error submitting bug report:', error);
59
+ logger.error('Error submitting bug report:', error);
59
60
  res.status(500).json({ success: false, error: error.message });
60
61
  }
61
62
  };