快速开始

  1. 访问 /login 登录后台。
  2. /dashboard/forms 创建表单,系统会自动发送验证邮件到接收邮箱。
  3. 点击验证邮件中的链接完成邮箱验证,表单才能生效。
  4. /dashboard/channels 配置 SMTP 并测试。
  5. /dashboard/submissions 监控提交记录。

HTML 接入

<form action="https://your-domain/f/YOUR_FORM_TOKEN" method="POST">
  <input name="name" required />
  <input name="email" type="email" required />
  <textarea name="message" required></textarea>
  <input type="text" name="_gotcha" style="display:none" />
  <button type="submit">提交</button>
</form>

建议保留 _gotcha 蜜罐字段防机器人。

JSON 提交

fetch("https://your-domain/f/YOUR_FORM_TOKEN", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({ 
    name: "Alice", 
    email: "alice@example.com", 
    message: "Hi" 
  })
});

邮箱验证

创建表单后,系统会自动向接收邮箱发送验证邮件。只有完成验证的邮箱才能接收表单提交。

验证流程

  1. 创建表单时输入接收邮箱
  2. 系统自动发送验证邮件
  3. 点击邮件中的验证链接
  4. 邮箱验证通过,表单开始生效

注意事项

  • 修改接收邮箱后需要重新验证
  • 未验证的邮箱无法接收表单提交
  • 验证链接有效期为永久有效

安全防护

来源域名白名单

可以在表单设置中配置允许提交的来源域名,防止表单地址被滥用。

# 配置示例
允许的来源域名:
- https://example.com
- https://www.example.com
- https://*.example.com (支持通配符)

蜜罐字段

表单中添加隐藏字段,机器人会填写但人类不会,用于识别自动化提交。

<input type="text" name="_gotcha" style="display:none" />

请求频率限制

系统自动限制同一IP的提交频率,支持设备指纹级限流。

图形验证码

登录、注册等操作支持图形验证码,防止暴力破解和机器人注册。可在后台开关控制。

注册审核

当管理员将注册默认状态设置为"待审核"时,新用户注册需要填写"注册申请",说明注册原因。注册申请会随审核邮件发送给管理员,作为审批依据,同时起到防机器人注册的作用。管理员可通过邮件中的链接一键通过或拒绝,也可在后台用户管理中操作。

成功页面

表单提交成功后,可以显示自定义的成功提示页面,支持多种主题样式。

主题选项

  • 蓝色经典 - 专业稳重的蓝色渐变
  • 绿色清新 - 自然舒适的绿色渐变
  • 紫色优雅 - 高贵典雅的紫色渐变
  • 橙色活力 - 热情活力的橙色渐变
  • 深色简约 - 现代感深色主题

配置选项

  • 成功文案 - 提交成功后显示的自定义消息
  • 成功跳转URL - 成功提示后自动跳转的地址
  • 主题选择 - 选择成功页面的外观主题

如果成功文案留空,将直接跳转到跳转URL,不显示成功页面。

渠道策略

  • 表单可绑定指定渠道,优先使用绑定渠道发送。
  • 绑定渠道失败自动回退到用户可用渠道。
  • 管理员可共享部分渠道给普通用户,并设置共享限制。
  • 渠道优先级数字越小越优先。
  • 可在「邮件队列」页面查看发送失败原因并手动重试。

自动回复

开启后,表单提交成功会自动向提交者的邮箱发送确认邮件,可自定义标题和正文模板。

Webhook 通知

表单提交后可向外部 URL 推送通知,便于对接飞书、企业微信、Slack 等第三方系统。

配置方式

在表单编辑器中填写 Webhook URL 和可选的 Webhook 密钥

推送格式

POST /your-webhook-url
Content-Type: application/json
X-Webhook-Signature: sha256=xxxx  // HMAC-SHA256 签名(如设置了密钥)

{
  "form_id": 1,
  "form_name": "联系表单",
  "submitted_at": "2026-05-05T12:00:00Z",
  "data": { "name": "张三", "email": "zhang@example.com" },
  "ip": "1.2.3.4"
}

签名验证

如果设置了 Webhook 密钥,请求头会包含 X-Webhook-Signature,值为 sha256= + 请求体的 HMAC-SHA256 十六进制摘要。接收方应验证签名以确保来源可信。

字段自定义

通过字段 Schema 定义表单字段的名称、标签、类型和是否必填,提交时系统自动校验。

配置方式

在表单编辑器中点击「添加字段」,设置字段名、标签、类型(文本/邮箱/电话/数字/多行文本/URL)和是否必填。

校验规则

  • 必填字段:提交数据中必须存在且非空
  • 邮箱类型:自动校验邮箱格式
  • 留空不校验:不定义字段 Schema 时,接受任意格式提交(向后兼容)

自动 HTTPS

Formail 集成 CertMagic,可自动向 Let's Encrypt 申请和续期 SSL 证书,无需手动配置。

启用方式

config.toml 中配置:

[server]
auto_tls = true
acme_email = "admin@your-domain.com"  # 证书到期通知邮箱

