@peopl-health/nexus 1.0.3 → 1.1.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.
@@ -0,0 +1,87 @@
1
+ // Export route definitions for customer servers to import
2
+ // These are the route patterns without controller dependencies
3
+
4
+ const assistantRouteDefinitions = {
5
+ 'POST /active': 'activeAssistantController',
6
+ 'POST /add-instruction': 'addInsAssistantController',
7
+ 'POST /add-msg': 'addMsgAssistantController',
8
+ 'POST /create': 'createAssistantController',
9
+ 'POST /get-info': 'getInfoAssistantController',
10
+ 'GET /list': 'listAssistantController',
11
+ 'POST /switch': 'switchAssistantController',
12
+ 'POST /stop': 'stopAssistantController'
13
+ };
14
+
15
+ const conversationRouteDefinitions = {
16
+ 'GET /': 'getConversationController',
17
+ 'GET /search': 'searchConversationsController',
18
+ 'GET /by-name': 'getConversationsByNameController',
19
+ 'GET /:phoneNumber': 'getConversationMessagesController',
20
+ 'GET /:phoneNumber/new': 'getNewMessagesController',
21
+ 'POST /reply': 'getConversationReplyController',
22
+ 'POST /send-template': 'sendTemplateToNewNumberController',
23
+ 'POST /:phoneNumber/read': 'markMessagesAsReadController'
24
+ };
25
+
26
+ const mediaRouteDefinitions = {
27
+ 'GET /:key(*)': 'getMediaController',
28
+ 'POST /upload': 'handleFileUpload'
29
+ };
30
+
31
+ const messageRouteDefinitions = {
32
+ 'POST /send': 'sendMessageController',
33
+ 'POST /send-bulk': 'sendBulkMessageController',
34
+ 'POST /send-bulk-airtable': 'sendBulkMessageAirtableController'
35
+ };
36
+
37
+ const templateRouteDefinitions = {
38
+ 'POST /text': 'createTemplate',
39
+ 'GET /': 'listTemplates',
40
+ 'GET /predefined': 'getPredefinedTemplates',
41
+ 'GET /:id': 'getTemplate',
42
+ 'GET /complete/:sid': 'getCompleteTemplate',
43
+ 'POST /flow': 'createFlow',
44
+ 'DELETE /flow/:sid': 'deleteFlow',
45
+ 'POST /approval': 'submitForApproval',
46
+ 'GET /status/:sid': 'checkApprovalStatus',
47
+ 'DELETE /:id': 'deleteTemplate'
48
+ };
49
+
50
+ // Helper function to create Express router from route definitions
51
+ const createRouter = (routeDefinitions, controllers) => {
52
+ const express = require('express');
53
+ const router = express.Router();
54
+
55
+ for (const [route, controllerName] of Object.entries(routeDefinitions)) {
56
+ const [method, path] = route.split(' ');
57
+ const controller = controllers[controllerName];
58
+
59
+ if (controller) {
60
+ router[method.toLowerCase()](path, controller);
61
+ }
62
+ }
63
+
64
+ return router;
65
+ };
66
+
67
+ // Helper function to setup all default routes with provided controllers
68
+ const setupDefaultRoutes = (app, controllers) => {
69
+ app.use('/api/assistant', createRouter(assistantRouteDefinitions, controllers));
70
+ app.use('/api/conversation', createRouter(conversationRouteDefinitions, controllers));
71
+ app.use('/api/media', createRouter(mediaRouteDefinitions, controllers));
72
+ app.use('/api/message', createRouter(messageRouteDefinitions, controllers));
73
+ app.use('/api/template', createRouter(templateRouteDefinitions, controllers));
74
+ };
75
+
76
+ module.exports = {
77
+ // Route definitions for customers to use with their own controllers
78
+ assistantRoutes: assistantRouteDefinitions,
79
+ conversationRoutes: conversationRouteDefinitions,
80
+ mediaRoutes: mediaRouteDefinitions,
81
+ messageRoutes: messageRouteDefinitions,
82
+ templateRoutes: templateRouteDefinitions,
83
+
84
+ // Helper functions
85
+ createRouter,
86
+ setupDefaultRoutes
87
+ };
@@ -1,22 +1,35 @@
1
- const { MessageParser } = require('./MessageParser');
2
- const { DefaultLLMProvider } = require('./DefaultLLMProvider');
3
- const { logger, createLogger } = require('./logger');
4
- const { delay, formatCode, calculateDelay } = require('./whatsappHelper');
1
+ const AssistantManager = require('./AssistantManager');
2
+ const DefaultLLMProvider = require('./DefaultLLMProvider');
3
+ const MessageParser = require('./MessageParser');
4
+ const logger = require('./logger');
5
5
  const { useMongoDBAuthState } = require('./mongoAuthConfig');
6
- const { convertTwilioToInternalFormat, downloadMediaFromTwilio, getMediaTypeFromContentType, extractTitle, ensureWhatsAppFormat } = require('./twilioHelper');
6
+ const {
7
+ convertTwilioToInternalFormat,
8
+ downloadMediaFromTwilio,
9
+ getMediaTypeFromContentType,
10
+ extractTitle,
11
+ ensureWhatsAppFormat
12
+ } = require('./twilioHelper');
13
+ const {
14
+ delay,
15
+ formatCode,
16
+ calculateDelay
17
+ } = require('./whatsappHelper');
7
18
 
