open mail and click url
This commit is contained in:
parent
833470cbdb
commit
2371aa727e
72
mail-service/src/controllers/trackingController.js
Normal file
72
mail-service/src/controllers/trackingController.js
Normal file
@ -0,0 +1,72 @@
|
||||
import { DeliveryLog } from '../models/index.js';
|
||||
|
||||
export default {
|
||||
async trackOpen(req, res) {
|
||||
try {
|
||||
const { deliveryLogId } = req.params;
|
||||
|
||||
// Находим запись в DeliveryLog
|
||||
const deliveryLog = await DeliveryLog.findByPk(deliveryLogId);
|
||||
|
||||
if (!deliveryLog) {
|
||||
return res.status(404).send('Not found');
|
||||
}
|
||||
|
||||
// Обновляем время открытия, если еще не было установлено
|
||||
if (!deliveryLog.opened_at) {
|
||||
await deliveryLog.update({
|
||||
opened_at: new Date()
|
||||
});
|
||||
console.log(`[Tracking] Email opened: deliveryLogId=${deliveryLogId}, campaignId=${deliveryLog.campaign_id}, subscriberId=${deliveryLog.subscriber_id}`);
|
||||
}
|
||||
|
||||
// Возвращаем прозрачный 1x1 пиксель
|
||||
const pixel = Buffer.from('iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==', 'base64');
|
||||
res.writeHead(200, {
|
||||
'Content-Type': 'image/png',
|
||||
'Content-Length': pixel.length,
|
||||
'Cache-Control': 'no-cache, no-store, must-revalidate',
|
||||
'Pragma': 'no-cache',
|
||||
'Expires': '0'
|
||||
});
|
||||
res.end(pixel);
|
||||
|
||||
} catch (err) {
|
||||
console.error('[Tracking] Error tracking email open:', err);
|
||||
res.status(500).send('Error');
|
||||
}
|
||||
},
|
||||
|
||||
async trackClick(req, res) {
|
||||
try {
|
||||
const { deliveryLogId } = req.params;
|
||||
const { url } = req.query;
|
||||
|
||||
if (!url) {
|
||||
return res.status(400).send('URL parameter required');
|
||||
}
|
||||
|
||||
// Находим запись в DeliveryLog
|
||||
const deliveryLog = await DeliveryLog.findByPk(deliveryLogId);
|
||||
|
||||
if (!deliveryLog) {
|
||||
return res.status(404).send('Not found');
|
||||
}
|
||||
|
||||
// Обновляем время клика, если еще не было установлено
|
||||
if (!deliveryLog.clicked_at) {
|
||||
await deliveryLog.update({
|
||||
clicked_at: new Date()
|
||||
});
|
||||
console.log(`[Tracking] Email clicked: deliveryLogId=${deliveryLogId}, campaignId=${deliveryLog.campaign_id}, subscriberId=${deliveryLog.subscriber_id}, url=${url}`);
|
||||
}
|
||||
|
||||
// Перенаправляем на оригинальный URL
|
||||
res.redirect(url);
|
||||
|
||||
} catch (err) {
|
||||
console.error('[Tracking] Error tracking email click:', err);
|
||||
res.status(500).send('Error');
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -8,6 +8,7 @@ import campaignRoutes from './campaign.js';
|
||||
import deliveryLogRoutes from './deliveryLog.js';
|
||||
import smtpServerRoutes from './smtpServer.js';
|
||||
import topicRoutes from './topic.js';
|
||||
import trackingRoutes from './tracking.js';
|
||||
|
||||
const router = Router();
|
||||
|
||||
@ -20,5 +21,6 @@ router.use('/campaigns', campaignRoutes);
|
||||
router.use('/delivery-logs', deliveryLogRoutes);
|
||||
router.use('/smtp-servers', smtpServerRoutes);
|
||||
router.use('/topics', topicRoutes);
|
||||
router.use('/track', trackingRoutes);
|
||||
|
||||
export default router;
|
||||
12
mail-service/src/routes/tracking.js
Normal file
12
mail-service/src/routes/tracking.js
Normal file
@ -0,0 +1,12 @@
|
||||
import express from 'express';
|
||||
import trackingController from '../controllers/trackingController.js';
|
||||
|
||||
const router = express.Router();
|
||||
|
||||
// Трекинг открытия письма
|
||||
router.get('/open/:deliveryLogId', trackingController.trackOpen);
|
||||
|
||||
// Трекинг клика по ссылке
|
||||
router.get('/click/:deliveryLogId', trackingController.trackClick);
|
||||
|
||||
export default router;
|
||||
@ -259,12 +259,26 @@ async function processEmailTask(task, topic) {
|
||||
});
|
||||
console.log(`[DynamicConsumer] Transporter created successfully`);
|
||||
|
||||
// Добавляем трекинг-пиксель для отслеживания открытия письма
|
||||
const trackingPixel = `<img src="http://${smtp.from_email}/api/mail/track/open/${deliveryLog.id}" width="1" height="1" style="display:none;" />`;
|
||||
|
||||
// Обрабатываем ссылки для отслеживания кликов
|
||||
const htmlWithClickTracking = task.html.replace(
|
||||
/<a\s+href=["']([^"']+)["']/gi,
|
||||
(match, url) => {
|
||||
const trackingUrl = `http://${smtp.from_email}/api/mail/track/click/${deliveryLog.id}?url=${encodeURIComponent(url)}`;
|
||||
return `<a href="${trackingUrl}"`;
|
||||
}
|
||||
);
|
||||
|
||||
const htmlWithTracking = htmlWithClickTracking + trackingPixel;
|
||||
|
||||
const mailOptions = {
|
||||
from: smtp.from_email,
|
||||
to: task.email,
|
||||
subject: task.subject,
|
||||
text: task.text,
|
||||
html: task.html,
|
||||
html: htmlWithTracking,
|
||||
headers: {
|
||||
'List-Unsubscribe': `<mailto:${smtp.from_email}?subject=unsubscribe>`,
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user