153 lines
4.2 KiB
JavaScript
153 lines
4.2 KiB
JavaScript
const { TrackingToken, Company, MailTemplate } = require('../models');
|
|
const { generateTrackingToken } = require('../utils/tokenGenerator');
|
|
const mailService = require('./mail.service');
|
|
const logger = require('../config/logger');
|
|
|
|
class TokenService {
|
|
async createToken(data) {
|
|
const { company_id, target_email, employee_name, template_type, from_name } = data;
|
|
|
|
// Generate unique token
|
|
let token = generateTrackingToken();
|
|
let isUnique = false;
|
|
let attempts = 0;
|
|
|
|
// Ensure token is unique
|
|
while (!isUnique && attempts < 5) {
|
|
const existing = await TrackingToken.findOne({ where: { token } });
|
|
if (!existing) {
|
|
isUnique = true;
|
|
} else {
|
|
token = generateTrackingToken();
|
|
attempts++;
|
|
}
|
|
}
|
|
|
|
if (!isUnique) {
|
|
throw new Error('Failed to generate unique token');
|
|
}
|
|
|
|
// Get company and template
|
|
const company = await Company.findByPk(company_id);
|
|
if (!company) {
|
|
throw new Error('Company not found');
|
|
}
|
|
|
|
const template = await MailTemplate.findOne({ where: { template_type } });
|
|
if (!template) {
|
|
throw new Error('Mail template not found');
|
|
}
|
|
|
|
// Create tracking token
|
|
const trackingToken = await TrackingToken.create({
|
|
token,
|
|
company_id,
|
|
target_email,
|
|
employee_name,
|
|
template_type,
|
|
from_name: from_name || null,
|
|
mail_subject: template.subject_template.replace('{{company_name}}', company.name),
|
|
});
|
|
|
|
// Update company stats
|
|
await company.increment('total_tokens');
|
|
|
|
logger.info(`Token created: ${token} for ${target_email}`);
|
|
|
|
return trackingToken;
|
|
}
|
|
|
|
async sendMail(tokenId) {
|
|
const token = await TrackingToken.findByPk(tokenId, {
|
|
include: [{ model: Company, as: 'company' }],
|
|
});
|
|
|
|
if (!token) {
|
|
throw new Error('Token not found');
|
|
}
|
|
|
|
if (token.mail_sent) {
|
|
throw new Error('Mail already sent for this token');
|
|
}
|
|
|
|
// Get mail template
|
|
const template = await MailTemplate.findOne({
|
|
where: { template_type: token.template_type },
|
|
});
|
|
|
|
if (!template) {
|
|
throw new Error('Mail template not found');
|
|
}
|
|
|
|
// Get base URL from settings or env
|
|
const { Settings } = require('../models');
|
|
const baseUrlSetting = await Settings.findOne({ where: { key: 'base_url' } });
|
|
const baseUrl = baseUrlSetting?.value || process.env.BASE_URL || 'http://localhost:3000';
|
|
|
|
// Prepare template data
|
|
const trackingUrl = `${baseUrl}/t/${token.token}`;
|
|
const currentDate = new Date().toLocaleDateString('tr-TR', {
|
|
year: 'numeric',
|
|
month: 'long',
|
|
day: 'numeric',
|
|
});
|
|
const currentYear = new Date().getFullYear();
|
|
|
|
const templateData = {
|
|
company_name: token.company.name,
|
|
employee_name: token.employee_name,
|
|
tracking_url: trackingUrl,
|
|
current_date: currentDate,
|
|
current_year: currentYear,
|
|
};
|
|
|
|
// Render mail body
|
|
const htmlBody = mailService.renderTemplate(template.body_html, templateData);
|
|
const subject = mailService.renderTemplate(template.subject_template, templateData);
|
|
|
|
// Send mail with custom from_name if provided
|
|
await mailService.sendMail(token.target_email, subject, htmlBody, token.from_name);
|
|
|
|
// Update token
|
|
await token.update({
|
|
mail_sent: true,
|
|
sent_at: new Date(),
|
|
});
|
|
|
|
logger.info(`Mail sent for token: ${token.token} to ${token.target_email}`);
|
|
|
|
return token;
|
|
}
|
|
|
|
async updateCompanyStats(companyId) {
|
|
const company = await Company.findByPk(companyId);
|
|
if (!company) return;
|
|
|
|
// Count tokens
|
|
const totalTokens = await TrackingToken.count({
|
|
where: { company_id: companyId },
|
|
});
|
|
|
|
const clickedTokens = await TrackingToken.count({
|
|
where: { company_id: companyId, clicked: true },
|
|
});
|
|
|
|
const totalClicks = await TrackingToken.sum('click_count', {
|
|
where: { company_id: companyId },
|
|
});
|
|
|
|
const clickRate = totalTokens > 0 ? ((clickedTokens / totalTokens) * 100).toFixed(2) : 0;
|
|
|
|
await company.update({
|
|
total_tokens: totalTokens,
|
|
total_clicks: totalClicks || 0,
|
|
click_rate: clickRate,
|
|
});
|
|
|
|
logger.info(`Company stats updated for: ${company.name}`);
|
|
}
|
|
}
|
|
|
|
module.exports = new TokenService();
|
|
|