@peopl-health/nexus 1.3.1 → 1.3.2

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,4 +1,3 @@
1
- // Use mongoose models directly to avoid conflicts
2
1
  const mongoose = require('mongoose');
3
2
  const { fetchConversationData, processConversations } = require('../services/conversationService');
4
3
  const { sendMessage } = require('../core/NexusMessaging');
@@ -1,11 +1,4 @@
1
- // Optional AWS config - will be undefined if not available
2
- let downloadFileFromS3, s3;
3
- try {
4
- downloadFileFromS3 = require('../config/awsConfig')?.downloadFileFromS3;
5
- s3 = require('../config/awsConfig')?.s3;
6
- } catch (e) {
7
- // AWS config not available
8
- }
1
+ const { s3, downloadFileFromS3 } = require('../config/awsConfig');
9
2
  const bucketName = process.env.AWS_S3_BUCKET_NAME;
10
3
 
11
4
 
@@ -24,6 +17,14 @@ const getMediaController = async (req, res) => {
24
17
  });
25
18
  }
26
19
 
20
+ // Validate configuration
21
+ if (!downloadFileFromS3 || typeof downloadFileFromS3 !== 'function') {
22
+ return res.status(500).json({ success: false, error: 'downloadFileFromS3 not configured. Call configureMediaController() to inject it.' });
23
+ }
24
+ if (!bucketName) {
25
+ return res.status(500).json({ success: false, error: 'AWS_S3_BUCKET_NAME not configured. Pass bucketName to configureMediaController() or set env.' });
26
+ }
27
+
27
28
  let mediaKey = key;
28
29
 
29
30
  console.log(`[MediaController] Final S3 key to fetch: ${mediaKey}`);
