# sms-server-cli 短信服务 Go SDK,用于对接 [sms-server](https://gitea.s1f.ren/shiran/sms-server) 的 HTTP API。 ``` 模块路径: gitea.s1f.ren/shiran/sms-server-cli Go 版本: 1.21+ ``` ## 安装 ```bash go get gitea.s1f.ren/shiran/sms-server-cli ``` ## 快速开始 ### 使用 ServiceToken(服务端对服务端) ```go package main import ( "context" "fmt" "log" smscli "gitea.s1f.ren/shiran/sms-server-cli" ) func main() { client := smscli.NewServiceClient("https://sms.example.com", "your-service-token") ctx := context.Background() // 创建签名 sig, err := client.CreateSignature(ctx, smscli.CreateSignatureReq{ Title: "我的应用", ApplicantName: "张三", }) if err != nil { log.Fatal(err) } fmt.Printf("签名 ID: %d\n", sig.ID) // 批量发送短信 resp, err := client.SendBatch(ctx, smscli.SendBatchReq{ SignatureID: sig.ID, TemplateID: 1, Params: map[string]string{"code": "123456"}, Phones: []string{"13800138000"}, }) if err != nil { log.Fatal(err) } fmt.Printf("消息 ID: %s, 计费条数: %d\n", resp.MsgID, resp.FeeCount) } ``` ### 使用 UserToken(用户令牌) ```go client := smscli.NewUserTokenClient("https://sms.example.com", "your-user-token") resp, err := client.SendBatch(ctx, smscli.SendBatchReq{ SignatureID: 1, TemplateID: 2, Params: map[string]string{"code": "654321"}, Phones: []string{"13900139000"}, }) ``` ## 认证方式 | 方式 | 构造函数 | Header | 适用场景 | |------|---------|--------|---------| | ServiceAuth | `NewServiceClient(baseURL, token)` | `Authorization: ServiceToken ` | 服务端对服务端调用 | | BearerAuth | `NewBearerClient(baseURL, token)` | `Authorization: Bearer ` | 已登录用户调用 | | UserTokenAuth | `NewUserTokenClient(baseURL, token)` | `Authorization: UserToken ` | 用户令牌调用 | ## 枚举值 ### ReviewStatus(审核状态) | 常量 | 值 | 说明 | |------|---|------| | `ReviewStatusDraft` | 0 | 草稿 | | `ReviewStatusReviewing` | 1 | 审核中 | | `ReviewStatusApproved` | 2 | 已通过 | | `ReviewStatusRejected` | 3 | 已驳回 | ### QuotaType(额度类型) | 常量 | 值 | 说明 | |------|---|------| | `QuotaTypeLongTerm` | 1 | 长期额度 | | `QuotaTypeShortTerm` | 2 | 短期额度 | | `QuotaTypeCycle` | 3 | 周期额度 | ### SendStatus(发送状态) | 常量 | 值 | 说明 | |------|---|------| | `SendStatusPending` | 0 | 待发送 | | `SendStatusSubmitted` | 1 | 已提交 | | `SendStatusSuccess` | 2 | 发送成功 | | `SendStatusFailed` | 3 | 发送失败 | | `SendStatusRejected` | 4 | 已拒绝 | ### AuthType(认证类型) | 常量 | 值 | 说明 | |------|---|------| | `AuthTypeAuthToken` | 1 | 登录令牌 | | `AuthTypeServiceToken` | 2 | 服务令牌 | | `AuthTypeUserToken` | 3 | 用户令牌 | ## API 参考 ### 签名管理(Signature) #### 用户接口 | 方法 | 说明 | |------|------| | `CreateSignature(ctx, req)` | 创建签名 | | `ListSignatures(ctx, query)` | 获取签名列表 | | `GetSignature(ctx, id)` | 获取签名详情 | | `UpdateSignature(ctx, id, req)` | 更新签名 | | `DeleteSignature(ctx, id)` | 删除签名 | | `SubmitSignature(ctx, id)` | 提交签名审核 | #### 管理员接口 | 方法 | 说明 | |------|------| | `AdminListSignatures(ctx, query)` | 获取签名列表(支持 UserID/Status 筛选) | | `AdminGetSignature(ctx, id)` | 获取签名详情 | | `AdminCreateSignature(ctx, req)` | 创建签名(可指定用户) | | `AdminUpdateSignature(ctx, id, req)` | 更新签名 | | `AdminDeleteSignature(ctx, id)` | 删除签名 | | `AdminSubmitSignature(ctx, id)` | 提交签名审核 | | `ApproveSignature(ctx, id)` | 审核通过签名 | | `RejectSignature(ctx, id, req)` | 驳回签名 | ### 模板管理(Template) #### 用户接口 | 方法 | 说明 | |------|------| | `CreateTemplate(ctx, req)` | 创建模板 | | `ListTemplates(ctx, query)` | 获取模板列表 | | `GetTemplate(ctx, id)` | 获取模板详情 | | `UpdateTemplate(ctx, id, req)` | 更新模板 | | `DeleteTemplate(ctx, id)` | 删除模板 | | `SubmitTemplate(ctx, id)` | 提交模板审核 | | `ListRecommendedTemplates(ctx, query)` | 获取推荐模板列表 | #### 管理员接口 | 方法 | 说明 | |------|------| | `AdminListTemplates(ctx, query)` | 获取模板列表(支持 UserID/Status 筛选) | | `AdminListRecommendedTemplates(ctx, query)` | 获取推荐模板列表 | | `AdminGetTemplate(ctx, id)` | 获取模板详情 | | `AdminCreateTemplate(ctx, req)` | 创建模板(可指定用户) | | `AdminUpdateTemplate(ctx, id, req)` | 更新模板 | | `AdminDeleteTemplate(ctx, id)` | 删除模板 | | `AdminSubmitTemplate(ctx, id)` | 提交模板审核 | | `ApproveTemplate(ctx, id)` | 审核通过模板 | | `RejectTemplate(ctx, id, req)` | 驳回模板 | | `CreateRecommendedTemplate(ctx, req)` | 创建推荐模板 | | `UpdateRecommendedTemplate(ctx, id, req)` | 更新推荐模板 | | `DeleteRecommendedTemplate(ctx, id)` | 删除推荐模板 | ### 用户令牌管理(Token) #### 用户接口 | 方法 | 说明 | |------|------| | `CreateUserToken(ctx, req)` | 创建令牌 | | `ListUserTokens(ctx, query)` | 获取令牌列表 | | `GetUserToken(ctx, id)` | 获取令牌详情 | | `UpdateUserToken(ctx, id, req)` | 更新令牌 | | `DeleteUserToken(ctx, id)` | 删除令牌 | | `ToggleUserToken(ctx, id)` | 切换令牌启用/禁用 | #### 管理员接口 | 方法 | 说明 | |------|------| | `AdminListUserTokens(ctx, query)` | 获取令牌列表(支持 UserID/Status 筛选) | | `AdminGetUserToken(ctx, id)` | 获取令牌详情 | | `AdminCreateUserToken(ctx, req)` | 创建令牌(可指定用户) | | `AdminUpdateUserToken(ctx, id, req)` | 更新令牌 | | `AdminDeleteUserToken(ctx, id)` | 删除令牌 | | `AdminToggleUserToken(ctx, id)` | 切换令牌启用/禁用 | ### 额度管理(Quota) #### 用户接口 | 方法 | 说明 | |------|------| | `ListQuotas(ctx, query)` | 获取额度列表 | | `GetQuotaSummary(ctx)` | 获取额度汇总 | #### 管理员接口 | 方法 | 说明 | |------|------| | `AdminListQuotas(ctx, query)` | 获取额度列表(支持 UserID 筛选) | | `AdminGetQuotaSummary(ctx, userID)` | 获取指定用户的额度汇总 | | `CreateQuota(ctx, req)` | 创建额度 | | `UpdateQuota(ctx, id, req)` | 更新额度 | | `DeleteQuota(ctx, id)` | 删除额度 | ### 发送管理(Send) #### 用户接口 | 方法 | 说明 | |------|------| | `SendBatch(ctx, req)` | 批量发送(相同内容,多号码) | | `SendMulti(ctx, req)` | 个性化群发(不同参数,多号码) | | `ListSendRecords(ctx, query)` | 获取发送记录列表 | | `GetSendStatus(ctx, msgID)` | 查询发送状态 | #### 管理员接口 | 方法 | 说明 | |------|------| | `AdminListSendRecords(ctx, query)` | 获取发送记录列表(支持 UserID 筛选) | | `AdminGetSendStatus(ctx, msgID)` | 查询发送状态 | ### 适配器管理(Adapter) #### 管理员接口 | 方法 | 说明 | |------|------| | `GetAdapterBalance(ctx)` | 查询适配器余额 | ## 响应结构 所有 API 的 HTTP 响应统一为以下 JSON 结构: ```json { "code": 0, "msg": "success", "data": { } } ``` SDK 会自动处理响应解析,`code != 0` 时返回包含 `msg` 的 error。 分页列表接口返回 `PaginationResult[T]`: ```json { "list": [], "total": 100, "page": 1 } ``` ## License MIT