Third-Party Integrations¶
Every external dependency Prism talks to, where it is wired, where its credentials live, and the gotchas that bite in production.
Validation legend: ✅ verified in code · 📄 documented/inferred from map · 💻 config file · ♻️ duplicated implementation · ⚰️ dead/disabled · ⚠️ risk/gotcha
1. Integration matrix¶
| Integration | Category | Purpose | Where used (file) | Auth / config location | Status |
|---|---|---|---|---|---|
| Gupshup | WhatsApp BSP | Onboarding, template approval, opt-in, catalogue, marketing/txn sends | controllers/gupshupOnboardingController.js, controllers/whatsappCatalogueController.js, processLibrary/whatsappMsgProcess.js |
Per-business creds in business_configs (Gupshup app/token) |
✅ |
| Meta WhatsApp (TSP) | WhatsApp direct | Meta Telecom-Service-Provider onboarding, access tokens, template create, Facebook Graph send | controllers/metaTSP.js, processLibrary/whatsappMsgProcess.js |
business_configs (Meta access token, WABA id); JWT |
✅ In Progress (roadmap B3.13) |
| Firebase / FCM | Push | Android/iOS push, topic subscription, token cleanup | commonFunctions/processNotiQueue.js, sendFcmNotification.js, subscribeToTopic.js, controllers/fcmInjestionController.js, parseFcmTokenController.js |
Per-business cert key in business_configs.fcm_cert_key; fcm-node, firebase-admin |
✅ ⚠️ |
| AWS SES / Nodemailer | Reports, alerts, campaign mailers, low-wallet emails | controllers/campaignController.js, campaignControllerMailHelper.js, dashboardController.js, report crons |
@aws-sdk/client-ses, nodemailer; recipients in crm_ecosystem.config.js MAIL_* |
✅ | |
| AWS S3 | Storage | QR PNGs, campaign uploads, chat media, report files | controllers/qrCodeController.js, helpDeskController.js, customerController.js, campaignController.js |
aws-sdk (SigV4); IAM creds via env/instance role |
✅ |
| Google Reviews / GMB | Reviews | Sync Google My Business reviews & ratings | controllers/ratingController.js, dashboardController.js |
google-auth-library, Google APIs |
📄 |
| Zomato / Swiggy reviews & orders | Aggregators | Order ingestion + review sync | commonFunctions/processCommonIngestion.js, parseOrderData.js, ratingController.js |
via crm_offer_middleware token in authorization_token |
📄 |
| DLT (SMS) | Compliance | DLT-registered sender IDs / template IDs for Indian SMS | commonFunctions/sendSms.js, crons/smsQueueCron.js |
sender_id + template mapping in campaign/business config | 📄 |
| PetPooja | POS | Order ingestion | controllers/petpoojaOrderIngestion.js, injestionController.petPooja |
crm_token in business_configs; source id 2 |
✅ ♻️ |
| UrbanPiper | POS | Order ingestion (aggregated) | via processCommonIngestion.js / commonIngestion route |
crm_offer_middleware token |
📄 |
| Posist | POS + loyalty | Order ingestion + bidirectional loyalty sync | controllers/posistCron.js, posistLoyaltyIntegration.js, injestionController.posist |
/posist/v1 routes; source id 7 |
✅ ♻️ |
| LS Central | POS | Order ingestion | injestionController.ls_center |
injestion_middleware hardcoded token ⚠️; source id 3 |
✅ ⚠️ |
| Rista | POS | Order ingestion | controllers/ristaOrderIngestion.js, injestionController.rista |
crm_offer_middleware; source id 6 |
✅ ♻️ |
| New Relic | APM | App performance monitoring | newrelic.js |
License key hardcoded newrelic.js:16 ⚠️ |
⚰️ present, not activated |
| Elastic APM | APM | Distributed tracing | index.js lines 1-13 (commented) |
APM server 13.234.209.100:8200 |
⚰️ disabled |
| Kafka (Amazon MSK) | Message bus | Order + WhatsApp event ingestion (serverless tier) | prism-services/src/services/kafka.js, serverless YMLs |
Broker URLs hardcoded in YML ⚠️; cluster flash |
✅ ⚠️ |
2. WhatsApp: two BSP paths¶
Prism sends WhatsApp two ways depending on the business's whatsapp_configuration_type:
- Gupshup (
whatsapp_configuration_type: "gupshup") — the incumbent BSP. Onboarding, template approval, opt-in and catalogue all flow throughgupshupOnboardingController.js(uses Axios +FormDatafor media/template uploads). Sends happen inprocessLibrary/whatsappMsgProcess.js. - Meta TSP / Facebook Graph (
"facebook") — the direct Meta path being rolled out (metaTSP.js, roadmap B3.13). Manages WABA profiles, access tokens and templates directly with Meta.
Send path: whatsapp_queue_YYYYMMDD collections are drained by two crons — sendWhatsappMessageCron.js (marketing, ~3s) and sendWhatsappTransactionalCron.js (transactional, ~1s) — which hand off to whatsappMsgProcess.js, which branches on config type.
Gotchas ⚠️
- No rate limiting on the send crons → Gupshup/Meta throttle-ban risk (map-04 §5.10).
- Delivery receipts are incomplete. Messages sit at process_status=3 ("pending webhook") but no monolith cron processes receipts; the serverless consumer-receipts Lambda is stubbed (log-only) (map-05 §3). This is the root of the WhatsApp volume-report mismatch (bug E1.3).
- Credentials are per business in business_configs, not centralized — an onboarding failure silently disables that tenant's WhatsApp.
3. Firebase / FCM (push)¶
Two libraries coexist: fcm-node/fcm-push (legacy) and firebase-admin (current).
- Send:
processNotiQueue.jsconsumes grouped push records frompushQueueCron.jsand sends viafirebase-admin(Androidpriority=high, iOScontentAvailable=true). - Cert loading:
sendFcmNotification.jsreadsbusiness_configs.fcm_cert_keyper parent business. - Topics:
subscribeToTopic.jssubscribes tokens (/topics/android,/topics/{parent_business_id}). - Token hygiene:
fcmInjestionController.jsingests tokens;parseFcmTokenController.js(⚰️ legacy) parsed invalid tokens via child process.
Gotcha ⚠️ — processNotiQueue.js calls admin.initializeApp({...}, appName + Date.now()) per batch group, creating a new Firebase app each time → memory-leak risk. Fix: cache one app per parent_business_id (map-04 §5.9).
4. Email (AWS SES via Nodemailer)¶
Reports (daily MIS, monthly WhatsApp/SMS, wallet, campaigns) and transactional alerts go out over Nodemailer backed by @aws-sdk/client-ses. Recipient lists are hardcoded in crm_ecosystem.config.js (MAIL_DAILY_MIS_REPORT, MAIL_PETPOOJA_HITS_REPORT, etc., lines 24-30 dev / 47-60 prod). Changing who gets a report requires an env change + PM2 restart, not a UI toggle.
5. AWS S3 (file storage)¶
Signed via aws-sdk (SigV4). Used for QR PNGs (qrCodeController.js), help-desk chat media (helpDeskController.js), campaign file uploads and generated reports. Uploads are multer-parsed multipart. No lifecycle/TTL policy documented — orphaned uploads accumulate.
6. Reviews: Google/GMB, Zomato, Swiggy¶
ratingController.js aggregates internal ratings with Google My Business reviews (google-auth-library) and aggregator reviews into ratings_reviews / rating_mis / google_reviews. Aggregator orders (Swiggy/Zomato) enter through processCommonIngestion.js via the common-ingestion route guarded by crm_offer_middleware.
7. SMS + DLT¶
Indian SMS requires DLT-registered sender IDs and template IDs. sendSms.js formats cost (base + GST), deducts from business_configs.wallet_balance, writes wallet_transactions, then dispatches. The send cron is smsQueueCron.js (batches of 8000, every ~3 min). Sender/template DLT mapping lives in campaign/business config.
8. POS partners¶
| POS | Source id | Route / cron | Auth |
|---|---|---|---|
| uEngage | 1 | injestionController.crmQueue / uengageOrderIngestion.js |
parent+child business id |
| PetPooja | 2 | injestionController.petPooja / petpoojaOrderIngestion.js |
crm_token |
| LS Central | 3 | injestionController.ls_center |
injestion_middleware ⚠️ hardcoded token |
| orderPush / UrbanPiper | 4 | commonIngestion |
crm_offer_middleware |
| Rista | 6 | injestionController.rista / ristaOrderIngestion.js |
crm_offer_middleware |
| Posist | 7 | injestionController.posist / posistCron.js / /posist/v1 |
route-scoped |
Gotcha ♻️ — POS orders arrive via two writers into crm_queue: the serverless orders-consumer Lambda and the monolith ingestion controllers/crons. No dedup → duplicate-order risk (map-05 §6). See High-Level Architecture §6.
9. APM (present but OFF ⚠️)¶
Both APM stacks are installed but inactive:
- Elastic APM — agent init commented out in index.js lines 1-13 (APM server 13.234.209.100:8200). ⚰️
- New Relic — newrelic.js present, app name crm, license key committed (newrelic.js:16), but not required/activated.
Consequence: there is no distributed tracing in production. Winston logs + the trace_id correlation are the only observability. See Debugging.
10. Kafka / Amazon MSK¶
The serverless tier (prism-services) uses MSK cluster flash (shared with the monolith's ElastiCache VPC). Topics: prism-ingest-orders, whatsapp-messages, whatsapp-receipts. Producer config in src/services/kafka.js; broker URLs are hardcoded in the serverless YMLs ⚠️. No DLQ, no retry config — a failing consumer just crashes the Lambda and the batch is retried at Kafka defaults (map-05 §8). See High-Level Architecture §4.
11. Credential inventory (do NOT reproduce values — refer by file:line)¶
| Secret | Location | Note |
|---|---|---|
| MongoDB Atlas URI (with password) | prism-services/serverless-orders.yml:51, serverless-whatsapp.yml:67,89 |
⚠️ plaintext in VCS |
| Kafka broker URLs | serverless YMLs | ⚠️ hardcoded |
| New Relic license | newrelic.js:16 |
⚠️ committed |
| JWT secrets | middlewares/jwtMiddleware.js:5, jwtWhatsappMiddleware.js:5 |
⚠️ hardcoded |
| Ingestion token | middlewares/injestion_middleware.js:8 |
⚠️ hardcoded |
| 3rd-party API key | middlewares/thirdPartyMiddleware.js:6 |
⚠️ hardcoded |
| Redis host | utilities/redis.js |
⚠️ hardcoded ElastiCache URL |
| SES recipients | crm_ecosystem.config.js MAIL_* |
plaintext config |
| Gupshup/Meta/FCM per-business creds | MongoDB business_configs |
not in VCS ✅ |
Full remediation plan: Technical Debt · Security.