115 lines
3.7 KiB
JavaScript
115 lines
3.7 KiB
JavaScript
const admin = require("firebase-admin");
|
|
const { onDocumentWritten } = require("firebase-functions/firestore");
|
|
const _ = require("lodash");
|
|
const { refList, db } = require("../index");
|
|
const { getSunoTimestamps } = require("./lyrics");
|
|
const { deleteFolder } = require("../helpers/firebase");
|
|
const { buildMonthKey } = require("../helpers/stats");
|
|
|
|
exports.onProjectWritten = onDocumentWritten(
|
|
"projects/{projectId}",
|
|
async (projectSnap) => {
|
|
try {
|
|
const { projectId } = projectSnap.params;
|
|
const beforeData = projectSnap?.data?.before?.data() || null;
|
|
const afterData = projectSnap?.data?.after?.data() || null;
|
|
|
|
if (!afterData) {
|
|
const { userId } = beforeData || {};
|
|
|
|
if (userId) {
|
|
await deleteFolder(`users/${userId}/projects/${projectId}/`);
|
|
}
|
|
|
|
const snapshot = await refList.tasks
|
|
.where("projectId", "==", projectId)
|
|
.get();
|
|
if (!snapshot.empty) {
|
|
const batch = db.batch();
|
|
snapshot.forEach((doc) => {
|
|
batch.delete(doc.ref);
|
|
});
|
|
await batch.commit();
|
|
}
|
|
|
|
return null;
|
|
} else if (!beforeData) {
|
|
//song create
|
|
} else {
|
|
if (!beforeData?.songUrl && afterData?.songUrl) {
|
|
await getSunoTimestamps(projectId);
|
|
await refList.projects.doc(projectId).update({ hasSong: true });
|
|
}
|
|
|
|
if (!beforeData?.playbackUrl && afterData?.playbackUrl) {
|
|
await refList.projects.doc(projectId).update({ hasPlayback: true });
|
|
}
|
|
}
|
|
|
|
const beforeViews = _.toFinite(_.get(beforeData, "views", 0));
|
|
const afterViews = _.toFinite(_.get(afterData, "views", 0));
|
|
const delta = afterViews - beforeViews;
|
|
|
|
if (delta > 0) {
|
|
const userIdRaw = _.get(afterData, "userId", null);
|
|
const userId =
|
|
_.isString(userIdRaw) && _.trim(userIdRaw).length
|
|
? _.trim(userIdRaw)
|
|
: null;
|
|
const now = admin.firestore.Timestamp.now();
|
|
const monthKey = buildMonthKey(now);
|
|
|
|
const statsDocRef = refList.projectStreamStats
|
|
.doc(projectId)
|
|
.collection("monthlyListens")
|
|
.doc(monthKey);
|
|
const totalsDocRef =
|
|
refList.projectStreamStatsMonthlyTotals.doc(monthKey);
|
|
|
|
await db.runTransaction(async (transaction) => {
|
|
const statsSnapshot = await transaction.get(statsDocRef);
|
|
const totalsSnapshot = await transaction.get(totalsDocRef);
|
|
const updatePayload = {
|
|
projectId,
|
|
userId,
|
|
monthKey,
|
|
updatedAt: now,
|
|
lastStreamAt: now,
|
|
lastDelta: delta,
|
|
streams: admin.firestore.FieldValue.increment(delta),
|
|
};
|
|
|
|
const hasFirstStream =
|
|
statsSnapshot.exists && statsSnapshot.data()?.firstStreamAt;
|
|
if (!hasFirstStream) {
|
|
updatePayload.firstStreamAt = now;
|
|
}
|
|
|
|
transaction.set(statsDocRef, updatePayload, { merge: true });
|
|
|
|
const totalsUpdatePayload = {
|
|
monthKey,
|
|
updatedAt: now,
|
|
lastStreamAt: now,
|
|
lastDelta: delta,
|
|
totalStreams: admin.firestore.FieldValue.increment(delta),
|
|
};
|
|
const totalsHasFirstStream =
|
|
totalsSnapshot.exists && totalsSnapshot.data()?.firstStreamAt;
|
|
if (!totalsHasFirstStream) {
|
|
totalsUpdatePayload.firstStreamAt = now;
|
|
}
|
|
transaction.set(totalsDocRef, totalsUpdatePayload, { merge: true });
|
|
});
|
|
}
|
|
|
|
return null;
|
|
} catch (error) {
|
|
console.log("onProjectViewsIncrement error", {
|
|
message: error?.message || String(error || ""),
|
|
});
|
|
return null;
|
|
}
|
|
},
|
|
);
|