mirror of
https://github.com/silenceper/wechat.git
synced 2026-02-05 21:22:27 +08:00
Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
39dbfd1c13 | ||
|
|
5ad3475cdb | ||
|
|
bcc41989ed | ||
|
|
e189b87e71 | ||
|
|
3cfa9e6c71 | ||
|
|
80d91d8316 | ||
|
|
c61154105b |
4
.github/workflows/go.yml
vendored
4
.github/workflows/go.yml
vendored
@@ -2,9 +2,9 @@ name: Go
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ master,release-* ]
|
||||
branches: [ master,release-*,v2 ]
|
||||
pull_request:
|
||||
branches: [ master,release-* ]
|
||||
branches: [ master,release-*,v2 ]
|
||||
|
||||
jobs:
|
||||
golangci:
|
||||
|
||||
@@ -56,15 +56,19 @@ type ResAccessToken struct {
|
||||
|
||||
//GetAccessToken 获取access_token,先从cache中获取,没有则从服务端获取
|
||||
func (ak *DefaultAccessToken) GetAccessToken() (accessToken string, err error) {
|
||||
// 先从cache中取
|
||||
accessTokenCacheKey := fmt.Sprintf("%s_access_token_%s", ak.cacheKeyPrefix, ak.appID)
|
||||
if val := ak.cache.Get(accessTokenCacheKey); val != nil {
|
||||
return val.(string), nil
|
||||
}
|
||||
|
||||
//加上lock,是为了防止在并发获取token时,cache刚好失效,导致从微信服务器上获取到不同token
|
||||
ak.accessTokenLock.Lock()
|
||||
defer ak.accessTokenLock.Unlock()
|
||||
|
||||
accessTokenCacheKey := fmt.Sprintf("%s_access_token_%s", ak.cacheKeyPrefix, ak.appID)
|
||||
val := ak.cache.Get(accessTokenCacheKey)
|
||||
if val != nil {
|
||||
accessToken = val.(string)
|
||||
return
|
||||
// 双检,防止重复从微信服务器获取
|
||||
if val := ak.cache.Get(accessTokenCacheKey); val != nil {
|
||||
return val.(string), nil
|
||||
}
|
||||
|
||||
//cache失效,从微信服务器获取
|
||||
|
||||
@@ -42,16 +42,20 @@ type ResTicket struct {
|
||||
|
||||
//GetTicket 获取jsapi_ticket
|
||||
func (js *DefaultJsTicket) GetTicket(accessToken string) (ticketStr string, err error) {
|
||||
//先从cache中取
|
||||
jsAPITicketCacheKey := fmt.Sprintf("%s_jsapi_ticket_%s", js.cacheKeyPrefix, js.appID)
|
||||
if val := js.cache.Get(jsAPITicketCacheKey); val != nil {
|
||||
return val.(string), nil
|
||||
}
|
||||
|
||||
js.jsAPITicketLock.Lock()
|
||||
defer js.jsAPITicketLock.Unlock()
|
||||
|
||||
//先从cache中取
|
||||
jsAPITicketCacheKey := fmt.Sprintf("%s_jsapi_ticket_%s", js.cacheKeyPrefix, js.appID)
|
||||
val := js.cache.Get(jsAPITicketCacheKey)
|
||||
if val != nil {
|
||||
ticketStr = val.(string)
|
||||
return
|
||||
// 双检,防止重复从微信服务器获取
|
||||
if val := js.cache.Get(jsAPITicketCacheKey); val != nil {
|
||||
return val.(string), nil
|
||||
}
|
||||
|
||||
var ticket ResTicket
|
||||
ticket, err = GetTicketFromServer(accessToken)
|
||||
if err != nil {
|
||||
|
||||
@@ -16,6 +16,14 @@ const (
|
||||
// https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/subscribe-message/subscribeMessage.getTemplateList.html
|
||||
getTemplateURL = "https://api.weixin.qq.com/wxaapi/newtmpl/gettemplate"
|
||||
|
||||
// 添加订阅模板
|
||||
// https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/subscribe-message/subscribeMessage.addTemplate.html
|
||||
addTemplateURL = "https://api.weixin.qq.com/wxaapi/newtmpl/addtemplate"
|
||||
|
||||
// 删除私有模板
|
||||
// https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/subscribe-message/subscribeMessage.deleteTemplate.html
|
||||
delTemplateURL = "https://api.weixin.qq.com/wxaapi/newtmpl/deltemplate"
|
||||
|
||||
// 统一服务消息
|
||||
// https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/uniform-message/uniformMessage.send.html
|
||||
uniformMessageSend = "https://api.weixin.qq.com/cgi-bin/message/wxopen/template/uniform_send"
|
||||
@@ -133,3 +141,55 @@ func (s *Subscribe) UniformSend(msg *UniformMessage) (err error) {
|
||||
}
|
||||
return util.DecodeWithCommonError(response, "UniformSend")
|
||||
}
|
||||
|
||||
type resSubscribeAdd struct {
|
||||
util.CommonError
|
||||
|
||||
TemplateID string `json:"priTmplId"`
|
||||
}
|
||||
|
||||
// Add 添加订阅消息模板
|
||||
func (s *Subscribe) Add(ShortID string, kidList []int, sceneDesc string) (templateID string, err error) {
|
||||
var accessToken string
|
||||
accessToken, err = s.GetAccessToken()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
var msg = struct {
|
||||
TemplateIDShort string `json:"tid"`
|
||||
SceneDesc string `json:"sceneDesc"`
|
||||
KidList []int `json:"kidList"`
|
||||
}{TemplateIDShort: ShortID, SceneDesc: sceneDesc, KidList: kidList}
|
||||
uri := fmt.Sprintf("%s?access_token=%s", addTemplateURL, accessToken)
|
||||
var response []byte
|
||||
response, err = util.PostJSON(uri, msg)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
var result resSubscribeAdd
|
||||
err = util.DecodeWithError(response, &result, "AddSubscribe")
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
templateID = result.TemplateID
|
||||
return
|
||||
}
|
||||
|
||||
// Delete 删除私有模板
|
||||
func (s *Subscribe) Delete(templateID string) (err error) {
|
||||
var accessToken string
|
||||
accessToken, err = s.GetAccessToken()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
var msg = struct {
|
||||
TemplateID string `json:"priTmplId"`
|
||||
}{TemplateID: templateID}
|
||||
uri := fmt.Sprintf("%s?access_token=%s", delTemplateURL, accessToken)
|
||||
var response []byte
|
||||
response, err = util.PostJSON(uri, msg)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return util.DecodeWithCommonError(response, "DeleteSubscribe")
|
||||
}
|
||||
|
||||
@@ -10,6 +10,8 @@ import (
|
||||
const (
|
||||
subscribeSendURL = "https://api.weixin.qq.com/cgi-bin/message/subscribe/bizsend"
|
||||
subscribeTemplateListURL = "https://api.weixin.qq.com/wxaapi/newtmpl/gettemplate"
|
||||
subscribeTemplateAddURL = "https://api.weixin.qq.com/wxaapi/newtmpl/addtemplate"
|
||||
subscribeTemplateDelURL = "https://api.weixin.qq.com/wxaapi/newtmpl/deltemplate"
|
||||
)
|
||||
|
||||
//Subscribe 订阅消息
|
||||
@@ -84,10 +86,62 @@ func (tpl *Subscribe) List() (templateList []*PrivateSubscribeItem, err error) {
|
||||
return
|
||||
}
|
||||
var res resPrivateSubscribeList
|
||||
err = util.DecodeWithError(response, &res, "ListSubscription")
|
||||
err = util.DecodeWithError(response, &res, "ListSubscribe")
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
templateList = res.SubscriptionList
|
||||
return
|
||||
}
|
||||
|
||||
type resSubscribeAdd struct {
|
||||
util.CommonError
|
||||
|
||||
TemplateID string `json:"priTmplId"`
|
||||
}
|
||||
|
||||
// Add 添加订阅消息模板
|
||||
func (tpl *Subscribe) Add(ShortID string, kidList []int, sceneDesc string) (templateID string, err error) {
|
||||
var accessToken string
|
||||
accessToken, err = tpl.GetAccessToken()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
var msg = struct {
|
||||
TemplateIDShort string `json:"tid"`
|
||||
SceneDesc string `json:"sceneDesc"`
|
||||
KidList []int `json:"kidList"`
|
||||
}{TemplateIDShort: ShortID, SceneDesc: sceneDesc, KidList: kidList}
|
||||
uri := fmt.Sprintf("%s?access_token=%s", subscribeTemplateAddURL, accessToken)
|
||||
var response []byte
|
||||
response, err = util.PostJSON(uri, msg)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
var result resSubscribeAdd
|
||||
err = util.DecodeWithError(response, &result, "AddSubscribe")
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
templateID = result.TemplateID
|
||||
return
|
||||
}
|
||||
|
||||
// Delete 删除私有模板
|
||||
func (tpl *Subscribe) Delete(templateID string) (err error) {
|
||||
var accessToken string
|
||||
accessToken, err = tpl.GetAccessToken()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
var msg = struct {
|
||||
TemplateID string `json:"priTmplId"`
|
||||
}{TemplateID: templateID}
|
||||
uri := fmt.Sprintf("%s?access_token=%s", subscribeTemplateDelURL, accessToken)
|
||||
var response []byte
|
||||
response, err = util.PostJSON(uri, msg)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return util.DecodeWithCommonError(response, "DeleteSubscribe")
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ type RefundedReqInfo struct {
|
||||
SettlementRefundFee *int `xml:"settlement_refund_fee"`
|
||||
RefundStatus *string `xml:"refund_status"`
|
||||
SuccessTime *string `xml:"success_time"`
|
||||
RefundRecvAccount *string `xml:"refund_recv_account"`
|
||||
RefundRecvAccount *string `xml:"refund_recv_accout"`
|
||||
RefundAccount *string `xml:"refund_account"`
|
||||
RefundRequestSource *string `xml:"refund_request_source"`
|
||||
}
|
||||
|
||||
@@ -31,8 +31,16 @@ const (
|
||||
SDKAccessTokenExpired Error = "AccessToken 已过期"
|
||||
// SDKApiFreqOutOfLimit 错误码:45009
|
||||
SDKApiFreqOutOfLimit Error = "接口请求次数超频"
|
||||
// SDKApiForbidden 错误码:48002
|
||||
SDKApiForbidden Error = "API 禁止调用"
|
||||
// SDKInvalidOpenKFID 错误码:95000
|
||||
SDKInvalidOpenKFID Error = "无效的 open_kfid"
|
||||
// SDKOpenKFIDNotExist 错误码:95004
|
||||
SDKOpenKFIDNotExist Error = "open_kfid 不存在"
|
||||
// SDKWeWorkAlready 错误码:95011
|
||||
SDKWeWorkAlready Error = "已在企业微信使用微信客服"
|
||||
// SDKApiNotOpen 错误码:95017
|
||||
SDKApiNotOpen Error = "API 功能没有被开启"
|
||||
)
|
||||
|
||||
//Error 输出错误信息
|
||||
@@ -63,8 +71,16 @@ func NewSDKErr(code int64, msgList ...string) Error {
|
||||
return SDKDecryptMSGFailed
|
||||
case 45009:
|
||||
return SDKApiFreqOutOfLimit
|
||||
case 48002:
|
||||
return SDKApiForbidden
|
||||
case 95000:
|
||||
return SDKInvalidOpenKFID
|
||||
case 95004:
|
||||
return SDKOpenKFIDNotExist
|
||||
case 95011:
|
||||
return SDKWeWorkAlready
|
||||
case 95017:
|
||||
return SDKApiNotOpen
|
||||
default:
|
||||
//返回未知的自定义错误
|
||||
if len(msgList) > 0 {
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
// +build linux
|
||||
|
||||
//Package msgaudit only for linux
|
||||
package msgaudit
|
||||
|
||||
// #cgo LDFLAGS: -L${SRCDIR}/lib -lWeWorkFinanceSdk_C
|
||||
@@ -7,9 +10,10 @@ package msgaudit
|
||||
import "C"
|
||||
import (
|
||||
"encoding/json"
|
||||
"unsafe"
|
||||
|
||||
"github.com/silenceper/wechat/v2/util"
|
||||
"github.com/silenceper/wechat/v2/work/config"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// Client 会话存档
|
||||
19
work/msgaudit/client_unsupport.go
Normal file
19
work/msgaudit/client_unsupport.go
Normal file
@@ -0,0 +1,19 @@
|
||||
// +build !linux linux,!cgo
|
||||
|
||||
//Package msgaudit for unsupport platform
|
||||
package msgaudit
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/silenceper/wechat/v2/work/config"
|
||||
)
|
||||
|
||||
// Client 会话存档
|
||||
type Client struct {
|
||||
}
|
||||
|
||||
// NewClient new
|
||||
func NewClient(cfg *config.Config) (*Client, error) {
|
||||
return nil, fmt.Errorf("会话存档功能目前只支持Linux平台运行,并且打开设置CGO_ENABLED=1")
|
||||
}
|
||||
Reference in New Issue
Block a user