@peopl-health/nexus 1.5.8 → 1.5.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.
Files changed (72) hide show
  1. package/CHANGELOG.md +0 -0
  2. package/LICENSE +0 -0
  3. package/MIGRATION_GUIDE.md +0 -0
  4. package/README.md +0 -0
  5. package/examples/.env.example +0 -0
  6. package/examples/assistants/BaseAssistant.js +1 -242
  7. package/examples/assistants/DoctorScheduleAssistant.js +83 -0
  8. package/examples/assistants/ExampleAssistant.js +0 -0
  9. package/examples/assistants/index.js +3 -1
  10. package/examples/basic-usage.js +8 -7
  11. package/examples/consumer-server.js +0 -0
  12. package/lib/adapters/BaileysProvider.js +0 -0
  13. package/lib/adapters/TwilioProvider.js +177 -5
  14. package/lib/adapters/index.js +0 -0
  15. package/lib/adapters/registry.js +0 -0
  16. package/lib/assistants/BaseAssistant.js +294 -0
  17. package/lib/assistants/index.js +5 -0
  18. package/lib/config/airtableConfig.js +0 -0
  19. package/lib/config/awsConfig.js +0 -0
  20. package/lib/config/configLoader.js +0 -0
  21. package/lib/config/llmConfig.js +0 -0
  22. package/lib/config/mongoAuthConfig.js +0 -0
  23. package/lib/config/runtimeConfig.js +0 -0
  24. package/lib/controllers/assistantController.js +0 -0
  25. package/lib/controllers/conversationController.js +0 -0
  26. package/lib/controllers/mediaController.js +0 -0
  27. package/lib/controllers/messageController.js +0 -0
  28. package/lib/controllers/templateController.js +0 -0
  29. package/lib/controllers/templateFlowController.js +0 -0
  30. package/lib/controllers/uploadController.js +0 -0
  31. package/lib/core/MessageProvider.js +0 -0
  32. package/lib/core/NexusMessaging.js +0 -0
  33. package/lib/core/index.js +0 -0
  34. package/lib/helpers/assistantHelper.js +0 -0
  35. package/lib/helpers/baileysHelper.js +0 -0
  36. package/lib/helpers/filesHelper.js +0 -0
  37. package/lib/helpers/llmsHelper.js +0 -0
  38. package/lib/helpers/mediaHelper.js +0 -0
  39. package/lib/helpers/mongoHelper.js +0 -0
  40. package/lib/helpers/qrHelper.js +0 -0
  41. package/lib/helpers/twilioHelper.js +0 -0
  42. package/lib/helpers/twilioMediaProcessor.js +0 -0
  43. package/lib/helpers/whatsappHelper.js +0 -0
  44. package/lib/index.d.ts +51 -0
  45. package/lib/index.js +6 -0
  46. package/lib/interactive/index.js +0 -0
  47. package/lib/interactive/registry.js +0 -0
  48. package/lib/interactive/twilioMapper.js +0 -0
  49. package/lib/models/agendaMessageModel.js +0 -0
  50. package/lib/models/index.js +0 -0
  51. package/lib/models/messageModel.js +2 -1
  52. package/lib/models/templateModel.js +0 -0
  53. package/lib/models/threadModel.js +0 -0
  54. package/lib/routes/index.js +0 -0
  55. package/lib/services/airtableService.js +0 -0
  56. package/lib/services/assistantService.js +66 -4
  57. package/lib/services/conversationService.js +0 -0
  58. package/lib/services/twilioService.js +0 -0
  59. package/lib/storage/MongoStorage.js +15 -4
  60. package/lib/storage/NoopStorage.js +0 -0
  61. package/lib/storage/index.js +0 -0
  62. package/lib/storage/registry.js +0 -0
  63. package/lib/templates/predefinedTemplates.js +0 -0
  64. package/lib/templates/templateStructure.js +0 -0
  65. package/lib/utils/dateUtils.js +0 -0
  66. package/lib/utils/defaultLLMProvider.js +0 -0
  67. package/lib/utils/errorHandler.js +0 -0
  68. package/lib/utils/index.js +0 -0
  69. package/lib/utils/logger.js +0 -0
  70. package/lib/utils/mediaValidator.js +0 -0
  71. package/lib/utils/messageParser.js +0 -0
  72. package/package.json +3 -3
