From da8ce3209a87413d70085e7d02153b72d066f326 Mon Sep 17 00:00:00 2001 From: rohit Date: Thu, 24 Jul 2025 10:43:38 +0530 Subject: [PATCH] schedulaer complete --- src/schedulers/callScheduler.js | 85 +++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 src/schedulers/callScheduler.js diff --git a/src/schedulers/callScheduler.js b/src/schedulers/callScheduler.js new file mode 100644 index 0000000..1ae9714 --- /dev/null +++ b/src/schedulers/callScheduler.js @@ -0,0 +1,85 @@ +const cron = require('node-cron'); +const moment = require('moment-timezone'); +const axios = require('axios'); +const { User } = require('../models'); + +const ongoingCalls = new Map(); // patientId -> { retryCount, lastAttemptTime } + +// Utility to call Retell API +async function initiateCall(patient) { + const agentId = patient.genderVoiceCall === 'male' + ? process.env.RETELL_MALE_AGENT_ID + : process.env.RETELL_FEMALE_AGENT_ID; + + const config = { + method: 'post', + url: 'https://api.retellai.com/v2/create-phone-call', + headers: { + 'Authorization': `Bearer ${process.env.RETELL_API_KEY}`, + 'Content-Type': 'application/json' + }, + data: JSON.stringify({ + from_number: process.env.RETELL_FROM_NUMBER, + to_number: patient.phoneNumber, + override_agent_id: agentId + }) + }; + + try { + const response = await axios(config); + console.log(`✅ Call initiated to ${patient.firstName}:`, response.data); + return true; // Call initiated successfully + } catch (err) { + console.error(`❌ Call failed for ${patient.firstName}:`, err.response?.data || err.message); + return false; + } +} + +// Cron job: runs every 1 minute +cron.schedule('* * * * *', async () => { + const nowUtc = moment.utc(); + + const patients = await User.findAll({ where: { role: 'patient' } }); + + for (const patient of patients) { + if (!patient.callTime || !patient.callFrequency || !patient.timeZone) continue; + + const userNow = nowUtc.clone().tz(patient.timeZone); + const currentDay = userNow.format('dddd').toLowerCase(); + + if (!patient.callFrequency.includes(currentDay)) continue; + + const [startStr, endStr] = patient.callTime.split('-'); + const startTime = moment.tz(startStr, 'HH:mm', patient.timeZone); + const endTime = moment.tz(endStr, 'HH:mm', patient.timeZone); + + if (!userNow.isBetween(startTime, endTime)) continue; + + const callKey = patient.id.toString(); + const retryInfo = ongoingCalls.get(callKey) || { retryCount: 0, lastAttemptTime: null }; + + const retryIntervalMs = { + '5m': 5 * 60 * 1000, + '10m': 10 * 60 * 1000, + '15m': 15 * 60 * 1000, + }[patient.retryInterval] || 5 * 60 * 1000; + + const canRetry = + !retryInfo.lastAttemptTime || + (Date.now() - retryInfo.lastAttemptTime > retryIntervalMs); + + if (retryInfo.retryCount < patient.maxRetry && canRetry) { + const callSuccess = await initiateCall(patient); + ongoingCalls.set(callKey, { + retryCount: callSuccess ? patient.maxRetry : retryInfo.retryCount + 1, + lastAttemptTime: Date.now() + }); + } + + // Cleanup if maxRetry reached or call was successful + if (ongoingCalls.get(callKey)?.retryCount >= patient.maxRetry) { + console.log(`📴 Call attempts completed for ${patient.firstName}`); + ongoingCalls.delete(callKey); + } + } +}); \ No newline at end of file