You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

89 lines
2.8 KiB

import nodemailer from "nodemailer";
import type { Transporter } from "nodemailer";
import { getGlobalConfigValue } from "#server/service/config";
import log4js from "logger";
const logger = log4js.getLogger("email");
export interface SmtpConfig {
host: string;
port: number;
user: string;
pass: string;
from: string;
secure: boolean;
}
export async function getSmtpConfig(): Promise<SmtpConfig> {
const [host, port, user, pass, from, secure] = await Promise.all([
getGlobalConfigValue("smtpHost"),
getGlobalConfigValue("smtpPort"),
getGlobalConfigValue("smtpUser"),
getGlobalConfigValue("smtpPass"),
getGlobalConfigValue("smtpFrom"),
getGlobalConfigValue("smtpSecure"),
]);
return { host, port, user, pass, from, secure };
}
export function createTransporter(config: SmtpConfig): Transporter {
return nodemailer.createTransport({
host: config.host,
port: config.port,
secure: config.secure,
auth: config.user
? { user: config.user, pass: config.pass }
: undefined,
});
}
export async function testSmtpConnection(config: SmtpConfig): Promise<{ success: boolean; message: string }> {
if (!config.host || !config.port) {
return { success: false, message: "SMTP 服务器地址和端口未配置" };
}
try {
const transporter = createTransporter(config);
await transporter.verify();
return { success: true, message: "SMTP 连接测试成功" };
} catch (err: unknown) {
const message = err instanceof Error ? err.message : "未知错误";
logger.error("SMTP connection test failed: %s", message);
return { success: false, message: `SMTP 连接失败: ${message}` };
}
}
export interface SendMailOptions {
to: string | string[];
subject: string;
text?: string;
html?: string;
}
export async function sendMail(options: SendMailOptions): Promise<{ success: boolean; message: string }> {
const config = await getSmtpConfig();
if (!config.host || !config.port) {
return { success: false, message: "SMTP 服务器未配置,请先在系统设置中配置邮件服务" };
}
if (!config.from) {
return { success: false, message: "发件人地址未配置" };
}
try {
const transporter = createTransporter(config);
const info = await transporter.sendMail({
from: config.from,
to: Array.isArray(options.to) ? options.to.join(", ") : options.to,
subject: options.subject,
text: options.text,
html: options.html,
});
logger.info("Email sent to %s, messageId: %s", options.to, info.messageId);
return { success: true, message: "邮件发送成功" };
} catch (err: unknown) {
const message = err instanceof Error ? err.message : "未知错误";
logger.error("Failed to send email to %s: %s", options.to, message);
return { success: false, message: `邮件发送失败: ${message}` };
}
}