8
19
  module.exports = {
9
- MessageParser,
20
+ AssistantManager,
10
21
  DefaultLLMProvider,
22
+ MessageParser,
11
23
  logger,
12
- createLogger,
13
- delay,
14
- formatCode,
15
- calculateDelay,
16
24
  useMongoDBAuthState,
25
+ // Twilio utilities
17
26
  convertTwilioToInternalFormat,
18
27
  downloadMediaFromTwilio,
19
28
  getMediaTypeFromContentType,
20
29
  extractTitle,
21
- ensureWhatsAppFormat
30
+ ensureWhatsAppFormat,
31
+ // WhatsApp utilities
32
+ delay,
33
+ formatCode,
34
+ calculateDelay
22
35
  };
@@ -1,6 +1,11 @@
1
1
  const { MongoClient } = require('mongodb');
2
2
 
3
- const { proto, Curve, signedKeyPair, generateRegistrationId } = require('baileys');
3
+ let baileys;
4
+ try {
5
+ baileys = require('baileys');
6
+ } catch (error) {
7
+ baileys = null;
8
+ }
4
9
  const { randomBytes } = require('crypto');
5
10
 
6
11
  async function connectToMongo(mongoClient) {
@@ -14,6 +19,11 @@ async function connectToMongo(mongoClient) {
14
19
  }
15
20
 
16
21
  async function initAuthCreds() {
22
+ if (!baileys) {
23
+ throw new Error('Baileys is required for auth credentials but not installed');
24
+ }
25
+
26
+ const { proto, Curve, signedKeyPair, generateRegistrationId } = baileys;
17
27
  const identityKey = Curve.generateKeyPair();
18
28
  return {
19
29
  noiseKey: Curve.generateKeyPair(),
@@ -110,8 +120,8 @@ async function useMongoDBAuthState(uri, dbName, sessionId) {
110
120
  const data = {};
111
121
  await Promise.all(ids.map(async (id) => {
112
122
  let value = await readData(`${type}-${id}`);
113
- if (type === 'app-state-sync-key') {
114
- value = proto.Message.AppStateSyncKeyData.fromObject(data);
123
+ if (type === 'app-state-sync-key' && baileys) {
124
+ value = baileys.proto.Message.AppStateSyncKeyData.fromObject(value);
115
125
  }
116
126
  data[id] = value;
117
127
  }));
@@ -22,8 +22,6 @@ function convertTwilioToInternalFormat(twilioMessage) {
22
22
 
23
23
  async function downloadMediaFromTwilio(mediaUrl, credentials) {
24
24
  try {
25
- console.log(`Downloading media from: ${mediaUrl}`);
26
-
27
25
  const response = await axios({
28
26
  method: 'GET',
29
27
  url: mediaUrl,
@@ -5,7 +5,6 @@ function delay(ms) {
5
5
  }
6
6
 
7
7
  function formatCode(codeBase) {
8
-
9
8
  const [number, domain] = codeBase.split('@');
10
9
 
11
10
  if (!number || !domain) {
@@ -44,13 +43,6 @@ function calculateDelay(sendTime, timeZone) {
44
43
  const randomDelay = Math.floor(Math.random() * 15001) + 15000;
45
44
  const delay = sendMoment.diff(now) + randomDelay;
46
45
 
47
- console.log(
48
- 'Scheduled Time:', sendMoment.format(),
49
- 'Current Time:', now.format(),
50
- 'Delay (minutes):', delay / 60000,
51
- 'Remaining Seconds:', delay % 60000
52
- );
53
-
54
46
  if (delay <= 0) {
55
47
  return 2500;
56
48
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@peopl-health/nexus",
3
- "version": "1.0.3",
3
+ "version": "1.1.0",
4
4
  "description": "Core messaging and assistant library for WhatsApp communication platforms",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -24,6 +24,10 @@
24
24
  "./utils": {
25
25
  "import": "./lib/utils/index.js",
26
26
  "require": "./lib/utils/index.js"
27
+ },
28
+ "./routes": {
29
+ "import": "./lib/routes/index.js",
30
+ "require": "./lib/routes/index.js"
27
31
  }
28
32
  },
29
33
  "scripts": {
@@ -31,7 +35,7 @@
31
35
  "dev": "tsc --watch",
32
36
  "test": "jest",
33
37
  "lint": "eslint lib/**/*.js",
34
- "prepublishOnly": "npm test && npm run lint",
38
+ "prepublishOnly": "npm run lint",
35
39
  "version": "npm run prepublishOnly && git add -A lib",
36
40
  "postversion": "git push && git push --tags"
37
41
  },
@@ -46,23 +50,24 @@
46
50
  "author": "PEOPL Health Tech",
47
51
  "license": "MIT",
48
52
  "dependencies": {
49
- "mongoose": "^7.5.0",
53
+ "axios": "^1.5.0",
50
54
  "moment-timezone": "^0.5.43",
55
+ "mongoose": "^7.5.0",
51
56
  "pino": "^8.15.0",
52
57
  "pino-pretty": "^10.2.0",
53
- "uuid": "^9.0.0",
54
- "axios": "^1.5.0"
58
+ "uuid": "^9.0.0"
55
59
  },
56
60
  "peerDependencies": {
57
61
  "baileys": "^6.4.0",
58
- "twilio": "^5.6.0",
59
- "openai": "^4.0.0"
62
+ "express": "4.21.2",
63
+ "openai": "^4.0.0",
64
+ "twilio": "^5.6.0"
60
65
  },
61
66
  "devDependencies": {
62
67
  "@types/node": "^20.5.0",
63
- "typescript": "^5.1.6",
68
+ "eslint": "^8.47.0",
64
69
  "jest": "^29.6.2",
65
- "eslint": "^8.47.0"
70
+ "typescript": "^5.1.6"
66
71
  },
67
72
  "engines": {
68
73
  "node": ">=20.0.0"