@@ -32,36 +33,37 @@ const getMediaController = async (req, res) => {
32
33
 
33
34
  if (!fileData || !fileData.Body) {
34
35
  console.error(`[MediaController] Media not found in S3: ${key}`);
35
-
36
- try {
37
- const prefix = key.split('/')[0];
38
- console.log(`[MediaController] Checking S3 for objects with prefix: ${prefix}/`);
39
-
40
- s3.listObjectsV2({
41
- Bucket: bucketName,
42
- Prefix: prefix + '/',
43
- MaxKeys: 10
44
- }).promise()
45
- .then(listData => {
46
- if (listData.Contents && listData.Contents.length > 0) {
47
- console.log(`[MediaController] Found ${listData.Contents.length} objects with similar prefix:`);
48
- listData.Contents.forEach(item => {
49
- console.log(`[MediaController] - ${item.Key} (${item.Size} bytes)`);
50
- if (item.Key.includes(key.split('/').pop().substring(0, 10))) {
51
- console.log(`[MediaController] !!! POTENTIAL MATCH: ${item.Key}`);
52
- }
53
- });
54
- } else {
55
- console.log(`[MediaController] No objects found with prefix: ${prefix}/`);
56
- }
57
- })
58
- .catch(listErr => {
59
- console.error(`[MediaController] Error listing objects: ${listErr.message}`);
60
- });
61
- } catch (listErr) {
62
- console.error(`[MediaController] Error setting up bucket listing: ${listErr.message}`);
36
+
37
+ if (s3) {
38
+ try {
39
+ const prefix = key.split('/') [0];
40
+ console.log(`[MediaController] Checking S3 for objects with prefix: ${prefix}/`);
41
+ s3.listObjectsV2({
42
+ Bucket: bucketName,
43
+ Prefix: prefix + '/',
44
+ MaxKeys: 10
45
+ }).promise()
46
+ .then(listData => {
47
+ if (listData.Contents && listData.Contents.length > 0) {
48
+ console.log(`[MediaController] Found ${listData.Contents.length} objects with similar prefix:`);
49
+ listData.Contents.forEach(item => {
50
+ console.log(`[MediaController] - ${item.Key} (${item.Size} bytes)`);
51
+ if (item.Key.includes(key.split('/').pop().substring(0, 10))) {
52
+ console.log(`[MediaController] !!! POTENTIAL MATCH: ${item.Key}`);
53
+ }
54
+ });
55
+ } else {
56
+ console.log(`[MediaController] No objects found with prefix: ${prefix}/`);
57
+ }
58
+ })
59
+ .catch(listErr => {
60
+ console.error(`[MediaController] Error listing objects: ${listErr.message}`);
61
+ });
62
+ } catch (listErr) {
63
+ console.error(`[MediaController] Error setting up bucket listing: ${listErr.message}`);
64
+ }
63
65
  }
64
-
66
+
65
67
  return res.status(404).json({
66
68
  success: false,
67
69
  error: 'Media not found in S3',
@@ -102,4 +104,4 @@ const getMediaController = async (req, res) => {
102
104
 
103
105
  module.exports = {
104
106
  getMediaController
105
- };
107
+ };
@@ -1,24 +1,11 @@
1
1
  const { Message } = require('../models/messageModel.js');
2
-
3
- // Import from Nexus core
4
- const { sendMessage } = require('../core/NexusMessaging');
5
-
6
- // Injectable dependencies with safe defaults
7
- let injected = {
8
- ScheduledMessage: null,
9
- getRecordByFilter: null,
10
- sendScheduledMessage: null
11
- };
12
-
13
- // Allow consumers to inject their model and services
14
- const configureMessageController = ({ ScheduledMessage, getRecordByFilter, sendScheduledMessage } = {}) => {
15
- if (ScheduledMessage) injected.ScheduledMessage = ScheduledMessage;
16
- if (getRecordByFilter) injected.getRecordByFilter = getRecordByFilter;
17
- if (sendScheduledMessage) injected.sendScheduledMessage = sendScheduledMessage;
18
- };
2
+ const { ScheduledMessage } = require('../models/agendaMessageModel.js');
3
+ const { getRecordByFilter } = require('../services/airtableService.js');
4
+ const { sendMessage, sendScheduledMessage } = require('../core/NexusMessaging');
19
5
 
20
6
  const moment = require('moment-timezone');
21
7
 
8
+
22
9
  const sendMessageController = async (req, res) => {
23
10
  const {
24
11
  fileUrl,
@@ -31,13 +18,10 @@ const sendMessageController = async (req, res) => {
31
18
  contentSid = null,
32
19
  variables = null
33
20
  } = req.body || {};
34
- const author = process.env.USER_DB_MONGO;
21
+ const author = (require('../config/runtimeConfig').get('USER_DB_MONGO'));
35
22
  const sendMoment = sendTime ? moment.tz(sendTime, timeZone) + 2500 : new Date();
36
23
 
37
24
  try {
38
- if (!injected.ScheduledMessage || typeof injected.ScheduledMessage.create !== 'function') {
39
- return res.status(500).json({ success: false, error: 'ScheduledMessage model not configured. Call configureMessageController() to inject it.' });
40
- }
41
25
  const messageData = {
42
26
  fileUrl,
43
27
  message,
@@ -51,7 +35,7 @@ const sendMessageController = async (req, res) => {
51
35
  extraDelay: 0,
52
36
  variables
53
37
  };
54
- await injected.ScheduledMessage.create(messageData);
38
+ await ScheduledMessage.create(messageData);
55
39
  console.log('Sending message with data:', messageData);
56
40
 
57
41
  const result = await sendMessage(messageData);
@@ -79,22 +63,16 @@ const sendBulkMessageController = async (req, res) => {
79
63
  contentSid = null,
80
64
  variables = null
81
65
  } = req.body || {};
82
- const author = process.env.USER_DB_MONGO;
66
+ const author = (require('../config/runtimeConfig').get('USER_DB_MONGO'));
83
67
  const sendMoment = sendTime ? moment.tz(sendTime, timeZone) + 20*1000 : new Date();
84
68
 
85
69
  try {
86
- if (!injected.ScheduledMessage || typeof injected.ScheduledMessage.create !== 'function') {
87
- return res.status(500).json({ success: false, error: 'ScheduledMessage model not configured. Call configureMessageController() to inject it.' });
88
- }
89
- if (!injected.sendScheduledMessage || typeof injected.sendScheduledMessage !== 'function') {
90
- return res.status(500).json({ success: false, error: 'sendScheduledMessage not configured. Call configureMessageController() to inject it.' });
91
- }
92
70
  let numSend = 0;
93
71
  let extraDelay = 0;
94
72
  let curMessage = message;
95
73
  const scheduledMessages = [];
96
74
  for (const code of codes) {
97
- const scheduledMessage = new injected.ScheduledMessage({
75
+ const scheduledMessage = new ScheduledMessage({
98
76
  fileUrl,
99
77
  message: curMessage,
100
78
  fileType,
@@ -119,8 +97,8 @@ const sendBulkMessageController = async (req, res) => {
119
97
  // Schedule all messages with Agenda in parallel
120
98
  const sentMessages = await Promise.all(
121
99
  scheduledMessages.map(async (message) => {
122
- const savedMessage = await injected.ScheduledMessage.create(message);
123
- return injected.sendScheduledMessage(savedMessage);
100
+ const savedMessage = await ScheduledMessage.create(message);
101
+ return sendScheduledMessage(savedMessage);
124
102
  })
125
103
  );
126
104
 
@@ -155,7 +133,7 @@ const sendBulkMessageAirtableController = async (req, res) => {
155
133
  condition = '1',
156
134
  variables = null
157
135
  } = req.body || {};
158
- const author = process.env.USER_DB_MONGO;
136
+ const author = (require('../config/runtimeConfig').get('USER_DB_MONGO'));
159
137
  const sendMoment = sendTime ? moment.tz(sendTime, timeZone) + 20*1000 : new Date();
160
138
 
161
139
  const regex = /\[(.*?)\]/g;
@@ -166,16 +144,7 @@ const sendBulkMessageAirtableController = async (req, res) => {
166
144
  }
167
145
 
168
146
  try {
169
- if (!injected.getRecordByFilter || typeof injected.getRecordByFilter !== 'function') {
170
- return res.status(500).json({ success: false, error: 'Airtable getRecordByFilter not configured. Call configureMessageController() to inject it.' });
171
- }
172
- if (!injected.ScheduledMessage || typeof injected.ScheduledMessage.create !== 'function') {
173
- return res.status(500).json({ success: false, error: 'ScheduledMessage model not configured. Call configureMessageController() to inject it.' });
174
- }
175
- if (!injected.sendScheduledMessage || typeof injected.sendScheduledMessage !== 'function') {
176
- return res.status(500).json({ success: false, error: 'sendScheduledMessage not configured. Call configureMessageController() to inject it.' });
177
- }
178
- const rows = await injected.getRecordByFilter(baseId, tableName, condition);
147
+ const rows = await getRecordByFilter(baseId, tableName, condition);
179
148
  let extraDelay = 0;
180
149
  let curMessage = message;
181
150
  const sentPhones = new Set();
@@ -220,8 +189,8 @@ const sendBulkMessageAirtableController = async (req, res) => {
220
189
 
221
190
  const sentMessages = await Promise.all(
222
191
  scheduledMessages.map(async (message) => {
223
- const savedMessage = await injected.ScheduledMessage.create(message);
224
- return injected.sendScheduledMessage(savedMessage);
192
+ const savedMessage = await ScheduledMessage.create(message);
193
+ return sendScheduledMessage(savedMessage);
225
194
  })
226
195
  );
227
196
 
@@ -272,6 +241,5 @@ module.exports = {
272
241
  sendMessageController,
273
242
  sendBulkMessageController,
274
243
  sendBulkMessageAirtableController,
275
- getLastInteractionController,
276
- configureMessageController
244
+ getLastInteractionController
277
245
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@peopl-health/nexus",
3
- "version": "1.3.1",
3
+ "version": "1.3.2",
4
4
  "description": "Core messaging and assistant library for WhatsApp communication platforms",
5
5
  "publishConfig": {
6
6
  "access": "public"