@@ -0,0 +1,294 @@
1
+ const llmConfig = require('../config/llmConfig');
2
+ const { Thread } = require('../models/threadModel');
3
+ const { getLastNMessages } = require('../helpers/assistantHelper');
4
+
5
+ /**
6
+ * Flexible base assistant implementation that integrates with OpenAI Threads
7
+ * and supports dynamic tool registration.
8
+ */
9
+ class BaseAssistant {
10
+ constructor(input = {}) {
11
+ const options = this._normalizeOptions(input);
12
+
13
+ this.assistantId = options.assistantId || null;
14
+ this.thread = options.thread || null;
15
+ this.status = options.status || 'idle';
16
+ this.replies = null;
17
+ this.lastMessages = null;
18
+ this.createdAt = new Date();
19
+
20
+ this.client = options.client || llmConfig.openaiClient || null;
21
+ this.tools = new Map();
22
+
23
+ if (Array.isArray(options.tools)) {
24
+ options.tools.forEach((tool) => this.registerTool(tool));
25
+ }
26
+
27
+ if (options.setup && typeof options.setup === 'function') {
28
+ options.setup.call(this, options);
29
+ }
30
+
31
+ if (this.assistantId) {
32
+ console.log(`Assistant ${this.assistantId} initialized.`);
33
+ }
34
+ }
35
+
36
+ _normalizeOptions(input) {
37
+ if (!input || typeof input !== 'object') {
38
+ return { thread: input };
39
+ }
40
+
41
+ if (input && input._id && !input.assistantId && !input.client && !input.tools) {
42
+ return { thread: input };
43
+ }
44
+
45
+ return input;
46
+ }
47
+
48
+ _ensureClient() {
49
+ if (!this.client) {
50
+ throw new Error('LLM client not configured. Ensure openaiClient is initialized.');
51
+ }
52
+ }
53
+
54
+ async getAssistantId() {
55
+ return this.assistantId;
56
+ }
57
+
58
+ async getStatus() {
59
+ return this.status;
60
+ }
61
+
62
+ async getNextAssistant() {
63
+ return this.nextAssistant || null;
64
+ }
65
+
66
+ setThread(thread) {
67
+ this.thread = thread;
68
+ }
69
+
70
+ setReplies(replies) {
71
+ this.replies = replies;
72
+ }
73
+
74
+ registerTool(nameOrConfig, schema, handler) {
75
+ let name;
76
+ let definition;
77
+ let executor;
78
+
79
+ if (typeof nameOrConfig === 'object' && nameOrConfig !== null) {
80
+ name = nameOrConfig.name;
81
+ definition = nameOrConfig.definition || nameOrConfig.schema || nameOrConfig;
82
+ executor = nameOrConfig.handler || nameOrConfig.execute || nameOrConfig.run;
83
+ } else {
84
+ name = nameOrConfig;
85
+ definition = schema;
86
+ executor = handler;
87
+ }
88
+
89
+ if (!name || typeof name !== 'string') {
90
+ throw new Error('Tool name is required');
91
+ }
92
+
93
+ if (!definition || typeof definition !== 'object') {
94
+ throw new Error(`Tool definition for '${name}' must be an object`);
95
+ }
96
+
97
+ if (!executor || typeof executor !== 'function') {
98
+ throw new Error(`Tool handler for '${name}' must be a function`);
99
+ }
100
+
101
+ const toolSchema = {
102
+ type: 'function',
103
+ function: {
104
+ name,
105
+ description: definition.description || 'Custom assistant tool',
106
+ parameters: definition.parameters || {
107
+ type: 'object',
108
+ properties: {},
109
+ additionalProperties: true
110
+ }
111
+ }
112
+ };
113
+
114
+ this.tools.set(name, {
115
+ schema: toolSchema,
116
+ execute: executor
117
+ });
118
+ }
119
+
120
+ getToolSchemas() {
121
+ return Array.from(this.tools.values()).map((value) => value.schema);
122
+ }
123
+
124
+ async executeTool(name, args) {
125
+ const tool = this.tools.get(name);
126
+ if (!tool) {
127
+ throw new Error(`Unknown tool '${name}' requested by assistant`);
128
+ }
129
+ return await tool.execute(args);
130
+ }
131
+
132
+ async createThread(code, context = {}) {
133
+ return await this.create(code, context);
134
+ }
135
+
136
+ async sendMessage(userId, message, options = {}) {
137
+ this._ensureClient();
138
+
139
+ if (!this.thread || !this.thread.thread_id) {
140
+ throw new Error('Assistant thread not initialized. Call create() before sendMessage().');
141
+ }
142
+
143
+ await this.client.beta.threads.messages.create(
144
+ this.thread.thread_id,
145
+ { role: 'user', content: message }
146
+ );
147
+
148
+ const runConfig = {
149
+ assistant_id: this.assistantId,
150
+ ...options
151
+ };
152
+
153
+ const toolSchemas = this.getToolSchemas();
154
+ if (toolSchemas.length > 0) {
155
+ runConfig.tools = toolSchemas;
156
+ }
157
+
158
+ const run = await this.client.beta.threads.runs.create(
159
+ this.thread.thread_id,
160
+ runConfig
161
+ );
162
+
163
+ return await this.waitForCompletion(this.thread.thread_id, run.id);
164
+ }
165
+
166
+ async waitForCompletion(threadId, runId, { interval = 2000, maxAttempts = 30 } = {}) {
167
+ this._ensureClient();
168
+ let attempts = 0;
169
+
170
+ while (attempts < maxAttempts) {
171
+ const run = await this.client.beta.threads.runs.retrieve(threadId, runId);
172
+
173
+ if (run.status === 'completed') {
174
+ return run;
175
+ }
176
+
177
+ if (run.status === 'requires_action') {
178
+ await this.handleRequiresAction(run);
179
+ } else if (['failed', 'cancelled', 'expired', 'incomplete'].includes(run.status)) {
180
+ throw new Error(`Assistant run ended with status '${run.status}'`);
181
+ }
182
+
183
+ await new Promise((resolve) => setTimeout(resolve, interval));
184
+ attempts += 1;
185
+ }
186
+
187
+ throw new Error('Assistant run timeout');
188
+ }
189
+
190
+ async getPreviousMessages(threadDoc) {
191
+ this._ensureClient();
192
+ const threadRef = threadDoc || this.thread;
193
+ if (!threadRef) return [];
194
+
195
+ const response = await this.client.beta.threads.messages.list(threadRef.thread_id, { order: 'asc' });
196
+ return response.data.map((msg) => {
197
+ const textContents = msg.content
198
+ .filter((part) => part.type === 'text')
199
+ .map((part) => part.text.value);
200
+ const content = textContents.length <= 1 ? textContents[0] || '' : textContents;
201
+ return { role: msg.role, content };
202
+ });
203
+ }
204
+
205
+ async create(code, context = {}) {
206
+ this._ensureClient();
207
+ this.status = 'active';
208
+
209
+ const whatsappId = context?.whatsapp_id || code;
210
+ if (whatsappId) {
211
+ this.lastMessages = await getLastNMessages(whatsappId, 20);
212
+ }
213
+
214
+ const initialMessages = await this.buildInitialMessages({ code, context });
215
+ const threadPayload = {};
216
+
217
+ if (initialMessages.length > 0) {
218
+ threadPayload.messages = initialMessages.map((msg) => ({
219
+ role: msg.role || 'assistant',
220
+ content: msg.content
221
+ }));
222
+ }
223
+
224
+ const thread = await this.client.beta.threads.create(threadPayload);
225
+ this.thread = thread;
226
+ return thread;
227
+ }
228
+
229
+ async buildInitialMessages({ code }) {
230
+ if (!this.lastMessages) return [];
231
+ return [{
232
+ role: 'assistant',
233
+ content: `Últimos mensajes para ${code}:
234
+ ${this.lastMessages}`
235
+ }];
236
+ }
237
+
238
+ async handleRequiresAction(run) {
239
+ const toolCalls = run?.required_action?.submit_tool_outputs?.tool_calls || [];
240
+ if (toolCalls.length === 0) {
241
+ return [];
242
+ }
243
+
244
+ const outputs = [];
245
+
246
+ for (const call of toolCalls) {
247
+ try {
248
+ const name = call.function?.name;
249
+ const args = call.function?.arguments ? JSON.parse(call.function.arguments) : {};
250
+ const result = await this.executeTool(name, args);
251
+ outputs.push({ tool_call_id: call.id, output: typeof result === 'string' ? result : JSON.stringify(result) });
252
+ } catch (error) {
253
+ console.error('[BaseAssistant] Tool execution failed', error);
254
+ outputs.push({
255
+ tool_call_id: call.id,
256
+ output: JSON.stringify({ success: false, error: error?.message || 'Tool execution failed' })
257
+ });
258
+ }
259
+ }
260
+
261
+ if (!this.client) {
262
+ console.warn('[BaseAssistant] Cannot submit tool outputs: client not configured');
263
+ return outputs;
264
+ }
265
+
266
+ await this.client.beta.threads.runs.submitToolOutputs(
267
+ run.thread_id,
268
+ run.id,
269
+ { tool_outputs: outputs }
270
+ );
271
+
272
+ return outputs;
273
+ }
274
+
275
+ async close() {
276
+ this.status = 'closed';
277
+ if (this.thread?.code && this.thread?.assistant_id) {
278
+ await Thread.updateOne(
279
+ { code: this.thread.code, assistant_id: this.thread.assistant_id },
280
+ { $set: { active: false } }
281
+ );
282
+ }
283
+
284
+ if (this.assistantId) {
285
+ console.log(`Assistant ${this.assistantId} closed`);
286
+ }
287
+
288
+ return `Assistant ${this.assistantId || ''} successfully closed.`.trim();
289
+ }
290
+ }
291
+
292
+ module.exports = {
293
+ BaseAssistant
294
+ };
@@ -0,0 +1,5 @@
1
+ const { BaseAssistant } = require('./BaseAssistant');
2
+
3
+ module.exports = {
4
+ BaseAssistant
5
+ };
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
package/lib/core/index.js CHANGED
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
package/lib/index.d.ts CHANGED
@@ -117,6 +117,48 @@ declare module '@peopl-health/nexus' {
117
117
  onFlow?: FlowHandler;
118
118
  }
