const admin = require("firebase-admin"); const timeDiff = (ds1, ds2) => { const d1 = new Date(ds1); const d2 = new Date(ds2); var diff = (d2.getTime() - d1.getTime()) / 1000; diff /= 60 * 60; return Math.abs(Math.round(diff)); }; const roomIdList = async (refs) => { const startedTime = new Date(); return await admin .firestore() .getAll(...refs) .then((roomDataList) => roomDataList.map((roomData) => { if ( !roomData.exists || (timeDiff(roomData.createTime.toDate(), startedTime) >= 24 && timeDiff(roomData.updateTime.toDate(), startedTime) >= 4) || timeDiff(roomData.updateTime.toDate(), startedTime) >= 12 ) { return roomData.id; } }) ) .then((ids) => ids.filter((v) => v !== undefined)); }; const batchDeleteRooms = async (roomList, totalNumber, batch, count = 0) => { if (roomList.length > 0 && count < 500) { const roomId = roomList.splice(0, 1)[0]; await admin .firestore() .collection(`rooms/${roomId}/messages`) .listDocuments() .then((docs) => { docs.map((doc) => { if (count < 500) { batch.delete(doc); count++; } }); return; }); await admin .firestore() .collection(`rooms/${roomId}/users`) .listDocuments() .then((docs) => { docs.map((doc) => { if (count < 500) { batch.delete(doc); count++; } }); return; }); if (count < 500) { await batch.delete(admin.firestore().collection("rooms").doc(roomId)); count++; } await batchDeleteRooms(roomList, totalNumber, batch, count); return; } else { console.info( `[DONE]\tWEBHOOKS/Room Clean Up\tDeleted all ${totalNumber} rooms` ); return; } }; module.exports = async (req, res) => { const roomList = await admin .firestore() .collection("rooms") .listDocuments() .then((rL) => rL) .catch((err) => { console.error( `Failed to run auto clean up (get room list) @ ${new Date().toLocaleTimeString()}`, err ); }); if (roomList.length > 0) { var ids = await roomIdList(roomList); if (ids.length > 0) { const totalNumber = ids.length; console.info( `[PROGRESS]\tWEBHOOKS/Room Clean Up\tROOMS ${JSON.stringify(ids)}` ); try { const batch = admin.firestore().batch(); await batchDeleteRooms(ids, totalNumber, batch); await batch.commit(); res.status(200).send({ message: `[${new Date().toLocaleString("en-US", { timeZone: "America/New_York", })}] [DONE] WEBHOOKS Room Clean Up ${totalNumber} rooms deleted`, }); } catch (err) { res.status(400).send({ message: `[${new Date().toLocaleString("en-US", { timeZone: "America/New_York", })}] [ERROR] WEBHOOKS Room Clean Up Batch delete failed - ${JSON.stringify( err )}`, }); } } else { console.info(`[DONE]\tWEBHOOKS/Room Clean Up\tNo rooms to delete`); res.status(200).send({ message: `[${new Date().toLocaleString("en-US", { timeZone: "America/New_York", })}] [DONE] WEBHOOKS Room Clean Up No rooms to delete`, }); } } return; };