Files
hotel777-manager/mailer.js
2026-05-03 18:59:12 +05:00

106 lines
4.2 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
const nodemailer = require('nodemailer');
let transporter = null;
let emailEnabled = true; // по умолчанию включено, при ошибке станет false
let verificationDone = false; // проверка выполнена хотя бы раз
function createTransporter() {
if (!process.env.SMTP_HOST || !process.env.SMTP_USER || !process.env.SMTP_PASS) {
console.warn('[MAILER] SMTP не настроен (отсутствуют переменные окружения). Почтовые уведомления отключены.');
return null;
}
return nodemailer.createTransport({
host: process.env.SMTP_HOST,
port: parseInt(process.env.SMTP_PORT) || 587,
secure: false,
auth: {
user: process.env.SMTP_USER,
pass: process.env.SMTP_PASS
}
});
}
// Функция проверки соединения с почтовым сервером
async function verifyEmailConnection() {
if (verificationDone) return emailEnabled;
transporter = createTransporter();
if (!transporter) {
emailEnabled = false;
verificationDone = true;
return false;
}
try {
await transporter.verify();
console.log('[MAILER] SMTP подключение успешно, уведомления активны.');
emailEnabled = true;
} catch (err) {
console.error('[MAILER] Ошибка подключения к SMTP:', err.message);
console.warn('[MAILER] Почтовые уведомления будут отключены до следующего перезапуска.');
emailEnabled = false;
transporter = null; // сбросим, чтобы не использовать нерабочий
} finally {
verificationDone = true;
}
return emailEnabled;
}
async function sendNotification(emails, subject, text) {
if (!emailEnabled) {
// Молча пропускаем, т.к. проверка уже показала неработоспособность
return;
}
if (!emails) return;
const recipients = emails.split(',').map(e => e.trim()).filter(Boolean);
if (recipients.length === 0) return;
// Если транспортер ещё не создан (не было вызова verify), создадим его
if (!transporter) {
transporter = createTransporter();
if (!transporter) {
emailEnabled = false;
return;
}
}
try {
await transporter.sendMail({
from: process.env.SMTP_USER,
to: recipients.join(','),
subject,
text
});
console.log(`Уведомление отправлено на ${recipients.join(', ')}`);
} catch (err) {
console.error('Ошибка отправки письма:', err);
// Если при отправке возникла ошибка, считаем почту нерабочей до перезапуска
if (emailEnabled) {
console.warn('[MAILER] Отключение почтовых уведомлений из-за ошибки отправки.');
emailEnabled = false;
}
}
}
async function notifyNewBooking(booking) {
const subject = `Новая заявка №${booking.external_id} (${process.env.SERVICE_NAME})`;
const text = `Поступила новая заявка на заселение.\n
Имя: ${booking.name}
Телефон: ${booking.phone_raw}
Даты: с ${booking.checkin_date} по ${booking.checkout_date}
Взрослых: ${booking.adults}, детей: ${booking.children}
Ссылка: ${process.env.SERVICE_URL}/admin/bookings`;
await sendNotification(process.env.EMAIL_NOTIFY_NEW, subject, text);
}
async function notifyBookingUpdate(booking, changes) {
const subject = `Изменение заявки №${booking.external_id} (${process.env.SERVICE_NAME})`;
const text = `Заявка №${booking.external_id} была изменена.\n
Новый статус: ${booking.status}
Комментарий: ${booking.comments || 'нет'}
Изменения: ${JSON.stringify(changes, null, 2)}
Ссылка: ${process.env.SERVICE_URL}/admin/bookings`;
await sendNotification(process.env.EMAIL_NOTIFY_UPDATE, subject, text);
}
module.exports = { verifyEmailConnection, notifyNewBooking, notifyBookingUpdate };