119
119
 
120
+ export interface AssistantToolDefinition {
121
+ name: string;
122
+ description?: string;
123
+ parameters?: any;
124
+ handler: (args: any) => any;
125
+ }
126
+
127
+ export interface AssistantConfigDefinition {
128
+ extends?: typeof BaseAssistant;
129
+ create?: (this: BaseAssistant, code: string, context?: any) => Promise<any>;
130
+ tools?: Array<AssistantToolDefinition | { name: string; definition?: any; handler: (args: any) => any }>;
131
+ setup?: (this: BaseAssistant, context: { assistantId: string; thread?: any; options?: any }) => void;
132
+ }
133
+
134
+ export class BaseAssistant {
135
+ constructor(options?: {
136
+ assistantId?: string;
137
+ thread?: any;
138
+ client?: any;
139
+ tools?: Array<AssistantToolDefinition | { name: string; definition?: any; handler: (args: any) => any }>;
140
+ setup?: (context: { assistantId: string; thread?: any; options?: any }) => void;
141
+ status?: string;
142
+ } | any);
143
+ assistantId: string | null;
144
+ thread: any;
145
+ status: string;
146
+ createdAt: Date;
147
+ registerTool(definition: AssistantToolDefinition | string, schema?: any, handler?: (args: any) => any): void;
148
+ getToolSchemas(): any[];
149
+ executeTool(name: string, args: any): Promise<any>;
150
+ getPreviousMessages(thread?: any): Promise<Array<{ role: string; content: any }>>;
151
+ createThread(code: string, context?: any): Promise<any>;
152
+ sendMessage(userId: string, message: string, options?: any): Promise<any>;
153
+ waitForCompletion(threadId: string, runId: string, opts?: { interval?: number; maxAttempts?: number }): Promise<any>;
154
+ create(code: string, context?: any): Promise<any>;
155
+ buildInitialMessages(context: { code: string; [key: string]: any }): Promise<Array<{ role: string; content: string }>>;
156
+ handleRequiresAction(run: any): Promise<any[]>;
157
+ close(): Promise<string>;
158
+ setThread(thread: any): void;
159
+ setReplies(replies: any): void;
160
+ }
161
+
120
162
  // Core Classes
