Files
shiran fe43b9bdce docs(README): 更新文档为中文并完善API参考
- 将README从英文翻译为中文
- 添加详细的API参考文档,包括所有管理接口和枚举值说明
- 补充安装、快速开始、认证方式等使用指南

refactor(client): 优化客户端代码结构并添加详细注释

- 为所有API方法添加中文注释和使用说明
- 改进Client结构体和Option配置的设计
- 统一错误处理和响应结构的文档说明
2026-04-18 15:54:19 +08:00

15 KiB
Raw Permalink Blame History

email-serverr-cli

Email Server API 的 Go 客户端库。提供管理端(ServiceAuth)与发件端(AppAuth)两种客户端, 覆盖邮件发送、账号、签名、配额、通道/发信、审核、队列、健康检查等全部后端能力。

  • 模块路径: gitea.s1f.ren/shiran/email-serverr-cli
  • 依赖: 仅使用标准库 net/httpencoding/json,无第三方依赖
  • 风格: 对每一类资源一个文件,请求/响应类型在 types.go,底层请求在 client.go

安装

go get gitea.s1f.ren/shiran/email-serverr-cli
import emailcli "gitea.s1f.ren/shiran/email-serverr-cli"

快速开始

管理客户端(ServiceAuth

client := emailcli.NewServiceClient(
    "https://your-server.com",
    "your-service-token",
)

accounts, err := client.ListAccounts(context.Background(), emailcli.AccountListQuery{
    PaginationQuery: emailcli.PaginationQuery{Page: 1, PageSize: 20},
})

发件客户端(AppAuth

client := emailcli.NewAppClient(
    "https://your-server.com",
    "your-app-key",
    "your-app-secret",
)

resp, err := client.SendMail(context.Background(), emailcli.SendMailReq{
    To:      []string{"recipient@example.com"},
    Subject: "Hello",
    Body:    "<h1>Hello World</h1>",
    // Channel 可选:不传时优先使用账号默认通道,其次使用允许通道列表首个可用项
})

客户端选项

client := emailcli.NewServiceClient(baseURL, token,
    emailcli.WithTimeout(60*time.Second),
    emailcli.WithHTTPClient(customClient),
)

认证方式

模式 构造函数 请求头 适用范围
ServiceAuth NewServiceClient Authorization: Bearer <token> 所有 /api/v1 管理接口
AppAuth NewAppClient X-App-Key + X-App-Secret POST /api/v1/mail/send

枚举值说明

Account.Status(账号状态)

含义
0 禁用
1 启用

Account.AuditMode(审核模式)

含义
0 免审核(直接入队)
1 自动(按规则判定)
2 人工(待审核)

Signature.Status(签名状态)

含义
0 待审核
1 已通过
2 已驳回

MailLog.Status(邮件状态)

含义
0 待审核
1 排队中
2 发送中
3 成功
4 失败
5 放弃
6 驳回

MailQuota.QuotaType(配额类型)

含义
1 总量配额(total 为总发送上限)
2 周期配额(到期自动重置)

MailQuota.CycleUnit(配额周期单位)

quota_type=2 时生效,取值:dayweekmonthyear

MailQuota.Status

含义
0 禁用
1 启用

Channel.Status / SenderAccount.Status

含义
0 禁用
1 启用

Channel.Strategy(发信挑选策略)

含义
round_robin 轮询(默认)
weight weight 加权随机
least_used 今日发送数最少优先

AuditRule.Action(规则动作)

含义
1 自动通过
2 自动驳回
3 转人工

AuditRule.RuleType / Target(规则类型与目标)

  • RuleType 取值: keywordregexdomain
  • Target 取值: subjectbodytofrom

MailAudit.AuditType(审核来源)

含义
1 自动
2 人工

MailAudit.Action(审核动作)

含义
1 通过
2 驳回

SendMailReq.ContentType

取值:text/plain(默认)、text/html


API 参考

所有管理接口挂载在 /api/v1 下。以下按功能模块分组,并给出方法签名、HTTP 路径与关键参数说明。

一、发送邮件(AppAuth

SendMail(ctx, req SendMailReq) -> *SendMailResp

POST /api/v1/mail/send

SendMailReq 字段:

字段 类型 必填 说明
To []string 收件人列表,至少 1 个
Cc []string 抄送
Bcc []string 密送
Subject string 主题
Body string 正文
ContentType string 默认 text/html
Channel string 通道 code。为空时按 账号默认通道 → 账号允许通道首个可用 顺序自动解析
SignatureID *uint 指定签名 ID(用户必须拥有且已审核)
SignatureTitle string 按 title + user_id 选择签名;未传则使用默认签名
Attachments []AttachmentItem 附件(filename + base64 content

SendMailResp 字段:

字段 类型 说明
MailLogID uint 创建的邮件日志 ID
Status string queued / pending_audit / rejected

二、账号管理(ServiceAuth

CreateAccount(ctx, req CreateAccountReq) -> *CreateAccountResp

POST /api/v1/accounts

字段 类型 必填 说明
UserID int 关联用户 ID
Name string 账号名称(≤100
AuditMode *int8 审核模式枚举,默认 0
RateLimit *int 频率限制(封/分钟),0 表示不限
DefaultChannelID *uint 默认发件通道 ID
AllowedChannels string 允许发件通道 ID 列表的 JSON 字符串,例如 "[1,2]"。为空时视作不限制
Remark string 备注

返回 CreateAccountResp(首次创建返回明文 AppSecret):

{ "id": 1, "app_key": "...", "app_secret": "只在此次展示", "name": "..." }

ListAccounts(ctx, q AccountListQuery) -> *PaginationResult[Account]

GET /api/v1/accounts?page=&page_size=&user_id=&status=&keyword=

参数 类型 说明
Page/PageSize int 分页,PageSize 默认 20
UserID *int 按用户筛选
Status *int8 账号状态(0/1
Keyword string 模糊匹配 nameremark

GetAccount(ctx, id uint) -> *Account

GET /api/v1/accounts/{id}

UpdateAccount(ctx, id uint, req UpdateAccountReq) -> *Account

PUT /api/v1/accounts/{id} 所有字段均为可选指针,只更新已传字段。

字段 类型 说明
Name *string
Status *int8 启用/禁用
AuditMode *int8
RateLimit *int
DefaultChannelID *uint 默认发件通道
AllowedChannels *string 允许发件通道 ID 列表 JSON
DefaultSignatureID *uint 默认签名 ID
Remark *string

DeleteAccount(ctx, id uint) error

DELETE /api/v1/accounts/{id}

ResetAccountSecret(ctx, id uint) -> *ResetSecretResp

POST /api/v1/accounts/{id}/reset-secret 返回新生成的明文 AppSecret


三、签名管理(ServiceAuth

CreateSignature(ctx, req CreateSignatureReq) -> *Signature

POST /api/v1/signatures

字段 类型 必填 说明
UserID int
AccountID *uint 绑定账号,为空表示用户全局签名
Title string 中文抬头
EnglishName string 英文标识(用于组装 From 地址)
Content string HTML 签名内容
Applicant string 申请人
ApplicantInfo string 申请说明

新建默认为 Status=0(待审核)。

ListSignatures(ctx, q SignatureListQuery) -> *PaginationResult[Signature]

GET /api/v1/signatures?page=&page_size=&user_id=&account_id=&status=&keyword=

GetSignature(ctx, id uint) / UpdateSignature / DeleteSignature

GET|PUT|DELETE /api/v1/signatures/{id}

AuditSignature(ctx, id uint, req AuditSignatureReq)

POST /api/v1/signatures/{id}/audit

字段 类型 说明
Action int8 1=通过,2=驳回
RejectReason string 驳回时建议填写
Auditor string 审核人标识

四、邮件日志(ServiceAuth

ListMailLogs(ctx, q MailLogListQuery) -> *PaginationResult[MailLog]

GET /api/v1/mail-logs

参数 类型 说明
UserID *int
AccountID *uint
Status *int8 MailLog.Status 枚举
StartDate/EndDate string YYYY-MM-DD
To string 收件人精确匹配
Keyword string 模糊匹配主题或收件人

GetMailLog(ctx, id uint) -> *MailLogDetail

GET /api/v1/mail-logs/{id} 返回 MailLog + 正文 Body

GetMailStats(ctx) -> []MailStatItem

GET /api/v1/mail-logs/statsStatus 分组的邮件数统计。


五、配额管理(ServiceAuth

CreateQuota(ctx, req CreateQuotaReq) -> *MailQuota

POST /api/v1/quotas

字段 类型 必填 说明
UserID int
AccountID uint
QuotaType int8 1=总量,2=周期
Total int 额度上限
ExpireAt string YYYY-MM-DD HH:mm:ss
CycleUnit string day / week / month / year
CycleResetAt string 周期起始时间

ListQuotas(ctx, q QuotaListQuery) · GetQuotaSummary(ctx, accountID) · UpdateQuota(ctx, id, req) · DeleteQuota(ctx, id)

UpdateQuotaReq 支持局部更新 TotalStatusExpireAtCycleUnitCycleResetAt

QuotaListQuery 过滤参数:UserIDAccountIDQuotaTypeStatus


六、通道与发信账号(ServiceAuth

通道 Channel

  • CreateChannel(ctx, req CreateChannelReq) -> *ChannelPOST /api/v1/channels
  • ListChannels(ctx, q ChannelListQuery) -> *PaginationResult[Channel]GET /api/v1/channels
  • UpdateChannel(ctx, id, req UpdateChannelReq) -> *ChannelPUT /api/v1/channels/{id}
  • DeleteChannel(ctx, id uint) errorDELETE /api/v1/channels/{id}

CreateChannelReq 字段:

字段 类型 必填 说明
Code string 唯一标识(发送邮件用)
Name string
Description string
Strategy string Channel.Strategy 枚举

发信账号 SenderAccount

  • CreateSender(ctx, channelID uint, req CreateSenderReq) -> *SenderAccountPOST /api/v1/channels/{channelID}/senders
  • ListSendersByChannel(ctx, channelID, q SenderListQuery) -> *PaginationResult[SenderAccount]GET /api/v1/channels/{channelID}/senders
  • UpdateSender(ctx, id uint, req UpdateSenderReq) -> *SenderAccountPUT /api/v1/senders/{id}
  • DeleteSender(ctx, id uint) errorDELETE /api/v1/senders/{id}

CreateSenderReq 关键字段:NameSmtpHostSmtpPortSmtpUserSmtpPasswordSmtpSSLFromNameFromAddressDailyLimitWeight


七、审核(ServiceAuth

  • ListAuditPending(ctx, q AuditPendingQuery) -> *PaginationResult[MailLog]GET /api/v1/audits/pending
  • GetAuditPendingDetail(ctx, id uint) -> *MailLogDetailGET /api/v1/audits/pending/{id}
  • ApproveAudit(ctx, id uint) errorPOST /api/v1/audits/{id}/approve
  • RejectAudit(ctx, id uint, req AuditRejectReq) errorPOST /api/v1/audits/{id}/reject
  • BatchApproveAudit(ctx, req BatchAuditApproveReq) errorPOST /api/v1/audits/batch/approve
  • BatchRejectAudit(ctx, req BatchAuditRejectReq) errorPOST /api/v1/audits/batch/reject
  • ListAuditLogs(ctx, q AuditLogQuery) -> *PaginationResult[MailAudit]GET /api/v1/audits/logs
  • GetAuditStats(ctx) -> *AuditStatsGET /api/v1/audits/stats

AuditPendingQuery 过滤:AccountIDUserIDKeywordAuditLogQuery 过滤:AccountIDUserIDActionAuditTypeStartDateEndDate


八、审核规则(ServiceAuth

  • CreateAuditRule(ctx, req CreateAuditRuleReq) -> *AuditRulePOST /api/v1/audit-rules
  • ListAuditRules(ctx) -> []AuditRuleGET /api/v1/audit-rules
  • GetAuditRule(ctx, id uint) -> *AuditRuleGET /api/v1/audit-rules/{id}
  • UpdateAuditRule(ctx, id uint, req UpdateAuditRuleReq) -> *AuditRulePUT /api/v1/audit-rules/{id}
  • DeleteAuditRule(ctx, id uint) errorDELETE /api/v1/audit-rules/{id}
  • UpdateAuditRuleStatus(ctx, id uint, status int8) -> *AuditRulePUT /api/v1/audit-rules/{id}/status
  • TestAuditRule(ctx, req TestAuditRuleReq) -> *TestAuditRuleRespPOST /api/v1/audit-rules/test

CreateAuditRuleReq 字段:

字段 类型 必填 说明
Name string
RuleType string AuditRule.RuleType 枚举
Target string AuditRule.Target 枚举
Condition string 关键词或正则表达式
Action int8 AuditRule.Action 枚举
Priority int 数字越大优先级越高
Remark string

九、队列(ServiceAuth

  • GetQueueStatus(ctx) -> *QueueStatusDataGET /api/v1/queue/status
  • ListQueuePending(ctx, q QueuePendingQuery) -> *PaginationResult[MailLog]GET /api/v1/queue/pending
  • CancelQueueItem(ctx, mailLogID uint) errorPOST /api/v1/queue/{mailLogID}/cancel
  • RetryQueueItem(ctx, mailLogID uint) errorPOST /api/v1/queue/{mailLogID}/retry

QueueStatusData 返回各通道队列长度与延迟队列长度:

type QueueStatusData struct {
    Queues     map[string]int64 `json:"queues"`      // key = channel code
    DelayQueue int64            `json:"delay_queue"`
}

十、健康检查(ServiceAuth

  • ListCheckLogs(ctx, q CheckLogQuery) -> *PaginationResult[CheckLog]GET /api/v1/check-logs
  • GetCheckSummary(ctx) -> []SenderHealthGET /api/v1/check-logs/summary
  • TriggerCheck(ctx, senderAccountID uint) -> *TriggerCheckRespPOST /api/v1/check-logs/trigger/{senderAccountID}

CheckLogQuery 过滤:SenderAccountIDReceivedStartDateEndDate


统一返回结构

后端所有接口统一使用:

{ "code": 200, "message": "ok", "data": { /* 业务数据 */ } }

SDK 内部会解包 data 并在非 200 时返回 *APIError

resp, err := client.SendMail(ctx, req)
if err != nil {
    var apiErr *emailcli.APIError
    if errors.As(err, &apiErr) {
        fmt.Printf("API error: code=%d message=%s\n", apiErr.Code, apiErr.Message)
    }
}

分页接口统一包装:

type PaginationResult[T any] struct {
    List     []T   `json:"list"`
    Total    int64 `json:"total"`
    Page     int   `json:"page"`
    PageSize int   `json:"page_size"`
}

License

MIT