@peopl-health/nexus
v2.5.4
Published
Core messaging and assistant library for WhatsApp communication platforms
Maintainers
Readme
@peopl-health/nexus
A concise, configurable messaging and assistant toolkit for WhatsApp. It supports Twilio (production‑ready) and Baileys (limited), optional Mongo storage, OpenAI assistants, templates/flows via Twilio Content API, and an event/middleware model so apps can customize behavior.
Install
npm install @peopl-health/nexus
# Providers / AI
npm install twilio baileys openaiQuick Start (Twilio)
const express = require('express');
const { Nexus, setupDefaultRoutes } = require('@peopl-health/nexus');
const nexus = new Nexus();
await nexus.initialize({
provider: 'twilio',
providerConfig: {
accountSid: process.env.TWILIO_ACCOUNT_SID,
authToken: process.env.TWILIO_AUTH_TOKEN,
phoneNumber: process.env.TWILIO_PHONE_NUMBER
},
// Storage (MongoStorage) and Mongo convenience
storage: 'mongo',
storageConfig: { dbName: 'nexus' }, // other options
mongoUri: process.env.MONGODB_URI, // convenience: passed into storageConfig.mongoUri
// Media convenience (inject only bucket name)
media: { bucketName: process.env.AWS_S3_BUCKET_NAME },
// Airtable convenience (pick default base or pass a Base ID)
airtable: {
base: 'calendar', // friendly key or base ID
apiKey: process.env.AIRTABLE_API_KEY
},
// Optional LLM (OpenAI)
llm: 'openai',
llmConfig: { apiKey: process.env.OPENAI_API_KEY }
});
// Built‑in routes (assistant, conversation, media, message, template)
const app = express();
app.use(express.json());
setupDefaultRoutes(app);
// Incoming webhooks
app.post('/webhook', async (req, res) => {
await nexus.processMessage(req.body);
res.sendStatus(200);
});Templates & Approvals (Twilio)
Nexus auto‑injects the active Twilio provider into the template controllers during initialize. Default routes under /api/template work immediately:
GET /api/templatelist templatesGET /api/template/:idget onePOST /api/template/textcreate text templatePOST /api/template/approvalsubmit for approvalGET /api/template/status/:sidcheck statusDELETE /api/template/:iddelete
Programmatic use:
const provider = nexus.getMessaging().getProvider();
const content = await provider.createTemplate({
friendly_name: 'hello_' + Date.now(),
language: 'es',
variables: { '1': 'Nombre' },
types: { 'twilio/text': { body: 'Hola {{1}}' } }
});
await provider.submitForApproval(content.sid, 'hello', 'UTILITY');
const status = await provider.checkApprovalStatus(content.sid);Interactive & Flows
Provider‑agnostic APIs with Twilio mapping (Baileys: not supported):
const { registerFlow, sendInteractive, registerInteractiveHandler, attachInteractiveRouter } = require('@peopl-health/nexus');
registerFlow('greeting_qr', {
type: 'quick-reply', language: 'es', body: 'Hola {{1}}', variables: { '1': 'Nombre' },
buttons: [{ text: 'Sí' }, { text: 'No' }]
});
await sendInteractive(nexus, { code: '+521555...', id: 'greeting_qr' });
registerInteractiveHandler({ type: 'button', id: /sí|si/i }, async (msg, messaging) => {
await messaging.sendMessage({ code: msg.from, message: '¡Confirmado!' });
});
attachInteractiveRouter(nexus);Storage (Adapters)
- Built‑in:
mongo(default),noop. - Register your adapter or pass an instance directly.
const { registerStorage } = require('@peopl-health/nexus/lib/storage/registry');
registerStorage('src', MyStorageClass);
await nexus.initialize({ storage: 'src', storageConfig: { /* ... */ } });
// OR
await nexus.initialize({ storage: new MyStorageClass(/* ... */) });Middleware & Events
Add middleware per type or global; subscribe to events.
const bus = nexus.getMessaging().getEventBus();
bus.on('message:received', (m) => console.log('rx', m.id));
nexus.getMessaging().use('message', async (msg, nx, next) => {
// sanitize/annotate
return next();
});Assistants (Optional)
Register assistant classes and (optionally) a custom resolver. OpenAI is supported via llm: 'openai'.
await nexus.initialize({
provider: 'twilio',
llm: 'openai', llmConfig: { apiKey: process.env.OPENAI_API_KEY },
assistants: {
registry: { SUPPORT: SupportAssistantClass, SALES: SalesAssistantClass },
getAssistantById: (id, thread) => null // optional override
}
});Routes (Importable)
Use setupDefaultRoutes(app) to mount everything, or pick from routes + createRouter() to mount subsets.
Examples
See:
- examples/basic-usage.js
- examples/assistants/
Configuration
You can configure Nexus via environment variables or at runtime using simple injection helpers. For production apps, prefer passing options or DI, and use envs as a fallback.
Providers/AI
- TWILIO_ACCOUNT_SID, TWILIO_AUTH_TOKEN, TWILIO_PHONE_NUMBER
- OPENAI_API_KEY
Mongo
- MONGODB_URI (or pass
mongoUriwhen callinginitializeMongoDB())
- MONGODB_URI (or pass
Airtable
- AIRTABLE_API_KEY
- AIRTABLE_BASE_ID (or specific IDs below)
- AIRTABLE_CALENDAR_ID, AIRTABLE_CONFIG_ID, AIRTABLE_HISTORIAL_CLINICO_ID
- AIRTABLE_LOGGING_ID, AIRTABLE_MONITOREO_ID, AIRTABLE_PROGRAMA_JUNTAS_ID
- AIRTABLE_SYMPTOMS_ID, AIRTABLE_WEBINARS_LEADS_ID
AWS (S3)
- AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_REGION (default: us-east-1)
- AWS_S3_BUCKET_NAME (or inject via
configureMediaController)
Misc
- NODE_ENV (affects logging and helpers)
- USER_DB_MONGO (used as author in message controller)
Injection points (dependency injection)
- Message scheduling (use your Agenda/Bull model + scheduler):
const { configureMessageController } = require('@peopl-health/nexus/lib/controllers/messageController');
const { AgendaMessage } = require('./src/models/agendaMessageModel');
const { sendScheduledMessage: appSchedule } = require('./src/messaging/scheduledMessageService');
const provider = nexus.getMessaging().getProvider(); // e.g., TwilioProvider
configureMessageController({
ScheduledMessage: AgendaMessage, // must expose create/find/findById/deleteOne
sendScheduledMessage: (saved) => appSchedule(provider.twilioClient, saved),
// Optional: only if you use bulk‑airtable
getRecordByFilter: require('@peopl-health/nexus/lib/services/airtableService').getRecordByFilter
});- Media (inject only your bucket name; AWS SDK is loaded by the lib):
const { configureMediaController } = require('@peopl-health/nexus/lib/controllers/mediaController');
configureMediaController({ bucketName: process.env.AWS_S3_BUCKET_NAME });- Storage settings (MongoStorage only):
// Store once; Nexus auto-injects media bucket from storage at startup
await nexus.getStorage().setConfig('media.bucketName', process.env.AWS_S3_BUCKET_NAME);Tips
- Connect Mongo before
app.listen()to avoid Mongoose buffering timeouts. - If you initialize OpenAI, pass
llm: 'openai'andllmConfig: { apiKey }tonexus.initialize. - Use the event bus + middleware for custom routing and transformations without forking the default handlers.
