Files
musicland/functions/src/users.js
T
2026-07-20 15:23:16 +02:00

132 lines
4.1 KiB
JavaScript

const admin = require('firebase-admin')
const { FieldValue } = require('firebase-admin/firestore')
const { onDocumentDeleted, onDocumentCreated } = require('firebase-functions/firestore')
const { refList } = require('../index')
const { ORDER_TYPES, createOrderDocument } = require('./helpers/orders')
const { deleteFolder } = require('../helpers/firebase')
const { Resend } = require('resend')
const { welcomeTemplate } = require('../helpers/email')
const { RESEND_API_KEY } = require('../config/secrets')
const { onRequest } = require('firebase-functions/https')
let resendClient = null
const getResendClient = () => {
if (!resendClient) {
resendClient = new Resend(RESEND_API_KEY.value())
}
return resendClient
}
const WELCOME_EMAIL_FROM = 'MusicLand <musicland@musicland.ai>'
const WELCOME_EMAIL_SUBJECT = 'Bienvenue sur MusicLand'
const USER_CREATED_OPTIONS = {
document: 'users/{userID}',
secrets: [RESEND_API_KEY],
}
exports.testWelcomMail = onRequest({ secrets: [RESEND_API_KEY] }, async (req, res) => {
if (req.method !== 'GET') {
res.set('Allow', 'GET')
return res.status(405).json({ success: false, error: 'Method not allowed' })
}
try {
const targetEmail = req.query.email || 'tdtomthomas@gmail.com'
const firstName = req.query.firstName || 'Toto'
const lastName = req.query.lastName || 'Test'
const { data, error } = await getResendClient().emails.send({
from: WELCOME_EMAIL_FROM,
to: [targetEmail],
subject: WELCOME_EMAIL_SUBJECT,
html: welcomeTemplate({ firstName, lastName }),
})
if (error) {
console.log('Failed to send welcome email:', error)
return res.status(500).json({ success: false, error: error.message || error.toString() })
}
console.log('Welcome email sent:', data)
return res.status(200).json({ success: true, data })
} catch (e) {
console.log(e)
return res.status(500).json({ success: false, error: e.message || e.toString() })
}
})
exports.onUserCreated = onDocumentCreated(USER_CREATED_OPTIONS, async (event) => {
try {
const { email = '', firstName = '', lastName = '' } = event?.data?.data() || {}
const userId = event?.params?.userID
try {
await createOrderDocument({
userId,
type: ORDER_TYPES.GIFT,
amount: 10,
metadata: { reason: 'WELCOME_BONUS' },
orderId: `welcome_${userId}`,
})
} catch (coinError) {
console.warn(
'[users-onUserCreated] Unable to grant welcome coins',
event?.params?.userID,
coinError?.message || coinError
)
}
if (email) {
try {
console.log(`Sending welcome email to ${email}`)
const { data, error } = await getResendClient().emails.send({
from: WELCOME_EMAIL_FROM,
to: [email],
subject: WELCOME_EMAIL_SUBJECT,
html: welcomeTemplate({ firstName, lastName }),
})
if (error) {
console.log('Failed to send welcome email:', error)
return
}
console.log('Welcome email sent:', data)
} catch (error) {
console.log('Failed to send welcome email:', error)
}
} else {
throw new Error('User created with empty email')
}
} catch (e) {
console.log(e)
}
})
exports.onUserDelete = onDocumentDeleted('users/{userID}', async (event) => {
try {
const userID = event?.params?.userID
await clearAllUserData(userID)
await deleteFolder(`users/${userID}/`)
await admin.auth().deleteUser(userID)
console.log(`User ${userID} deleted successfully`)
} catch (e) {
console.log(e)
}
})
async function clearAllUserData(userID) {
const deleteAll = async (ref, key, operator = '==') => {
const snapshot = await ref.where(key, operator, userID).get()
snapshot.forEach((item) => item.ref.delete())
}
const removeFromArray = async (ref, arrayName) => {
const snapshot = await ref.where(arrayName, 'array-contains', userID).get()
snapshot.forEach((item) =>
item.ref.update({
[arrayName]: FieldValue.arrayRemove(userID),
})
)
}
await deleteAll(refList.projects, 'userId')
await deleteAll(refList.playlists, 'createdBy')
}