5b4774e9c1
- 新增完整的Go客户端库实现,支持邮件服务器API的各种操作 - 实现账户管理、签名管理、邮件发送、审计、配额、通道等功能模块 - 提供ServiceAuth和AppAuth两种认证模式的客户端 - 添加详细的README文档,包含安装指南和使用示例 - 配置.gitignore文件以忽略构建产物和开发工具配置 - 支持分页查询、错误处理和客户端选项配置
485 lines
14 KiB
Go
485 lines
14 KiB
Go
package emailcli
|
|
|
|
import "time"
|
|
|
|
// PaginationResult is the generic paginated response wrapper.
|
|
type PaginationResult[T any] struct {
|
|
List []T `json:"list"`
|
|
Total int64 `json:"total"`
|
|
Page int `json:"page"`
|
|
PageSize int `json:"page_size"`
|
|
}
|
|
|
|
type PaginationQuery struct {
|
|
Page int `json:"page,omitempty"`
|
|
PageSize int `json:"page_size,omitempty"`
|
|
}
|
|
|
|
// --- GormModel fields ---
|
|
|
|
type GormModel struct {
|
|
ID uint `json:"ID"`
|
|
CreatedAt time.Time `json:"CreatedAt"`
|
|
UpdatedAt time.Time `json:"UpdatedAt"`
|
|
DeletedAt *time.Time `json:"DeletedAt"`
|
|
}
|
|
|
|
// --- Account ---
|
|
|
|
type Account struct {
|
|
GormModel
|
|
UserID int `json:"user_id"`
|
|
Name string `json:"name"`
|
|
AppKey string `json:"app_key"`
|
|
Status int8 `json:"status"`
|
|
AuditMode int8 `json:"audit_mode"`
|
|
RateLimit int `json:"rate_limit"`
|
|
AllowedChannels string `json:"allowed_channels"`
|
|
DefaultSignatureID *uint `json:"default_signature_id"`
|
|
Remark string `json:"remark"`
|
|
}
|
|
|
|
type CreateAccountReq struct {
|
|
UserID int `json:"user_id"`
|
|
Name string `json:"name"`
|
|
AuditMode *int8 `json:"audit_mode,omitempty"`
|
|
RateLimit *int `json:"rate_limit,omitempty"`
|
|
Remark string `json:"remark,omitempty"`
|
|
}
|
|
|
|
type CreateAccountResp struct {
|
|
ID uint `json:"id"`
|
|
AppKey string `json:"app_key"`
|
|
AppSecret string `json:"app_secret"`
|
|
Name string `json:"name"`
|
|
}
|
|
|
|
type UpdateAccountReq struct {
|
|
Name *string `json:"name,omitempty"`
|
|
Status *int8 `json:"status,omitempty"`
|
|
AuditMode *int8 `json:"audit_mode,omitempty"`
|
|
RateLimit *int `json:"rate_limit,omitempty"`
|
|
AllowedChannels *string `json:"allowed_channels,omitempty"`
|
|
DefaultSignatureID *uint `json:"default_signature_id,omitempty"`
|
|
Remark *string `json:"remark,omitempty"`
|
|
}
|
|
|
|
type AccountListQuery struct {
|
|
PaginationQuery
|
|
UserID *int `json:"user_id,omitempty"`
|
|
Status *int8 `json:"status,omitempty"`
|
|
Keyword string `json:"keyword,omitempty"`
|
|
}
|
|
|
|
type ResetSecretResp struct {
|
|
AppSecret string `json:"app_secret"`
|
|
}
|
|
|
|
// --- Signature ---
|
|
|
|
type Signature struct {
|
|
GormModel
|
|
UserID int `json:"user_id"`
|
|
AccountID *uint `json:"account_id"`
|
|
Title string `json:"title"`
|
|
EnglishName string `json:"english_name"`
|
|
Content string `json:"content"`
|
|
Applicant string `json:"applicant"`
|
|
ApplicantInfo string `json:"applicant_info"`
|
|
Status int8 `json:"status"`
|
|
RejectReason string `json:"reject_reason"`
|
|
Auditor string `json:"auditor"`
|
|
AuditedAt *time.Time `json:"audited_at"`
|
|
}
|
|
|
|
type CreateSignatureReq struct {
|
|
UserID int `json:"user_id"`
|
|
AccountID *uint `json:"account_id,omitempty"`
|
|
Title string `json:"title"`
|
|
EnglishName string `json:"english_name"`
|
|
Content string `json:"content,omitempty"`
|
|
Applicant string `json:"applicant,omitempty"`
|
|
ApplicantInfo string `json:"applicant_info,omitempty"`
|
|
}
|
|
|
|
type UpdateSignatureReq struct {
|
|
Title *string `json:"title,omitempty"`
|
|
EnglishName *string `json:"english_name,omitempty"`
|
|
Content *string `json:"content,omitempty"`
|
|
Applicant *string `json:"applicant,omitempty"`
|
|
ApplicantInfo *string `json:"applicant_info,omitempty"`
|
|
}
|
|
|
|
type AuditSignatureReq struct {
|
|
Status int8 `json:"status"`
|
|
RejectReason string `json:"reject_reason,omitempty"`
|
|
}
|
|
|
|
type SignatureListQuery struct {
|
|
PaginationQuery
|
|
AccountID *uint `json:"account_id,omitempty"`
|
|
Status *int8 `json:"status,omitempty"`
|
|
UserID *int `json:"user_id,omitempty"`
|
|
Keyword string `json:"keyword,omitempty"`
|
|
}
|
|
|
|
// --- Mail ---
|
|
|
|
type SendMailReq struct {
|
|
To []string `json:"to"`
|
|
Cc []string `json:"cc,omitempty"`
|
|
Bcc []string `json:"bcc,omitempty"`
|
|
Subject string `json:"subject"`
|
|
Body string `json:"body"`
|
|
ContentType string `json:"content_type,omitempty"`
|
|
Channel string `json:"channel"`
|
|
SignatureID *uint `json:"signature_id,omitempty"`
|
|
SignatureTitle string `json:"signature_title,omitempty"`
|
|
Attachments []AttachmentItem `json:"attachments,omitempty"`
|
|
}
|
|
|
|
type AttachmentItem struct {
|
|
Filename string `json:"filename"`
|
|
Content string `json:"content"`
|
|
}
|
|
|
|
type SendMailResp struct {
|
|
MailLogID uint `json:"mail_log_id"`
|
|
Status string `json:"status"`
|
|
}
|
|
|
|
// --- Mail Log ---
|
|
|
|
type MailLog struct {
|
|
GormModel
|
|
UserID int `json:"user_id"`
|
|
AccountID uint `json:"account_id"`
|
|
ChannelID *uint `json:"channel_id"`
|
|
SenderAccountID *uint `json:"sender_account_id"`
|
|
SignatureID *uint `json:"signature_id"`
|
|
MessageID string `json:"message_id"`
|
|
FromAddress string `json:"from_address"`
|
|
ToAddresses string `json:"to_addresses"`
|
|
CcAddresses string `json:"cc_addresses"`
|
|
BccAddresses string `json:"bcc_addresses"`
|
|
Subject string `json:"subject"`
|
|
ContentType string `json:"content_type"`
|
|
HasAttachment bool `json:"has_attachment"`
|
|
SourceIP string `json:"source_ip"`
|
|
SourceType string `json:"source_type"`
|
|
Status int8 `json:"status"`
|
|
RetryCount int `json:"retry_count"`
|
|
MaxRetry int `json:"max_retry"`
|
|
ErrorMessage string `json:"error_message"`
|
|
SentAt *time.Time `json:"sent_at"`
|
|
}
|
|
|
|
type MailLogListQuery struct {
|
|
PaginationQuery
|
|
UserID *int `json:"user_id,omitempty"`
|
|
AccountID *uint `json:"account_id,omitempty"`
|
|
Status *int8 `json:"status,omitempty"`
|
|
StartDate string `json:"start_date,omitempty"`
|
|
EndDate string `json:"end_date,omitempty"`
|
|
To string `json:"to,omitempty"`
|
|
Keyword string `json:"keyword,omitempty"`
|
|
}
|
|
|
|
type MailLogDetail struct {
|
|
Log MailLog `json:"log"`
|
|
Body string `json:"body"`
|
|
}
|
|
|
|
type MailStatItem struct {
|
|
Status int8 `json:"status"`
|
|
Count int64 `json:"count"`
|
|
}
|
|
|
|
// --- Quota ---
|
|
|
|
type MailQuota struct {
|
|
GormModel
|
|
UserID int `json:"user_id"`
|
|
AccountID uint `json:"account_id"`
|
|
QuotaType int8 `json:"quota_type"`
|
|
Total int `json:"total"`
|
|
Used int `json:"used"`
|
|
ExpireAt *time.Time `json:"expire_at"`
|
|
CycleUnit string `json:"cycle_unit"`
|
|
CycleResetAt *time.Time `json:"cycle_reset_at"`
|
|
Status int8 `json:"status"`
|
|
}
|
|
|
|
type CreateQuotaReq struct {
|
|
AccountID uint `json:"account_id"`
|
|
QuotaType int8 `json:"quota_type"`
|
|
Total int `json:"total"`
|
|
ExpireAt string `json:"expire_at,omitempty"`
|
|
CycleUnit string `json:"cycle_unit,omitempty"`
|
|
CycleResetAt string `json:"cycle_reset_at,omitempty"`
|
|
}
|
|
|
|
type UpdateQuotaReq struct {
|
|
Total *int `json:"total,omitempty"`
|
|
Status *int8 `json:"status,omitempty"`
|
|
}
|
|
|
|
type QuotaListQuery struct {
|
|
PaginationQuery
|
|
AccountID *uint `json:"account_id,omitempty"`
|
|
UserID *int `json:"user_id,omitempty"`
|
|
Status *int8 `json:"status,omitempty"`
|
|
}
|
|
|
|
type QuotaSummary struct {
|
|
AccountID uint `json:"account_id"`
|
|
TotalQuota int `json:"total_quota"`
|
|
TotalUsed int `json:"total_used"`
|
|
TotalRemaining int `json:"total_remaining"`
|
|
Details []MailQuota `json:"details"`
|
|
}
|
|
|
|
// --- Channel ---
|
|
|
|
type Channel struct {
|
|
GormModel
|
|
Name string `json:"name"`
|
|
Code string `json:"code"`
|
|
Description string `json:"description"`
|
|
Strategy string `json:"strategy"`
|
|
Status int8 `json:"status"`
|
|
}
|
|
|
|
type CreateChannelReq struct {
|
|
Name string `json:"name"`
|
|
Code string `json:"code"`
|
|
Description string `json:"description,omitempty"`
|
|
Strategy string `json:"strategy,omitempty"`
|
|
}
|
|
|
|
type UpdateChannelReq struct {
|
|
Name *string `json:"name,omitempty"`
|
|
Description *string `json:"description,omitempty"`
|
|
Strategy *string `json:"strategy,omitempty"`
|
|
Status *int8 `json:"status,omitempty"`
|
|
}
|
|
|
|
type ChannelListQuery struct {
|
|
PaginationQuery
|
|
Status *int8 `json:"status,omitempty"`
|
|
Keyword string `json:"keyword,omitempty"`
|
|
}
|
|
|
|
// --- Sender Account ---
|
|
|
|
type SenderAccount struct {
|
|
GormModel
|
|
ChannelID uint `json:"channel_id"`
|
|
Name string `json:"name"`
|
|
SmtpHost string `json:"smtp_host"`
|
|
SmtpPort int `json:"smtp_port"`
|
|
SmtpUser string `json:"smtp_user"`
|
|
SmtpSSL bool `json:"smtp_ssl"`
|
|
FromName string `json:"from_name"`
|
|
FromAddress string `json:"from_address"`
|
|
DailyLimit int `json:"daily_limit"`
|
|
DailySent int `json:"daily_sent"`
|
|
Weight int `json:"weight"`
|
|
Status int8 `json:"status"`
|
|
LastCheckAt *time.Time `json:"last_check_at"`
|
|
LastCheckResult string `json:"last_check_result"`
|
|
}
|
|
|
|
type CreateSenderReq struct {
|
|
Name string `json:"name"`
|
|
SmtpHost string `json:"smtp_host"`
|
|
SmtpPort int `json:"smtp_port"`
|
|
SmtpUser string `json:"smtp_user"`
|
|
SmtpPassword string `json:"smtp_password"`
|
|
SmtpSSL *bool `json:"smtp_ssl,omitempty"`
|
|
FromName string `json:"from_name,omitempty"`
|
|
FromAddress string `json:"from_address"`
|
|
DailyLimit *int `json:"daily_limit,omitempty"`
|
|
Weight *int `json:"weight,omitempty"`
|
|
}
|
|
|
|
type UpdateSenderReq struct {
|
|
Name *string `json:"name,omitempty"`
|
|
SmtpHost *string `json:"smtp_host,omitempty"`
|
|
SmtpPort *int `json:"smtp_port,omitempty"`
|
|
SmtpUser *string `json:"smtp_user,omitempty"`
|
|
SmtpPassword *string `json:"smtp_password,omitempty"`
|
|
SmtpSSL *bool `json:"smtp_ssl,omitempty"`
|
|
FromName *string `json:"from_name,omitempty"`
|
|
FromAddress *string `json:"from_address,omitempty"`
|
|
DailyLimit *int `json:"daily_limit,omitempty"`
|
|
Weight *int `json:"weight,omitempty"`
|
|
Status *int8 `json:"status,omitempty"`
|
|
}
|
|
|
|
type SenderListQuery struct {
|
|
PaginationQuery
|
|
Status *int8 `json:"status,omitempty"`
|
|
Keyword string `json:"keyword,omitempty"`
|
|
}
|
|
|
|
// --- Audit ---
|
|
|
|
type MailAudit struct {
|
|
GormModel
|
|
MailLogID uint `json:"mail_log_id"`
|
|
UserID int `json:"user_id"`
|
|
AccountID uint `json:"account_id"`
|
|
AuditType int8 `json:"audit_type"`
|
|
Action int8 `json:"action"`
|
|
RejectReason string `json:"reject_reason"`
|
|
HitRules string `json:"hit_rules"`
|
|
Auditor string `json:"auditor"`
|
|
AuditedAt time.Time `json:"audited_at"`
|
|
}
|
|
|
|
type AuditPendingQuery struct {
|
|
PaginationQuery
|
|
UserID *int `json:"user_id,omitempty"`
|
|
AccountID *uint `json:"account_id,omitempty"`
|
|
Keyword string `json:"keyword,omitempty"`
|
|
}
|
|
|
|
type AuditLogQuery struct {
|
|
PaginationQuery
|
|
AuditType *int8 `json:"audit_type,omitempty"`
|
|
Action *int8 `json:"action,omitempty"`
|
|
UserID *int `json:"user_id,omitempty"`
|
|
StartDate string `json:"start_date,omitempty"`
|
|
EndDate string `json:"end_date,omitempty"`
|
|
}
|
|
|
|
type AuditRejectReq struct {
|
|
RejectReason string `json:"reject_reason"`
|
|
}
|
|
|
|
type BatchAuditApproveReq struct {
|
|
MailLogIDs []uint `json:"mail_log_ids"`
|
|
}
|
|
|
|
type BatchAuditRejectReq struct {
|
|
MailLogIDs []uint `json:"mail_log_ids"`
|
|
RejectReason string `json:"reject_reason"`
|
|
}
|
|
|
|
type AuditStats struct {
|
|
PendingCount int64 `json:"pending_count"`
|
|
TodayDetails []AuditDetailCount `json:"today_details"`
|
|
}
|
|
|
|
type AuditDetailCount struct {
|
|
AuditType int8 `json:"audit_type"`
|
|
Action int8 `json:"action"`
|
|
Count int64 `json:"count"`
|
|
}
|
|
|
|
// --- Audit Rule ---
|
|
|
|
type AuditRule struct {
|
|
GormModel
|
|
Name string `json:"name"`
|
|
RuleType string `json:"rule_type"`
|
|
Target string `json:"target"`
|
|
Condition string `json:"condition"`
|
|
Action int8 `json:"action"`
|
|
Priority int `json:"priority"`
|
|
Status int8 `json:"status"`
|
|
Remark string `json:"remark"`
|
|
}
|
|
|
|
type CreateAuditRuleReq struct {
|
|
Name string `json:"name"`
|
|
RuleType string `json:"rule_type"`
|
|
Target string `json:"target"`
|
|
Condition string `json:"condition"`
|
|
Action int8 `json:"action"`
|
|
Priority *int `json:"priority,omitempty"`
|
|
Remark string `json:"remark,omitempty"`
|
|
}
|
|
|
|
type UpdateAuditRuleReq struct {
|
|
Name *string `json:"name,omitempty"`
|
|
RuleType *string `json:"rule_type,omitempty"`
|
|
Target *string `json:"target,omitempty"`
|
|
Condition *string `json:"condition,omitempty"`
|
|
Action *int8 `json:"action,omitempty"`
|
|
Priority *int `json:"priority,omitempty"`
|
|
Status *int8 `json:"status,omitempty"`
|
|
Remark *string `json:"remark,omitempty"`
|
|
}
|
|
|
|
type TestAuditRuleReq struct {
|
|
Subject string `json:"subject,omitempty"`
|
|
Body string `json:"body,omitempty"`
|
|
To []string `json:"to,omitempty"`
|
|
From string `json:"from,omitempty"`
|
|
AccountID uint `json:"account_id,omitempty"`
|
|
}
|
|
|
|
type TestAuditRuleResp struct {
|
|
Action string `json:"action"`
|
|
HitRules []HitRuleEntry `json:"hit_rules"`
|
|
}
|
|
|
|
type HitRuleEntry struct {
|
|
RuleID uint `json:"rule_id"`
|
|
RuleName string `json:"rule_name"`
|
|
RuleType string `json:"rule_type"`
|
|
}
|
|
|
|
// --- Queue ---
|
|
|
|
type QueueStatusData struct {
|
|
Queues map[string]int `json:"queues"`
|
|
DelayQueue int `json:"delay_queue"`
|
|
}
|
|
|
|
type QueuePendingQuery struct {
|
|
PaginationQuery
|
|
ChannelID *uint `json:"channel_id,omitempty"`
|
|
UserID *int `json:"user_id,omitempty"`
|
|
AccountID *uint `json:"account_id,omitempty"`
|
|
}
|
|
|
|
// --- Check ---
|
|
|
|
type CheckLog struct {
|
|
ID uint `json:"id"`
|
|
SenderAccountID uint `json:"sender_account_id"`
|
|
VerificationCode string `json:"verification_code"`
|
|
SentAt string `json:"sent_at"`
|
|
Received bool `json:"received"`
|
|
ReceivedAt *string `json:"received_at"`
|
|
LatencyMs int `json:"latency_ms"`
|
|
ErrorMessage string `json:"error_message"`
|
|
CreatedAt string `json:"created_at"`
|
|
}
|
|
|
|
type CheckLogQuery struct {
|
|
PaginationQuery
|
|
SenderAccountID *uint `json:"sender_account_id,omitempty"`
|
|
StartDate string `json:"start_date,omitempty"`
|
|
EndDate string `json:"end_date,omitempty"`
|
|
}
|
|
|
|
type SenderHealth struct {
|
|
SenderAccountID uint `json:"sender_account_id"`
|
|
Name string `json:"name"`
|
|
FromAddress string `json:"from_address"`
|
|
Status int8 `json:"status"`
|
|
LastCheckResult string `json:"last_check_result"`
|
|
TotalChecks int64 `json:"total_checks"`
|
|
SuccessChecks int64 `json:"success_checks"`
|
|
}
|
|
|
|
type TriggerCheckResp struct {
|
|
Result string `json:"result"`
|
|
Error string `json:"error,omitempty"`
|
|
CheckLog *CheckLog `json:"check_log,omitempty"`
|
|
}
|