Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
102 changes: 68 additions & 34 deletions functions/upcomingRoom-Message-Notification/src/main.js
Original file line number Diff line number Diff line change
@@ -1,61 +1,95 @@
const sdk = require("node-appwrite");

const admin = require('firebase-admin');
const { getMessaging } = require('firebase-admin/messaging');
const serviceAccount = require("./resonate-service-account.json");

const app = admin.initializeApp({
credential: admin.credential.cert(serviceAccount)
});

module.exports = async function ({ req, res, log, error }) {
var subscribersTokens = [];
const subscribersTokens = [];
const client = new sdk.Client();
const database = new sdk.Databases(client);
const query = sdk.Query;
const { roomId, payload } = JSON.parse(req.body);

client.setEndpoint(
process.env.APPWRITE_ENDPOINT ?? 'https://cloud.appwrite.io/v1'
)
.setProject(process.env.APPWRITE_FUNCTION_PROJECT_ID)
.setKey(process.env.APPWRITE_API_KEY);
log(process.env.APPWRITE_FUNCTION_PROJECT_ID);

log("Send Notification");
log(roomId);
log(payload);
let subscriberList = await database.listDocuments(process.env.UpcomingRoomsDataBaseID, process.env.SubscriberCollectionID, [query.equal('upcomingRoomId', [roomId])]);
log("here as well")
subscriberList.documents.forEach(subscriber => {
for (const token of subscriber["registrationTokens"]) {
subscribersTokens.push(token);

try {
const body = typeof req.body === 'string' ? JSON.parse(req.body) : req.body;
const { roomId, payload } = body;

if (!roomId || !payload) {
return res.json({
message: 'Missing required fields',
error: 'roomId and payload are required'
}, 400);
}
});
let document = await database.getDocument(process.env.UpcomingRoomsDataBaseID, process.env.UpcomingRoomsCollectionID, roomId);
for (const creator_token of document["creator_fcm_tokens"]) {
subscribersTokens.push(creator_token);
}
log(subscribersTokens);
const message = {
notification: payload,
tokens: subscribersTokens,
priority: "high",
android: {
priority: "high"

log(`Sending notification for room: ${roomId}`);

const subscriberList = await database.listDocuments(
process.env.UpcomingRoomsDataBaseID,
process.env.SubscriberCollectionID,
[query.equal('upcomingRoomId', [roomId])]
);

subscriberList.documents.forEach(subscriber => {
if (subscriber["registrationTokens"] && Array.isArray(subscriber["registrationTokens"])) {
subscribersTokens.push(...subscriber["registrationTokens"]);
}
});

const roomDocument = await database.getDocument(
process.env.UpcomingRoomsDataBaseID,
process.env.UpcomingRoomsCollectionID,
roomId
);

if (roomDocument["creator_fcm_tokens"] && Array.isArray(roomDocument["creator_fcm_tokens"])) {
subscribersTokens.push(...roomDocument["creator_fcm_tokens"]);
}
};
getMessaging(app).sendEachForMulticast(message)
.then((response) => {

// Deduplicate tokens
const uniqueTokens = [...new Set(subscribersTokens)];

if (uniqueTokens.length > 0) {
const message = {
notification: payload,
tokens: uniqueTokens,
android: {
priority: "high"
},
apns: {
headers: {
"apns-priority": "10"
}
}
};

const response = await getMessaging(app).sendEachForMulticast(message);
if (response.failureCount > 0) {
log('Failed');
log(`Failed to send ${response.failureCount} notifications`);
} else {
log('Notifications were sent successfully');
}
} else {
log('No tokens found to send notifications.');
}

return res.json({
message: 'Notification process completed'
});

return res.json({
message: 'Notification sent'
});
} catch (err) {
error(`Error in upcomingRoom-Message-Notification: ${err.message}`);
return res.json({
message: 'Error occurred',
error: err.message
}, 500);
}
}


131 changes: 62 additions & 69 deletions functions/upcomingRoom-isTime-checker/src/main.js
Original file line number Diff line number Diff line change
@@ -1,88 +1,81 @@
const sdk = require("node-appwrite");
// const admin = require('firebase-admin');

const admin = require('firebase-admin');
// const { getMessaging } = require('firebase-admin/messaging');
// const serviceAccount = require("./resonate-service-account.json");
// const app = admin.initializeApp({
// credential: admin.credential.cert(serviceAccount)
// });

module.exports = async function ({ req, res, log }) {
var subscribersTokens = [];
module.exports = async function ({ req, res, log, error }) {
const client = new sdk.Client();
const database = new sdk.Databases(client);
const query = sdk.Query;
log("here");

client.setEndpoint(
process.env.APPWRITE_ENDPOINT ?? 'https://cloud.appwrite.io/v1'
)
.setProject(process.env.APPWRITE_FUNCTION_PROJECT_ID)
.setKey(process.env.APPWRITE_API_KEY);
log(process.env.APPWRITE_FUNCTION_PROJECT_ID);
log("here also");
let upcomingRoomsList = await database.listDocuments(process.env.UpcomingRoomsDataBaseID, process.env.UpcomingRoomsCollectionID);
log("here as well");
for (const document of upcomingRoomsList.documents) {
log("now here");
var scheduledDateTime = document["scheduledDateTime"];
log(scheduledDateTime);
var splittedDateTime = scheduledDateTime.split('T');
var extractedDate = splittedDateTime[0];
var extractedTime = splittedDateTime[1];
var SplittingDate = extractedDate.split("-");
const year = Number(SplittingDate[0]);
const month = Number(SplittingDate[1]);
const day = Number(SplittingDate[2]);
var SplittingTime = extractedTime.split(":");
const hour = Number(SplittingTime[0]);
const minutes = Number(SplittingTime[1]);
const upcomingRoomDate = Date.UTC(year, month - 1, day, hour, minutes);
log(upcomingRoomDate);
const now = new Date();
const nowTime = now.getTime();
log(nowTime);

var timeLeft = upcomingRoomDate - nowTime;
var timeLeftInMinutes = timeLeft / (1000 * 60);
log(timeLeftInMinutes);
if (timeLeftInMinutes <= 5 && timeLeftInMinutes >= -5 && document["isTime"] == false) {
await database.updateDocument(process.env.UpcomingRoomsDataBaseID, process.env.UpcomingRoomsCollectionID, document.$id, {
"isTime": true
})
// log("Send Notification");
// let subscriberList = await database.listDocuments(process.env.UpcomingRoomsDataBaseID, process.env.SubscriberCollectionID, [query.equal('upcomingRoomId', [document.$id])]);
// log("here as well")
// subscriberList.documents.forEach(subscriber => {
// for (const token of subscriber["registrationTokens"]) {
// subscribersTokens.push(token);
// }
// });
// for (const creator_token of document["creator_fcm_tokens"]) {
// subscribersTokens.push(creator_token);
// }
// log(subscribersTokens);
// const message = {
// notification: {
// title: 'Room Reminder',
// body: `The room ${document["name"]} will Start Soon`
// },
// tokens: subscribersTokens,
// priority: "high",
// android: {
// priority: "high"
// }
// };
// getMessaging(app).sendEachForMulticast(message)
// .then((response) => {
// if (response.failureCount > 0) {
// log('Failed');
// } else {
// log('Notifications were sent successfully');
// }
// });
try {
const upcomingRoomsList = await database.listDocuments(
process.env.UpcomingRoomsDataBaseID,
process.env.UpcomingRoomsCollectionID
);

for (const document of upcomingRoomsList.documents) {
const scheduledDateTime = document["scheduledDateTime"];

if (!scheduledDateTime) {
log(`Skipping document ${document.$id}: missing scheduledDateTime`);
continue;
}

// Use standard Date parsing (handles ISO 8601 correctly)
const upcomingRoomDate = new Date(scheduledDateTime).getTime();

if (isNaN(upcomingRoomDate)) {
log(`Skipping document ${document.$id}: invalid date format "${scheduledDateTime}"`);
continue;
}

const nowTime = new Date().getTime();

const timeLeft = upcomingRoomDate - nowTime;
const timeLeftInMinutes = timeLeft / (1000 * 60);

// Check if time is within +/- 5 minutes and not yet marked
if (timeLeftInMinutes <= 5 && timeLeftInMinutes >= -5 && document["isTime"] === false) {
await database.updateDocument(
process.env.UpcomingRoomsDataBaseID,
process.env.UpcomingRoomsCollectionID,
document.$id,
{
"isTime": true
}
);

// Log explicitly when an action is taken
log(`Activated room: ${document.$id}`);

/*
// Notification logic (legacy)
var subscribersTokens = [];
// ... (rest of the commented notification logic kept if needed for reference,
// essentially user logic seems to be to keep it commented for now as they didn't ask to implement it)
*/
}
}

return res.json({
message: 'Time check completed successfully'
});

} catch (err) {
error(`Error in upcomingRoom-isTime-checker: ${err.message}`);
return res.json({
message: 'Error occurred during time check',
error: err.message
}, 500);
}
return res.json({
message: 'set verified'
});
};