functions
This commit is contained in:
+90
-106
@@ -1,69 +1,12 @@
|
||||
const admin = require("firebase-admin");
|
||||
const { onDocumentWritten } = require("firebase-functions/firestore");
|
||||
const { refList } = require("../index");
|
||||
const _ = require("lodash");
|
||||
const { refList, db } = require("../index");
|
||||
const { getSunoTimestamps } = require("./lyrics");
|
||||
const { deleteFolder } = require("../helpers/firebase");
|
||||
const { buildMonthKey } = require("../helpers/stats");
|
||||
|
||||
const firestore = admin.firestore();
|
||||
|
||||
const buildMonthKey = (timestamp) => {
|
||||
const date = timestamp.toDate();
|
||||
const year = date.getUTCFullYear();
|
||||
const month = String(date.getUTCMonth() + 1).padStart(2, "0");
|
||||
return `${year}-${month}`;
|
||||
};
|
||||
|
||||
exports.onProjectUpdate = onDocumentWritten(
|
||||
"projects/{projectId}",
|
||||
async (projectSnap) => {
|
||||
try {
|
||||
const { projectId } = projectSnap.params;
|
||||
|
||||
const currentData = projectSnap?.data?.after?.data() || null;
|
||||
const previousData = projectSnap?.data?.before?.data() || null;
|
||||
|
||||
if (!previousData?.songUrl && currentData?.songUrl) {
|
||||
await getSunoTimestamps(projectId);
|
||||
}
|
||||
|
||||
if (!currentData) {
|
||||
const { userId } = previousData || {};
|
||||
|
||||
//delete folder
|
||||
await deleteFolder(`users/${userId}/projects/${projectId}/`);
|
||||
|
||||
//delete tasks
|
||||
const snapshot = await refList.tasks
|
||||
.where("projectId", "==", projectId)
|
||||
.get();
|
||||
if (snapshot.empty) return null;
|
||||
const batch = admin.firestore().batch();
|
||||
snapshot.forEach((doc) => {
|
||||
batch.delete(doc.ref);
|
||||
});
|
||||
await batch.commit();
|
||||
} else {
|
||||
if (previousData) {
|
||||
// edit
|
||||
if (!previousData?.songUrl && currentData?.songUrl) {
|
||||
await refList.projects.doc(projectId).update({
|
||||
hasSong: true,
|
||||
});
|
||||
}
|
||||
if (!previousData?.playbackUrl && currentData?.playbackUrl) {
|
||||
await refList.projects.doc(projectId).update({
|
||||
hasPlayback: true,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
exports.onProjectViewsIncrement = onDocumentWritten(
|
||||
exports.onProjectWritten = onDocumentWritten(
|
||||
"projects/{projectId}",
|
||||
async (projectSnap) => {
|
||||
try {
|
||||
@@ -71,53 +14,94 @@ exports.onProjectViewsIncrement = onDocumentWritten(
|
||||
const beforeData = projectSnap?.data?.before?.data() || null;
|
||||
const afterData = projectSnap?.data?.after?.data() || null;
|
||||
|
||||
if (!afterData) return null;
|
||||
if (!afterData) {
|
||||
const { userId } = beforeData || {};
|
||||
|
||||
const beforeViews =
|
||||
typeof beforeData?.views === "number" && Number.isFinite(beforeData.views)
|
||||
? beforeData.views
|
||||
: 0;
|
||||
const afterViews =
|
||||
typeof afterData?.views === "number" && Number.isFinite(afterData.views)
|
||||
? afterData.views
|
||||
: 0;
|
||||
const delta = afterViews - beforeViews;
|
||||
|
||||
if (delta <= 0) return null;
|
||||
|
||||
const userId =
|
||||
typeof afterData?.userId === "string" && afterData.userId.trim().length
|
||||
? afterData.userId.trim()
|
||||
: null;
|
||||
const now = admin.firestore.Timestamp.now();
|
||||
const monthKey = buildMonthKey(now);
|
||||
|
||||
const statsDocRef = firestore
|
||||
.collection("projectStreamStats")
|
||||
.doc(projectId)
|
||||
.collection("monthly")
|
||||
.doc(monthKey);
|
||||
|
||||
await firestore.runTransaction(async (transaction) => {
|
||||
const statsSnapshot = await transaction.get(statsDocRef);
|
||||
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;
|
||||
if (userId) {
|
||||
await deleteFolder(`users/${userId}/projects/${projectId}/`);
|
||||
}
|
||||
|
||||
transaction.set(statsDocRef, updatePayload, { merge: true });
|
||||
});
|
||||
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) {
|
||||
@@ -126,5 +110,5 @@ exports.onProjectViewsIncrement = onDocumentWritten(
|
||||
});
|
||||
return null;
|
||||
}
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user