工作原理

  • 自动监听 443(HTTPS)和 80(HTTP 跳转)端口
  • 首次访问某域名时自动签发证书(约 10 秒)
  • 证书本地持久化缓存,重启不丢失
  • 到期前 30 天自动续期,无需人工干预
  • 支持多域名自适应,访问什么域名就签发什么证书

反向代理访问控制

可配置为只允许通过 Nginx 等反向代理访问,禁止直接通过端口访问,增强安全性。

配置方式

config.toml 中配置:

[direct_access]
allow = false                    # 禁止直连
key_name = "x-access-key-name"  # 请求头名称
key = "your_secret_key"         # 请求头值

Nginx 配置示例

location / {
    proxy_pass http://127.0.0.1:8080;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header x-access-key-name your_secret_key;
}

未携带正确请求头的直连请求将返回 403。

CLI 工具

Formail 支持通过命令行参数执行管理操作,执行完毕后自动退出,不会启动 Web 服务。可在服务运行时从另一个终端安全执行。

修改管理员账号

# 修改管理员用户名
./formail -admin newadmin@example.com

# 修改管理员密码
./formail -adminpwd newpassword123

# 同时修改用户名和密码
./formail -admin newadmin@example.com -adminpwd newpassword123

CLI 模式仅连接数据库执行更新,执行完毕立即退出,不影响正在运行的服务。

HTTP 邮件 API

除了表单接收,Formail 还提供 HTTP API,允许通过 API Key 直接发送邮件,无需 HTML 表单。适合程序化发送通知、账单、验证码等场景。

获取 API Key

  1. 在控制台进入 /dashboard/apikeys
  2. 点击「新建 API Key」,填写名称和可选的绑定渠道。
  3. 创建后可在列表中随时复制完整 Key。

发送接口

POST /v1/emails
Authorization: Bearer fm_your_api_key
Content-Type: application/json

{
  "to": "recipient@example.com",
  "subject": "Hello from Formail",
  "text": "This is a plain text email.",
  "html": "<p>This is an <b>HTML</b> email.</p>"
}

参数说明

  • to:收件人,字符串或数组(支持多收件人)
  • subject:邮件主题(必填)
  • text:纯文本正文(text 或 html 至少填一个)
  • html:HTML 正文(可选)

发件地址由绑定渠道决定;未绑定则按账号下渠道优先级自动选择。

Shell 示例

curl -X POST https://your-domain/v1/emails \
  -H "Authorization: Bearer fm_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "to": "recipient@example.com",
    "subject": "Hello",
    "text": "Hello from Formail API"
  }'

PowerShell 示例

$headers = @{
    "Authorization" = "Bearer fm_your_api_key"
    "Content-Type"  = "application/json"
}
$body = @{
    to      = "recipient@example.com"
    subject = "Hello"
    text    = "Hello from Formail API"
} | ConvertTo-Json

Invoke-RestMethod -Uri "https://your-domain/v1/emails" `
                  -Method POST `
                  -Headers $headers `
                  -Body $body

响应格式

成功:{"code":200,"data":{"message":"sent"}}

失败:{"code":500,"message":"some emails failed: ..."}

发信记录

每次 API 发信均会记录日志,可在控制台「提交记录 → API 发信记录」查看,也可在「数据统计」页面查看 API 发信统计。

常见 API

公开接口

  • POST /api/auth/login - 密码登录
  • POST /api/auth/login-code - 邮箱验证码登录
  • POST /api/auth/send-code - 发送邮箱验证码
  • POST /api/auth/register - 邮箱验证码注册
  • POST /f/:token - 静态表单提交
  • GET /verify/:token - 邮箱验证

需鉴权接口

需在请求头添加 Authorization: Bearer <token>

  • GET /api/auth/me - 获取当前用户信息
  • POST /api/auth/change-password - 修改密码
  • GET /api/forms - 表单列表(管理员可传 user_id 筛选)
  • POST /api/forms - 创建表单
  • PUT /api/forms/:id - 更新表单
  • DELETE /api/forms/:id - 删除表单
  • POST /api/forms/:id/resend-verify - 重发验证邮件
  • GET /api/channels - 渠道列表
  • GET /api/channels/bindable - 可绑定渠道
  • POST /api/channels - 创建渠道
  • POST /api/channels/:id/test - 测试渠道连通性
  • GET /api/submissions?page=1&limit=20 - 分页查询提交记录
  • DELETE /api/submissions/:id - 删除提交记录
  • POST /api/submissions/batch-delete - 批量删除({"ids":[1,2,3]}
  • GET /api/submissions/export - CSV 导出
  • GET /api/stats/overview - 数据统计总览
  • GET /api/stats/daily?days=30 - 每日趋势
  • GET /api/stats/forms - 表单排行
  • GET /api/stats/channels - 渠道统计
  • GET /api/stats/api - API 发信统计
  • GET /api/apikeys - API Key 列表
  • POST /api/apikeys - 创建 API Key({"name":"...","channel_id":0}
  • PUT /api/apikeys/:id - 修改 API Key 渠道绑定
  • DELETE /api/apikeys/:id - 删除 API Key
  • GET /api/api-logs - API 发信日志(可传 api_key_idpage
  • GET /api/mail-queue - 邮件队列列表(管理员)

API Key 鉴权接口

需在请求头添加 Authorization: Bearer fm_xxx(API Key 格式)