File: /home/cafsindia/ai_allyindian_com/routes/call.js
const express = require('express');
const router = express.Router();
const axios = require('axios');
const CallLog = require('../models/CallLog');
const { v4: uuidv4 } = require('uuid');
const { SarvamAIClient } = require("sarvamai");
// Prompts
const LANGUAGE_PROMPTS = {
ta: 'நீங்கள் ஒரு நிபுணர் மென்மையான நிதி ஆலோசகர். வாடிக்கையாளரின் மொழியில் பேசுங்கள், அவர்களின் சந்தா திட்ட நேரத்தை உறுதிசெய்யவும், தேவையான தகவல்களை கேட்டு, உறுதிப்படுத்தவும்.',
hi: 'आप एक विशेषज्ञ, विनम्र म्यूचुअल फंड एजेंट हैं। ग्राहक की भाषा में संवाद करें, अपॉइंटमेंट तय करें, आवश्यक जानकारी पूछें और पुष्टि करें।',
kn: 'ನೀವು ಪರಿಣಿತ, ವಿನಮ್ರ ಮ್ಯೂಚುಯಲ್ ಫಂಡ್ ಏಜೆಂಟ್ ಆಗಿದ್ದೀರಿ. ಗ್ರಾಹಕರ ಭಾಷೆಯಲ್ಲಿ ಮಾತನಾಡಿ, ಸಭೆ ನಿಗದಿ ಮಾಡಿ, ಅಗತ್ಯ ಮಾಹಿತಿಯನ್ನು ಕೇಳಿ ಮತ್ತು ದೃಢೀಕರಿಸಿ.',
en: 'You are an expert, polite mutual fund agent. Speak in the customer’s language, fix their mutual fund appointment, ask for and confirm any required details.'
};
// Mock: Initiate Call
function initiateCall(mobile, welcome_message) {
return { call_id: uuidv4(), status: 'initiated', mobile, welcome_message };
}
// POST /call_create
router.post('/call_create', async (req, res) => {
const { mobile, welcome_message } = req.body;
if (!mobile || !welcome_message)
return res.status(400).json({ error: 'mobile and welcome_message required' });
const call = initiateCall(mobile, welcome_message);
await CallLog.create({
call_id: call.call_id,
mobile,
customer_text: welcome_message,
timestamps: new Date()
});
res.json({ call_id: call.call_id, status: 'call started' });
});
// Language detection (basic)
function detectLanguage(text) {
if (/[\u0B80-\u0BFF]/.test(text)) return 'ta';
if (/[\u0900-\u097F]/.test(text)) return 'hi';
if (/[\u0C80-\u0CFF]/.test(text)) return 'kn';
return 'en';
}
const client = new SarvamAIClient({
apiSubscriptionKey: process.env.SARVAM_API_KEY
});
// Sample conversations
const MF_EXPERT_EXAMPLES = {
ta: [
{ role: "user", content: "Hi, I want to book an appointment." },
{ role: "assistant", content: "Sure sir, eppo venum ungalaikku? morning or evening?" },
{ role: "user", content: "Naalaiku morning 11 ku iruka?" },
{ role: "assistant", content: "Sariya sir, naalaiku 11 manikku fix panniduren. Ungaloda name and number sollunga." }
],
kn: [
{ role: "user", content: "Hi, I need MF appointment" },
{ role: "assistant", content: "Sure saar, yava time nimge sariyagutte?" }
],
en: [
{ role: "user", content: "Hi, I want to book an appointment for mutual fund consultation." },
{ role: "assistant", content: "Sure! What date and time work best for you?" }
]
};
// 🚀 Improved cleanAIReply function
function cleanAIReply(ai_reply) {
return ai_reply
.replace(/<think>[\s\S]*?<\/think>/gi, '')
.replace(/^<think>.*$/gim, '')
.replace(/^Wait[\s\n]*$/gim, '')
.replace(/[^\w\s.,?!\u0B80-\u0BFF\u0C80-\u0CFF\u0900-\u097F]/g, '')
.replace(/\s{2,}/g, ' ')
.trim()
.split(/\s+/).slice(0, 20).join(' ');
}
// 📝 Enhanced Appointment Booking Prompts
const APPOINTMENT_PROMPTS = {
ta: 'நீங்கள் ஒரு நிபுணர் மென்மையான நிதி ஆலோசகர். கீழ்க்கண்டவற்றை மட்டும் செய்யுங்கள்: 1. வாடிக்கையாளரின் பெயர், தேதி, நேரம் மற்றும் தொடர்பு எண்ணைக் கேளுங்கள் 2. ஒப்புக்கொள்ளப்பட்ட விவரங்களை மீண்டும் சொல்லி உறுதிப்படுத்துங்கள் 3. 20 வார்த்தைகளுக்குள் பதிலளிக்கவும். நட்புடன் பேசுங்கள்!',
hi: 'आप एक विशेषज्ञ, विनम्र म्यूचुअल फंड एजेंट हैं। केवल यह करें: 1. ग्राहक का नाम, तारीख, समय और संपर्क नंबर पूछें 2. सहमत विवरण दोहराकर पुष्टि करें 3. 20 शब्दों के भीतर उत्तर दें। मित्रतापूर्वक बात करें!',
kn: 'ನೀವು ಪರಿಣಿತ, ವಿನಮ್ರ ಮ್ಯೂಚುಯಲ್ ಫಂಡ್ ಏಜೆಂಟ್ ಆಗಿದ್ದೀರಿ. ಇದನ್ನು ಮಾತ್ರ ಮಾಡಿ: 1. ಗ್ರಾಹಕರ ಹೆಸರು, ದಿನಾಂಕ, ಸಮಯ ಮತ್ತು ಸಂಪರ್ಕ ಸಂಖ್ಯೆ ಕೇಳಿ 2. ಒಪ್ಪಿಕೊಂಡ ವಿವರಗಳನ್ನು ಪುನರಾವರ್ತಿಸಿ ಖಚಿತಪಡಿಸಿ 3. 20 ಪದಗಳೊಳಗೆ ಉತ್ತರಿಸಿ. ಸ್ನೇಹಪೂರ್ವಕವಾಗಿ ಮಾತನಾಡಿ!',
en: 'You are an expert mutual fund agent. Do ONLY this: 1. Ask for name, date, time and contact number 2. Confirm by repeating agreed details 3. Respond within 20 words. Speak friendly!'
};
// POST /call_response
router.post('/call_response', async (req, res) => {
const { call_id, customer_text } = req.body;
if (!call_id || !customer_text) {
return res.status(400).json({ error: 'call_id and customer_text required' });
}
const lang = detectLanguage(customer_text);
const isAppointmentQuery = !/(explain|what is|mutual fund)/i.test(customer_text);
try {
// 🎯 Focused prompt selection
const SYSTEM_PROMPT = isAppointmentQuery
? APPOINTMENT_PROMPTS[lang] || APPOINTMENT_PROMPTS.en
: `Briefly explain mutual funds in simple terms in ${lang} (20 words max)`;
const response = await client.chat.completions({
messages: [
{ role: "system", content: SYSTEM_PROMPT },
{ role: "user", content: customer_text }
],
temperature: 0.2
});
let ai_reply = response.choices[0]?.message?.content || '';
ai_reply = cleanAIReply(ai_reply);
// 📞 Log interaction
await CallLog.create({
call_id,
customer_text,
ai_reply,
language: lang,
timestamps: new Date()
});
res.json({ reply: ai_reply, language: lang });
} catch (error) {
console.error('AI Error:', error);
// ⏱️ Fallback responses by language
const fallbacks = {
ta: 'தயவு செய்து சிறிது நேரம் காத்திருக்கவும், மீண்டும் முயற்சிக்கிறேன்.',
hi: 'कृपया प्रतीक्षा करें, मैं कुछ समय बाद पुन: प्रयास करता हूँ।',
kn: 'ದಯವಿಟ್ಟು ಕೆಲವು ನಿಮಿಷಗಳ ಕಾಲ ನಿರೀಕ್ಷಿಸಿ, ನಾನು ಮತ್ತೆ ಪ್ರಯತ್ನಿಸುತ್ತೇನೆ.',
en: 'Please hold, retrying shortly...'
};
res.json({ reply: fallbacks[lang] || 'Please wait', language: lang });
}
});
module.exports = router;