Skip to content

Latest commit

 

History

24 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Nozomi Relay

Nozomi Relay 是一个基于 Go 的轻量级邮件中转服务,用于从下游 SMTP 转发到腾讯云 SES 等多个邮件推送服务 API。

由于严格的风控政策,目前大量邮件提供商已经不再支持使用 SMTP 发送邮件,而是强制使用自家的 API。但是,常见的下游应用程序(例如 Rauthy, Gitea 等)仍然只能支持 SMTP 发信。本服务支持接收 SMTP 邮件后用 JavaScript 规则提取变量(例如验证码),再调用上游模板 Sendmail 接口。

Nozomi

功能

  • Go + Gin + SQLite 后端
  • 内置 SMTP relay,支持配置多个下游 SMTP 账号
  • 腾讯云 SES / Resend / Brevo API 支持
  • 同步腾讯云模板列表与模板变量
  • JavaScript 规则脚本提取下游邮件内容并映射模板变量
  • 支持按时区设置不同邮件提供商的每日额度重置时间,避免超额扣费
  • 发送历史、错误日志、腾讯云回调事件记录
  • Ant Design 管理面板,含统计、配置、模板、规则、账号、日志

开发运行

后端:

cd backend
cp .env.example .env
go run ./cmd/server

前端:

cd Nozomi-Admin
npm run dev

默认地址:

如果你希望把管理面板挂到子路径,例如 https://auth.kirari.fun/nozomi,可以设置:

NOZOMI_WEB_BASE_PATH=/nozomi/

这个值会同时影响:

  • 管理面板静态资源前缀
  • 前端路由前缀
  • API 路径前缀,例如 /nozomi/api/...
  • 登录 cookie 的 Path

默认管理员账号来自 backend/.env,默认下游 SMTP 账号为 anonymous(空密码,仅在显式启用无认证 SMTP 时使用)。

数据库默认使用 SQLite,也可以切换到 PostgreSQL:

NOZOMI_DB_DRIVER=postgresql
NOZOMI_DB_DSN=postgres://nozomi:password@postgres:5432/nozomi?sslmode=disable

嵌入式 Docker 镜像的前端资源路径必须与运行时路径一致,例如:

docker build --build-arg NOZOMI_WEB_BASE_PATH=/nozomi/ -t nozomi .

嵌入式构建会把该路径写入二进制;若运行时覆盖为不同值,服务会拒绝启动并报告配置不一致。

将现有 SQLite 数据一次性导入空的 PostgreSQL 数据库:

./nozomi-relay \
  --migrate-sqlite /data/nozomi.sqlite3 \
  --postgres-dsn 'postgres://nozomi:password@postgres:5432/nozomi?sslmode=disable'

这是离线迁移命令,执行前必须停止对源 SQLite 的写入。迁移要求目标表为空,并在一个事务中创建目标 schema、复制全部数据和重置 sequence;任一表失败都会回滚。

如果你从局域网 IP 访问前端,比如 http://192.168.31.221:5173,需要在后端 .env 里把 NOZOMI_CORS_ORIGINS 加上对应的完整 origin,例如:

NOZOMI_CORS_ORIGINS=http://localhost:5173,http://127.0.0.1:5173,http://192.168.31.221:5173

开发模式下,前端 npm run dev 仍然是通过 Vite 代理把 /api 转发到 http://127.0.0.1:5000,不是直接从浏览器打 5000。

构建模式

项目支持两种构建模式:

前后端分离模式

只构建 Go 后端,前端单独部署或用 Vite 开发服务运行:

./scripts/build.sh separate
./dist/nozomi-relay

这是默认的 API-only 二进制,不包含前端静态文件。

合并模式

先构建前端,再把 Nozomi-Admin/dist 嵌入 Go 二进制,由 Go 同时提供 API 和管理面板静态服务:

NOZOMI_WEB_BASE_PATH=/nozomi/ \
./scripts/build.sh embedded
./dist/nozomi-relay-embedded

启动后访问后端 HTTP 地址即可打开管理面板,例如默认的 http://127.0.0.1:5000;如果设置了 NOZOMI_WEB_BASE_PATH=/nozomi/,则访问 http://127.0.0.1:5000/nozomi/api/* 会跟随这个前缀,例如 /nozomi/api/*;其它路径会优先返回静态文件,未命中时回退到 index.html 以支持前端路由。

注意:

  • 这里必须使用带尾部斜杠的 NOZOMI_WEB_BASE_PATH=/nozomi/
  • 如果写成 /nozomi,Vite 构建出的静态资源路径可能仍然是根路径 /assets/...
  • 挂在反向代理子路径下时,这会直接导致管理面板白屏

运行时可以用命令行参数控制是否启用内置静态服务:

./dist/nozomi-relay-embedded -web auto
./dist/nozomi-relay-embedded -web off

普通分离模式二进制即使使用 -web auto 也不会提供前端静态文件,因为构建时没有嵌入 dist。

Docker

项目根目录提供了单容器 Dockerfile。它会先构建 Nozomi-Admin,再把前端嵌入 Go 二进制,启动后同时提供管理面板、HTTP API 和 SMTP relay。

docker build -t nozomi-relay .
docker run --rm -p 5000:5000 -p 2525:2525 -v nozomi-data:/data nozomi-relay

如果放在反向代理后面,HTTP 通常只暴露给内部网络;SMTP 2525 仍然需要单独映射到宿主机,供下游应用连接。

规则脚本

规则脚本运行在 Go 内嵌 JavaScript 引擎中,后端提供 input

{
  from,
  to,
  subject,
  text,
  html,
  headers,
  raw
}

脚本返回 null 表示不匹配;匹配时返回:

({
  templateId: 100001, // 腾讯云模板 ID
  subject: input.subject, // 邮件主题
  variables: { // 模板变量映射
    code: "123456",
    action: "登录"
  }
})

后端会检查 variables 是否填满腾讯云模板中解析到的 {{变量名}}

腾讯云回调

在腾讯云 SES 控制台配置回调地址:

https://你的域名/nozomi/api/callback/tencent

如果没有设置 NOZOMI_WEB_BASE_PATH,则仍然是根路径下的 /api/callback/tencent

当前版本记录 deliveredbouncedroppedopenclick 等事件,并根据 bulkId / messageId 关联发送历史。

About

一个基于 Go 的轻量级邮件中转服务,用于从下游 SMTP 转发到腾讯云 SES 等多个邮件推送服务 API。

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages