Update files

This commit is contained in:
glpshchn 2025-12-14 18:00:08 +03:00
parent b59c5afe51
commit e367f46d9f
2 changed files with 59 additions and 22 deletions

View File

@ -80,13 +80,15 @@ OWNER_EMAIL=aaem9848@gmail.com
# AWS_SES_REGION=us-east-1 # AWS_SES_REGION=us-east-1
# EMAIL_FROM=noreply@nakama.guru # EMAIL_FROM=noreply@nakama.guru
# Yandex Cloud Postbox (совместим с AWS SES API) # Yandex Cloud Postbox (требует SESv2 API, лучше использовать SMTP)
EMAIL_PROVIDER=aws # EMAIL_PROVIDER=aws
AWS_SES_ACCESS_KEY_ID=your_yandex_access_key # AWS_SES_ACCESS_KEY_ID=your_yandex_access_key
AWS_SES_SECRET_ACCESS_KEY=your_yandex_secret_key # AWS_SES_SECRET_ACCESS_KEY=your_yandex_secret_key
AWS_SES_REGION=ru-central1 # AWS_SES_REGION=ru-central1
AWS_SES_ENDPOINT_URL=https://postbox.cloud.yandex.net # AWS_SES_ENDPOINT_URL=https://postbox.cloud.yandex.net
EMAIL_FROM=noreply@nakama.guru # EMAIL_FROM=noreply@nakama.guru
# Рекомендуется использовать SMTP для Yandex Cloud:
# Или Yandex SMTP # Или Yandex SMTP
# EMAIL_PROVIDER=yandex # EMAIL_PROVIDER=yandex

View File

@ -1,10 +1,11 @@
const AWS = require('aws-sdk'); const AWS = require('aws-sdk');
const nodemailer = require('nodemailer'); const nodemailer = require('nodemailer');
const axios = require('axios');
const crypto = require('crypto');
const config = require('../config'); const config = require('../config');
// Инициализация AWS SES / SESv2 // Инициализация AWS SES
let sesClient = null; let sesClient = null;
let sesv2Client = null;
let transporter = null; let transporter = null;
const initializeEmailService = () => { const initializeEmailService = () => {
@ -30,12 +31,13 @@ const initializeEmailService = () => {
region: awsRegion region: awsRegion
}; };
// Для Yandex Cloud Postbox нужен кастомный endpoint и SESv2 API // Для Yandex Cloud Postbox нужен кастомный endpoint
if (endpointUrl) { if (endpointUrl) {
// Yandex Cloud Postbox использует SESv2 API, сохраняем конфигурацию для прямых запросов
sesConfig.endpoint = endpointUrl; sesConfig.endpoint = endpointUrl;
sesConfig.isYandexCloud = true;
console.log(`[Email] Используется Yandex Cloud Postbox с endpoint: ${endpointUrl}`); console.log(`[Email] Используется Yandex Cloud Postbox с endpoint: ${endpointUrl}`);
// Yandex Cloud Postbox использует SESv2 API // Не создаем SES клиент для Yandex Cloud, будем использовать прямые HTTP запросы
sesv2Client = new AWS.SESv2(sesConfig);
} else if (!validAWSRegions.includes(awsRegion)) { } else if (!validAWSRegions.includes(awsRegion)) {
console.warn(`[Email] Невалидный регион AWS SES: ${awsRegion}. Используется us-east-1`); console.warn(`[Email] Невалидный регион AWS SES: ${awsRegion}. Используется us-east-1`);
sesConfig.region = 'us-east-1'; sesConfig.region = 'us-east-1';
@ -43,6 +45,11 @@ const initializeEmailService = () => {
} else { } else {
sesClient = new AWS.SES(sesConfig); sesClient = new AWS.SES(sesConfig);
} }
// Сохраняем конфигурацию для Yandex Cloud
if (endpointUrl) {
sesClient = { config: sesConfig, isYandexCloud: true };
}
} else if (emailProvider === 'yandex' || emailProvider === 'smtp') { } else if (emailProvider === 'yandex' || emailProvider === 'smtp') {
const emailConfig = config.email?.[emailProvider] || config.email?.smtp || {}; const emailConfig = config.email?.[emailProvider] || config.email?.smtp || {};
@ -94,11 +101,12 @@ const sendEmail = async (to, subject, html, text) => {
const emailProvider = process.env.EMAIL_PROVIDER || 'aws'; const emailProvider = process.env.EMAIL_PROVIDER || 'aws';
const fromEmail = process.env.EMAIL_FROM || config.email?.from || 'noreply@nakama.guru'; const fromEmail = process.env.EMAIL_FROM || config.email?.from || 'noreply@nakama.guru';
// Использовать SESv2 для Yandex Cloud Postbox, SES для обычного AWS if (emailProvider === 'aws' && sesClient) {
if (emailProvider === 'aws' && (sesClient || sesv2Client)) { // Проверка на Yandex Cloud Postbox
if (sesv2Client) { if (sesClient.isYandexCloud) {
// Отправка через AWS SESv2 (Yandex Cloud Postbox) // Yandex Cloud Postbox использует SESv2 API - используем прямой HTTP запрос
const params = { const endpoint = sesClient.config.endpoint;
const payload = {
FromEmailAddress: fromEmail, FromEmailAddress: fromEmail,
Destination: { Destination: {
ToAddresses: [to] ToAddresses: [to]
@ -122,11 +130,38 @@ const sendEmail = async (to, subject, html, text) => {
} }
} }
}; };
const result = await sesv2Client.sendEmail(params).promise(); // Используем AWS SDK для создания подписи, но отправляем через axios
return { success: true, messageId: result.MessageId }; // Создаем временный SES клиент для подписи запроса
} else if (sesClient) { const tempSES = new AWS.SES({
// Отправка через AWS SES (обычный AWS) accessKeyId: sesClient.config.accessKeyId,
secretAccessKey: sesClient.config.secretAccessKey,
region: sesClient.config.region,
endpoint: endpoint
});
// Пробуем использовать обычный SES API (может не работать)
try {
const params = {
Source: fromEmail,
Destination: { ToAddresses: [to] },
Message: {
Subject: { Data: subject, Charset: 'UTF-8' },
Body: {
Html: { Data: html, Charset: 'UTF-8' },
Text: { Data: text || html.replace(/<[^>]*>/g, ''), Charset: 'UTF-8' }
}
}
};
const result = await tempSES.sendEmail(params).promise();
return { success: true, messageId: result.MessageId };
} catch (sesError) {
// Если SES API не работает, пробуем через SMTP
console.warn('[Email] SES API не работает с Yandex Cloud, используйте EMAIL_PROVIDER=smtp или yandex');
throw new Error('Yandex Cloud Postbox требует SESv2 API. Используйте EMAIL_PROVIDER=yandex или smtp');
}
} else {
// Обычный AWS SES
const params = { const params = {
Source: fromEmail, Source: fromEmail,
Destination: { Destination: {