start and stop with particular Customer send notification

master^2
Bhaskar 9 months ago
parent 65e805f2a1
commit e1f74c0914

@ -1727,10 +1727,13 @@ admin.initializeApp({
// Event listener for motorStart
eventEmitter.on(
'motorStart',
async (fcmTokens, tankName, blockName, startTime, motorOnType, manual_threshold_time, typeOfWater) => {
async (customerId, fcmTokens, tankName, blockName, startTime, motorOnType, manual_threshold_time, typeOfWater) => {
try {
// Log the FCM tokens to check their format
console.log("FCM Tokens:", fcmTokens);
// Retrieve the user information
const users = await User.find({ fcmIds: { $in: fcmTokens } });
const users = await User.find({ customerId: customerId, fcmIds: { $in: fcmTokens } });
console.log("users", users);
const userNames = users.map(user => user.username).join(', ');
console.log("userNames", userNames);
@ -1756,20 +1759,93 @@ eventEmitter.on(
`Will stop after: '${manual_threshold_time}' mins`;
// Send the notification
await sendNotification(fcmTokens, 'Arminta Water Management', message);
await sendNotification(customerId, fcmTokens, 'Arminta Water Management', message);
} catch (error) {
console.error('Error in motorStart event:', error);
}
}
);
// eventEmitter.on(
// "motorStart",
// async (customerId, fcmTokens, tankName, blockName, startTime, motorOnType, manual_threshold_time, typeOfWater) => {
// try {
// // Flatten and clean up FCM tokens
// const flatFcmTokens = fcmTokens.flat();
// const validFcmTokens = flatFcmTokens.filter(token => typeof token === 'string' && token.trim() !== '');
// // Retrieve users with matching `customerId` and valid `fcmIds`
// const users = await User.find({
// customerId: customerId,
// fcmIds: { $in: validFcmTokens } // Ensure fcmId exists in the database
// });
// console.log("Users Found:", users);
// // Check if we found any users
// if (!users.length) {
// console.log("No users found for motorStart event.");
// return;
// }
// // Extract usernames and their valid FCM tokens
// const matchedTokens = users.flatMap(user => user.fcmIds.filter(token => validFcmTokens.includes(token)));
// console.log("Matched FCM Tokens:", matchedTokens);
// // Check if there are valid tokens to send notifications
// if (matchedTokens.length === 0) {
// console.log("No valid FCM tokens found for sending notifications.");
// return;
// }
// const startMethod = motorOnType === "Mobile APP" ? "Mobile APP" : "Manual";
// const motorName = `${tankName}-${blockName}-${typeOfWater}`;
// // Prepare the message
// // const message = `Motor ${motorOnType} started in tank ${tankName} at ${startTime}.`;
// const message =
// `🚰 Motor Name: ${motorName}\n` +
// `🚰 Tank Name: '${tankName}'\n` +
// `🏢 Block Name: '${blockName}'\n` +
// `👤 Started by: ${userNames}\n` +
// `📱 Mode: '${startMethod}'\n` +
// `🕒 Pump started at: ${startTime} \n` +
// `Will stop after: '${manual_threshold_time}' mins`;
// // Send notification to the matched users
// await sendNotification(customerId, matchedTokens, "Motor Start Notification", message);
// } catch (error) {
// console.error("Error in motorStart event:", error);
// }
// }
// );
// Event listener for motorStop
// Event listener for motorStop
eventEmitter.on(
'motorStop',
async (fcmTokens, tankName, blockName, stopTime, motorOnType, totalWaterPumped, typeOfWater) => {
async (customerId, fcmTokens, tankName, blockName, stopTime, motorOnType, totalWaterPumped, typeOfWater) => {
try {
// Retrieve the user information
const users = await User.find({ fcmIds: { $in: fcmTokens } });
// Log the FCM tokens to check their format
console.log("FCM Tokens:", fcmTokens);
// Retrieve the user information based on customerId
const users = await User.find({ customerId: customerId, fcmIds: { $in: fcmTokens } });
console.log("users", users);
// If no users are found, log a message and return
if (users.length === 0) {
console.log(`No users found for customerId: ${customerId}`);
return;
}
const userNames = users.map(user => user.username).join(', ');
const stopMethod = motorOnType === "Mobile APP" ? "Mobile APP" : "Manual";
@ -1790,16 +1866,17 @@ eventEmitter.on(
`👤 Stopped by: ${userNames}\n` +
`📱 Mode: '${stopMethod}'\n` +
`🕒 Pump stopped at: ${stopTime}\n` +
`💧 Total water pumped: ${totalWaterPumped} liters\n`; // Ensure this line is properly terminated
`💧 Total water pumped: ${totalWaterPumped} liters\n`;
// Send the notification
await sendNotification(fcmTokens, 'Arminta Water Management', message);
await sendNotification(customerId, fcmTokens, 'Arminta Water Management', message);
} catch (error) {
console.error('Error in motorStop event:', error);
}
}
);
eventEmitter.on(
'motorStartAutomatic',
async (fcmTokens, tankName, blockName, startTime, motorOnType, manual_threshold_time, typeOfWater,threshold) => {
@ -2227,45 +2304,153 @@ const emitWithTimestamp = (eventName, fcmTokens, motorId, waterLevel) => {
// }
// };
const sendNotification = async (fcmIds, title, body) => {
// const sendNotification = async (fcmIds, title, body) => {
// try {
// if (!fcmIds || fcmIds.length === 0) {
// throw new Error('No FCM tokens provided.');
// }
// const flatTokens = fcmIds.flat();
// if (flatTokens.length === 0) {
// throw new Error('Flattened FCM token list is empty.');
// }
// // Iterate over each token and send individually
// const promises = flatTokens.map(async (token) => {
// try {
// const response = await admin.messaging().send({
// notification: { title, body },
// token,
// data: {
// 'target': 'tank_levels',
// },
// });
// console.log(`Notification sent successfully to token: ${token}`, response);
// } catch (error) {
// console.error(`Failed to send notification to token: ${token}`, error);
// // Check for specific error indicating an invalid token
// if (error.code === 'messaging/registration-token-not-registered') {
// // Remove the invalid token from the database
// await User.updateOne(
// { fcmIds: token }, // Ensure you're targeting the right user with the invalid token
// { $pull: { fcmIds: token } } // Remove the invalid token
// );
// console.log(`Removed invalid token: ${token}`);
// }
// }
// });
// await Promise.all(promises);
// } catch (error) {
// console.error('Error sending notifications:', error);
// }
// };
const sendNotification = async (customerId, fcmIds, title, body) => {
try {
if (!fcmIds || fcmIds.length === 0) {
throw new Error('No FCM tokens provided.');
if (!customerId) {
throw new Error("Customer ID is required.");
}
const flatTokens = fcmIds.flat();
if (!Array.isArray(fcmIds) || fcmIds.length === 0) {
throw new Error("No FCM tokens provided or invalid format.");
}
// Safely flatten the tokens
const flatTokens = fcmIds.flat ? fcmIds.flat() : fcmIds; // Use flat() if available
if (flatTokens.length === 0) {
throw new Error('Flattened FCM token list is empty.');
throw new Error("Flattened FCM token list is empty.");
}
// Fetch user notification settings
const users = await User.find({ customerId }).select("fcmIds notificationPreference lastNotificationSent");
// Iterate over users to send notifications based on their preferences
const promises = users.map(async (user) => {
const { fcmIds: userFcmIds, notificationPreference, lastNotificationSent } = user;
// Check if userFcmIds is an array
if (!Array.isArray(userFcmIds)) {
console.log(`Invalid fcmIds for customer ID: ${customerId}`);
return;
}
// Iterate over each token and send individually
const promises = flatTokens.map(async (token) => {
// Filter tokens that belong to the user
const validTokens = flatTokens.filter(token => userFcmIds.includes(token));
if (validTokens.length === 0) {
console.log(`No matching FCM tokens for customer ID: ${customerId}`);
return;
}
// Handle notification preference
if (notificationPreference === "never") {
console.log(`Notifications disabled for customer ID: ${customerId}`);
return;
}
const now = new Date();
const lastSent = new Date(lastNotificationSent || 0);
// If preference is not "always", check the timing
if (notificationPreference !== "always") {
let minInterval = 0;
switch (notificationPreference) {
case "6_hours":
minInterval = 6 * 60 * 60 * 1000; // 6 hours
break;
case "8_hours":
minInterval = 8 * 60 * 60 * 1000; // 8 hours
break;
case "1_month":
minInterval = 30 * 24 * 60 * 60 * 1000; // 1 month
break;
}
// Skip sending if the time restriction hasn't passed
if (now - lastSent < minInterval) {
console.log(`Skipping notification for customer ID: ${customerId} due to time restriction.`);
return;
}
}
// Send notifications
const notificationPromises = validTokens.map(async (token) => {
try {
const response = await admin.messaging().send({
notification: { title, body },
token,
data: {
'target': 'tank_levels',
},
data: { target: "tank_levels" },
});
console.log(`Notification sent successfully to token: ${token}`, response);
} catch (error) {
console.error(`Failed to send notification to token: ${token}`, error);
// Check for specific error indicating an invalid token
if (error.code === 'messaging/registration-token-not-registered') {
// Remove the invalid token from the database
// Handle token errors
if (error.code === "messaging/registration-token-not-registered") {
await User.updateOne(
{ fcmIds: token }, // Ensure you're targeting the right user with the invalid token
{ $pull: { fcmIds: token } } // Remove the invalid token
{ customerId },
{ $pull: { fcmIds: token } } // Remove invalid token
);
console.log(`Removed invalid token: ${token}`);
}
}
});
await Promise.all(notificationPromises);
// Update lastNotificationSent timestamp if not "always"
if (notificationPreference !== "always") {
await User.updateOne({ customerId }, { lastNotificationSent: now });
}
});
await Promise.all(promises);
} catch (error) {
console.error('Error sending notifications:', error);
console.error("Error sending notifications:", error);
}
};
@ -2274,6 +2459,7 @@ const sendNotification = async (fcmIds, title, body) => {
// const sendPushNotification = async (registrationToken, title, body) => {
// const message = {
// notification: {
@ -2844,7 +3030,8 @@ exports.motorAction = async (req, reply) => {
if (!notificationSentStatus.motorStart) {
eventEmitter.emit(
'motorStart',
fcmToken,
customerId,
fcmToken, // Ensure this is an array of tokens
tankName,
blockName,
startTime,
@ -2853,8 +3040,9 @@ exports.motorAction = async (req, reply) => {
typeOfWater
);
notificationSentStatus.motorStart = true; // Set flag to true to prevent duplicate notifications
notificationSentStatus.motorStart = true; // Prevent duplicate notifications
}
// Start checking water level every 30 minutes
if (!waterLevelCheckInterval) {
waterLevelCheckInterval = setInterval(async () => {
@ -2880,6 +3068,7 @@ exports.motorAction = async (req, reply) => {
const totalWaterPumped = await calculateTotalPumpedWater(customerId, motorId, start_instance_id); // A function to calculate total water pumped
eventEmitter.emit(
'motorStop',
customerId,
fcmToken,
tankName,
blockName,

@ -123,6 +123,15 @@ const userSchema = new mongoose.Schema(
fcmIds: [{ type: String }], // Changed to an array of strings
deviceId: { type: String, default: null },
notificationPreference: {
type: String,
enum: ["never", "always", "6_hours", "8_hours", "1_month"],
default: "always", // Default is now "always"
},
lastNotificationSent: {
type: Date,
default: null, // Initially, no notifications sent
},
createdAt: {
type: Date,
default: function () {

Loading…
Cancel
Save