121
163
  export abstract class MessageProvider {
122
164
  constructor(config: any);
@@ -127,6 +169,15 @@ declare module '@peopl-health/nexus' {
127
169
  abstract disconnect(): Promise<void>;
128
170
  }
129
171
 
172
+ export function registerAssistant(
173
+ assistantId: string,
174
+ definition: typeof BaseAssistant | ((thread?: any) => any) | AssistantConfigDefinition
175
+ ): any;
176
+
177
+ export function configureAssistantsLLM(client: any): void;
178
+ export function overrideGetAssistantById(resolver: (assistantId: string, thread?: any) => any): void;
179
+ export function configureAssistants(config: any): void;
180
+
130
181
  export class TwilioProvider extends MessageProvider {
131
182
  constructor(config: TwilioConfig);
132
183
  initialize(): Promise<void>;
package/lib/index.js CHANGED
@@ -16,6 +16,7 @@ const {
16
16
  } = require('./services/assistantService');
17
17
  const { TwilioProvider } = require('./adapters/TwilioProvider');
18
18
  const { BaileysProvider } = require('./adapters/BaileysProvider');
19
+ const { BaseAssistant: CoreBaseAssistant } = require('./assistants/BaseAssistant');
19
20
 
20
21
  /**
21
22
  * Main Nexus class that orchestrates all components
@@ -312,6 +313,11 @@ module.exports = {
312
313
  MongoStorage,
313
314
  MessageParser,
314
315
  DefaultLLMProvider,
316
+ BaseAssistant: CoreBaseAssistant,
317
+ registerAssistant,
318
+ configureAssistantsLLM,
319
+ overrideGetAssistantById,
320
+ configureAssistants: setAssistantsConfig,
315
321
  routes,
316
322
  setupDefaultRoutes: routes.setupDefaultRoutes,
317
323
  createRouter: routes.createRouter,
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -68,7 +68,8 @@ async function insertMessage(values) {
68
68
  reply_id: values.reply_id,
69
69
  from_me: values.from_me,
70
70
  processed: skipNumbers.includes(values.numero),
71
- media: values.media ? values.media : null
71
+ media: values.media ? values.media : null,
72
+ content_sid: values.content_sid || null
72
73
  };
73
74
 
74
75
  await Message.findOneAndUpdate(
File without changes
File without changes
File without changes
File without changes
@@ -3,6 +3,8 @@ const AWS = require('../config/awsConfig.js');
3
3
  const { combineImagesToPDF, cleanupFiles } = require('../helpers/filesHelper.js');
4
4
  const { addRecord } = require('../services/airtableService.js');
5
5
  const runtimeConfig = require('../config/runtimeConfig');
6
+ const llmConfig = require('../config/llmConfig');
7
+ const { BaseAssistant } = require('../assistants/BaseAssistant');
6
8
 
7
9
  let llmProvider = null;
8
10
  const configureLLMProvider = (provider) => {
@@ -27,8 +29,54 @@ const configureAssistants = (config) => {
27
29
  assistantConfig = config;
28
30
  };
29
31
 
30
- const registerAssistant = (assistantId, AssistantClass) => {
31
- assistantRegistry[assistantId] = AssistantClass;
32
+ const registerAssistant = (assistantId, definition) => {
33
+ if (!assistantId || typeof assistantId !== 'string') {
34
+ throw new Error('registerAssistant requires a string assistantId');
35
+ }
36
+
37
+ if (typeof definition === 'function') {
38
+ assistantRegistry[assistantId] = definition;
39
+ return definition;
40
+ }
41
+
42
+ if (definition && typeof definition === 'object') {
43
+ const {
44
+ extends: ParentClass = BaseAssistant,
45
+ create,
46
+ tools = [],
47
+ setup
48
+ } = definition;
49
+
50
+ class ConfiguredAssistant extends ParentClass {
51
+ constructor(options = {}) {
52
+ super({
53
+ ...options,
54
+ assistantId,
55
+ client: options.client || llmProvider || llmConfig.openaiClient || null,
56
+ tools: [...tools, ...(options.tools || [])]
57
+ });
58
+
59
+ if (typeof setup === 'function') {
60
+ setup.call(this, {
61
+ assistantId,
62
+ thread: this.thread,
63
+ options
64
+ });
65
+ }
66
+ }
67
+ }
68
+
69
+ if (typeof create === 'function') {
70
+ ConfiguredAssistant.prototype.create = async function(code, context) {
71
+ return await create.call(this, code, context);
72
+ };
73
+ }
74
+
75
+ assistantRegistry[assistantId] = ConfiguredAssistant;
76
+ return ConfiguredAssistant;
77
+ }
78
+
79
+ throw new Error('registerAssistant expects a class/function or configuration object');
32
80
  };
33
81
 
34
82
  const overrideGetAssistantById = (resolverFn) => {
@@ -51,8 +99,22 @@ const getAssistantById = (assistant_id, thread) => {
51
99
  if (!AssistantClass) {
52
100
  throw new Error(`Assistant '${assistant_id}' not found. Available assistants: ${Object.keys(assistantRegistry).join(', ')}`);
53
101
  }
54
-
55
- return new AssistantClass(thread);
102
+
103
+ const sharedClient = llmProvider || llmConfig.openaiClient || null;
104
+
105
+ if (AssistantClass.prototype instanceof BaseAssistant) {
106
+ return new AssistantClass({
107
+ assistantId: assistant_id,
108
+ thread,
109
+ client: sharedClient
110
+ });
111
+ }
112
+
113
+ try {
114
+ return new AssistantClass(thread);
115
+ } catch (error) {
116
+ return new AssistantClass({ thread, assistantId: assistant_id, client: sharedClient });
117
+ }
56
118
  };
57
119
 
58
120
 
File without changes
File without changes
@@ -66,10 +66,11 @@ class MongoStorage {
66
66
  from: messageData?.from,
67
67
  provider: messageData?.provider || 'unknown',
68
68
  hasRaw: Boolean(messageData?.raw),
69
- hasMedia: Boolean(messageData?.media || messageData?.fileUrl)
69
+ hasMedia: Boolean(messageData?.media || messageData?.fileUrl),
70
+ hasContentSid: Boolean(messageData?.contentSid)
70
71
  });
71
72
  const enrichedMessage = await this._enrichTwilioMedia(messageData);
72
- const values = this.buildLegacyMessageValues(enrichedMessage);
73
+ const values = this.buildMessageValues(enrichedMessage);
73
74
  const { insertMessage } = require('../models/messageModel');
74
75
  await insertMessage(values);
75
76
  console.log('[MongoStorage] Message stored', {
@@ -166,7 +167,8 @@ class MongoStorage {
166
167
  return trimmed;
167
168
  }
168
169
 
169
- buildLegacyMessageValues(messageData = {}) {
170
+
171
+ buildMessageValues(messageData = {}) {
170
172
  const numero = messageData.to || messageData.code || messageData.numero || messageData.from;
171
173
  const rawNumero = typeof numero === 'string' ? numero : '';
172
174
  const normalizedNumero = this.normalizeNumero(rawNumero);
@@ -175,7 +177,16 @@ class MongoStorage {
175
177
  const now = new Date();
176
178
  const timestamp = now.toISOString();
177
179
  const nombre = messageData.nombre_whatsapp || messageData.author || messageData.fromName || runtimeConfig.get('USER_DB_MONGO') || process.env.USER_DB_MONGO || 'Nexus';
178
- const textBody = messageData.message || messageData.body || (messageData.contentSid ? `[Template:${messageData.contentSid}]` : isMedia ? `[Media:${messageData.fileType || 'attachment'}]` : '');
180
+
181
+ // Use message body directly (template rendering is now handled by the provider)
182
+ let textBody = messageData.message || messageData.body;
183
+
184
+ if (!textBody && isMedia) {
185
+ textBody = `[Media:${messageData.fileType || 'attachment'}]`;
186
+ } else if (!textBody) {
187
+ textBody = '';
188
+ }
189
+
179
190
  const providerId = messageData.messageId || messageData.sid || messageData.id || messageData._id || `pending-${now.getTime()}-${Math.floor(Math.random()*1000)}`;
180
191
 
181
192
  const media = messageData.media || (messageData.fileUrl ? {
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@peopl-health/nexus",
3
- "version": "1.5.8",
3
+ "version": "1.5.10",
4
4
  "description": "Core messaging and assistant library for WhatsApp communication platforms",
5
5
  "keywords": [
6
6
  "whatsapp",
@@ -73,7 +73,7 @@
73
73
  "airtable": "^0.12.2",
74
74
  "aws-sdk": "2.1674.0",
75
75
  "axios": "^1.5.0",
76
- "dotenv": "^16.4.7",
76
+ "dotenv": "^16.6.1",
77
77
  "moment-timezone": "^0.5.43",
78
78
  "mongoose": "^7.5.0",
79
79
  "multer": "1.4.5-lts.1",
@@ -102,4 +102,4 @@
102
102
  "publishConfig": {
103
103
  "access": "public"
104
104
  }
105
- }
105
+ }