diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index ff23cfda2..2647f2b6a 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -2,9 +2,9 @@ name: Go on: push: - branches: [ master,release-*,v2 ] + branches: [ master,release-*,v2,feature/** ] pull_request: - branches: [ master,release-*,v2 ] + branches: [ master,release-*,v2,feature/** ] jobs: golangci: diff --git a/credential/default_access_token.go b/credential/default_access_token.go index 90dffd1eb..b4d9d4c82 100644 --- a/credential/default_access_token.go +++ b/credential/default_access_token.go @@ -66,9 +66,11 @@ func (ak *DefaultAccessToken) GetAccessToken() (accessToken string, err error) { func (ak *DefaultAccessToken) GetAccessTokenContext(ctx context.Context) (accessToken string, err error) { // 先从cache中取 accessTokenCacheKey := fmt.Sprintf("%s_access_token_%s", ak.cacheKeyPrefix, ak.appID) - val := ak.cache.Get(accessTokenCacheKey) - if accessToken = val.(string); accessToken != "" { - return + + if val := ak.cache.Get(accessTokenCacheKey); val != nil { + if accessToken = val.(string); accessToken != "" { + return + } } // 加上lock,是为了防止在并发获取token时,cache刚好失效,导致从微信服务器上获取到不同token @@ -76,9 +78,10 @@ func (ak *DefaultAccessToken) GetAccessTokenContext(ctx context.Context) (access defer ak.accessTokenLock.Unlock() // 双检,防止重复从微信服务器获取 - val = ak.cache.Get(accessTokenCacheKey) - if accessToken = val.(string); accessToken != "" { - return + if val := ak.cache.Get(accessTokenCacheKey); val != nil { + if accessToken = val.(string); accessToken != "" { + return + } } // cache失效,从微信服务器获取 diff --git a/doc/api/work.md b/doc/api/work.md index 117c20b42..445d6c0f3 100644 --- a/doc/api/work.md +++ b/doc/api/work.md @@ -90,10 +90,12 @@ host: https://qyapi.weixin.qq.com/ | 名称 | 请求方式 | URL | 是否已实现 | 使用方法 | 贡献者 | |:---------:|------|:----------------------------------------| ---------- | ------------------------------- |----------| | 获取子部门ID列表 | GET | /cgi-bin/department/simplelist | YES | (r *Client) DepartmentSimpleList| MARKWANG | +| 获取部门列表 | GET | /cgi-bin/department/list | YES | (r *Client) DepartmentList| just5325, ourines | | 获取部门成员 | GET | /cgi-bin/user/simplelist | YES | (r *Client) UserSimpleList | MARKWANG | | 获取成员ID列表 | Post | /cgi-bin/user/list_id | YES | (r *Client) UserListId | MARKWANG | + ## 素材管理 [官方文档](https://developer.work.weixin.qq.com/document/path/91054) @@ -116,5 +118,14 @@ host: https://qyapi.weixin.qq.com/ | ---------------- | -------- | --------------------- | ---------- | -------------------------- | -------- | | 群机器人发送消息 | POST | /cgi-bin/webhook/send | YES | (r *Client) RobotBroadcast | chcthink | +## 打卡 + +[官方文档](https://developer.work.weixin.qq.com/document/path/96497) + +| 名称 | 请求方式 | URL | 是否已实现 | 使用方法 | 贡献者 | +|----------| -------- | --------------------- | ---------- | -------------------------- |---------| +| 获取打卡日报数据 | POST | /cgi-bin/checkin/getcheckin_daydata | YES | (r *Client) GetDayData | Thinker | +| 获取打卡月报数据 | POST | /cgi-bin/checkin/getcheckin_monthdata | YES | (r *Client) GetMonthData | Thinker | + ## 应用管理 TODO diff --git a/domain/openapi/mgnt.go b/domain/openapi/mgnt.go index 02621d4f6..9e0754df4 100644 --- a/domain/openapi/mgnt.go +++ b/domain/openapi/mgnt.go @@ -2,12 +2,12 @@ package openapi import "github.com/silenceper/wechat/v2/util" -// GetAPIQuotaParams 查询API调用额度参数 +// GetAPIQuotaParams 查询 API 调用额度参数 type GetAPIQuotaParams struct { - CgiPath string `json:"cgi_path"` // api的请求地址,例如"/cgi-bin/message/custom/send";不要前缀“https://api.weixin.qq.com” ,也不要漏了"/",否则都会76003的报错 + CgiPath string `json:"cgi_path"` // api 的请求地址,例如"/cgi-bin/message/custom/send";不要前缀“https://api.weixin.qq.com” ,也不要漏了"/",否则都会 76003 的报错 } -// APIQuota API调用额度 +// APIQuota API 调用额度 type APIQuota struct { util.CommonError Quota struct { @@ -17,20 +17,20 @@ type APIQuota struct { } `json:"quota"` // 详情 } -// GetRidInfoParams 查询rid信息参数 +// GetRidInfoParams 查询 rid 信息参数 type GetRidInfoParams struct { - Rid string `json:"rid"` // 调用接口报错返回的rid + Rid string `json:"rid"` // 调用接口报错返回的 rid } -// RidInfo rid信息 +// RidInfo rid 信息 type RidInfo struct { util.CommonError Request struct { InvokeTime int64 `json:"invoke_time"` // 发起请求的时间戳 CostInMs int64 `json:"cost_in_ms"` // 请求毫秒级耗时 - RequestURL string `json:"request_url"` // 请求的URL参数 - RequestBody string `json:"request_body"` // post请求的请求参数 + RequestURL string `json:"request_url"` // 请求的 URL 参数 + RequestBody string `json:"request_body"` // post 请求的请求参数 ResponseBody string `json:"response_body"` // 接口请求返回参数 - ClientIP string `json:"client_ip"` // 接口请求的客户端ip - } `json:"request"` // 该rid对应的请求详情 + ClientIP string `json:"client_ip"` // 接口请求的客户端 ip + } `json:"request"` // 该 rid 对应的请求详情 } diff --git a/miniprogram/message/consts.go b/miniprogram/message/consts.go index a044078f4..496bb9cdd 100644 --- a/miniprogram/message/consts.go +++ b/miniprogram/message/consts.go @@ -22,9 +22,9 @@ const ( MsgTypeMiniProgramPage = "miniprogrampage" // MsgTypeEvent 事件 MsgTypeEvent MsgType = "event" - // DataTypeXML XML格式数据 + // DataTypeXML XML 格式数据 DataTypeXML = "xml" - // DataTypeJSON JSON格式数据 + // DataTypeJSON JSON 格式数据 DataTypeJSON = "json" ) diff --git a/miniprogram/message/customer_message.go b/miniprogram/message/customer_message.go index ce3830f9d..0f0abd308 100644 --- a/miniprogram/message/customer_message.go +++ b/miniprogram/message/customer_message.go @@ -28,7 +28,7 @@ type MediaText struct { Content string `json:"content"` } -// MediaResource 消息使用的临时素材id +// MediaResource 消息使用的临时素材 id type MediaResource struct { MediaID string `json:"media_id"` } @@ -51,7 +51,7 @@ type MediaLink struct { // CustomerMessage 客服消息 type CustomerMessage struct { - ToUser string `json:"touser"` // 接受者OpenID + ToUser string `json:"touser"` // 接受者 OpenID Msgtype MsgType `json:"msgtype"` // 客服消息类型 Text *MediaText `json:"text,omitempty"` // 可选 Image *MediaResource `json:"image,omitempty"` // 可选 diff --git a/miniprogram/message/message.go b/miniprogram/message/message.go index 89e4b8d70..77dccfeba 100644 --- a/miniprogram/message/message.go +++ b/miniprogram/message/message.go @@ -9,6 +9,8 @@ import ( "sort" "strings" + "github.com/tidwall/gjson" + "github.com/silenceper/wechat/v2/miniprogram/context" "github.com/silenceper/wechat/v2/miniprogram/security" "github.com/silenceper/wechat/v2/util" @@ -18,11 +20,11 @@ import ( type ConfirmReceiveMethod int8 const ( - // EventTypeTradeManageRemindAccessAPI 提醒接入发货信息管理服务API + // EventTypeTradeManageRemindAccessAPI 提醒接入发货信息管理服务 API // 小程序完成账期授权时/小程序产生第一笔交易时/已产生交易但从未发货的小程序,每天一次 EventTypeTradeManageRemindAccessAPI EventType = "trade_manage_remind_access_api" // EventTypeTradeManageRemindShipping 提醒需要上传发货信息 - // 曾经发过货的小程序,订单超过48小时未发货时 + // 曾经发过货的小程序,订单超过 48 小时未发货时 EventTypeTradeManageRemindShipping EventType = "trade_manage_remind_shipping" // EventTypeTradeManageOrderSettlement 订单将要结算或已经结算 // 订单完成发货时/订单结算时 @@ -39,14 +41,27 @@ const ( EventTypeXpayGoodsDeliverNotify EventType = "xpay_goods_deliver_notify" // EventTypeXpayCoinPayNotify 代币支付推送事件 EventTypeXpayCoinPayNotify EventType = "xpay_coin_pay_notify" + // EventSubscribePopup 用户操作订阅通知弹窗事件推送,用户在图文等场景内订阅通知的操作 + EventSubscribePopup EventType = "subscribe_msg_popup_event" + // EventSubscribeMsgChange 用户管理订阅通知,用户在服务通知管理页面做通知管理时的操作 + EventSubscribeMsgChange EventType = "subscribe_msg_change_event" + // EventSubscribeMsgSent 发送订阅通知,调用 bizsend 接口发送通知 + EventSubscribeMsgSent EventType = "subscribe_msg_sent_event" // ConfirmReceiveMethodAuto 自动确认收货 ConfirmReceiveMethodAuto ConfirmReceiveMethod = 1 // ConfirmReceiveMethodManual 手动确认收货 ConfirmReceiveMethodManual ConfirmReceiveMethod = 2 ) +const ( + // InfoTypeAcceptSubscribeMessage 接受订阅通知 + InfoTypeAcceptSubscribeMessage InfoType = "accept" + // InfoTypeRejectSubscribeMessage 拒绝订阅通知 + InfoTypeRejectSubscribeMessage InfoType = "reject" +) + // PushReceiver 接收消息推送 -// 暂仅支付Aes加密方式 +// 暂仅支付 Aes 加密方式 type PushReceiver struct { *context.Context } @@ -58,16 +73,16 @@ func NewPushReceiver(ctx *context.Context) *PushReceiver { } } -// GetMsg 获取接收到的消息(如果是加密的返回解密数据) +// GetMsg 获取接收到的消息 (如果是加密的返回解密数据) func (receiver *PushReceiver) GetMsg(r *http.Request) (string, []byte, error) { // 判断请求格式 var dataType string contentType := r.Header.Get("Content-Type") if strings.HasPrefix(contentType, "text/xml") { - // xml格式 + // xml 格式 dataType = DataTypeXML } else { - // json格式 + // json 格式 dataType = DataTypeJSON } @@ -108,7 +123,7 @@ func (receiver *PushReceiver) GetMsg(r *http.Request) (string, []byte, error) { return dataType, byteData, err } -// GetMsgData 获取接收到的消息(解密数据) +// GetMsgData 获取接收到的消息 (解密数据) func (receiver *PushReceiver) GetMsgData(r *http.Request) (MsgType, EventType, PushData, error) { dataType, decryptMsg, err := receiver.GetMsg(r) if err != nil { @@ -144,7 +159,7 @@ func (receiver *PushReceiver) GetMsgData(r *http.Request) (MsgType, EventType, P func (receiver *PushReceiver) getEvent(dataType string, eventType EventType, decryptMsg []byte) (PushData, error) { switch eventType { case EventTypeTradeManageRemindAccessAPI: - // 提醒接入发货信息管理服务API + // 提醒接入发货信息管理服务 API var pushData PushDataRemindAccessAPI err := receiver.unmarshal(dataType, decryptMsg, &pushData) return &pushData, err @@ -188,25 +203,104 @@ func (receiver *PushReceiver) getEvent(dataType string, eventType EventType, dec var pushData PushDataXpayCoinPayNotify err := receiver.unmarshal(dataType, decryptMsg, &pushData) return &pushData, err + case EventSubscribePopup: + // 用户操作订阅通知弹窗事件推送 + return receiver.unmarshalSubscribePopup(dataType, decryptMsg) + case EventSubscribeMsgChange: + // 用户管理订阅通知事件推送 + return receiver.unmarshalSubscribeMsgChange(dataType, decryptMsg) + case EventSubscribeMsgSent: + // 用户发送订阅通知事件推送 + return receiver.unmarshalSubscribeMsgSent(dataType, decryptMsg) } // 暂不支持其他事件类型,直接返回解密后的数据,由调用方处理 return decryptMsg, nil } // unmarshal 解析推送的数据 -func (receiver *PushReceiver) unmarshal(dateType string, decryptMsg []byte, pushData interface{}) error { - if dateType == DataTypeXML { +func (receiver *PushReceiver) unmarshal(dataType string, decryptMsg []byte, pushData interface{}) error { + if dataType == DataTypeXML { return xml.Unmarshal(decryptMsg, pushData) } return json.Unmarshal(decryptMsg, pushData) } +// unmarshalSubscribePopup +func (receiver *PushReceiver) unmarshalSubscribePopup(dataType string, decryptMsg []byte) (PushData, error) { + var pushData PushDataSubscribePopup + err := receiver.unmarshal(dataType, decryptMsg, &pushData) + if err == nil { + listData := gjson.Get(string(decryptMsg), "List") + if listData.IsObject() { + listItem := SubscribeMsgPopupEventList{} + if parseErr := json.Unmarshal([]byte(listData.Raw), &listItem); parseErr != nil { + return &pushData, parseErr + } + pushData.SetSubscribeMsgPopupEvents([]SubscribeMsgPopupEventList{listItem}) + } else if listData.IsArray() { + listItems := make([]SubscribeMsgPopupEventList, 0) + if parseErr := json.Unmarshal([]byte(listData.Raw), &listItems); parseErr != nil { + return &pushData, parseErr + } + pushData.SetSubscribeMsgPopupEvents(listItems) + } + } + + return &pushData, err +} + +// unmarshalSubscribeMsgChange 解析用户管理订阅通知事件推送 +func (receiver *PushReceiver) unmarshalSubscribeMsgChange(dataType string, decryptMsg []byte) (PushData, error) { + var pushData PushDataSubscribeMsgChange + err := receiver.unmarshal(dataType, decryptMsg, &pushData) + if err == nil { + listData := gjson.Get(string(decryptMsg), "List") + if listData.IsObject() { + listItem := SubscribeMsgChangeList{} + if parseErr := json.Unmarshal([]byte(listData.Raw), &listItem); parseErr != nil { + return &pushData, parseErr + } + pushData.SetSubscribeMsgChangeEvents([]SubscribeMsgChangeList{listItem}) + } else if listData.IsArray() { + listItems := make([]SubscribeMsgChangeList, 0) + if parseErr := json.Unmarshal([]byte(listData.Raw), &listItems); parseErr != nil { + return &pushData, parseErr + } + pushData.SetSubscribeMsgChangeEvents(listItems) + } + } + return &pushData, err +} + +// unmarshalSubscribeMsgSent 解析用户发送订阅通知事件推送 +func (receiver *PushReceiver) unmarshalSubscribeMsgSent(dataType string, decryptMsg []byte) (PushData, error) { + var pushData PushDataSubscribeMsgSent + err := receiver.unmarshal(dataType, decryptMsg, &pushData) + if err == nil { + listData := gjson.Get(string(decryptMsg), "List") + if listData.IsObject() { + listItem := SubscribeMsgSentList{} + if parseErr := json.Unmarshal([]byte(listData.Raw), &listItem); parseErr != nil { + return &pushData, parseErr + } + pushData.SetSubscribeMsgSentEvents([]SubscribeMsgSentList{listItem}) + } else if listData.IsArray() { + listItems := make([]SubscribeMsgSentList, 0) + if parseErr := json.Unmarshal([]byte(listData.Raw), &listItems); parseErr != nil { + return &pushData, parseErr + } + pushData.SetSubscribeMsgSentEvents(listItems) + } + } + return &pushData, err +} + // DataReceived 接收到的数据 type DataReceived struct { Encrypt string `json:"Encrypt" xml:"Encrypt"` // 加密的消息体 } -// PushData 推送的数据(已转对应的结构体) +// PushData 推送的数据 (已转对应的结构体) type PushData interface{} // CommonPushData 推送数据通用部分 @@ -216,7 +310,7 @@ type CommonPushData struct { Event EventType `json:"Event" xml:"Event"` // 事件类型 ToUserName string `json:"ToUserName" xml:"ToUserName"` // 小程序的原始 ID FromUserName string `json:"FromUserName" xml:"FromUserName"` // 发送方账号(一个 OpenID,此时发送方是系统账号) - CreateTime int64 `json:"CreateTime" xml:"CreateTime"` // 消息创建时间 (整型),时间戳 + CreateTime int64 `json:"CreateTime" xml:"CreateTime"` // 消息创建时间(整型),时间戳 } // MediaCheckAsyncData 媒体内容安全异步审查结果通知 @@ -272,7 +366,7 @@ type PushDataRemindShipping struct { Msg string `json:"msg" xml:"msg"` // 消息文本内容 } -// PushDataRemindAccessAPI 提醒接入发货信息管理服务API信息 +// PushDataRemindAccessAPI 提醒接入发货信息管理服务 API 信息 type PushDataRemindAccessAPI struct { CommonPushData Msg string `json:"msg" xml:"msg"` // 消息文本内容 @@ -281,9 +375,9 @@ type PushDataRemindAccessAPI struct { // PushDataAddExpressPath 运单轨迹更新信息 type PushDataAddExpressPath struct { CommonPushData - DeliveryID string `json:"DeliveryID" xml:"DeliveryID"` // 快递公司ID - WayBillID string `json:"WaybillId" xml:"WaybillId"` // 运单ID - OrderID string `json:"OrderId" xml:"OrderId"` // 订单ID + DeliveryID string `json:"DeliveryID" xml:"DeliveryID"` // 快递公司 ID + WayBillID string `json:"WaybillId" xml:"WaybillId"` // 运单 ID + OrderID string `json:"OrderId" xml:"OrderId"` // 订单 ID Version int `json:"Version" xml:"Version"` // 轨迹版本号(整型) Count int `json:"Count" xml:"Count"` // 轨迹节点数(整型) Actions []*PushDataAddExpressPathAction `json:"Actions" xml:"Actions"` // 轨迹节点列表 @@ -304,10 +398,10 @@ type PushDataSecVodUpload struct { // SecVodUploadEvent 短剧媒资上传完成事件 type SecVodUploadEvent struct { - MediaID string `json:"media_id" xml:"media_id"` // 媒资id + MediaID string `json:"media_id" xml:"media_id"` // 媒资 id SourceContext string `json:"source_context" xml:"source_context"` // 透传上传接口中开发者设置的值。 - Errcode int `json:"errcode" xml:"errcode"` // 错误码,上传失败时该值非 - Errmsg string `json:"errmsg" xml:"errmsg"` // 错误提示 + ErrCode int `json:"errcode" xml:"errcode"` // 错误码,上传失败时该值非 + ErrMsg string `json:"errmsg" xml:"errmsg"` // 错误提示 } // PushDataSecVodAudit 短剧媒资审核状态 @@ -318,14 +412,14 @@ type PushDataSecVodAudit struct { // SecVodAuditEvent 短剧媒资审核状态事件 type SecVodAuditEvent struct { - DramaID string `json:"drama_id" xml:"drama_id"` // 剧目id + DramaID string `json:"drama_id" xml:"drama_id"` // 剧目 id SourceContext string `json:"source_context" xml:"source_context"` // 透传上传接口中开发者设置的值 - AuditDetail DramaAuditDetail `json:"audit_detail" xml:"audit_detail"` // 剧目审核结果,单独每一集的审核结果可以根据drama_id查询剧集详情得到 + AuditDetail DramaAuditDetail `json:"audit_detail" xml:"audit_detail"` // 剧目审核结果,单独每一集的审核结果可以根据 drama_id 查询剧集详情得到 } // DramaAuditDetail 剧目审核结果 type DramaAuditDetail struct { - Status int `json:"status" xml:"status"` // 审核状态,0为无效值;1为审核中;2为最终失败;3为审核通过;4为驳回重填 + Status int `json:"status" xml:"status"` // 审核状态,0 为无效值;1 为审核中;2 为最终失败;3 为审核通过;4 为驳回重填 CreateTime int64 `json:"create_time" xml:"create_time"` // 提审时间戳 AuditTime int64 `json:"audit_time" xml:"audit_time"` // 审核时间戳 } @@ -333,9 +427,9 @@ type DramaAuditDetail struct { // PushDataXpayGoodsDeliverNotify 道具发货推送 type PushDataXpayGoodsDeliverNotify struct { CommonPushData - OpenID string `json:"OpenId" xml:"OpenId"` // 用户openid + OpenID string `json:"OpenId" xml:"OpenId"` // 用户 openid OutTradeNo string `json:"OutTradeNo" xml:"OutTradeNo"` // 业务订单号 - Env int `json:"Env" xml:"Env"` //,环境配置 0:现网环境(也叫正式环境)1:沙箱环境 + Env int `json:"Env" xml:"Env"` // ,环境配置 0:现网环境(也叫正式环境)1:沙箱环境 WeChatPayInfo WeChatPayInfo `json:"WeChatPayInfo" xml:"WeChatPayInfo"` // 微信支付信息 非微信支付渠道可能没有 GoodsInfo GoodsInfo `json:"GoodsInfo" xml:"GoodsInfo"` // 道具参数信息 } @@ -344,14 +438,14 @@ type PushDataXpayGoodsDeliverNotify struct { type WeChatPayInfo struct { MchOrderNo string `json:"MchOrderNo" xml:"MchOrderNo"` // 微信支付商户单号 TransactionID string `json:"TransactionId" xml:"TransactionId"` // 交易单号(微信支付订单号) - PaidTime int64 `json:"PaidTime" xml:"PaidTime"` // 用户支付时间,Linux秒级时间戳 + PaidTime int64 `json:"PaidTime" xml:"PaidTime"` // 用户支付时间,Linux 秒级时间戳 } // GoodsInfo 道具参数信息 type GoodsInfo struct { - ProductID string `json:"ProductId" xml:"ProductId"` // 道具ID + ProductID string `json:"ProductId" xml:"ProductId"` // 道具 ID Quantity int `json:"Quantity" xml:"Quantity"` // 数量 - OrigPrice int64 `json:"OrigPrice" xml:"OrigPrice"` // 物品原始价格 (单位:分) + OrigPrice int64 `json:"OrigPrice" xml:"OrigPrice"` // 物品原始价格(单位:分) ActualPrice int64 `json:"ActualPrice" xml:"ActualPrice"` // 物品实际支付价格(单位:分) Attach string `json:"Attach" xml:"Attach"` // 透传信息 } @@ -359,9 +453,9 @@ type GoodsInfo struct { // PushDataXpayCoinPayNotify 代币支付推送 type PushDataXpayCoinPayNotify struct { CommonPushData - OpenID string `json:"OpenId" xml:"OpenId"` // 用户openid + OpenID string `json:"OpenId" xml:"OpenId"` // 用户 openid OutTradeNo string `json:"OutTradeNo" xml:"OutTradeNo"` // 业务订单号 - Env int `json:"Env" xml:"Env"` //,环境配置 0:现网环境(也叫正式环境)1:沙箱环境 + Env int `json:"Env" xml:"Env"` // ,环境配置 0:现网环境(也叫正式环境)1:沙箱环境 WeChatPayInfo WeChatPayInfo `json:"WeChatPayInfo" xml:"WeChatPayInfo"` // 微信支付信息 非微信支付渠道可能没有 CoinInfo CoinInfo `json:"CoinInfo" xml:"CoinInfo"` // 代币参数信息 } @@ -369,7 +463,117 @@ type PushDataXpayCoinPayNotify struct { // CoinInfo 代币参数信息 type CoinInfo struct { Quantity int `json:"Quantity" xml:"Quantity"` // 数量 - OrigPrice int64 `json:"OrigPrice" xml:"OrigPrice"` // 物品原始价格 (单位:分) + OrigPrice int64 `json:"OrigPrice" xml:"OrigPrice"` // 物品原始价格(单位:分) ActualPrice int64 `json:"ActualPrice" xml:"ActualPrice"` // 物品实际支付价格(单位:分) Attach string `json:"Attach" xml:"Attach"` // 透传信息 } + +// PushDataSubscribePopup 用户操作订阅通知弹窗事件推送 +type PushDataSubscribePopup struct { + CommonPushData + subscribeMsgPopupEventList []SubscribeMsgPopupEventList `json:"-"` + SubscribeMsgPopupEvent SubscribeMsgPopupEvent `xml:"SubscribeMsgPopupEvent"` +} + +// SubscribeMsgPopupEvent 用户操作订阅通知弹窗消息回调 +type SubscribeMsgPopupEvent struct { + List []SubscribeMsgPopupEventList `xml:"List"` +} + +// SubscribeMsgPopupEventList 订阅消息事件列表 +type SubscribeMsgPopupEventList struct { + TemplateID string `xml:"TemplateId" json:"TemplateId"` + SubscribeStatusString string `xml:"SubscribeStatusString" json:"SubscribeStatusString"` + PopupScene string `xml:"PopupScene" json:"PopupScene"` +} + +// SetSubscribeMsgPopupEvents 设置订阅消息事件 +func (s *PushDataSubscribePopup) SetSubscribeMsgPopupEvents(list []SubscribeMsgPopupEventList) { + s.subscribeMsgPopupEventList = list +} + +// GetSubscribeMsgPopupEvents 获取订阅消息事件数据 +func (s *PushDataSubscribePopup) GetSubscribeMsgPopupEvents() []SubscribeMsgPopupEventList { + if s.subscribeMsgPopupEventList != nil { + return s.subscribeMsgPopupEventList + } + + if s.SubscribeMsgPopupEvent.List == nil || len(s.SubscribeMsgPopupEvent.List) < 1 { + return nil + } + return s.SubscribeMsgPopupEvent.List +} + +// PushDataSubscribeMsgChange 用户管理订阅通知事件推送 +type PushDataSubscribeMsgChange struct { + CommonPushData + SubscribeMsgChangeEvent SubscribeMsgChangeEvent `xml:"SubscribeMsgChangeEvent"` + subscribeMsgChangeList []SubscribeMsgChangeList `json:"-"` +} + +// SubscribeMsgChangeEvent 用户管理订阅通知回调 +type SubscribeMsgChangeEvent struct { + List []SubscribeMsgChangeList `xml:"List" json:"List"` +} + +// SubscribeMsgChangeList 订阅消息事件列表 +type SubscribeMsgChangeList struct { + TemplateID string `xml:"TemplateId" json:"TemplateId"` + SubscribeStatusString string `xml:"SubscribeStatusString" json:"SubscribeStatusString"` +} + +// SetSubscribeMsgChangeEvents 设置订阅消息事件 +func (s *PushDataSubscribeMsgChange) SetSubscribeMsgChangeEvents(list []SubscribeMsgChangeList) { + s.subscribeMsgChangeList = list +} + +// GetSubscribeMsgChangeEvents 获取订阅消息事件数据 +func (s *PushDataSubscribeMsgChange) GetSubscribeMsgChangeEvents() []SubscribeMsgChangeList { + if s.subscribeMsgChangeList != nil { + return s.subscribeMsgChangeList + } + + if s.SubscribeMsgChangeEvent.List == nil || len(s.SubscribeMsgChangeEvent.List) < 1 { + return nil + } + + return s.SubscribeMsgChangeEvent.List +} + +// PushDataSubscribeMsgSent 用户发送订阅通知事件推送 +type PushDataSubscribeMsgSent struct { + CommonPushData + SubscribeMsgSentEvent SubscribeMsgSentEvent `xml:"SubscribeMsgSentEvent"` + subscribeMsgSentEventList []SubscribeMsgSentList `json:"-"` +} + +// SubscribeMsgSentEvent 用户发送订阅通知回调 +type SubscribeMsgSentEvent struct { + List []SubscribeMsgSentList `xml:"List" json:"List"` +} + +// SubscribeMsgSentList 订阅消息事件列表 +type SubscribeMsgSentList struct { + TemplateID string `xml:"TemplateId" json:"TemplateId"` + MsgID string `xml:"MsgID" json:"MsgID"` + ErrorCode int `xml:"ErrorCode" json:"ErrorCode"` + ErrorStatus string `xml:"ErrorStatus" json:"ErrorStatus"` +} + +// SetSubscribeMsgSentEvents 设置订阅消息事件 +func (s *PushDataSubscribeMsgSent) SetSubscribeMsgSentEvents(list []SubscribeMsgSentList) { + s.subscribeMsgSentEventList = list +} + +// GetSubscribeMsgSentEvents 获取订阅消息事件数据 +func (s *PushDataSubscribeMsgSent) GetSubscribeMsgSentEvents() []SubscribeMsgSentList { + if s.subscribeMsgSentEventList != nil { + return s.subscribeMsgSentEventList + } + + if s.SubscribeMsgSentEvent.List == nil || len(s.SubscribeMsgSentEvent.List) < 1 { + return nil + } + + return s.SubscribeMsgSentEvent.List +} diff --git a/miniprogram/message/reply.go b/miniprogram/message/reply.go new file mode 100644 index 000000000..b7fba069f --- /dev/null +++ b/miniprogram/message/reply.go @@ -0,0 +1,15 @@ +package message + +import "errors" + +// ErrInvalidReply 无效的回复 +var ErrInvalidReply = errors.New("无效的回复信息") + +// ErrUnsupportedReply 不支持的回复类型 +var ErrUnsupportedReply = errors.New("不支持的回复消息") + +// Reply 消息回复 +type Reply struct { + MsgType MsgType + MsgData interface{} +} diff --git a/miniprogram/minidrama/domain.go b/miniprogram/minidrama/domain.go index 5e2d24181..eb63095db 100644 --- a/miniprogram/minidrama/domain.go +++ b/miniprogram/minidrama/domain.go @@ -180,7 +180,7 @@ type MediaInfo struct { CreateTime int64 `json:"create_time"` // 上传时间,时间戳。 ExpireTime int64 `json:"expire_time"` // 过期时间,时间戳。 DramaID int64 `json:"drama_id"` // 所属剧目 id。 - FileSize string `json:"file_size"` // 媒资文件大小,单位:字节。 + FileSize int64 `json:"file_size"` // 媒资文件大小,单位:字节。 Duration int64 `json:"duration"` // 播放时长,单位:秒。 Name string `json:"name"` // 媒资文件名。 Description string `json:"description"` // 描述。 diff --git a/miniprogram/minidrama/minidrama.go b/miniprogram/minidrama/minidrama.go index aaadf50dc..2028d666a 100644 --- a/miniprogram/minidrama/minidrama.go +++ b/miniprogram/minidrama/minidrama.go @@ -27,7 +27,7 @@ import ( ) // SingleFileUpload 单文件上传 -func (s *MiniDrama) SingleFileUpload(ctx context.Context, in *SingleFileUploadRequest) (out *SingleFileUploadResponse, err error) { +func (s *MiniDrama) SingleFileUpload(ctx context.Context, in *SingleFileUploadRequest) (out SingleFileUploadResponse, err error) { var address string if address, err = s.requestAddress(ctx, singleFileUpload); err != nil { return @@ -76,12 +76,12 @@ func (s *MiniDrama) SingleFileUpload(ctx context.Context, in *SingleFileUploadRe return } // 使用通用方法返回错误 - err = util.DecodeWithError(response, out, "SingleFileUpload") + err = util.DecodeWithError(response, &out, "SingleFileUpload") return } // PullUpload 拉取上传 -func (s *MiniDrama) PullUpload(ctx context.Context, in *PullUploadRequest) (out *PullUploadResponse, err error) { +func (s *MiniDrama) PullUpload(ctx context.Context, in *PullUploadRequest) (out PullUploadResponse, err error) { var address string if address, err = s.requestAddress(ctx, pullUpload); err != nil { return @@ -92,12 +92,12 @@ func (s *MiniDrama) PullUpload(ctx context.Context, in *PullUploadRequest) (out } // 使用通用方法返回错误 - err = util.DecodeWithError(response, out, "PullUpload") + err = util.DecodeWithError(response, &out, "PullUpload") return } // GetTask 查询任务状态 -func (s *MiniDrama) GetTask(ctx context.Context, in *GetTaskRequest) (out *GetTaskResponse, err error) { +func (s *MiniDrama) GetTask(ctx context.Context, in *GetTaskRequest) (out GetTaskResponse, err error) { var address string if address, err = s.requestAddress(ctx, getTask); err != nil { return @@ -109,12 +109,12 @@ func (s *MiniDrama) GetTask(ctx context.Context, in *GetTaskRequest) (out *GetTa } // 使用通用方法返回错误 - err = util.DecodeWithError(response, out, "GetTask") + err = util.DecodeWithError(response, &out, "GetTask") return } // ApplyUpload 申请分片上传 -func (s *MiniDrama) ApplyUpload(ctx context.Context, in *ApplyUploadRequest) (out *ApplyUploadResponse, err error) { +func (s *MiniDrama) ApplyUpload(ctx context.Context, in *ApplyUploadRequest) (out ApplyUploadResponse, err error) { var address string if address, err = s.requestAddress(ctx, applyUpload); err != nil { return @@ -126,13 +126,13 @@ func (s *MiniDrama) ApplyUpload(ctx context.Context, in *ApplyUploadRequest) (ou } // 使用通用方法返回错误 - err = util.DecodeWithError(response, out, "ApplyUpload") + err = util.DecodeWithError(response, &out, "ApplyUpload") return } // UploadPart 上传分片 // Content-Type 需要指定为 multipart/form-data; boundary=,<箭头括号>表示必须替换为有效值的变量。 -func (s *MiniDrama) UploadPart(ctx context.Context, in *UploadPartRequest) (out *UploadPartResponse, err error) { +func (s *MiniDrama) UploadPart(ctx context.Context, in *UploadPartRequest) (out UploadPartResponse, err error) { var address string if address, err = s.requestAddress(ctx, uploadPart); err != nil { return @@ -165,12 +165,12 @@ func (s *MiniDrama) UploadPart(ctx context.Context, in *UploadPartRequest) (out } // 使用通用方法返回错误 - err = util.DecodeWithError(response, out, "UploadPart") + err = util.DecodeWithError(response, &out, "UploadPart") return } // CommitUpload 确认上传 -func (s *MiniDrama) CommitUpload(ctx context.Context, in *CommitUploadRequest) (out *CommitUploadResponse, err error) { +func (s *MiniDrama) CommitUpload(ctx context.Context, in *CommitUploadRequest) (out CommitUploadResponse, err error) { var address string if address, err = s.requestAddress(ctx, commitUpload); err != nil { return @@ -182,12 +182,12 @@ func (s *MiniDrama) CommitUpload(ctx context.Context, in *CommitUploadRequest) ( } // 使用通用方法返回错误 - err = util.DecodeWithError(response, out, "CommitUpload") + err = util.DecodeWithError(response, &out, "CommitUpload") return } // ListMedia 获取媒体列表 -func (s *MiniDrama) ListMedia(ctx context.Context, in *ListMediaRequest) (out *ListMediaResponse, err error) { +func (s *MiniDrama) ListMedia(ctx context.Context, in *ListMediaRequest) (out ListMediaResponse, err error) { var address string if address, err = s.requestAddress(ctx, listMedia); err != nil { return @@ -199,12 +199,12 @@ func (s *MiniDrama) ListMedia(ctx context.Context, in *ListMediaRequest) (out *L } // 使用通用方法返回错误 - err = util.DecodeWithError(response, out, "ListMedia") + err = util.DecodeWithError(response, &out, "ListMedia") return } // GetMedia 获取媒资详细信息 -func (s *MiniDrama) GetMedia(ctx context.Context, in *GetMediaRequest) (out *GetMediaResponse, err error) { +func (s *MiniDrama) GetMedia(ctx context.Context, in *GetMediaRequest) (out GetMediaResponse, err error) { var address string if address, err = s.requestAddress(ctx, getMedia); err != nil { return @@ -216,12 +216,12 @@ func (s *MiniDrama) GetMedia(ctx context.Context, in *GetMediaRequest) (out *Get } // 使用通用方法返回错误 - err = util.DecodeWithError(response, out, "GetMedia") + err = util.DecodeWithError(response, &out, "GetMedia") return } // GetMediaLink 获取媒资播放链接 -func (s *MiniDrama) GetMediaLink(ctx context.Context, in *GetMediaLinkRequest) (out *GetMediaLinkResponse, err error) { +func (s *MiniDrama) GetMediaLink(ctx context.Context, in *GetMediaLinkRequest) (out GetMediaLinkResponse, err error) { var address string if address, err = s.requestAddress(ctx, getMediaLink); err != nil { return @@ -233,12 +233,12 @@ func (s *MiniDrama) GetMediaLink(ctx context.Context, in *GetMediaLinkRequest) ( } // 使用通用方法返回错误 - err = util.DecodeWithError(response, out, "GetMediaLink") + err = util.DecodeWithError(response, &out, "GetMediaLink") return } // DeleteMedia 删除媒体 -func (s *MiniDrama) DeleteMedia(ctx context.Context, in *DeleteMediaRequest) (out *DeleteMediaResponse, err error) { +func (s *MiniDrama) DeleteMedia(ctx context.Context, in *DeleteMediaRequest) (out DeleteMediaResponse, err error) { var address string if address, err = s.requestAddress(ctx, deleteMedia); err != nil { return @@ -250,12 +250,12 @@ func (s *MiniDrama) DeleteMedia(ctx context.Context, in *DeleteMediaRequest) (ou } // 使用通用方法返回错误 - err = util.DecodeWithError(response, out, "DeleteMedia") + err = util.DecodeWithError(response, &out, "DeleteMedia") return } // AuditDrama 审核剧本 -func (s *MiniDrama) AuditDrama(ctx context.Context, in *AuditDramaRequest) (out *AuditDramaResponse, err error) { +func (s *MiniDrama) AuditDrama(ctx context.Context, in *AuditDramaRequest) (out AuditDramaResponse, err error) { var address string if address, err = s.requestAddress(ctx, auditDrama); err != nil { return @@ -267,12 +267,12 @@ func (s *MiniDrama) AuditDrama(ctx context.Context, in *AuditDramaRequest) (out } // 使用通用方法返回错误 - err = util.DecodeWithError(response, out, "AuditDrama") + err = util.DecodeWithError(response, &out, "AuditDrama") return } // ListDramas 获取剧目列表 -func (s *MiniDrama) ListDramas(ctx context.Context, in *ListDramasRequest) (out *ListDramasResponse, err error) { +func (s *MiniDrama) ListDramas(ctx context.Context, in *ListDramasRequest) (out ListDramasResponse, err error) { var address string if address, err = s.requestAddress(ctx, listDramas); err != nil { return @@ -284,12 +284,12 @@ func (s *MiniDrama) ListDramas(ctx context.Context, in *ListDramasRequest) (out } // 使用通用方法返回错误 - err = util.DecodeWithError(response, out, "ListDramas") + err = util.DecodeWithError(response, &out, "ListDramas") return } // GetDrama 获取剧目信息 -func (s *MiniDrama) GetDrama(ctx context.Context, in *GetDramaRequest) (out *GetDramaResponse, err error) { +func (s *MiniDrama) GetDrama(ctx context.Context, in *GetDramaRequest) (out GetDramaResponse, err error) { var address string if address, err = s.requestAddress(ctx, getDrama); err != nil { return @@ -300,12 +300,12 @@ func (s *MiniDrama) GetDrama(ctx context.Context, in *GetDramaRequest) (out *Get return } // 使用通用方法返回错误 - err = util.DecodeWithError(response, out, "GetDrama") + err = util.DecodeWithError(response, &out, "GetDrama") return } // GetCdnUsageData 查询 CDN 用量数据 -func (s *MiniDrama) GetCdnUsageData(ctx context.Context, in *GetCdnUsageDataRequest) (out *GetCdnUsageDataResponse, err error) { +func (s *MiniDrama) GetCdnUsageData(ctx context.Context, in *GetCdnUsageDataRequest) (out GetCdnUsageDataResponse, err error) { var address string if address, err = s.requestAddress(ctx, getCdnUsageData); err != nil { return @@ -316,12 +316,12 @@ func (s *MiniDrama) GetCdnUsageData(ctx context.Context, in *GetCdnUsageDataRequ return } // 使用通用方法返回错误 - err = util.DecodeWithError(response, out, "GetCdnUsageData") + err = util.DecodeWithError(response, &out, "GetCdnUsageData") return } // GetCdnLogs 查询 CDN 日志 -func (s *MiniDrama) GetCdnLogs(ctx context.Context, in *GetCdnLogsRequest) (out *GetCdnLogsResponse, err error) { +func (s *MiniDrama) GetCdnLogs(ctx context.Context, in *GetCdnLogsRequest) (out GetCdnLogsResponse, err error) { var address string if address, err = s.requestAddress(ctx, getCdnLogs); err != nil { return @@ -332,7 +332,7 @@ func (s *MiniDrama) GetCdnLogs(ctx context.Context, in *GetCdnLogsRequest) (out return } // 使用通用方法返回错误 - err = util.DecodeWithError(response, out, "GetCdnLogs") + err = util.DecodeWithError(response, &out, "GetCdnLogs") return } diff --git a/miniprogram/virtualpayment/virtualpayment.go b/miniprogram/virtualpayment/virtualpayment.go index b3386dabb..1da90c3cb 100644 --- a/miniprogram/virtualpayment/virtualpayment.go +++ b/miniprogram/virtualpayment/virtualpayment.go @@ -37,7 +37,7 @@ func (s *VirtualPayment) SetSessionKey(sessionKey string) { } // QueryUserBalance 查询虚拟支付余额 -func (s *VirtualPayment) QueryUserBalance(ctx context.Context, in *QueryUserBalanceRequest) (out *QueryUserBalanceResponse, err error) { +func (s *VirtualPayment) QueryUserBalance(ctx context.Context, in *QueryUserBalanceRequest) (out QueryUserBalanceResponse, err error) { var jsonByte []byte if jsonByte, err = json.Marshal(in); err != nil { return @@ -60,12 +60,12 @@ func (s *VirtualPayment) QueryUserBalance(ctx context.Context, in *QueryUserBala } // 使用通用方法返回错误 - err = util.DecodeWithError(response, out, "QueryUserBalance") + err = util.DecodeWithError(response, &out, "QueryUserBalance") return } // CurrencyPay currency pay 扣减代币(一般用于代币支付) -func (s *VirtualPayment) CurrencyPay(ctx context.Context, in *CurrencyPayRequest) (out *CurrencyPayResponse, err error) { +func (s *VirtualPayment) CurrencyPay(ctx context.Context, in *CurrencyPayRequest) (out CurrencyPayResponse, err error) { var jsonByte []byte if jsonByte, err = json.Marshal(in); err != nil { return @@ -88,12 +88,12 @@ func (s *VirtualPayment) CurrencyPay(ctx context.Context, in *CurrencyPayRequest } // 使用通用方法返回错误 - err = util.DecodeWithError(response, out, "CurrencyPay") + err = util.DecodeWithError(response, &out, "CurrencyPay") return } // QueryOrder 查询创建的订单(现金单,非代币单) -func (s *VirtualPayment) QueryOrder(ctx context.Context, in *QueryOrderRequest) (out *QueryOrderResponse, err error) { +func (s *VirtualPayment) QueryOrder(ctx context.Context, in *QueryOrderRequest) (out QueryOrderResponse, err error) { var jsonByte []byte if jsonByte, err = json.Marshal(in); err != nil { return @@ -116,12 +116,12 @@ func (s *VirtualPayment) QueryOrder(ctx context.Context, in *QueryOrderRequest) } // 使用通用方法返回错误 - err = util.DecodeWithError(response, out, "QueryOrder") + err = util.DecodeWithError(response, &out, "QueryOrder") return } // CancelCurrencyPay 取消订单 代币支付退款 (currency_pay 接口的逆操作) -func (s *VirtualPayment) CancelCurrencyPay(ctx context.Context, in *CancelCurrencyPayRequest) (out *CancelCurrencyPayResponse, err error) { +func (s *VirtualPayment) CancelCurrencyPay(ctx context.Context, in *CancelCurrencyPayRequest) (out CancelCurrencyPayResponse, err error) { var jsonByte []byte if jsonByte, err = json.Marshal(in); err != nil { return @@ -144,13 +144,13 @@ func (s *VirtualPayment) CancelCurrencyPay(ctx context.Context, in *CancelCurren } // 使用通用方法返回错误 - err = util.DecodeWithError(response, out, "CancelCurrencyPay") + err = util.DecodeWithError(response, &out, "CancelCurrencyPay") return } // NotifyProvideGoods 通知发货 // 通知已经发货完成(只能通知现金单),正常通过 xpay_goods_deliver_notify 消息推送返回成功就不需要调用这个 api 接口。这个接口用于异常情况推送不成功时手动将单改成已发货状态 -func (s *VirtualPayment) NotifyProvideGoods(ctx context.Context, in *NotifyProvideGoodsRequest) (out *NotifyProvideGoodsResponse, err error) { +func (s *VirtualPayment) NotifyProvideGoods(ctx context.Context, in *NotifyProvideGoodsRequest) (out NotifyProvideGoodsResponse, err error) { var jsonByte []byte if jsonByte, err = json.Marshal(in); err != nil { return @@ -174,12 +174,12 @@ func (s *VirtualPayment) NotifyProvideGoods(ctx context.Context, in *NotifyProvi } // 使用通用方法返回错误 - err = util.DecodeWithError(response, out, "NotifyProvideGoods") + err = util.DecodeWithError(response, &out, "NotifyProvideGoods") return } // PresentCurrency 代币赠送接口,由于目前不支付按单号查赠送单的功能,所以当需要赠送的时候可以一直重试到返回 0 或者返回 268490004(重复操作)为止 -func (s *VirtualPayment) PresentCurrency(ctx context.Context, in *PresentCurrencyRequest) (out *PresentCurrencyResponse, err error) { +func (s *VirtualPayment) PresentCurrency(ctx context.Context, in *PresentCurrencyRequest) (out PresentCurrencyResponse, err error) { var jsonByte []byte if jsonByte, err = json.Marshal(in); err != nil { return @@ -203,12 +203,12 @@ func (s *VirtualPayment) PresentCurrency(ctx context.Context, in *PresentCurrenc } // 使用通用方法返回错误 - err = util.DecodeWithError(response, out, "PresentCurrency") + err = util.DecodeWithError(response, &out, "PresentCurrency") return } // DownloadBill 下载订单交易账单 -func (s *VirtualPayment) DownloadBill(ctx context.Context, in *DownloadBillRequest) (out *DownloadBillResponse, err error) { +func (s *VirtualPayment) DownloadBill(ctx context.Context, in *DownloadBillRequest) (out DownloadBillResponse, err error) { var jsonByte []byte if jsonByte, err = json.Marshal(in); err != nil { return @@ -232,12 +232,12 @@ func (s *VirtualPayment) DownloadBill(ctx context.Context, in *DownloadBillReque } // 使用通用方法返回错误 - err = util.DecodeWithError(response, out, "DownloadBill") + err = util.DecodeWithError(response, &out, "DownloadBill") return } // RefundOrder 退款 对使用 jsapi 接口下的单进行退款 -func (s *VirtualPayment) RefundOrder(ctx context.Context, in *RefundOrderRequest) (out *RefundOrderResponse, err error) { +func (s *VirtualPayment) RefundOrder(ctx context.Context, in *RefundOrderRequest) (out RefundOrderResponse, err error) { var jsonByte []byte if jsonByte, err = json.Marshal(in); err != nil { return @@ -261,12 +261,12 @@ func (s *VirtualPayment) RefundOrder(ctx context.Context, in *RefundOrderRequest } // 使用通用方法返回错误 - err = util.DecodeWithError(response, out, "RefundOrder") + err = util.DecodeWithError(response, &out, "RefundOrder") return } // CreateWithdrawOrder 创建提现单 -func (s *VirtualPayment) CreateWithdrawOrder(ctx context.Context, in *CreateWithdrawOrderRequest) (out *CreateWithdrawOrderResponse, err error) { +func (s *VirtualPayment) CreateWithdrawOrder(ctx context.Context, in *CreateWithdrawOrderRequest) (out CreateWithdrawOrderResponse, err error) { var jsonByte []byte if jsonByte, err = json.Marshal(in); err != nil { return @@ -290,12 +290,12 @@ func (s *VirtualPayment) CreateWithdrawOrder(ctx context.Context, in *CreateWith } // 使用通用方法返回错误 - err = util.DecodeWithError(response, out, "CreateWithdrawOrder") + err = util.DecodeWithError(response, &out, "CreateWithdrawOrder") return } // QueryWithdrawOrder 查询提现单 -func (s *VirtualPayment) QueryWithdrawOrder(ctx context.Context, in *QueryWithdrawOrderRequest) (out *QueryWithdrawOrderResponse, err error) { +func (s *VirtualPayment) QueryWithdrawOrder(ctx context.Context, in *QueryWithdrawOrderRequest) (out QueryWithdrawOrderResponse, err error) { var jsonByte []byte if jsonByte, err = json.Marshal(in); err != nil { return @@ -319,12 +319,12 @@ func (s *VirtualPayment) QueryWithdrawOrder(ctx context.Context, in *QueryWithdr } // 使用通用方法返回错误 - err = util.DecodeWithError(response, out, "QueryWithdrawOrder") + err = util.DecodeWithError(response, &out, "QueryWithdrawOrder") return } // StartUploadGoods 开始上传商品 -func (s *VirtualPayment) StartUploadGoods(ctx context.Context, in *StartUploadGoodsRequest) (out *StartUploadGoodsResponse, err error) { +func (s *VirtualPayment) StartUploadGoods(ctx context.Context, in *StartUploadGoodsRequest) (out StartUploadGoodsResponse, err error) { var jsonByte []byte if jsonByte, err = json.Marshal(in); err != nil { return @@ -348,12 +348,12 @@ func (s *VirtualPayment) StartUploadGoods(ctx context.Context, in *StartUploadGo } // 使用通用方法返回错误 - err = util.DecodeWithError(response, out, "StartUploadGoods") + err = util.DecodeWithError(response, &out, "StartUploadGoods") return } // QueryUploadGoods 查询上传商品 -func (s *VirtualPayment) QueryUploadGoods(ctx context.Context, in *QueryUploadGoodsRequest) (out *QueryUploadGoodsResponse, err error) { +func (s *VirtualPayment) QueryUploadGoods(ctx context.Context, in *QueryUploadGoodsRequest) (out QueryUploadGoodsResponse, err error) { var jsonByte []byte if jsonByte, err = json.Marshal(in); err != nil { return @@ -377,12 +377,12 @@ func (s *VirtualPayment) QueryUploadGoods(ctx context.Context, in *QueryUploadGo } // 使用通用方法返回错误 - err = util.DecodeWithError(response, out, "QueryUploadGoods") + err = util.DecodeWithError(response, &out, "QueryUploadGoods") return } // StartPublishGoods 开始发布商品 -func (s *VirtualPayment) StartPublishGoods(ctx context.Context, in *StartPublishGoodsRequest) (out *StartPublishGoodsResponse, err error) { +func (s *VirtualPayment) StartPublishGoods(ctx context.Context, in *StartPublishGoodsRequest) (out StartPublishGoodsResponse, err error) { var jsonByte []byte if jsonByte, err = json.Marshal(in); err != nil { return @@ -406,12 +406,12 @@ func (s *VirtualPayment) StartPublishGoods(ctx context.Context, in *StartPublish } // 使用通用方法返回错误 - err = util.DecodeWithError(response, out, "StartPublishGoods") + err = util.DecodeWithError(response, &out, "StartPublishGoods") return } // QueryPublishGoods 查询发布商品 -func (s *VirtualPayment) QueryPublishGoods(ctx context.Context, in *QueryPublishGoodsRequest) (out *QueryPublishGoodsResponse, err error) { +func (s *VirtualPayment) QueryPublishGoods(ctx context.Context, in *QueryPublishGoodsRequest) (out QueryPublishGoodsResponse, err error) { var jsonByte []byte if jsonByte, err = json.Marshal(in); err != nil { return @@ -435,7 +435,7 @@ func (s *VirtualPayment) QueryPublishGoods(ctx context.Context, in *QueryPublish } // 使用通用方法返回错误 - err = util.DecodeWithError(response, out, "QueryPublishGoods") + err = util.DecodeWithError(response, &out, "QueryPublishGoods") return } diff --git a/officialaccount/message/message.go b/officialaccount/message/message.go index 41ffedcff..e5fa2456f 100644 --- a/officialaccount/message/message.go +++ b/officialaccount/message/message.go @@ -27,15 +27,15 @@ const ( MsgTypeVideo MsgType = "video" // MsgTypeMiniprogrampage 表示小程序卡片消息 MsgTypeMiniprogrampage MsgType = "miniprogrampage" - // MsgTypeShortVideo 表示短视频消息[限接收] + // MsgTypeShortVideo 表示短视频消息 [限接收] MsgTypeShortVideo MsgType = "shortvideo" - // MsgTypeLocation 表示坐标消息[限接收] + // MsgTypeLocation 表示坐标消息 [限接收] MsgTypeLocation MsgType = "location" - // MsgTypeLink 表示链接消息[限接收] + // MsgTypeLink 表示链接消息 [限接收] MsgTypeLink MsgType = "link" - // MsgTypeMusic 表示音乐消息[限回复] + // MsgTypeMusic 表示音乐消息 [限回复] MsgTypeMusic MsgType = "music" - // MsgTypeNews 表示图文消息[限回复] + // MsgTypeNews 表示图文消息 [限回复] MsgTypeNews MsgType = "news" // MsgTypeTransfer 表示消息消息转发到客服 MsgTypeTransfer MsgType = "transfer_customer_service" @@ -91,7 +91,7 @@ const ( const ( // 微信开放平台需要用到 - // InfoTypeVerifyTicket 返回ticket + // InfoTypeVerifyTicket 返回 ticket InfoTypeVerifyTicket InfoType = "component_verify_ticket" // InfoTypeAuthorized 授权 InfoTypeAuthorized InfoType = "authorized" @@ -108,8 +108,8 @@ type MixMessage struct { CommonToken // 基本消息 - MsgID int64 `xml:"MsgId"` // 其他消息推送过来是MsgId - TemplateMsgID int64 `xml:"MsgID"` // 模板消息推送成功的消息是MsgID + MsgID int64 `xml:"MsgId"` // 其他消息推送过来是 MsgId + TemplateMsgID int64 `xml:"MsgID"` // 模板消息推送成功的消息是 MsgID Content string `xml:"Content"` Recognition string `xml:"Recognition"` PicURL string `xml:"PicUrl"` @@ -166,17 +166,17 @@ type MixMessage struct { // 事件相关:发布能力 PublishEventInfo struct { - PublishID int64 `xml:"publish_id"` // 发布任务id + PublishID int64 `xml:"publish_id"` // 发布任务 id PublishStatus freepublish.PublishStatus `xml:"publish_status"` // 发布状态 - ArticleID string `xml:"article_id"` // 当发布状态为0时(即成功)时,返回图文的 article_id,可用于“客服消息”场景 + ArticleID string `xml:"article_id"` // 当发布状态为 0 时(即成功)时,返回图文的 article_id,可用于“客服消息”场景 ArticleDetail struct { Count uint `xml:"count"` // 文章数量 Item []struct { Index uint `xml:"idx"` // 文章对应的编号 ArticleURL string `xml:"article_url"` // 图文的永久链接 } `xml:"item"` - } `xml:"article_detail"` // 当发布状态为0时(即成功)时,返回内容 - FailIndex []uint `xml:"fail_idx"` // 当发布状态为2或4时,返回不通过的文章编号,第一篇为 1;其他发布状态则为空 + } `xml:"article_detail"` // 当发布状态为 0 时(即成功)时,返回内容 + FailIndex []uint `xml:"fail_idx"` // 当发布状态为 2 或 4 时,返回不通过的文章编号,第一篇为 1;其他发布状态则为空 } `xml:"PublishEventInfo"` // 第三方平台相关 @@ -222,19 +222,19 @@ type MixMessage struct { TraceID string `xml:"trace_id"` StatusCode int `xml:"status_code"` - //小程序名称审核结果事件推送 - Ret int32 `xml:"ret"` //审核结果 2:失败,3:成功 - NickName string `xml:"nickname"` //小程序昵称 + // 小程序名称审核结果事件推送 + Ret int32 `xml:"ret"` // 审核结果 2:失败,3:成功 + NickName string `xml:"nickname"` // 小程序昵称 // 设备相关 device.MsgDevice - //小程序审核通知 - SuccTime int `xml:"SuccTime"` //审核成功时的时间戳 - FailTime int `xml:"FailTime"` //审核不通过的时间戳 - DelayTime int `xml:"DelayTime"` //审核延后时的时间戳 - Reason string `xml:"Reason"` //审核不通过的原因 - ScreenShot string `xml:"ScreenShot"` //审核不通过的截图示例。用 | 分隔的 media_id 的列表,可通过获取永久素材接口拉取截图内容 + // 小程序审核通知 + SuccTime int `xml:"SuccTime"` // 审核成功时的时间戳 + FailTime int `xml:"FailTime"` // 审核不通过的时间戳 + DelayTime int `xml:"DelayTime"` // 审核延后时的时间戳 + Reason string `xml:"Reason"` // 审核不通过的原因 + ScreenShot string `xml:"ScreenShot"` // 审核不通过的截图示例。用 | 分隔的 media_id 的列表,可通过获取永久素材接口拉取截图内容 } // SubscribeMsgPopupEvent 订阅通知事件推送的消息体 @@ -282,7 +282,7 @@ type ResponseEncryptedXMLMsg struct { Nonce string `xml:"Nonce" json:"Nonce"` } -// CDATA 使用该类型,在序列化为 xml 文本时文本会被解析器忽略 +// CDATA 使用该类型,在序列化为 xml 文本时文本会被解析器忽略 type CDATA string // MarshalXML 实现自己的序列化方法 diff --git a/officialaccount/oauth/oauth.go b/officialaccount/oauth/oauth.go index c7c647a3d..58ebfcd64 100644 --- a/officialaccount/oauth/oauth.go +++ b/officialaccount/oauth/oauth.go @@ -1,6 +1,7 @@ package oauth import ( + ctx2 "context" "encoding/json" "fmt" "net/http" @@ -73,11 +74,28 @@ type ResAccessToken struct { UnionID string `json:"unionid"` } +// GetUserInfoByCodeContext 通过网页授权的code 换取用户的信息 +func (oauth *Oauth) GetUserInfoByCodeContext(ctx ctx2.Context, code string) (result UserInfo, err error) { + var ( + token ResAccessToken + ) + if token, err = oauth.GetUserAccessTokenContext(ctx, code); err != nil { + return + } + + return oauth.GetUserInfoContext(ctx, token.AccessToken, token.OpenID, "") +} + // GetUserAccessToken 通过网页授权的code 换取access_token(区别于context中的access_token) func (oauth *Oauth) GetUserAccessToken(code string) (result ResAccessToken, err error) { + return oauth.GetUserAccessTokenContext(ctx2.Background(), code) +} + +// GetUserAccessTokenContext 通过网页授权的code 换取access_token(区别于context中的access_token) with context +func (oauth *Oauth) GetUserAccessTokenContext(ctx ctx2.Context, code string) (result ResAccessToken, err error) { urlStr := fmt.Sprintf(accessTokenURL, oauth.AppID, oauth.AppSecret, code) var response []byte - response, err = util.HTTPGet(urlStr) + response, err = util.HTTPGetContext(ctx, urlStr) if err != nil { return } @@ -94,9 +112,14 @@ func (oauth *Oauth) GetUserAccessToken(code string) (result ResAccessToken, err // RefreshAccessToken 刷新access_token func (oauth *Oauth) RefreshAccessToken(refreshToken string) (result ResAccessToken, err error) { + return oauth.RefreshAccessTokenContext(ctx2.Background(), refreshToken) +} + +// RefreshAccessTokenContext 刷新access_token with context +func (oauth *Oauth) RefreshAccessTokenContext(ctx ctx2.Context, refreshToken string) (result ResAccessToken, err error) { urlStr := fmt.Sprintf(refreshAccessTokenURL, oauth.AppID, refreshToken) var response []byte - response, err = util.HTTPGet(urlStr) + response, err = util.HTTPGetContext(ctx, urlStr) if err != nil { return } @@ -113,9 +136,14 @@ func (oauth *Oauth) RefreshAccessToken(refreshToken string) (result ResAccessTok // CheckAccessToken 检验access_token是否有效 func (oauth *Oauth) CheckAccessToken(accessToken, openID string) (b bool, err error) { + return oauth.CheckAccessTokenContext(ctx2.Background(), accessToken, openID) +} + +// CheckAccessTokenContext 检验access_token是否有效 with context +func (oauth *Oauth) CheckAccessTokenContext(ctx ctx2.Context, accessToken, openID string) (b bool, err error) { urlStr := fmt.Sprintf(checkAccessTokenURL, accessToken, openID) var response []byte - response, err = util.HTTPGet(urlStr) + response, err = util.HTTPGetContext(ctx, urlStr) if err != nil { return } @@ -149,12 +177,17 @@ type UserInfo struct { // GetUserInfo 如果scope为 snsapi_userinfo 则可以通过此方法获取到用户基本信息 func (oauth *Oauth) GetUserInfo(accessToken, openID, lang string) (result UserInfo, err error) { + return oauth.GetUserInfoContext(ctx2.Background(), accessToken, openID, lang) +} + +// GetUserInfoContext 如果scope为 snsapi_userinfo 则可以通过此方法获取到用户基本信息 with context +func (oauth *Oauth) GetUserInfoContext(ctx ctx2.Context, accessToken, openID, lang string) (result UserInfo, err error) { if lang == "" { lang = "zh_CN" } urlStr := fmt.Sprintf(userInfoURL, accessToken, openID, lang) var response []byte - response, err = util.HTTPGet(urlStr) + response, err = util.HTTPGetContext(ctx, urlStr) if err != nil { return } diff --git a/officialaccount/server/server.go b/officialaccount/server/server.go index c741ee6cd..b0547dfdb 100644 --- a/officialaccount/server/server.go +++ b/officialaccount/server/server.go @@ -73,7 +73,7 @@ func (srv *Server) Serve() error { if err != nil { return err } - // 非安全模式下,请求处理方法返回为nil则直接回复success给微信服务器 + // 非安全模式下,请求处理方法返回为 nil 则直接回复 success 给微信服务器 if response == nil && !srv.isSafeMode { srv.String("success") return nil @@ -198,7 +198,7 @@ func (srv *Server) parseRequestMessage(rawXMLMsgBytes []byte) (msg *message.MixM if err != nil { return } - // nonstandard json, 目前小程序订阅消息返回数据格式不标准,订阅消息模板单个List返回是对象,多个List返回是数组。 + // nonstandard json, 目前小程序订阅消息返回数据格式不标准,订阅消息模板单个 List 返回是对象,多个 List 返回是数组。 if msg.MsgType == message.MsgTypeEvent { listData := gjson.Get(string(rawXMLMsgBytes), "List") if listData.IsObject() { @@ -284,7 +284,7 @@ func (srv *Server) Send() (err error) { if err != nil { return } - // TODO 如果获取不到timestamp nonce 则自己生成 + // TODO 如果获取不到 timestamp nonce 则自己生成 timestamp := srv.timestamp timestampStr := strconv.FormatInt(timestamp, 10) msgSignature := util.Signature(srv.Token, timestampStr, srv.nonce, string(encryptedMsg)) diff --git a/util/http.go b/util/http.go index 46dcb8f26..b36477448 100644 --- a/util/http.go +++ b/util/http.go @@ -17,6 +17,16 @@ import ( "golang.org/x/crypto/pkcs12" ) +// URIModifier URI修改器 +type URIModifier func(uri string) string + +var uriModifier URIModifier + +// SetURIModifier 设置URI修改器 +func SetURIModifier(fn URIModifier) { + uriModifier = fn +} + // HTTPGet get 请求 func HTTPGet(uri string) ([]byte, error) { return HTTPGetContext(context.Background(), uri) @@ -24,6 +34,9 @@ func HTTPGet(uri string) ([]byte, error) { // HTTPGetContext get 请求 func HTTPGetContext(ctx context.Context, uri string) ([]byte, error) { + if uriModifier != nil { + uri = uriModifier(uri) + } request, err := http.NewRequestWithContext(ctx, http.MethodGet, uri, nil) if err != nil { return nil, err @@ -47,6 +60,9 @@ func HTTPPost(uri string, data string) ([]byte, error) { // HTTPPostContext post 请求 func HTTPPostContext(ctx context.Context, uri string, data []byte, header map[string]string) ([]byte, error) { + if uriModifier != nil { + uri = uriModifier(uri) + } body := bytes.NewBuffer(data) request, err := http.NewRequestWithContext(ctx, http.MethodPost, uri, body) if err != nil { @@ -71,6 +87,9 @@ func HTTPPostContext(ctx context.Context, uri string, data []byte, header map[st // PostJSONContext post json 数据请求 func PostJSONContext(ctx context.Context, uri string, obj interface{}) ([]byte, error) { + if uriModifier != nil { + uri = uriModifier(uri) + } jsonBuf := new(bytes.Buffer) enc := json.NewEncoder(jsonBuf) enc.SetEscapeHTML(false) @@ -146,6 +165,9 @@ type MultipartFormField struct { // PostMultipartForm 上传文件或其他多个字段 func PostMultipartForm(fields []MultipartFormField, uri string) (respBody []byte, err error) { + if uriModifier != nil { + uri = uriModifier(uri) + } bodyBuf := &bytes.Buffer{} bodyWriter := multipart.NewWriter(bodyBuf) @@ -198,6 +220,9 @@ func PostMultipartForm(fields []MultipartFormField, uri string) (respBody []byte // PostXML perform a HTTP/POST request with XML body func PostXML(uri string, obj interface{}) ([]byte, error) { + if uriModifier != nil { + uri = uriModifier(uri) + } xmlData, err := xml.Marshal(obj) if err != nil { return nil, err @@ -259,6 +284,9 @@ func pkcs12ToPem(p12 []byte, password string) tls.Certificate { // PostXMLWithTLS perform a HTTP/POST request with XML body and TLS func PostXMLWithTLS(uri string, obj interface{}, ca, key string) ([]byte, error) { + if uriModifier != nil { + uri = uriModifier(uri) + } xmlData, err := xml.Marshal(obj) if err != nil { return nil, err diff --git a/work/addresslist/department.go b/work/addresslist/department.go index dc773dc19..b2feca0bf 100644 --- a/work/addresslist/department.go +++ b/work/addresslist/department.go @@ -12,7 +12,8 @@ const ( // departmentSimpleListURL 获取子部门ID列表 departmentSimpleListURL = "https://qyapi.weixin.qq.com/cgi-bin/department/simplelist?access_token=%s&id=%d" // departmentListURL 获取部门列表 - departmentListURL = "https://qyapi.weixin.qq.com/cgi-bin/department/list?access_token=%s" + departmentListURL = "https://qyapi.weixin.qq.com/cgi-bin/department/list?access_token=%s" + departmentListByIDURL = "https://qyapi.weixin.qq.com/cgi-bin/department/list?access_token=%s&id=%d" // departmentGetURL 获取单个部门详情 https://qyapi.weixin.qq.com/cgi-bin/department/get?access_token=ACCESS_TOKEN&id=ID departmentGetURL = "https://qyapi.weixin.qq.com/cgi-bin/department/get?access_token=%s&id=%d" ) @@ -80,10 +81,8 @@ func (r *Client) DepartmentCreate(req *DepartmentCreateRequest) (*DepartmentCrea return nil, err } result := &DepartmentCreateResponse{} - if err = util.DecodeWithError(response, result, "DepartmentCreate"); err != nil { - return nil, err - } - return result, nil + err = util.DecodeWithError(response, result, "DepartmentCreate") + return result, err } // DepartmentSimpleList 获取子部门ID列表 @@ -101,30 +100,44 @@ func (r *Client) DepartmentSimpleList(departmentID int) ([]*DepartmentID, error) return nil, err } result := &DepartmentSimpleListResponse{} - if err = util.DecodeWithError(response, result, "DepartmentSimpleList"); err != nil { - return nil, err - } - return result.DepartmentID, nil + err = util.DecodeWithError(response, result, "DepartmentSimpleList") + return result.DepartmentID, err } // DepartmentList 获取部门列表 // @desc https://developer.work.weixin.qq.com/document/path/90208 func (r *Client) DepartmentList() ([]*Department, error) { + return r.DepartmentListByID(0) +} + +// DepartmentListByID 获取部门列表 +// +// departmentID 部门id。获取指定部门及其下的子部门(以及子部门的子部门等等,递归) +// +// @desc https://developer.work.weixin.qq.com/document/path/90208 +func (r *Client) DepartmentListByID(departmentID int) ([]*Department, error) { + var formatURL string + // 获取accessToken accessToken, err := r.GetAccessToken() if err != nil { return nil, err } + + if departmentID > 0 { + formatURL = fmt.Sprintf(departmentListByIDURL, accessToken, departmentID) + } else { + formatURL = fmt.Sprintf(departmentListURL, accessToken) + } + // 发起http请求 - response, err := util.HTTPGet(fmt.Sprintf(departmentListURL, accessToken)) + response, err := util.HTTPGet(formatURL) if err != nil { return nil, err } // 按照结构体解析返回值 result := &DepartmentListResponse{} - if err = util.DecodeWithError(response, result, "DepartmentList"); err != nil { - return nil, err - } + err = util.DecodeWithError(response, result, "DepartmentList") // 返回数据 return result.Department, err } @@ -144,8 +157,6 @@ func (r *Client) DepartmentGet(departmentID int) (*Department, error) { return nil, err } result := &DepartmentGetResponse{} - if err = util.DecodeWithError(response, result, "DepartmentGet"); err != nil { - return nil, err - } - return &result.Department, nil + err = util.DecodeWithError(response, result, "DepartmentGet") + return &result.Department, err } diff --git a/work/addresslist/linkedcorp.go b/work/addresslist/linkedcorp.go index d00fac28f..3d85e67e9 100644 --- a/work/addresslist/linkedcorp.go +++ b/work/addresslist/linkedcorp.go @@ -41,10 +41,8 @@ func (r *Client) GetPermList() (*GetPermListResponse, error) { return nil, err } result := &GetPermListResponse{} - if err = util.DecodeWithError(response, result, "GetPermList"); err != nil { - return nil, err - } - return result, nil + err = util.DecodeWithError(response, result, "GetPermList") + return result, err } // GetLinkedCorpUserRequest 获取互联企业成员详细信息请求 @@ -111,10 +109,8 @@ func (r *Client) GetLinkedCorpUser(req *GetLinkedCorpUserRequest) (*GetLinkedCor return nil, err } result := &GetLinkedCorpUserResponse{} - if err = util.DecodeWithError(response, result, "GetLinkedCorpUser"); err != nil { - return nil, err - } - return result, nil + err = util.DecodeWithError(response, result, "GetLinkedCorpUser") + return result, err } // LinkedCorpSimpleListRequest 获取互联企业部门成员请求 @@ -151,10 +147,8 @@ func (r *Client) LinkedCorpSimpleList(req *LinkedCorpSimpleListRequest) (*Linked return nil, err } result := &LinkedCorpSimpleListResponse{} - if err = util.DecodeWithError(response, result, "LinkedCorpSimpleList"); err != nil { - return nil, err - } - return result, nil + err = util.DecodeWithError(response, result, "LinkedCorpSimpleList") + return result, err } // LinkedCorpUserListRequest 获取互联企业部门成员详情请求 @@ -183,10 +177,8 @@ func (r *Client) LinkedCorpUserList(req *LinkedCorpUserListRequest) (*LinkedCorp return nil, err } result := &LinkedCorpUserListResponse{} - if err = util.DecodeWithError(response, result, "LinkedCorpUserList"); err != nil { - return nil, err - } - return result, nil + err = util.DecodeWithError(response, result, "LinkedCorpUserList") + return result, err } // LinkedCorpDepartmentListRequest 获取互联企业部门列表请求 @@ -223,8 +215,6 @@ func (r *Client) LinkedCorpDepartmentList(req *LinkedCorpDepartmentListRequest) return nil, err } result := &LinkedCorpDepartmentListResponse{} - if err = util.DecodeWithError(response, result, "LinkedCorpDepartmentList"); err != nil { - return nil, err - } - return result, nil + err = util.DecodeWithError(response, result, "LinkedCorpDepartmentList") + return result, err } diff --git a/work/addresslist/tag.go b/work/addresslist/tag.go index 3e976e3e5..08a5c0018 100644 --- a/work/addresslist/tag.go +++ b/work/addresslist/tag.go @@ -51,10 +51,8 @@ func (r *Client) CreateTag(req *CreateTagRequest) (*CreateTagResponse, error) { return nil, err } result := &CreateTagResponse{} - if err = util.DecodeWithError(response, result, "CreateTag"); err != nil { - return nil, err - } - return result, nil + err = util.DecodeWithError(response, result, "CreateTag") + return result, err } type ( @@ -129,10 +127,8 @@ func (r *Client) GetTag(tagID int) (*GetTagResponse, error) { return nil, err } result := &GetTagResponse{} - if err = util.DecodeWithError(response, result, "GetTag"); err != nil { - return nil, err - } - return result, nil + err = util.DecodeWithError(response, result, "GetTag") + return result, err } type ( @@ -165,10 +161,8 @@ func (r *Client) AddTagUsers(req *AddTagUsersRequest) (*AddTagUsersResponse, err return nil, err } result := &AddTagUsersResponse{} - if err = util.DecodeWithError(response, result, "AddTagUsers"); err != nil { - return nil, err - } - return result, nil + err = util.DecodeWithError(response, result, "AddTagUsers") + return result, err } type ( @@ -201,10 +195,8 @@ func (r *Client) DelTagUsers(req *DelTagUsersRequest) (*DelTagUsersResponse, err return nil, err } result := &DelTagUsersResponse{} - if err = util.DecodeWithError(response, result, "DelTagUsers"); err != nil { - return nil, err - } - return result, nil + err = util.DecodeWithError(response, result, "DelTagUsers") + return result, err } type ( @@ -235,8 +227,6 @@ func (r *Client) ListTag() (*ListTagResponse, error) { return nil, err } result := &ListTagResponse{} - if err = util.DecodeWithError(response, result, "ListTag"); err != nil { - return nil, err - } - return result, nil + err = util.DecodeWithError(response, result, "ListTag") + return result, err } diff --git a/work/addresslist/user.go b/work/addresslist/user.go index 07cc8f55e..61bb14612 100644 --- a/work/addresslist/user.go +++ b/work/addresslist/user.go @@ -61,10 +61,7 @@ func (r *Client) UserSimpleList(departmentID int) ([]*UserList, error) { } result := &UserSimpleListResponse{} err = util.DecodeWithError(response, result, "UserSimpleList") - if err != nil { - return nil, err - } - return result.UserList, nil + return result.UserList, err } type ( @@ -153,10 +150,8 @@ func (r *Client) UserCreate(req *UserCreateRequest) (*UserCreateResponse, error) return nil, err } result := &UserCreateResponse{} - if err = util.DecodeWithError(response, result, "UserCreate"); err != nil { - return nil, err - } - return result, nil + err = util.DecodeWithError(response, result, "UserCreate") + return result, err } // UserGetResponse 获取部门成员响应 @@ -245,10 +240,7 @@ func (r *Client) UserGet(UserID string) (*UserGetResponse, error) { } result := &UserGetResponse{} err = util.DecodeWithError(response, result, "UserGet") - if err != nil { - return nil, err - } - return result, nil + return result, err } type ( @@ -279,10 +271,8 @@ func (r *Client) UserDelete(userID string) (*UserDeleteResponse, error) { return nil, err } result := &UserDeleteResponse{} - if err = util.DecodeWithError(response, result, "UserDelete"); err != nil { - return nil, err - } - return result, nil + err = util.DecodeWithError(response, result, "UserDelete") + return result, err } // UserListIDRequest 获取成员ID列表请求 @@ -324,10 +314,8 @@ func (r *Client) UserListID(req *UserListIDRequest) (*UserListIDResponse, error) return nil, err } result := &UserListIDResponse{} - if err = util.DecodeWithError(response, result, "UserListID"); err != nil { - return nil, err - } - return result, nil + err = util.DecodeWithError(response, result, "UserListID") + return result, err } type ( @@ -366,10 +354,8 @@ func (r *Client) ConvertToOpenID(userID string) (string, error) { return "", err } result := &convertToOpenIDResponse{} - if err = util.DecodeWithError(response, result, "ConvertToOpenID"); err != nil { - return "", err - } - return result.OpenID, nil + err = util.DecodeWithError(response, result, "ConvertToOpenID") + return result.OpenID, err } type ( @@ -408,8 +394,6 @@ func (r *Client) ConvertToUserID(openID string) (string, error) { return "", err } result := &convertToUserIDResponse{} - if err = util.DecodeWithError(response, result, "ConvertToUserID"); err != nil { - return "", err - } - return result.UserID, nil + err = util.DecodeWithError(response, result, "ConvertToUserID") + return result.UserID, err } diff --git a/work/appchat/appchat.go b/work/appchat/appchat.go index 65d565082..076680de3 100644 --- a/work/appchat/appchat.go +++ b/work/appchat/appchat.go @@ -82,11 +82,9 @@ func (r *Client) Send(apiName string, request interface{}) (*SendResponse, error } // 按照结构体解析返回值 result := &SendResponse{} - if err = util.DecodeWithError(response, result, apiName); err != nil { - return nil, err - } + err = util.DecodeWithError(response, result, apiName) // 返回数据 - return result, nil + return result, err } // SendText 发送文本消息 diff --git a/work/checkin/checkin.go b/work/checkin/checkin.go deleted file mode 100644 index 7dbd0a381..000000000 --- a/work/checkin/checkin.go +++ /dev/null @@ -1,69 +0,0 @@ -package checkin - -import ( - "fmt" - - "github.com/silenceper/wechat/v2/util" -) - -const ( - // getCheckinDataURL 获取打卡记录数据 - getCheckinDataURL = "https://qyapi.weixin.qq.com/cgi-bin/checkin/getcheckindata?access_token=%s" -) - -type ( - // GetCheckinDataRequest 获取打卡记录数据请求 - GetCheckinDataRequest struct { - OpenCheckinDataType int64 `json:"opencheckindatatype"` - StartTime int64 `json:"starttime"` - EndTime int64 `json:"endtime"` - UserIDList []string `json:"useridlist"` - } - // GetCheckinDataResponse 获取打卡记录数据响应 - GetCheckinDataResponse struct { - util.CommonError - CheckinData []*GetCheckinDataItem `json:"checkindata"` - } - // GetCheckinDataItem 打卡记录数据 - GetCheckinDataItem struct { - UserID string `json:"userid"` - GroupName string `json:"groupname"` - CheckinType string `json:"checkin_type"` - ExceptionType string `json:"exception_type"` - CheckinTime int64 `json:"checkin_time"` - LocationTitle string `json:"location_title"` - LocationDetail string `json:"location_detail"` - WifiName string `json:"wifiname"` - Notes string `json:"notes"` - WifiMac string `json:"wifimac"` - MediaIDs []string `json:"mediaids"` - SchCheckinTime int64 `json:"sch_checkin_time"` - GroupID int64 `json:"groupid"` - ScheduleID int64 `json:"schedule_id"` - TimelineID int64 `json:"timeline_id"` - Lat int64 `json:"lat,omitempty"` - Lng int64 `json:"lng,omitempty"` - DeviceID string `json:"deviceid,omitempty"` - } -) - -// GetCheckinData 获取打卡记录数据 -// @see https://developer.work.weixin.qq.com/document/path/90262 -func (r *Client) GetCheckinData(req *GetCheckinDataRequest) (*GetCheckinDataResponse, error) { - var ( - accessToken string - err error - ) - if accessToken, err = r.GetAccessToken(); err != nil { - return nil, err - } - var response []byte - if response, err = util.PostJSON(fmt.Sprintf(getCheckinDataURL, accessToken), req); err != nil { - return nil, err - } - result := &GetCheckinDataResponse{} - if err = util.DecodeWithError(response, result, "GetCheckinData"); err != nil { - return nil, err - } - return result, nil -} diff --git a/work/checkin/record.go b/work/checkin/record.go new file mode 100644 index 000000000..18e97fa51 --- /dev/null +++ b/work/checkin/record.go @@ -0,0 +1,660 @@ +package checkin + +import ( + "fmt" + + "github.com/silenceper/wechat/v2/util" +) + +const ( + // getCheckinDataURL 获取打卡记录数据 + getCheckinDataURL = "https://qyapi.weixin.qq.com/cgi-bin/checkin/getcheckindata?access_token=%s" + // getDayDataURL 获取打卡日报数据 + getDayDataURL = "https://qyapi.weixin.qq.com/cgi-bin/checkin/getcheckin_daydata?access_token=%s" + // getMonthDataURL 获取打卡月报数据 + getMonthDataURL = "https://qyapi.weixin.qq.com/cgi-bin/checkin/getcheckin_monthdata?access_token=%s" + // getCorpOptionURL 获取企业所有打卡规则 + getCorpOptionURL = "https://qyapi.weixin.qq.com/cgi-bin/checkin/getcorpcheckinoption?access_token=%s" + // getOptionURL 获取员工打卡规则 + getOptionURL = "https://qyapi.weixin.qq.com/cgi-bin/checkin/getcheckinoption?access_token=%s" + // getScheduleListURL 获取打卡人员排班信息 + getScheduleListURL = "https://qyapi.weixin.qq.com/cgi-bin/checkin/getcheckinschedulist?access_token=%s" + // getHardwareDataURL获取设备打卡数据 + getHardwareDataURL = "https://qyapi.weixin.qq.com/cgi-bin/hardware/get_hardware_checkin_data?access_token=%s" +) + +type ( + // GetCheckinDataRequest 获取打卡记录数据请求 + GetCheckinDataRequest struct { + OpenCheckinDataType int64 `json:"opencheckindatatype"` + StartTime int64 `json:"starttime"` + EndTime int64 `json:"endtime"` + UserIDList []string `json:"useridlist"` + } + // GetCheckinDataResponse 获取打卡记录数据响应 + GetCheckinDataResponse struct { + util.CommonError + CheckinData []*GetCheckinDataItem `json:"checkindata"` + } + // GetCheckinDataItem 打卡记录数据 + GetCheckinDataItem struct { + UserID string `json:"userid"` + GroupName string `json:"groupname"` + CheckinType string `json:"checkin_type"` + ExceptionType string `json:"exception_type"` + CheckinTime int64 `json:"checkin_time"` + LocationTitle string `json:"location_title"` + LocationDetail string `json:"location_detail"` + WifiName string `json:"wifiname"` + Notes string `json:"notes"` + WifiMac string `json:"wifimac"` + MediaIDs []string `json:"mediaids"` + SchCheckinTime int64 `json:"sch_checkin_time"` + GroupID int64 `json:"groupid"` + ScheduleID int64 `json:"schedule_id"` + TimelineID int64 `json:"timeline_id"` + Lat int64 `json:"lat,omitempty"` + Lng int64 `json:"lng,omitempty"` + DeviceID string `json:"deviceid,omitempty"` + } +) + +// GetCheckinData 获取打卡记录数据 +// @see https://developer.work.weixin.qq.com/document/path/90262 +func (r *Client) GetCheckinData(req *GetCheckinDataRequest) (*GetCheckinDataResponse, error) { + var ( + accessToken string + err error + ) + if accessToken, err = r.GetAccessToken(); err != nil { + return nil, err + } + var response []byte + if response, err = util.PostJSON(fmt.Sprintf(getCheckinDataURL, accessToken), req); err != nil { + return nil, err + } + result := &GetCheckinDataResponse{} + err = util.DecodeWithError(response, result, "GetCheckinData") + return result, err +} + +type ( + // GetDayDataResponse 获取打卡日报数据 + GetDayDataResponse struct { + util.CommonError + Datas []DayDataItem `json:"datas"` + } + + // DayDataItem 日报 + DayDataItem struct { + BaseInfo DayBaseInfo `json:"base_info"` + SummaryInfo DaySummaryInfo `json:"summary_info"` + HolidayInfos []HolidayInfo `json:"holiday_infos"` + ExceptionInfos []ExceptionInfo `json:"exception_infos"` + OtInfo OtInfo `json:"ot_info"` + SpItems []SpItem `json:"sp_items"` + } + + // DayBaseInfo 基础信息 + DayBaseInfo struct { + Date int64 `json:"date"` + RecordType int64 `json:"record_type"` + Name string `json:"name"` + NameEx string `json:"name_ex"` + DepartsName string `json:"departs_name"` + AcctID string `json:"acctid"` + DayType int64 `json:"day_type"` + RuleInfo DayRuleInfo `json:"rule_info"` + } + + // DayCheckInTime 当日打卡时间 + DayCheckInTime struct { + WorkSec int64 `json:"work_sec"` + OffWorkSec int64 `json:"off_work_sec"` + } + + // DayRuleInfo 打卡人员所属规则信息 + DayRuleInfo struct { + GroupID int64 `json:"groupid"` + GroupName string `json:"groupname"` + ScheduleID int64 `json:"scheduleid"` + ScheduleName string `json:"schedulename"` + CheckInTimes []DayCheckInTime `json:"checkintime"` + } + + // DaySummaryInfo 汇总信息 + DaySummaryInfo struct { + CheckinCount int64 `json:"checkin_count"` + RegularWorkSec int64 `json:"regular_work_sec"` + StandardWorkSec int64 `json:"standard_work_sec"` + EarliestTime int64 `json:"earliest_time"` + LastestTime int64 `json:"lastest_time"` + } + + // HolidayInfo 假勤相关信息 + HolidayInfo struct { + SpNumber string `json:"sp_number"` + SpTitle SpTitle `json:"sp_title"` + SpDescription SpDescription `json:"sp_description"` + } + + // SpTitle 假勤信息摘要-标题信息 + SpTitle struct { + Data []SpData `json:"data"` + } + + // SpDescription 假勤信息摘要-描述信息 + SpDescription struct { + Data []SpData `json:"data"` + } + + // SpData 假勤信息(多种语言描述,目前只有中文一种) + SpData struct { + Lang string `json:"lang"` + Text string `json:"text"` + } + + // SpItem 假勤统计信息 + SpItem struct { + Count int64 `json:"count"` + Duration int64 `json:"duration"` + TimeType int64 `json:"time_type"` + Type int64 `json:"type"` + VacationID int64 `json:"vacation_id"` + Name string `json:"name"` + } + + // ExceptionInfo 校准状态信息 + ExceptionInfo struct { + Count int64 `json:"count"` + Duration int64 `json:"duration"` + Exception int64 `json:"exception"` + } + + // OtInfo 加班信息 + OtInfo struct { + OtStatus int64 `json:"ot_status"` + OtDuration int64 `json:"ot_duration"` + ExceptionDuration []uint64 `json:"exception_duration"` + } +) + +// GetDayData 获取打卡日报数据 +// @see https://developer.work.weixin.qq.com/document/path/96498 +func (r *Client) GetDayData(req *GetCheckinDataRequest) (result *GetDayDataResponse, err error) { + var ( + response []byte + accessToken string + ) + if accessToken, err = r.GetAccessToken(); err != nil { + return + } + if response, err = util.PostJSON(fmt.Sprintf(getDayDataURL, accessToken), req); err != nil { + return + } + + result = new(GetDayDataResponse) + err = util.DecodeWithError(response, result, "GetDayData") + return +} + +type ( + // GetMonthDataResponse 获取打卡月报数据 + GetMonthDataResponse struct { + util.CommonError + Datas []MonthDataItem `json:"datas"` + } + + // MonthDataItem 月报数据 + MonthDataItem struct { + BaseInfo MonthBaseInfo `json:"base_info"` + SummaryInfo MonthSummaryInfo `json:"summary_info"` + ExceptionInfos []ExceptionInfo `json:"exception_infos"` + SpItems []SpItem `json:"sp_items"` + OverWorkInfo OverWorkInfo `json:"overwork_info"` + } + + // MonthBaseInfo 基础信息 + MonthBaseInfo struct { + RecordType int64 `json:"record_type"` + Name string `json:"name"` + NameEx string `json:"name_ex"` + DepartsName string `json:"departs_name"` + AcctID string `json:"acctid"` + RuleInfo MonthRuleInfo `json:"rule_info"` + } + + // MonthRuleInfo 打卡人员所属规则信息 + MonthRuleInfo struct { + GroupID int64 `json:"groupid"` + GroupName string `json:"groupname"` + } + + // MonthSummaryInfo 汇总信息 + MonthSummaryInfo struct { + WorkDays int64 `json:"work_days"` + ExceptDays int64 `json:"except_days"` + RegularDays int64 `json:"regular_days"` + RegularWorkSec int64 `json:"regular_work_sec"` + StandardWorkSec int64 `json:"standard_work_sec"` + } + + // OverWorkInfo 加班情况 + OverWorkInfo struct { + WorkdayOverSec int64 `json:"workday_over_sec"` + HolidayOverSec int64 `json:"holidays_over_sec"` + RestDayOverSec int64 `json:"restdays_over_sec"` + } +) + +// GetMonthData 获取打卡月报数据 +// @see https://developer.work.weixin.qq.com/document/path/96499 +func (r *Client) GetMonthData(req *GetCheckinDataRequest) (result *GetMonthDataResponse, err error) { + var ( + response []byte + accessToken string + ) + if accessToken, err = r.GetAccessToken(); err != nil { + return + } + if response, err = util.PostJSON(fmt.Sprintf(getMonthDataURL, accessToken), req); err != nil { + return + } + + result = new(GetMonthDataResponse) + err = util.DecodeWithError(response, result, "GetMonthData") + return +} + +// GetCorpOptionResponse 获取企业所有打卡规则响应 +type GetCorpOptionResponse struct { + util.CommonError + Group []CorpOptionGroup `json:"group"` +} + +// CorpOptionGroup 企业规则信息列表 +type CorpOptionGroup struct { + GroupType int64 `json:"grouptype"` + GroupID int64 `json:"groupid"` + GroupName string `json:"groupname"` + CheckinDate []GroupCheckinDate `json:"checkindate"` + SpeWorkdays []SpeWorkdays `json:"spe_workdays"` + SpeOffDays []SpeOffDays `json:"spe_offdays"` + SyncHolidays bool `json:"sync_holidays"` + NeedPhoto bool `json:"need_photo"` + NoteCanUseLocalPic bool `json:"note_can_use_local_pic"` + AllowCheckinOffWorkday bool `json:"allow_checkin_offworkday"` + AllowApplyOffWorkday bool `json:"allow_apply_offworkday"` + WifiMacInfos []WifiMacInfos `json:"wifimac_infos"` + LocInfos []LocInfos `json:"loc_infos"` + Range []Range `json:"range"` + CreateTime int64 `json:"create_time"` + WhiteUsers []string `json:"white_users"` + Type int64 `json:"type"` + ReporterInfo ReporterInfo `json:"reporterinfo"` + OtInfo GroupOtInfo `json:"ot_info"` + OtApplyInfo OtApplyInfo `json:"otapplyinfo"` + Uptime int64 `json:"uptime"` + AllowApplyBkCnt int64 `json:"allow_apply_bk_cnt"` + OptionOutRange int64 `json:"option_out_range"` + CreateUserID string `json:"create_userid"` + UseFaceDetect bool `json:"use_face_detect"` + AllowApplyBkDayLimit int64 `json:"allow_apply_bk_day_limit"` + UpdateUserID string `json:"update_userid"` + BukaRestriction int64 `json:"buka_restriction"` + ScheduleList []ScheduleList `json:"schedulelist"` + OffWorkIntervalTime int64 `json:"offwork_interval_time"` +} + +// GroupCheckinDate 打卡时间,当规则类型为排班时没有意义 +type GroupCheckinDate struct { + Workdays []int64 `json:"workdays"` + CheckinTime []GroupCheckinTime `json:"checkintime"` + NoNeedOffWork bool `json:"noneed_offwork"` + LimitAheadTime int64 `json:"limit_aheadtime"` + FlexOnDutyTime int64 `json:"flex_on_duty_time"` + FlexOffDutyTime int64 `json:"flex_off_duty_time"` +} + +// GroupCheckinTime 工作日上下班打卡时间信息 +type GroupCheckinTime struct { + WorkSec int64 `json:"work_sec"` + OffWorkSec int64 `json:"off_work_sec"` + RemindWorkSec int64 `json:"remind_work_sec"` + RemindOffWorkSec int64 `json:"remind_off_work_sec"` +} + +// SpeWorkdays 特殊日期-必须打卡日期信息 +type SpeWorkdays struct { + Timestamp int64 `json:"timestamp"` + Notes string `json:"notes"` + CheckinTime []GroupCheckinTime `json:"checkintime"` +} + +// SpeOffDays 特殊日期-不用打卡日期信息 +type SpeOffDays struct { + Timestamp int64 `json:"timestamp"` + Notes string `json:"notes"` +} + +// WifiMacInfos 打卡地点-WiFi打卡信息 +type WifiMacInfos struct { + WifiName string `json:"wifiname"` + WifiMac string `json:"wifimac"` +} + +// LocInfos 打卡地点-位置打卡信息 +type LocInfos struct { + Lat int64 `json:"lat"` + Lng int64 `json:"lng"` + LocTitle string `json:"loc_title"` + LocDetail string `json:"loc_detail"` + Distance int64 `json:"distance"` +} + +// Range 打卡人员信息 +type Range struct { + PartyID []string `json:"partyid"` + UserID []string `json:"userid"` + TagID []int64 `json:"tagid"` +} + +// ReporterInfo 汇报对象信息 +type ReporterInfo struct { + Reporters []Reporters `json:"reporters"` + UpdateTime int64 `json:"updatetime"` +} + +// Reporters 汇报对象,每个汇报人用userid表示 +type Reporters struct { + UserID string `json:"userid"` +} + +// GroupOtInfo 加班信息 +type GroupOtInfo struct { + Type int64 `json:"type"` + AllowOtWorkingDay bool `json:"allow_ot_workingday"` + AllowOtNonWorkingDay bool `json:"allow_ot_nonworkingday"` + OtCheckInfo OtCheckInfo `json:"otcheckinfo"` +} + +// OtCheckInfo 以打卡时间为准-加班时长计算规则信息 +type OtCheckInfo struct { + OtWorkingDayTimeStart int64 `json:"ot_workingday_time_start"` + OtWorkingDayTimeMin int64 `json:"ot_workingday_time_min"` + OtWorkingDayTimeMax int64 `json:"ot_workingday_time_max"` + OtNonworkingDayTimeMin int64 `json:"ot_nonworkingday_time_min"` + OtNonworkingDayTimeMax int64 `json:"ot_nonworkingday_time_max"` + OtNonworkingDaySpanDayTime int64 `json:"ot_nonworkingday_spanday_time"` + OtWorkingDayRestInfo OtRestInfo `json:"ot_workingday_restinfo"` + OtNonWorkingDayRestInfo OtRestInfo `json:"ot_nonworkingday_restinfo"` +} + +// OtRestInfo 加班-休息扣除配置信息 +type OtRestInfo struct { + Type int64 `json:"type"` + FixTimeRule FixTimeRule `json:"fix_time_rule"` + CalOtTimeRule CalOtTimeRule `json:"cal_ottime_rule"` +} + +// FixTimeRule 工作日加班-指定休息时间配置信息 +type FixTimeRule struct { + FixTimeBeginSec int64 `json:"fix_time_begin_sec"` + FixTimeEndSec int64 `json:"fix_time_end_sec"` +} + +// CalOtTimeRule 工作日加班-按加班时长扣除配置信息 +type CalOtTimeRule struct { + Items []CalOtTimeRuleItem `json:"items"` +} + +// CalOtTimeRuleItem 工作日加班-按加班时长扣除条件信息 +type CalOtTimeRuleItem struct { + OtTime int64 `json:"ot_time"` + RestTime int64 `json:"rest_time"` +} + +// OtApplyInfo 以加班申请核算打卡记录相关信息 +type OtApplyInfo struct { + AllowOtWorkingDay bool `json:"allow_ot_workingday"` + AllowOtNonWorkingDay bool `json:"allow_ot_nonworkingday"` + Uiptime int64 `json:"uptime"` + OtNonworkingDaySpanDayTime int64 `json:"ot_nonworkingday_spanday_time"` + OtWorkingDayRestInfo OtRestInfo `json:"ot_workingday_restinfo"` + OtNonWorkingDayRestInfo OtRestInfo `json:"ot_nonworkingday_restinfo"` +} + +// ScheduleList 排班信息列表 +type ScheduleList struct { + ScheduleID int64 `json:"schedule_id"` + ScheduleName string `json:"schedule_name"` + TimeSection []TimeSection `json:"time_section"` + LimitAheadTime int64 `json:"limit_aheadtime"` + NoNeedOffWork bool `json:"noneed_offwork"` + LimitOffTime int64 `json:"limit_offtime"` + FlexOnDutyTime int64 `json:"flex_on_duty_time"` + FlexOffDutyTime int64 `json:"flex_off_duty_time"` + AllowFlex bool `json:"allow_flex"` + LateRule LateRule `json:"late_rule"` + MaxAllowArriveEarly int64 `json:"max_allow_arrive_early"` + MaxAllowArriveLate int64 `json:"max_allow_arrive_late"` +} + +// TimeSection 班次上下班时段信息 +type TimeSection struct { + TimeID int64 `json:"time_id"` + WorkSec int64 `json:"work_sec"` + OffWorkSec int64 `json:"off_work_sec"` + RemindWorkSec int64 `json:"remind_work_sec"` + RemindOffWorkSec int64 `json:"remind_off_work_sec"` + RestBeginTime int64 `json:"rest_begin_time"` + RestEndTime int64 `json:"rest_end_time"` + AllowRest bool `json:"allow_rest"` +} + +// LateRule 晚走晚到时间规则信息 +type LateRule struct { + AllowOffWorkAfterTime bool `json:"allow_offwork_after_time"` + TimeRules []TimeRule `json:"timerules"` +} + +// TimeRule 迟到规则时间 +type TimeRule struct { + OffWorkAfterTime int64 `json:"offwork_after_time"` + OnWorkFlexTime int64 `json:"onwork_flex_time"` +} + +// GetCorpOption 获取企业所有打卡规则 +// @see https://developer.work.weixin.qq.com/document/path/93384 +func (r *Client) GetCorpOption() (*GetCorpOptionResponse, error) { + var ( + accessToken string + err error + ) + if accessToken, err = r.GetAccessToken(); err != nil { + return nil, err + } + var response []byte + if response, err = util.HTTPPost(fmt.Sprintf(getCorpOptionURL, accessToken), ""); err != nil { + return nil, err + } + result := &GetCorpOptionResponse{} + err = util.DecodeWithError(response, result, "GetCorpOption") + return result, err +} + +// GetOptionRequest 获取员工打卡规则请求 +type GetOptionRequest struct { + Datetime int64 `json:"datetime"` + UserIDList []string `json:"useridlist"` +} + +// GetOptionResponse 获取员工打卡规则响应 +type GetOptionResponse struct { + util.CommonError + Info []OptionInfo `json:"info"` +} + +// OptionInfo 打卡规则列表 +type OptionInfo struct { + UserID string `json:"userid"` + Group OptionGroup `json:"group"` +} + +// OptionGroup 打卡规则相关信息 +type OptionGroup struct { + GroupType int64 `json:"grouptype"` + GroupID int64 `json:"groupid"` + GroupName string `json:"groupname"` + CheckinDate []OptionCheckinDate `json:"checkindate"` + SpeWorkdays []SpeWorkdays `json:"spe_workdays"` + SpeOffDays []SpeOffDays `json:"spe_offdays"` + SyncHolidays bool `json:"sync_holidays"` + NeedPhoto bool `json:"need_photo"` + WifiMacInfos []WifiMacInfos `json:"wifimac_infos"` + NoteCanUseLocalPic bool `json:"note_can_use_local_pic"` + AllowCheckinOffWorkday bool `json:"allow_checkin_offworkday"` + AllowApplyOffWorkday bool `json:"allow_apply_offworkday"` + LocInfos []LocInfos `json:"loc_infos"` + ScheduleList []ScheduleList `json:"schedulelist"` + BukaRestriction int64 `json:"buka_restriction"` +} + +// OptionCheckinDate 打卡时间配置 +type OptionCheckinDate struct { + Workdays []int64 `json:"workdays"` + CheckinTime []GroupCheckinTime `json:"checkintime"` + FlexTime int64 `json:"flex_time"` + NoNeedOffWork bool `json:"noneed_offwork"` + LimitAheadTime int64 `json:"limit_aheadtime"` + FlexOnDutyTime int64 `json:"flex_on_duty_time"` + FlexOffDutyTime int64 `json:"flex_off_duty_time"` +} + +// GetOption 获取员工打卡规则 +// see https://developer.work.weixin.qq.com/document/path/90263 +func (r *Client) GetOption(req *GetOptionRequest) (*GetOptionResponse, error) { + var ( + accessToken string + err error + ) + if accessToken, err = r.GetAccessToken(); err != nil { + return nil, err + } + var response []byte + if response, err = util.PostJSON(fmt.Sprintf(getOptionURL, accessToken), req); err != nil { + return nil, err + } + result := &GetOptionResponse{} + err = util.DecodeWithError(response, result, "GetOption") + return result, err +} + +// GetScheduleListRequest 获取打卡人员排班信息请求 +type GetScheduleListRequest struct { + StartTime int64 `json:"starttime"` + EndTime int64 `json:"endtime"` + UserIDList []string `json:"useridlist"` +} + +// GetScheduleListResponse 获取打卡人员排班信息响应 +type GetScheduleListResponse struct { + util.CommonError + ScheduleList []ScheduleItem `json:"schedule_list"` +} + +// ScheduleItem 排班表信息 +type ScheduleItem struct { + UserID string `json:"userid"` + YearMonth int64 `json:"yearmonth"` + GroupID int64 `json:"groupid"` + GroupName string `json:"groupname"` + Schedule Schedule `json:"schedule"` +} + +// Schedule 个人排班信息 +type Schedule struct { + ScheduleList []ScheduleListItem `json:"scheduleList"` +} + +// ScheduleListItem 个人排班表信息 +type ScheduleListItem struct { + Day int64 `json:"day"` + ScheduleInfo ScheduleInfo `json:"schedule_info"` +} + +// ScheduleInfo 个人当日排班信息 +type ScheduleInfo struct { + ScheduleID int64 `json:"schedule_id"` + ScheduleName string `json:"schedule_name"` + TimeSection []ScheduleTimeSection `json:"time_section"` +} + +// ScheduleTimeSection 班次上下班时段信息 +type ScheduleTimeSection struct { + ID int64 `json:"id"` + WorkSec int64 `json:"work_sec"` + OffWorkSec int64 `json:"off_work_sec"` + RemindWorkSec int64 `json:"remind_work_sec"` + RemindOffWorkSec int64 `json:"remind_off_work_sec"` +} + +// GetScheduleList 获取打卡人员排班信息 +// see https://developer.work.weixin.qq.com/document/path/93380 +func (r *Client) GetScheduleList(req *GetScheduleListRequest) (*GetScheduleListResponse, error) { + var ( + accessToken string + err error + ) + if accessToken, err = r.GetAccessToken(); err != nil { + return nil, err + } + var response []byte + if response, err = util.PostJSON(fmt.Sprintf(getScheduleListURL, accessToken), req); err != nil { + return nil, err + } + result := &GetScheduleListResponse{} + err = util.DecodeWithError(response, result, "GetScheduleList") + return result, err +} + +// GetHardwareDataRequest 获取设备打卡数据请求 +type GetHardwareDataRequest struct { + FilterType int64 `json:"filter_type"` + StartTime int64 `json:"starttime"` + EndTime int64 `json:"endtime"` + UserIDList []string `json:"useridlist"` +} + +// GetHardwareDataResponse 获取设备打卡数据响应 +type GetHardwareDataResponse struct { + util.CommonError + CheckinData []HardwareCheckinData `json:"checkindata"` +} + +// HardwareCheckinData 设备打卡数据 +type HardwareCheckinData struct { + UserID string `json:"userid"` + CheckinTime int64 `json:"checkin_time"` + DeviceSn string `json:"device_sn"` + DeviceName string `json:"device_name"` +} + +// GetHardwareData 获取设备打卡数据 +// see https://developer.work.weixin.qq.com/document/path/94126 +func (r *Client) GetHardwareData(req *GetHardwareDataRequest) (*GetHardwareDataResponse, error) { + var ( + accessToken string + err error + ) + if accessToken, err = r.GetAccessToken(); err != nil { + return nil, err + } + var response []byte + if response, err = util.PostJSON(fmt.Sprintf(getHardwareDataURL, accessToken), req); err != nil { + return nil, err + } + result := &GetHardwareDataResponse{} + err = util.DecodeWithError(response, result, "GetHardwareData") + return result, err +} diff --git a/work/externalcontact/callback.go b/work/externalcontact/callback.go index f57034038..14aa1c981 100644 --- a/work/externalcontact/callback.go +++ b/work/externalcontact/callback.go @@ -38,8 +38,6 @@ func (r *Client) GetCallbackMessage(encryptedMsg []byte) (msg EventCallbackMessa if err != nil { return } - if err = xml.Unmarshal(bData, &msg); err != nil { - return - } + err = xml.Unmarshal(bData, &msg) return } diff --git a/work/externalcontact/contact_way.go b/work/externalcontact/contact_way.go index 150f05b97..6420006bf 100644 --- a/work/externalcontact/contact_way.go +++ b/work/externalcontact/contact_way.go @@ -102,10 +102,8 @@ func (r *Client) AddContactWay(req *AddContactWayRequest) (*AddContactWayRespons return nil, err } result := &AddContactWayResponse{} - if err = util.DecodeWithError(response, result, "AddContactWay"); err != nil { - return nil, err - } - return result, nil + err = util.DecodeWithError(response, result, "AddContactWay") + return result, err } type ( @@ -153,10 +151,8 @@ func (r *Client) GetContactWay(req *GetContactWayRequest) (*GetContactWayRespons return nil, err } result := &GetContactWayResponse{} - if err = util.DecodeWithError(response, result, "GetContactWay"); err != nil { - return nil, err - } - return result, nil + err = util.DecodeWithError(response, result, "GetContactWay") + return result, err } type ( @@ -195,10 +191,8 @@ func (r *Client) UpdateContactWay(req *UpdateContactWayRequest) (*UpdateContactW return nil, err } result := &UpdateContactWayResponse{} - if err = util.DecodeWithError(response, result, "UpdateContactWay"); err != nil { - return nil, err - } - return result, nil + err = util.DecodeWithError(response, result, "UpdateContactWay") + return result, err } type ( @@ -236,10 +230,8 @@ func (r *Client) ListContactWay(req *ListContactWayRequest) (*ListContactWayResp return nil, err } result := &ListContactWayResponse{} - if err = util.DecodeWithError(response, result, "ListContactWay"); err != nil { - return nil, err - } - return result, nil + err = util.DecodeWithError(response, result, "ListContactWay") + return result, err } type ( @@ -268,8 +260,6 @@ func (r *Client) DelContactWay(req *DelContactWayRequest) (*DelContactWayRespons return nil, err } result := &DelContactWayResponse{} - if err = util.DecodeWithError(response, result, "DelContactWay"); err != nil { - return nil, err - } - return result, nil + err = util.DecodeWithError(response, result, "DelContactWay") + return result, err } diff --git a/work/externalcontact/customer_acquisition.go b/work/externalcontact/customer_acquisition.go index e8d55f1a7..e2d8ea104 100644 --- a/work/externalcontact/customer_acquisition.go +++ b/work/externalcontact/customer_acquisition.go @@ -54,10 +54,8 @@ func (r *Client) ListLink(req *ListLinkRequest) (*ListLinkResponse, error) { return nil, err } result := &ListLinkResponse{} - if err = util.DecodeWithError(response, result, "ListLink"); err != nil { - return nil, err - } - return result, nil + err = util.DecodeWithError(response, result, "ListLink") + return result, err } type ( @@ -102,10 +100,8 @@ func (r *Client) GetCustomerAcquisition(req *GetCustomerAcquisitionRequest) (*Ge return nil, err } result := &GetCustomerAcquisitionResponse{} - if err = util.DecodeWithError(response, result, "GetCustomerAcquisition"); err != nil { - return nil, err - } - return result, nil + err = util.DecodeWithError(response, result, "GetCustomerAcquisition") + return result, err } type ( @@ -137,10 +133,8 @@ func (r *Client) CreateCustomerAcquisitionLink(req *CreateCustomerAcquisitionLin return nil, err } result := &CreateCustomerAcquisitionLinkResponse{} - if err = util.DecodeWithError(response, result, "CreateCustomerAcquisitionLink"); err != nil { - return nil, err - } - return result, nil + err = util.DecodeWithError(response, result, "CreateCustomerAcquisitionLink") + return result, err } type ( @@ -172,10 +166,8 @@ func (r *Client) UpdateCustomerAcquisitionLink(req *UpdateCustomerAcquisitionLin return nil, err } result := &UpdateCustomerAcquisitionLinkResponse{} - if err = util.DecodeWithError(response, result, "UpdateCustomerAcquisitionLink"); err != nil { - return nil, err - } - return result, nil + err = util.DecodeWithError(response, result, "UpdateCustomerAcquisitionLink") + return result, err } type ( @@ -204,10 +196,8 @@ func (r *Client) DeleteCustomerAcquisitionLink(req *DeleteCustomerAcquisitionLin return nil, err } result := &DeleteCustomerAcquisitionLinkResponse{} - if err = util.DecodeWithError(response, result, "DeleteCustomerAcquisitionLink"); err != nil { - return nil, err - } - return result, nil + err = util.DecodeWithError(response, result, "DeleteCustomerAcquisitionLink") + return result, err } type ( @@ -247,10 +237,8 @@ func (r *Client) GetCustomerInfoWithCustomerAcquisitionLink(req *GetCustomerInfo return nil, err } result := &GetCustomerInfoWithCustomerAcquisitionLinkResponse{} - if err = util.DecodeWithError(response, result, "GetCustomerInfoWithCustomerAcquisitionLink"); err != nil { - return nil, err - } - return result, nil + err = util.DecodeWithError(response, result, "GetCustomerInfoWithCustomerAcquisitionLink") + return result, err } type ( @@ -279,14 +267,12 @@ func (r *Client) CustomerAcquisitionQuota() (*CustomerAcquisitionQuotaResponse, return nil, err } var response []byte - if response, err = util.HTTPGet((fmt.Sprintf(customerAcquisitionQuotaURL, accessToken))); err != nil { + if response, err = util.HTTPGet(fmt.Sprintf(customerAcquisitionQuotaURL, accessToken)); err != nil { return nil, err } result := &CustomerAcquisitionQuotaResponse{} - if err = util.DecodeWithError(response, result, "CustomerAcquisitionQuota"); err != nil { - return nil, err - } - return result, nil + err = util.DecodeWithError(response, result, "CustomerAcquisitionQuota") + return result, err } type ( @@ -319,8 +305,6 @@ func (r *Client) CustomerAcquisitionStatistic(req *CustomerAcquisitionStatisticR return nil, err } result := &CustomerAcquisitionStatisticResponse{} - if err = util.DecodeWithError(response, result, "CustomerAcquisitionStatistic"); err != nil { - return nil, err - } - return result, nil + err = util.DecodeWithError(response, result, "CustomerAcquisitionStatistic") + return result, err } diff --git a/work/externalcontact/external_user.go b/work/externalcontact/external_user.go index b8a4bd19c..2c58d73b6 100644 --- a/work/externalcontact/external_user.go +++ b/work/externalcontact/external_user.go @@ -50,10 +50,7 @@ func (r *Client) GetExternalUserList(userID string) ([]string, error) { } var result ExternalUserListResponse err = util.DecodeWithError(response, &result, "GetExternalUserList") - if err != nil { - return nil, err - } - return result.ExternalUserID, nil + return result.ExternalUserID, err } // ExternalUserDetailResponse 外部联系人详情响应 @@ -104,7 +101,7 @@ type Tag struct { // WechatChannel 视频号添加的场景 type WechatChannel struct { NickName string `json:"nickname"` - Source string `json:"source"` + Source int `json:"source"` } // GetExternalUserDetail 获取外部联系人详情 @@ -125,10 +122,7 @@ func (r *Client) GetExternalUserDetail(externalUserID string, nextCursor ...stri } result := &ExternalUserDetailResponse{} err = util.DecodeWithError(response, result, "get_external_user_detail") - if err != nil { - return nil, err - } - return result, nil + return result, err } // BatchGetExternalUserDetailsRequest 批量获取外部联系人详情请求 @@ -196,10 +190,7 @@ func (r *Client) BatchGetExternalUserDetails(request BatchGetExternalUserDetails } var result ExternalUserDetailListResponse err = util.DecodeWithError(response, &result, "BatchGetExternalUserDetails") - if err != nil { - return nil, err - } - return result.ExternalContactList, nil + return result.ExternalContactList, err } // UpdateUserRemarkRequest 修改客户备注信息请求体 @@ -265,10 +256,8 @@ func (r *Client) ListCustomerStrategy(req *ListCustomerStrategyRequest) (*ListCu return nil, err } result := &ListCustomerStrategyResponse{} - if err = util.DecodeWithError(response, result, "ListCustomerStrategy"); err != nil { - return nil, err - } - return result, nil + err = util.DecodeWithError(response, result, "ListCustomerStrategy") + return result, err } // GetCustomerStrategyRequest 获取规则组详情请求 @@ -332,10 +321,8 @@ func (r *Client) GetCustomerStrategy(req *GetCustomerStrategyRequest) (*GetCusto return nil, err } result := &GetCustomerStrategyResponse{} - if err = util.DecodeWithError(response, result, "GetCustomerStrategy"); err != nil { - return nil, err - } - return result, nil + err = util.DecodeWithError(response, result, "GetCustomerStrategy") + return result, err } // GetRangeCustomerStrategyRequest 获取规则组管理范围请求 @@ -374,10 +361,8 @@ func (r *Client) GetRangeCustomerStrategy(req *GetRangeCustomerStrategyRequest) return nil, err } result := &GetRangeCustomerStrategyResponse{} - if err = util.DecodeWithError(response, result, "GetRangeCustomerStrategy"); err != nil { - return nil, err - } - return result, nil + err = util.DecodeWithError(response, result, "GetRangeCustomerStrategy") + return result, err } // CreateCustomerStrategyRequest 创建新的规则组请求 @@ -410,10 +395,8 @@ func (r *Client) CreateCustomerStrategy(req *CreateCustomerStrategyRequest) (*Cr return nil, err } result := &CreateCustomerStrategyResponse{} - if err = util.DecodeWithError(response, result, "CreateCustomerStrategy"); err != nil { - return nil, err - } - return result, nil + err = util.DecodeWithError(response, result, "CreateCustomerStrategy") + return result, err } // EditCustomerStrategyRequest 编辑规则组及其管理范围请求 diff --git a/work/externalcontact/follow_user.go b/work/externalcontact/follow_user.go index 67469b8e8..43d9c493c 100644 --- a/work/externalcontact/follow_user.go +++ b/work/externalcontact/follow_user.go @@ -31,8 +31,5 @@ func (r *Client) GetFollowUserList() ([]string, error) { } var result followerUserResponse err = util.DecodeWithError(response, &result, "GetFollowUserList") - if err != nil { - return nil, err - } - return result.FollowUser, nil + return result.FollowUser, err } diff --git a/work/externalcontact/groupchat.go b/work/externalcontact/groupchat.go index 6ead0c0a8..018c397e7 100644 --- a/work/externalcontact/groupchat.go +++ b/work/externalcontact/groupchat.go @@ -44,10 +44,8 @@ func (r *Client) GetGroupChatList(req *GroupChatListRequest) (*GroupChatListResp return nil, err } result := &GroupChatListResponse{} - if err = util.DecodeWithError(response, result, "GetGroupChatList"); err != nil { - return nil, err - } - return result, nil + err = util.DecodeWithError(response, result, "GetGroupChatList") + return result, err } type ( @@ -106,10 +104,8 @@ func (r *Client) GetGroupChatDetail(req *GroupChatDetailRequest) (*GroupChatDeta return nil, err } result := &GroupChatDetailResponse{} - if err = util.DecodeWithError(response, result, "GetGroupChatDetail"); err != nil { - return nil, err - } - return result, nil + err = util.DecodeWithError(response, result, "GetGroupChatDetail") + return result, err } type ( @@ -137,8 +133,6 @@ func (r *Client) OpengIDToChatID(req *OpengIDToChatIDRequest) (*OpengIDToChatIDR return nil, err } result := &OpengIDToChatIDResponse{} - if err = util.DecodeWithError(response, result, "GetGroupChatDetail"); err != nil { - return nil, err - } - return result, nil + err = util.DecodeWithError(response, result, "GetGroupChatDetail") + return result, err } diff --git a/work/externalcontact/join_way.go b/work/externalcontact/join_way.go index 818a8ca7e..b9c11400a 100644 --- a/work/externalcontact/join_way.go +++ b/work/externalcontact/join_way.go @@ -44,10 +44,8 @@ func (r *Client) AddJoinWay(req *AddJoinWayRequest) (*AddJoinWayResponse, error) return nil, err } result := &AddJoinWayResponse{} - if err = util.DecodeWithError(response, result, "AddJoinWay"); err != nil { - return nil, err - } - return result, nil + err = util.DecodeWithError(response, result, "AddJoinWay") + return result, err } type ( @@ -91,10 +89,8 @@ func (r *Client) GetJoinWay(req *JoinWayConfigRequest) (*GetJoinWayResponse, err return nil, err } result := &GetJoinWayResponse{} - if err = util.DecodeWithError(response, result, "GetJoinWay"); err != nil { - return nil, err - } - return result, nil + err = util.DecodeWithError(response, result, "GetJoinWay") + return result, err } // UpdateJoinWayRequest 更新群配置的请求参数 diff --git a/work/externalcontact/moment.go b/work/externalcontact/moment.go index 4742b4e51..8086fa629 100644 --- a/work/externalcontact/moment.go +++ b/work/externalcontact/moment.go @@ -112,10 +112,8 @@ func (r *Client) AddMomentTask(req *AddMomentTaskRequest) (*AddMomentTaskRespons return nil, err } result := &AddMomentTaskResponse{} - if err = util.DecodeWithError(response, result, "AddMomentTask"); err != nil { - return nil, err - } - return result, nil + err = util.DecodeWithError(response, result, "AddMomentTask") + return result, err } // GetMomentTaskResultResponse 获取任务创建结果响应 @@ -161,10 +159,8 @@ func (r *Client) GetMomentTaskResult(jobID string) (*GetMomentTaskResultResponse return nil, err } result := &GetMomentTaskResultResponse{} - if err = util.DecodeWithError(response, result, "GetMomentTaskResult"); err != nil { - return nil, err - } - return result, nil + err = util.DecodeWithError(response, result, "GetMomentTaskResult") + return result, err } // CancelMomentTaskRequest 停止发表企业朋友圈请求 @@ -264,10 +260,8 @@ func (r *Client) GetMomentList(req *GetMomentListRequest) (*GetMomentListRespons return nil, err } result := &GetMomentListResponse{} - if err = util.DecodeWithError(response, result, "GetMomentList"); err != nil { - return nil, err - } - return result, nil + err = util.DecodeWithError(response, result, "GetMomentList") + return result, err } // GetMomentTaskRequest 获取客户朋友圈企业发表的列表请求 @@ -305,10 +299,8 @@ func (r *Client) GetMomentTask(req *GetMomentTaskRequest) (*GetMomentTaskRespons return nil, err } result := &GetMomentTaskResponse{} - if err = util.DecodeWithError(response, result, "GetMomentTask"); err != nil { - return nil, err - } - return result, nil + err = util.DecodeWithError(response, result, "GetMomentTask") + return result, err } // GetMomentCustomerListRequest 获取客户朋友圈发表时选择的可见范围请求 @@ -347,10 +339,8 @@ func (r *Client) GetMomentCustomerList(req *GetMomentCustomerListRequest) (*GetM return nil, err } result := &GetMomentCustomerListResponse{} - if err = util.DecodeWithError(response, result, "GetMomentCustomerList"); err != nil { - return nil, err - } - return result, nil + err = util.DecodeWithError(response, result, "GetMomentCustomerList") + return result, err } // GetMomentSendResultRequest 获取客户朋友圈发表后的可见客户列表请求 @@ -388,10 +378,8 @@ func (r *Client) GetMomentSendResult(req *GetMomentSendResultRequest) (*GetMomen return nil, err } result := &GetMomentSendResultResponse{} - if err = util.DecodeWithError(response, result, "GetMomentSendResult"); err != nil { - return nil, err - } - return result, nil + err = util.DecodeWithError(response, result, "GetMomentSendResult") + return result, err } // GetMomentCommentsRequest 获取客户朋友圈的互动数据请求 @@ -436,10 +424,8 @@ func (r *Client) GetMomentComments(req *GetMomentCommentsRequest) (*GetMomentCom return nil, err } result := &GetMomentCommentsResponse{} - if err = util.DecodeWithError(response, result, "GetMomentComments"); err != nil { - return nil, err - } - return result, nil + err = util.DecodeWithError(response, result, "GetMomentComments") + return result, err } // ListMomentStrategyRequest 获取规则组列表请求 @@ -475,10 +461,8 @@ func (r *Client) ListMomentStrategy(req *ListMomentStrategyRequest) (*ListMoment return nil, err } result := &ListMomentStrategyResponse{} - if err = util.DecodeWithError(response, result, "ListMomentStrategy"); err != nil { - return nil, err - } - return result, nil + err = util.DecodeWithError(response, result, "ListMomentStrategy") + return result, err } // GetMomentStrategyRequest 获取规则组详情请求 @@ -524,10 +508,8 @@ func (r *Client) GetMomentStrategy(req *GetMomentStrategyRequest) (*GetMomentStr return nil, err } result := &GetMomentStrategyResponse{} - if err = util.DecodeWithError(response, result, "GetMomentStrategy"); err != nil { - return nil, err - } - return result, nil + err = util.DecodeWithError(response, result, "GetMomentStrategy") + return result, err } // GetRangeMomentStrategyRequest 获取规则组管理范围请求 @@ -566,10 +548,8 @@ func (r *Client) GetRangeMomentStrategy(req *GetRangeMomentStrategyRequest) (*Ge return nil, err } result := &GetRangeMomentStrategyResponse{} - if err = util.DecodeWithError(response, result, "GetRangeMomentStrategy"); err != nil { - return nil, err - } - return result, nil + err = util.DecodeWithError(response, result, "GetRangeMomentStrategy") + return result, err } // CreateMomentStrategyRequest 创建新的规则组请求 @@ -602,10 +582,8 @@ func (r *Client) CreateMomentStrategy(req *CreateMomentStrategyRequest) (*Create return nil, err } result := &CreateMomentStrategyResponse{} - if err = util.DecodeWithError(response, result, "CreateMomentStrategy"); err != nil { - return nil, err - } - return result, nil + err = util.DecodeWithError(response, result, "CreateMomentStrategy") + return result, err } // EditMomentStrategyRequest 编辑规则组及其管理范围请求 diff --git a/work/externalcontact/msg.go b/work/externalcontact/msg.go index b99136727..9ebd3243c 100644 --- a/work/externalcontact/msg.go +++ b/work/externalcontact/msg.go @@ -38,8 +38,23 @@ type AddMsgTemplateRequest struct { Sender string `json:"sender,omitempty"` Text MsgText `json:"text"` Attachments []*Attachment `json:"attachments"` + AllowSelect bool `json:"allow_select,omitempty"` + ChatIDList []string `json:"chat_id_list,omitempty"` + TagFilter TagFilter `json:"tag_filter,omitempty"` } +type ( + // TagFilter 标签过滤 + TagFilter struct { + GroupList []TagGroupList `json:"group_list"` + } + + // TagGroupList 标签组 + TagGroupList struct { + TagList []string `json:"tag_list"` + } +) + // MsgText 文本消息 type MsgText struct { Content string `json:"content"` @@ -106,10 +121,8 @@ func (r *Client) AddMsgTemplate(req *AddMsgTemplateRequest) (*AddMsgTemplateResp return nil, err } result := &AddMsgTemplateResponse{} - if err = util.DecodeWithError(response, result, "AddMsgTemplate"); err != nil { - return nil, err - } - return result, nil + err = util.DecodeWithError(response, result, "AddMsgTemplate") + return result, err } // GetGroupMsgListV2Request 获取群发记录列表请求 @@ -155,10 +168,8 @@ func (r *Client) GetGroupMsgListV2(req *GetGroupMsgListV2Request) (*GetGroupMsgL return nil, err } result := &GetGroupMsgListV2Response{} - if err = util.DecodeWithError(response, result, "GetGroupMsgListV2"); err != nil { - return nil, err - } - return result, nil + err = util.DecodeWithError(response, result, "GetGroupMsgListV2") + return result, err } // GetGroupMsgTaskRequest 获取群发成员发送任务列表请求 @@ -197,10 +208,8 @@ func (r *Client) GetGroupMsgTask(req *GetGroupMsgTaskRequest) (*GetGroupMsgTaskR return nil, err } result := &GetGroupMsgTaskResponse{} - if err = util.DecodeWithError(response, result, "GetGroupMsgTask"); err != nil { - return nil, err - } - return result, nil + err = util.DecodeWithError(response, result, "GetGroupMsgTask") + return result, err } // GetGroupMsgSendResultRequest 获取企业群发成员执行结果请求 @@ -242,10 +251,8 @@ func (r *Client) GetGroupMsgSendResult(req *GetGroupMsgSendResultRequest) (*GetG return nil, err } result := &GetGroupMsgSendResultResponse{} - if err = util.DecodeWithError(response, result, "GetGroupMsgSendResult"); err != nil { - return nil, err - } - return result, nil + err = util.DecodeWithError(response, result, "GetGroupMsgSendResult") + return result, err } // SendWelcomeMsgRequest 发送新客户欢迎语请求 @@ -275,22 +282,19 @@ func (r *Client) SendWelcomeMsg(req *SendWelcomeMsgRequest) error { return err } result := &SendWelcomeMsgResponse{} - if err = util.DecodeWithError(response, result, "SendWelcomeMsg"); err != nil { - return err - } - return nil + return util.DecodeWithError(response, result, "SendWelcomeMsg") } // AddGroupWelcomeTemplateRequest 添加入群欢迎语素材请求 type AddGroupWelcomeTemplateRequest struct { - Text MsgText `json:"text"` - Image AttachmentImg `json:"image"` - Link AttachmentLink `json:"link"` - MiniProgram AttachmentMiniProgram `json:"miniprogram"` - File AttachmentFile `json:"file"` - Video AttachmentVideo `json:"video"` - AgentID int `json:"agentid"` - Notify int `json:"notify"` + Text MsgText `json:"text"` + Image *AttachmentImg `json:"image,omitempty"` + Link *AttachmentLink `json:"link,omitempty"` + MiniProgram *AttachmentMiniProgram `json:"miniprogram,omitempty"` + File *AttachmentFile `json:"file,omitempty"` + Video *AttachmentVideo `json:"video,omitempty"` + AgentID int `json:"agentid,omitempty"` + Notify int `json:"notify,omitempty"` } // AddGroupWelcomeTemplateResponse 添加入群欢迎语素材响应 @@ -314,22 +318,20 @@ func (r *Client) AddGroupWelcomeTemplate(req *AddGroupWelcomeTemplateRequest) (* return nil, err } result := &AddGroupWelcomeTemplateResponse{} - if err = util.DecodeWithError(response, result, "AddGroupWelcomeTemplate"); err != nil { - return nil, err - } - return result, nil + err = util.DecodeWithError(response, result, "AddGroupWelcomeTemplate") + return result, err } // EditGroupWelcomeTemplateRequest 编辑入群欢迎语素材请求 type EditGroupWelcomeTemplateRequest struct { - TemplateID string `json:"template_id"` - Text MsgText `json:"text"` - Image AttachmentImg `json:"image"` - Link AttachmentLink `json:"link"` - MiniProgram AttachmentMiniProgram `json:"miniprogram"` - File AttachmentFile `json:"file"` - Video AttachmentVideo `json:"video"` - AgentID int `json:"agentid"` + TemplateID string `json:"template_id"` + Text MsgText `json:"text"` + Image *AttachmentImg `json:"image"` + Link *AttachmentLink `json:"link"` + MiniProgram *AttachmentMiniProgram `json:"miniprogram"` + File *AttachmentFile `json:"file"` + Video *AttachmentVideo `json:"video"` + AgentID int `json:"agentid"` } // EditGroupWelcomeTemplateResponse 编辑入群欢迎语素材响应 @@ -352,10 +354,7 @@ func (r *Client) EditGroupWelcomeTemplate(req *EditGroupWelcomeTemplateRequest) return err } result := &EditGroupWelcomeTemplateResponse{} - if err = util.DecodeWithError(response, result, "EditGroupWelcomeTemplate"); err != nil { - return err - } - return nil + return util.DecodeWithError(response, result, "EditGroupWelcomeTemplate") } // GetGroupWelcomeTemplateRequest 获取入群欢迎语素材请求 @@ -367,11 +366,11 @@ type GetGroupWelcomeTemplateRequest struct { type GetGroupWelcomeTemplateResponse struct { util.CommonError Text MsgText `json:"text"` - Image AttachmentImg `json:"image"` - Link AttachmentLink `json:"link"` - MiniProgram AttachmentMiniProgram `json:"miniprogram"` - File AttachmentFile `json:"file"` - Video AttachmentVideo `json:"video"` + Image AttachmentImg `json:"image,omitempty"` + Link AttachmentLink `json:"link,omitempty"` + MiniProgram AttachmentMiniProgram `json:"miniprogram,omitempty"` + File AttachmentFile `json:"file,omitempty"` + Video AttachmentVideo `json:"video,omitempty"` } // GetGroupWelcomeTemplate 获取入群欢迎语素材 @@ -389,10 +388,8 @@ func (r *Client) GetGroupWelcomeTemplate(req *GetGroupWelcomeTemplateRequest) (* return nil, err } result := &GetGroupWelcomeTemplateResponse{} - if err = util.DecodeWithError(response, result, "GetGroupWelcomeTemplate"); err != nil { - return nil, err - } - return result, nil + err = util.DecodeWithError(response, result, "GetGroupWelcomeTemplate") + return result, err } // DelGroupWelcomeTemplateRequest 删除入群欢迎语素材请求 @@ -421,10 +418,7 @@ func (r *Client) DelGroupWelcomeTemplate(req *DelGroupWelcomeTemplateRequest) er return err } result := &DelGroupWelcomeTemplateResponse{} - if err = util.DecodeWithError(response, result, "DelGroupWelcomeTemplate"); err != nil { - return err - } - return nil + return util.DecodeWithError(response, result, "DelGroupWelcomeTemplate") } // RemindGroupMsgSendRequest 提醒成员群发请求 diff --git a/work/externalcontact/statistic.go b/work/externalcontact/statistic.go index 2e00ae2ba..e639062b5 100644 --- a/work/externalcontact/statistic.go +++ b/work/externalcontact/statistic.go @@ -60,10 +60,7 @@ func (r *Client) GetUserBehaviorData(req *GetUserBehaviorRequest) ([]BehaviorDat } var result GetUserBehaviorResponse err = util.DecodeWithError(response, &result, "GetUserBehaviorData") - if err != nil { - return nil, err - } - return result.BehaviorData, nil + return result.BehaviorData, err } type ( @@ -126,10 +123,7 @@ func (r *Client) GetGroupChatStat(req *GetGroupChatStatRequest) (*GetGroupChatSt } result := &GetGroupChatStatResponse{} err = util.DecodeWithError(response, result, "GetGroupChatStat") - if err != nil { - return nil, err - } - return result, nil + return result, err } type ( @@ -169,8 +163,5 @@ func (r *Client) GetGroupChatStatByDay(req *GetGroupChatStatByDayRequest) ([]Get } var result GetGroupChatStatByDayResponse err = util.DecodeWithError(response, &result, "GetGroupChatStatByDay") - if err != nil { - return nil, err - } - return result.Items, nil + return result.Items, err } diff --git a/work/externalcontact/tag.go b/work/externalcontact/tag.go index 921752b3f..00c268071 100644 --- a/work/externalcontact/tag.go +++ b/work/externalcontact/tag.go @@ -77,10 +77,7 @@ func (r *Client) GetCropTagList(req GetCropTagRequest) ([]TagGroup, error) { } var result GetCropTagListResponse err = util.DecodeWithError(response, &result, "GetCropTagList") - if err != nil { - return nil, err - } - return result.TagGroup, nil + return result.TagGroup, err } // AddCropTagRequest 添加企业标签请求 @@ -123,10 +120,7 @@ func (r *Client) AddCropTag(req AddCropTagRequest) (*TagGroup, error) { } var result AddCropTagResponse err = util.DecodeWithError(response, &result, "AddCropTag") - if err != nil { - return nil, err - } - return &result.TagGroup, nil + return &result.TagGroup, err } // EditCropTagRequest 编辑客户企业标签请求 @@ -256,10 +250,8 @@ func (r *Client) GetStrategyTagList(req *GetStrategyTagListRequest) (*GetStrateg return nil, err } result := &GetStrategyTagListResponse{} - if err = util.DecodeWithError(response, result, "GetStrategyTagList"); err != nil { - return nil, err - } - return result, nil + err = util.DecodeWithError(response, result, "GetStrategyTagList") + return result, err } // AddStrategyTagRequest 为指定规则组创建企业客户标签请求 @@ -315,10 +307,8 @@ func (r *Client) AddStrategyTag(req *AddStrategyTagRequest) (*AddStrategyTagResp return nil, err } result := &AddStrategyTagResponse{} - if err = util.DecodeWithError(response, result, "AddStrategyTag"); err != nil { - return nil, err - } - return result, nil + err = util.DecodeWithError(response, result, "AddStrategyTag") + return result, err } // EditStrategyTagRequest 编辑指定规则组下的企业客户标签请求 diff --git a/work/externalcontact/transfer.go b/work/externalcontact/transfer.go index a0ee0d57f..4b74a0f0b 100644 --- a/work/externalcontact/transfer.go +++ b/work/externalcontact/transfer.go @@ -58,10 +58,8 @@ func (r *Client) TransferCustomer(req *TransferCustomerRequest) (*TransferCustom return nil, err } result := &TransferCustomerResponse{} - if err = util.DecodeWithError(response, result, "TransferCustomer"); err != nil { - return nil, err - } - return result, nil + err = util.DecodeWithError(response, result, "TransferCustomer") + return result, err } // TransferResultRequest 查询客户接替状态请求 @@ -100,10 +98,8 @@ func (r *Client) TransferResult(req *TransferResultRequest) (*TransferResultResp return nil, err } result := &TransferResultResponse{} - if err = util.DecodeWithError(response, result, "TransferResult"); err != nil { - return nil, err - } - return result, nil + err = util.DecodeWithError(response, result, "TransferResult") + return result, err } // GroupChatOnJobTransferRequest 分配在职成员的客户群请求 @@ -140,10 +136,8 @@ func (r *Client) GroupChatOnJobTransfer(req *GroupChatOnJobTransferRequest) (*Gr return nil, err } result := &GroupChatOnJobTransferResponse{} - if err = util.DecodeWithError(response, result, "GroupChatOnJobTransfer"); err != nil { - return nil, err - } - return result, nil + err = util.DecodeWithError(response, result, "GroupChatOnJobTransfer") + return result, err } // GetUnassignedListRequest 获取待分配的离职成员列表请求 @@ -182,10 +176,8 @@ func (r *Client) GetUnassignedList(req *GetUnassignedListRequest) (*GetUnassigne return nil, err } result := &GetUnassignedListResponse{} - if err = util.DecodeWithError(response, result, "GetUnassignedList"); err != nil { - return nil, err - } - return result, nil + err = util.DecodeWithError(response, result, "GetUnassignedList") + return result, err } // ResignedTransferCustomerRequest 分配离职成员的客户请求 @@ -216,10 +208,8 @@ func (r *Client) ResignedTransferCustomer(req *ResignedTransferCustomerRequest) return nil, err } result := &ResignedTransferCustomerResponse{} - if err = util.DecodeWithError(response, result, "ResignedTransferCustomer"); err != nil { - return nil, err - } - return result, nil + err = util.DecodeWithError(response, result, "ResignedTransferCustomer") + return result, err } // ResignedTransferResultRequest 查询离职客户接替状态请求 @@ -251,10 +241,8 @@ func (r *Client) ResignedTransferResult(req *ResignedTransferResultRequest) (*Re return nil, err } result := &ResignedTransferResultResponse{} - if err = util.DecodeWithError(response, result, "ResignedTransferResult"); err != nil { - return nil, err - } - return result, nil + err = util.DecodeWithError(response, result, "ResignedTransferResult") + return result, err } // GroupChatTransferRequest 分配离职成员的客户群请求 @@ -284,8 +272,6 @@ func (r *Client) GroupChatTransfer(req *GroupChatTransferRequest) (*GroupChatTra return nil, err } result := &GroupChatTransferResponse{} - if err = util.DecodeWithError(response, result, "GroupChatTransfer"); err != nil { - return nil, err - } - return result, nil + err = util.DecodeWithError(response, result, "GroupChatTransfer") + return result, err } diff --git a/work/invoice/invoice.go b/work/invoice/invoice.go index b72754d4b..d145b079c 100644 --- a/work/invoice/invoice.go +++ b/work/invoice/invoice.go @@ -86,10 +86,8 @@ func (r *Client) GetInvoiceInfo(req *GetInvoiceInfoRequest) (*GetInvoiceInfoResp return nil, err } result := &GetInvoiceInfoResponse{} - if err = util.DecodeWithError(response, result, "GetInvoiceInfo"); err != nil { - return nil, err - } - return result, nil + err = util.DecodeWithError(response, result, "GetInvoiceInfo") + return result, err } // UpdateInvoiceStatusRequest 更新发票状态请求 @@ -184,8 +182,6 @@ func (r *Client) GetInvoiceInfoBatch(req *GetInvoiceInfoBatchRequest) (*GetInvoi return nil, err } result := &GetInvoiceInfoBatchResponse{} - if err = util.DecodeWithError(response, result, "GetInvoiceInfoBatch"); err != nil { - return nil, err - } - return result, nil + err = util.DecodeWithError(response, result, "GetInvoiceInfoBatch") + return result, err } diff --git a/work/kf/callback.go b/work/kf/callback.go index 57ade5452..a62cb1a9e 100644 --- a/work/kf/callback.go +++ b/work/kf/callback.go @@ -92,8 +92,6 @@ func (r *Client) GetCallbackMessage(encryptedMsg []byte) (msg CallbackMessage, e if err != nil { return msg, NewSDKErr(40016) } - if err = xml.Unmarshal(bData, &msg); err != nil { - return msg, err - } + err = xml.Unmarshal(bData, &msg) return msg, err } diff --git a/work/kf/statistic.go b/work/kf/statistic.go index 831c0fe4e..f4f7416d8 100644 --- a/work/kf/statistic.go +++ b/work/kf/statistic.go @@ -59,10 +59,8 @@ func (r *Client) GetCorpStatistic(req *GetCorpStatisticRequest) (*GetCorpStatist return nil, err } result := &GetCorpStatisticResponse{} - if err = util.DecodeWithError(response, result, "GetCorpStatistic"); err != nil { - return nil, err - } - return result, nil + err = util.DecodeWithError(response, result, "GetCorpStatistic") + return result, err } // GetServicerStatisticRequest 获取「客户数据统计」接待人员明细数据请求 @@ -120,8 +118,6 @@ func (r *Client) GetServicerStatistic(req *GetServicerStatisticRequest) (*GetSer return nil, err } result := &GetServicerStatisticResponse{} - if err = util.DecodeWithError(response, result, "GetServicerStatistic"); err != nil { - return nil, err - } - return result, nil + err = util.DecodeWithError(response, result, "GetServicerStatistic") + return result, err } diff --git a/work/material/media.go b/work/material/media.go index 45358fc93..b32785a5c 100644 --- a/work/material/media.go +++ b/work/material/media.go @@ -52,10 +52,8 @@ func (r *Client) UploadImg(filename string) (*UploadImgResponse, error) { return nil, err } result := &UploadImgResponse{} - if err = util.DecodeWithError(response, result, "UploadImg"); err != nil { - return nil, err - } - return result, nil + err = util.DecodeWithError(response, result, "UploadImg") + return result, err } // UploadTempFile 上传临时素材 @@ -74,10 +72,8 @@ func (r *Client) UploadTempFile(filename string, mediaType string) (*UploadTempF return nil, err } result := &UploadTempFileResponse{} - if err = util.DecodeWithError(response, result, "UploadTempFile"); err != nil { - return nil, err - } - return result, nil + err = util.DecodeWithError(response, result, "UploadTempFile") + return result, err } // UploadAttachment 上传附件资源 @@ -97,8 +93,6 @@ func (r *Client) UploadAttachment(filename string, mediaType string, attachmentT return nil, err } result := &UploadAttachmentResponse{} - if err = util.DecodeWithError(response, result, "UploadAttachment"); err != nil { - return nil, err - } - return result, nil + err = util.DecodeWithError(response, result, "UploadAttachment") + return result, err } diff --git a/work/message/message.go b/work/message/message.go index 2598688be..ef6d24d89 100644 --- a/work/message/message.go +++ b/work/message/message.go @@ -99,11 +99,9 @@ func (r *Client) Send(apiName string, request interface{}) (*SendResponse, error } // 按照结构体解析返回值 result := &SendResponse{} - if err = util.DecodeWithError(response, result, apiName); err != nil { - return nil, err - } + err = util.DecodeWithError(response, result, apiName) // 返回数据 - return result, nil + return result, err } // SendText 发送文本消息 diff --git a/work/msgaudit/client_linux.go b/work/msgaudit/client_linux.go index 9b1c04de8..80d21a2f7 100644 --- a/work/msgaudit/client_linux.go +++ b/work/msgaudit/client_linux.go @@ -149,10 +149,7 @@ func (s *Client) GetRawChatData(seq uint64, limit uint64, proxy string, passwd s var data ChatDataResponse err := json.Unmarshal(buf, &data) - if err != nil { - return ChatDataResponse{}, err - } - return data, nil + return data, err } // DecryptData 解析密文.企业微信自有解密内容 diff --git a/work/oauth/oauth.go b/work/oauth/oauth.go index f1acf616b..add4b0284 100644 --- a/work/oauth/oauth.go +++ b/work/oauth/oauth.go @@ -123,10 +123,8 @@ func (ctr *Oauth) GetUserInfo(code string) (*GetUserInfoResponse, error) { return nil, err } result := &GetUserInfoResponse{} - if err = util.DecodeWithError(response, result, "GetUserInfo"); err != nil { - return nil, err - } - return result, nil + err = util.DecodeWithError(response, result, "GetUserInfo") + return result, err } // GetUserDetailRequest 获取访问用户敏感信息请求 @@ -162,8 +160,6 @@ func (ctr *Oauth) GetUserDetail(req *GetUserDetailRequest) (*GetUserDetailRespon return nil, err } result := &GetUserDetailResponse{} - if err = util.DecodeWithError(response, result, "GetUserDetail"); err != nil { - return nil, err - } - return result, nil + err = util.DecodeWithError(response, result, "GetUserDetail") + return result, err }