feat: 添加邮件服务器客户端库的基础功能
- 新增完整的Go客户端库实现,支持邮件服务器API的各种操作 - 实现账户管理、签名管理、邮件发送、审计、配额、通道等功能模块 - 提供ServiceAuth和AppAuth两种认证模式的客户端 - 添加详细的README文档,包含安装指南和使用示例 - 配置.gitignore文件以忽略构建产物和开发工具配置 - 支持分页查询、错误处理和客户端选项配置
This commit is contained in:
@@ -0,0 +1,484 @@
|
||||
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"`
|
||||
}
|
||||
Reference in New Issue
Block a user