mirror of
https://dev.azure.com/globalhealthx/EMR/_git/helix-engage-server
synced 2026-05-18 20:08:19 +00:00
feat: WhatsApp AI assistant — provider-agnostic messaging with Gupshup
Provider-agnostic WhatsApp integration for AI-driven appointment booking: - MessagingProvider interface (sendText, sendButtons, sendList, parseInbound) - GupshupProvider implementation (Gupshup WhatsApp API) - MessagingService — AI orchestration with tools (department/doctor/slot lists via interactive WhatsApp messages, appointment booking, caller resolution + context injection) - Redis conversation history (24h TTL, matches WhatsApp session window) - Webhook controller at POST /api/messaging/webhook Swappable to Ozonetel or Meta Cloud API by implementing MessagingProvider and switching MESSAGING_PROVIDER env var. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
36
src/messaging/messaging.controller.ts
Normal file
36
src/messaging/messaging.controller.ts
Normal file
@@ -0,0 +1,36 @@
|
||||
import { Controller, Post, Body, Logger } from '@nestjs/common';
|
||||
import { MessagingProvider } from './providers/messaging-provider.interface';
|
||||
import { MessagingService } from './messaging.service';
|
||||
|
||||
@Controller('api/messaging')
|
||||
export class MessagingController {
|
||||
private readonly logger = new Logger(MessagingController.name);
|
||||
|
||||
constructor(
|
||||
private readonly provider: MessagingProvider,
|
||||
private readonly messaging: MessagingService,
|
||||
) {}
|
||||
|
||||
@Post('webhook')
|
||||
async webhook(@Body() body: any) {
|
||||
this.logger.log(`[WA-WEBHOOK] Received: ${JSON.stringify(body).substring(0, 300)}`);
|
||||
|
||||
if (!this.provider.validateWebhook(body)) {
|
||||
this.logger.warn('[WA-WEBHOOK] Validation failed — ignoring');
|
||||
return { status: 'ignored', reason: 'validation failed' };
|
||||
}
|
||||
|
||||
const message = this.provider.parseInbound(body);
|
||||
if (!message) {
|
||||
this.logger.log('[WA-WEBHOOK] Non-message event — skipped');
|
||||
return { status: 'ok', type: body?.type ?? 'unknown' };
|
||||
}
|
||||
|
||||
// Handle async — don't block webhook response
|
||||
this.messaging.handleInbound(message).catch(err => {
|
||||
this.logger.error(`[WA-WEBHOOK] handleInbound failed: ${err.message}`);
|
||||
});
|
||||
|
||||
return { status: 'ok' };
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user