|
|
@ -2688,6 +2688,111 @@ const sendNotification = async (customerId, fcmIds, title, body) => {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const sendDailyConsumptionNotification = async () => {
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
|
|
const now = new Date();
|
|
|
|
|
|
|
|
const currentTime = moment(now).format("HH:mm"); // e.g., "09:30"
|
|
|
|
|
|
|
|
const currentDate = moment(now).format("DD-MMM-YYYY"); // e.g., "28-Feb-2025"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
console.log(`🕒 Checking users for scheduled notifications at ${currentTime}`);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Fetch users who have set notifications for the current time
|
|
|
|
|
|
|
|
const users = await User.find({
|
|
|
|
|
|
|
|
allowNotifications: true,
|
|
|
|
|
|
|
|
notificationTime: currentTime,
|
|
|
|
|
|
|
|
}).select("customerId fcmIds lastNotificationSent");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (users.length === 0) {
|
|
|
|
|
|
|
|
console.log("⏳ No users have notifications scheduled for this time.");
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (const user of users) {
|
|
|
|
|
|
|
|
const { customerId, fcmIds } = user;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Ensure user has valid FCM tokens
|
|
|
|
|
|
|
|
if (!Array.isArray(fcmIds) || fcmIds.length === 0) {
|
|
|
|
|
|
|
|
console.log(`⚠️ No valid FCM tokens found for customer ID: ${customerId}`);
|
|
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Fetch last 24-hour consumption data
|
|
|
|
|
|
|
|
const startTime = moment(now).subtract(1, "days").format("DD-MMM-YYYY - HH:mm");
|
|
|
|
|
|
|
|
const endTime = moment(now).format("DD-MMM-YYYY - HH:mm");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
console.log(`📅 Fetching consumption for ${customerId} from ${startTime} to ${endTime}`);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const consumptions = await TankConsumptionOriginalSchema.find({
|
|
|
|
|
|
|
|
customerId,
|
|
|
|
|
|
|
|
time: { $gte: startTime, $lt: endTime },
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (consumptions.length === 0) {
|
|
|
|
|
|
|
|
console.log(`❌ No consumption data found for ${customerId}`);
|
|
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Calculate consumption per water type
|
|
|
|
|
|
|
|
let totalConsumption = 0;
|
|
|
|
|
|
|
|
let consumptionByType = {};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (const record of consumptions) {
|
|
|
|
|
|
|
|
const { typeofwater, consumption } = record;
|
|
|
|
|
|
|
|
const consumptionValue = parseInt(consumption, 10) || 0;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!consumptionByType[typeofwater]) {
|
|
|
|
|
|
|
|
consumptionByType[typeofwater] = 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
consumptionByType[typeofwater] += consumptionValue;
|
|
|
|
|
|
|
|
totalConsumption += consumptionValue;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Prepare notification message
|
|
|
|
|
|
|
|
let notificationBody = `🚰 Water Consumption Report for ${currentDate}:\n`;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (const type in consumptionByType) {
|
|
|
|
|
|
|
|
const percentage = totalConsumption ? ((consumptionByType[type] / totalConsumption) * 100).toFixed(2) : 0;
|
|
|
|
|
|
|
|
notificationBody += `\n💧 Type: ${type}\n` +
|
|
|
|
|
|
|
|
`Total Consumption: ${consumptionByType[type]} liters (${percentage}%)\n`;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
console.log(`📩 Preparing notification for ${customerId}:`, notificationBody);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Send notification to FCM tokens
|
|
|
|
|
|
|
|
const notificationPromises = fcmIds.map(async (token) => {
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
|
|
const response = await admin.messaging().send({
|
|
|
|
|
|
|
|
notification: { title: "Daily Water Consumption Report", body: notificationBody },
|
|
|
|
|
|
|
|
token,
|
|
|
|
|
|
|
|
data: { target: "/tank_levels" },
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
console.log(`✅ Notification sent to token: ${token}`);
|
|
|
|
|
|
|
|
console.log("FCM Response:", response);
|
|
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
|
|
console.error(`❌ Failed to send notification to token: ${token}`, error);
|
|
|
|
|
|
|
|
if (error.code === "messaging/registration-token-not-registered") {
|
|
|
|
|
|
|
|
await User.updateOne({ customerId }, { $pull: { fcmIds: token } });
|
|
|
|
|
|
|
|
console.log(`🚫 Removed invalid token: ${token}`);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
await Promise.all(notificationPromises);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
|
|
console.error("❌ Error sending daily consumption notifications:", error);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Schedule the function to run every minute to check for user notification times
|
|
|
|
|
|
|
|
cron.schedule("* * * * *", async () => {
|
|
|
|
|
|
|
|
console.log("🔄 Running daily consumption notification check...");
|
|
|
|
|
|
|
|
await sendDailyConsumptionNotification();
|
|
|
|
|
|
|
|
}, {
|
|
|
|
|
|
|
|
timezone: "Asia/Kolkata",
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -6816,16 +6921,16 @@ const calculateDailyConsumptionAndNotify = async () => {
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// Schedule the cron job to run daily at 9 AM
|
|
|
|
// Schedule the cron job to run daily at 9 AM
|
|
|
|
cron.schedule(
|
|
|
|
// cron.schedule(
|
|
|
|
"0 9 * * *",
|
|
|
|
// "0 9 * * *",
|
|
|
|
async () => {
|
|
|
|
// async () => {
|
|
|
|
console.log("Starting daily consumption notification task...");
|
|
|
|
// console.log("Starting daily consumption notification task...");
|
|
|
|
await calculateDailyConsumptionAndNotify();
|
|
|
|
// await calculateDailyConsumptionAndNotify();
|
|
|
|
},
|
|
|
|
// },
|
|
|
|
{
|
|
|
|
// {
|
|
|
|
timezone: "Asia/Kolkata", // Specify the timezone
|
|
|
|
// timezone: "Asia/Kolkata", // Specify the timezone
|
|
|
|
}
|
|
|
|
// }
|
|
|
|
);
|
|
|
|
// );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const calculateConsumptionAndNotify = async () => {
|
|
|
|
const calculateConsumptionAndNotify = async () => {
|
|
|
@ -7262,12 +7367,12 @@ const calculateWaterLevelAndNotify = async () => {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Run the function every minute to check if any user needs a notification
|
|
|
|
// Run the function every minute to check if any user needs a notification
|
|
|
|
cron.schedule('* * * * *', async () => {
|
|
|
|
// cron.schedule('* * * * *', async () => {
|
|
|
|
console.log("Checking for user notification times...");
|
|
|
|
// console.log("Checking for user notification times...");
|
|
|
|
await calculateWaterLevelAndNotify();
|
|
|
|
// await calculateWaterLevelAndNotify();
|
|
|
|
}, {
|
|
|
|
// }, {
|
|
|
|
timezone: "Asia/Kolkata",
|
|
|
|
// timezone: "Asia/Kolkata",
|
|
|
|
});
|
|
|
|
// });
|
|
|
|
|
|
|
|
|
|
|
|
//run the every one hour
|
|
|
|
//run the every one hour
|
|
|
|
// cron.schedule('0 */3 * * *', async () => {
|
|
|
|
// cron.schedule('0 */3 * * *', async () => {
|
|
|
|