Files
rentall-app/backend/services/email/domain/UserEngagementEmailService.js
2026-01-21 19:00:55 -05:00

179 lines
5.2 KiB
JavaScript

const EmailClient = require("../core/EmailClient");
const TemplateManager = require("../core/TemplateManager");
const logger = require("../../../utils/logger");
/**
* UserEngagementEmailService handles user engagement emails
* This service is responsible for:
* - Sending first listing celebration emails
* - Other user engagement and milestone emails
*/
class UserEngagementEmailService {
constructor() {
this.emailClient = new EmailClient();
this.templateManager = new TemplateManager();
this.initialized = false;
}
/**
* Initialize the user engagement email service
* @returns {Promise<void>}
*/
async initialize() {
if (this.initialized) return;
await Promise.all([
this.emailClient.initialize(),
this.templateManager.initialize(),
]);
this.initialized = true;
logger.info("User Engagement Email Service initialized successfully");
}
/**
* Send first listing celebration email to owner
* @param {Object} owner - Owner user object
* @param {string} owner.firstName - Owner's first name
* @param {string} owner.email - Owner's email address
* @param {Object} item - Item object
* @param {number} item.id - Item ID
* @param {string} item.name - Item name
* @returns {Promise<{success: boolean, messageId?: string, error?: string}>}
*/
async sendFirstListingCelebrationEmail(owner, item) {
if (!this.initialized) {
await this.initialize();
}
try {
const frontendUrl = process.env.FRONTEND_URL;
const variables = {
ownerName: owner.firstName || "there",
itemName: item.name,
itemId: item.id,
viewItemUrl: `${frontendUrl}/items/${item.id}`,
};
const htmlContent = await this.templateManager.renderTemplate(
"firstListingCelebrationToOwner",
variables,
);
const subject = `Congratulations! Your first item is live on Village Share`;
return await this.emailClient.sendEmail(
owner.email,
subject,
htmlContent,
);
} catch (error) {
logger.error("Failed to send first listing celebration email", { error });
return { success: false, error: error.message };
}
}
/**
* Send item deletion notification email to owner
* @param {Object} owner - Owner user object
* @param {string} owner.firstName - Owner's first name
* @param {string} owner.email - Owner's email address
* @param {Object} item - Item object
* @param {number} item.id - Item ID
* @param {string} item.name - Item name
* @param {string} deletionReason - Reason for deletion
* @returns {Promise<{success: boolean, messageId?: string, error?: string}>}
*/
async sendItemDeletionNotificationToOwner(owner, item, deletionReason) {
if (!this.initialized) {
await this.initialize();
}
try {
const frontendUrl = process.env.FRONTEND_URL;
const supportEmail = process.env.CUSTOMER_SUPPORT_EMAIL;
const variables = {
ownerName: owner.firstName || "there",
itemName: item.name,
deletionReason,
supportEmail,
dashboardUrl: `${frontendUrl}/owning`,
};
const htmlContent = await this.templateManager.renderTemplate(
"itemDeletionToOwner",
variables,
);
const subject = `Important: Your listing "${item.name}" has been removed`;
return await this.emailClient.sendEmail(
owner.email,
subject,
htmlContent,
);
} catch (error) {
logger.error("Failed to send item deletion notification email", {
error,
});
return { success: false, error: error.message };
}
}
/**
* Send notification when a user's account is banned
* @param {Object} bannedUser - User who was banned
* @param {string} bannedUser.firstName - Banned user's first name
* @param {string} bannedUser.email - Banned user's email
* @param {Object} admin - Admin who performed the ban
* @param {string} admin.firstName - Admin's first name
* @param {string} admin.lastName - Admin's last name
* @param {string} banReason - Reason for the ban
* @returns {Promise<{success: boolean, messageId?: string, error?: string}>}
*/
async sendUserBannedNotification(bannedUser, admin, banReason) {
if (!this.initialized) {
await this.initialize();
}
try {
const supportEmail = process.env.CUSTOMER_SUPPORT_EMAIL;
const variables = {
userName: bannedUser.firstName || "there",
banReason: banReason,
supportEmail: supportEmail,
};
const htmlContent = await this.templateManager.renderTemplate(
"userBannedNotification",
variables,
);
const subject =
"Important: Your Village Share Account Has Been Suspended";
const result = await this.emailClient.sendEmail(
bannedUser.email,
subject,
htmlContent,
);
if (result.success) {
logger.info("User banned notification email sent", {
email: bannedUser.email,
});
}
return result;
} catch (error) {
logger.error("Failed to send user banned notification email", { error });
return { success: false, error: error.message };
}
}
}
module.exports = UserEngagementEmailService;