mirror of
https://github.com/silenceper/wechat.git
synced 2025-12-19 16:52:24 +08:00
feat: improve comment and upgrade golang version 1.16 (#604)
* feat: improve action config and code comment * feat: improve comment and upgrade golang version 1.16 * feat: improve import
This commit is contained in:
12
.github/workflows/go.yml
vendored
12
.github/workflows/go.yml
vendored
@@ -10,17 +10,17 @@ jobs:
|
||||
golangci:
|
||||
strategy:
|
||||
matrix:
|
||||
go-version: [1.15.x,1.16.x,1.17.x]
|
||||
go-version: [1.16.x,1.17.x,1.18.x]
|
||||
name: golangci-lint
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/setup-go@v2
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-go@v3
|
||||
- uses: actions/checkout@v3
|
||||
- name: golangci-lint
|
||||
uses: golangci/golangci-lint-action@v3.1.0
|
||||
uses: golangci/golangci-lint-action@v3.2.0
|
||||
with:
|
||||
# Required: the version of golangci-lint is required and must be specified without patch version: we always use the latest patch version.
|
||||
version: v1.31
|
||||
version: latest
|
||||
build:
|
||||
name: Test
|
||||
runs-on: ubuntu-latest
|
||||
@@ -38,7 +38,7 @@ jobs:
|
||||
# strategy set
|
||||
strategy:
|
||||
matrix:
|
||||
go: ["1.15", "1.16", "1.17", "1.18"]
|
||||
go: ["1.16", "1.17", "1.18"]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
2
doc.go
2
doc.go
@@ -7,4 +7,6 @@ Package wechat provide wechat sdk for go
|
||||
更多信息:https://github.com/silenceper/wechat
|
||||
|
||||
*/
|
||||
|
||||
// Package wechat provide wechat sdk for go
|
||||
package wechat
|
||||
|
||||
2
go.mod
2
go.mod
@@ -1,6 +1,6 @@
|
||||
module github.com/silenceper/wechat/v2
|
||||
|
||||
go 1.15
|
||||
go 1.16
|
||||
|
||||
require (
|
||||
github.com/bradfitz/gomemcache v0.0.0-20220106215444-fb4bf637b56d
|
||||
|
||||
@@ -18,6 +18,7 @@ type InvokeCloudFunctionRes struct {
|
||||
}
|
||||
|
||||
// InvokeCloudFunction 云函数调用
|
||||
//
|
||||
//reference:https://developers.weixin.qq.com/miniprogram/dev/wxcloud/reference-http-api/functions/invokeCloudFunction.html
|
||||
func (tcb *Tcb) InvokeCloudFunction(env, name, args string) (*InvokeCloudFunctionRes, error) {
|
||||
accessToken, err := tcb.GetAccessToken()
|
||||
|
||||
@@ -192,6 +192,7 @@ type DatabaseCountRes struct {
|
||||
}
|
||||
|
||||
// DatabaseMigrateImport 数据库导入
|
||||
//
|
||||
//reference:https://developers.weixin.qq.com/miniprogram/dev/wxcloud/reference-http-api/database/databaseMigrateImport.html
|
||||
func (tcb *Tcb) DatabaseMigrateImport(req *DatabaseMigrateImportReq) (*DatabaseMigrateImportRes, error) {
|
||||
accessToken, err := tcb.GetAccessToken()
|
||||
@@ -209,6 +210,7 @@ func (tcb *Tcb) DatabaseMigrateImport(req *DatabaseMigrateImportReq) (*DatabaseM
|
||||
}
|
||||
|
||||
// DatabaseMigrateExport 数据库导出
|
||||
//
|
||||
//reference:https://developers.weixin.qq.com/miniprogram/dev/wxcloud/reference-http-api/database/databaseMigrateExport.html
|
||||
func (tcb *Tcb) DatabaseMigrateExport(req *DatabaseMigrateExportReq) (*DatabaseMigrateExportRes, error) {
|
||||
accessToken, err := tcb.GetAccessToken()
|
||||
@@ -226,6 +228,7 @@ func (tcb *Tcb) DatabaseMigrateExport(req *DatabaseMigrateExportReq) (*DatabaseM
|
||||
}
|
||||
|
||||
// DatabaseMigrateQueryInfo 数据库迁移状态查询
|
||||
//
|
||||
//reference:https://developers.weixin.qq.com/miniprogram/dev/wxcloud/reference-http-api/database/databaseMigrateQueryInfo.html
|
||||
func (tcb *Tcb) DatabaseMigrateQueryInfo(env string, jobID int64) (*DatabaseMigrateQueryInfoRes, error) {
|
||||
accessToken, err := tcb.GetAccessToken()
|
||||
@@ -261,6 +264,7 @@ func (tcb *Tcb) UpdateIndex(req *UpdateIndexReq) error {
|
||||
}
|
||||
|
||||
// DatabaseCollectionAdd 新增集合
|
||||
//
|
||||
//reference:https://developers.weixin.qq.com/miniprogram/dev/wxcloud/reference-http-api/database/databaseCollectionAdd.html
|
||||
func (tcb *Tcb) DatabaseCollectionAdd(env, collectionName string) error {
|
||||
accessToken, err := tcb.GetAccessToken()
|
||||
@@ -279,6 +283,7 @@ func (tcb *Tcb) DatabaseCollectionAdd(env, collectionName string) error {
|
||||
}
|
||||
|
||||
// DatabaseCollectionDelete 删除集合
|
||||
//
|
||||
//reference:https://developers.weixin.qq.com/miniprogram/dev/wxcloud/reference-http-api/database/databaseCollectionDelete.html
|
||||
func (tcb *Tcb) DatabaseCollectionDelete(env, collectionName string) error {
|
||||
accessToken, err := tcb.GetAccessToken()
|
||||
@@ -297,6 +302,7 @@ func (tcb *Tcb) DatabaseCollectionDelete(env, collectionName string) error {
|
||||
}
|
||||
|
||||
// DatabaseCollectionGet 获取特定云环境下集合信息
|
||||
//
|
||||
//reference:https://developers.weixin.qq.com/miniprogram/dev/wxcloud/reference-http-api/database/databaseCollectionGet.html
|
||||
func (tcb *Tcb) DatabaseCollectionGet(env string, limit, offset int64) (*DatabaseCollectionGetRes, error) {
|
||||
accessToken, err := tcb.GetAccessToken()
|
||||
@@ -318,6 +324,7 @@ func (tcb *Tcb) DatabaseCollectionGet(env string, limit, offset int64) (*Databas
|
||||
}
|
||||
|
||||
// DatabaseAdd 数据库插入记录
|
||||
//
|
||||
//reference:https://developers.weixin.qq.com/miniprogram/dev/wxcloud/reference-http-api/database/databaseAdd.html
|
||||
func (tcb *Tcb) DatabaseAdd(env, query string) (*DatabaseAddRes, error) {
|
||||
accessToken, err := tcb.GetAccessToken()
|
||||
@@ -338,6 +345,7 @@ func (tcb *Tcb) DatabaseAdd(env, query string) (*DatabaseAddRes, error) {
|
||||
}
|
||||
|
||||
// DatabaseDelete 数据库插入记录
|
||||
//
|
||||
//reference:https://developers.weixin.qq.com/miniprogram/dev/wxcloud/reference-http-api/database/databaseDelete.html
|
||||
func (tcb *Tcb) DatabaseDelete(env, query string) (*DatabaseDeleteRes, error) {
|
||||
accessToken, err := tcb.GetAccessToken()
|
||||
@@ -358,6 +366,7 @@ func (tcb *Tcb) DatabaseDelete(env, query string) (*DatabaseDeleteRes, error) {
|
||||
}
|
||||
|
||||
// DatabaseUpdate 数据库插入记录
|
||||
//
|
||||
//reference:https://developers.weixin.qq.com/miniprogram/dev/wxcloud/reference-http-api/database/databaseUpdate.html
|
||||
func (tcb *Tcb) DatabaseUpdate(env, query string) (*DatabaseUpdateRes, error) {
|
||||
accessToken, err := tcb.GetAccessToken()
|
||||
@@ -378,6 +387,7 @@ func (tcb *Tcb) DatabaseUpdate(env, query string) (*DatabaseUpdateRes, error) {
|
||||
}
|
||||
|
||||
// DatabaseQuery 数据库查询记录
|
||||
//
|
||||
//reference:https://developers.weixin.qq.com/miniprogram/dev/wxcloud/reference-http-api/database/databaseQuery.html
|
||||
func (tcb *Tcb) DatabaseQuery(env, query string) (*DatabaseQueryRes, error) {
|
||||
accessToken, err := tcb.GetAccessToken()
|
||||
@@ -398,6 +408,7 @@ func (tcb *Tcb) DatabaseQuery(env, query string) (*DatabaseQueryRes, error) {
|
||||
}
|
||||
|
||||
// DatabaseCount 统计集合记录数或统计查询语句对应的结果记录数
|
||||
//
|
||||
//reference:https://developers.weixin.qq.com/miniprogram/dev/wxcloud/reference-http-api/database/databaseCount.html
|
||||
func (tcb *Tcb) DatabaseCount(env, query string) (*DatabaseCountRes, error) {
|
||||
accessToken, err := tcb.GetAccessToken()
|
||||
|
||||
@@ -71,6 +71,7 @@ type BatchDeleteFileRes struct {
|
||||
}
|
||||
|
||||
// UploadFile 上传文件
|
||||
//
|
||||
//reference:https://developers.weixin.qq.com/miniprogram/dev/wxcloud/reference-http-api/storage/uploadFile.html
|
||||
func (tcb *Tcb) UploadFile(env, path string) (*UploadFileRes, error) {
|
||||
accessToken, err := tcb.GetAccessToken()
|
||||
@@ -92,6 +93,7 @@ func (tcb *Tcb) UploadFile(env, path string) (*UploadFileRes, error) {
|
||||
}
|
||||
|
||||
// BatchDownloadFile 获取文件下载链接
|
||||
//
|
||||
//reference:https://developers.weixin.qq.com/miniprogram/dev/wxcloud/reference-http-api/storage/batchDownloadFile.html
|
||||
func (tcb *Tcb) BatchDownloadFile(env string, fileList []*DownloadFile) (*BatchDownloadFileRes, error) {
|
||||
accessToken, err := tcb.GetAccessToken()
|
||||
@@ -113,6 +115,7 @@ func (tcb *Tcb) BatchDownloadFile(env string, fileList []*DownloadFile) (*BatchD
|
||||
}
|
||||
|
||||
// BatchDeleteFile 批量删除文件
|
||||
//
|
||||
//reference:https://developers.weixin.qq.com/miniprogram/dev/wxcloud/reference-http-api/storage/batchDeleteFile.html
|
||||
func (tcb *Tcb) BatchDeleteFile(env string, fileIDList []string) (*BatchDeleteFileRes, error) {
|
||||
accessToken, err := tcb.GetAccessToken()
|
||||
|
||||
@@ -228,7 +228,7 @@ func (csm *Manager) UploadHeadImg(kfAccount, fileName string) (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
//SendTypingStatus 下发客服输入状态给用户
|
||||
// SendTypingStatus 下发客服输入状态给用户
|
||||
func (csm *Manager) SendTypingStatus(openid string, cmd TypingStatus) (err error) {
|
||||
var accessToken string
|
||||
accessToken, err = csm.GetAccessToken()
|
||||
|
||||
@@ -302,6 +302,7 @@ type reqBatchGetMaterial struct {
|
||||
}
|
||||
|
||||
// BatchGetMaterial 批量获取永久素材
|
||||
//
|
||||
//reference:https://developers.weixin.qq.com/doc/offiaccount/Asset_Management/Get_materials_list.html
|
||||
func (material *Material) BatchGetMaterial(permanentMaterialType PermanentMaterialType, offset, count int64) (list ArticleList, err error) {
|
||||
var accessToken string
|
||||
|
||||
@@ -151,8 +151,8 @@ func (tpl *Subscribe) Delete(templateID string) (err error) {
|
||||
|
||||
// PublicTemplateCategory 公众号类目
|
||||
type PublicTemplateCategory struct {
|
||||
ID int `json:"id"` //类目ID
|
||||
Name string `json:"name"` //类目的中文名
|
||||
ID int `json:"id"` // 类目ID
|
||||
Name string `json:"name"` // 类目的中文名
|
||||
}
|
||||
|
||||
type resSubscribeCategoryList struct {
|
||||
@@ -186,13 +186,13 @@ func (tpl *Subscribe) GetCategory() (categoryList []*PublicTemplateCategory, err
|
||||
type PublicTemplateKeyWords struct {
|
||||
KeyWordsID int `json:"kid"` // 关键词 id
|
||||
Name string `json:"name"` // 关键词内容
|
||||
Example string `json:"example"` //关键词内容对应的示例
|
||||
Example string `json:"example"` // 关键词内容对应的示例
|
||||
Rule string `json:"rule"` // 参数类型
|
||||
}
|
||||
|
||||
type resPublicTemplateKeyWordsList struct {
|
||||
util.CommonError
|
||||
KeyWordsList []*PublicTemplateKeyWords `json:"data"` //关键词列表
|
||||
KeyWordsList []*PublicTemplateKeyWords `json:"data"` // 关键词列表
|
||||
}
|
||||
|
||||
// GetPubTplKeyWordsByID 获取模板中的关键词
|
||||
@@ -227,8 +227,8 @@ type PublicTemplateTitle struct {
|
||||
|
||||
type resPublicTemplateTitleList struct {
|
||||
util.CommonError
|
||||
Count int `json:"count"` //公共模板列表总数
|
||||
TemplateTitleList []*PublicTemplateTitle `json:"data"` //模板标题列表
|
||||
Count int `json:"count"` // 公共模板列表总数
|
||||
TemplateTitleList []*PublicTemplateTitle `json:"data"` // 模板标题列表
|
||||
}
|
||||
|
||||
// GetPublicTemplateTitleList 获取类目下的公共模板
|
||||
|
||||
@@ -5,7 +5,7 @@ import (
|
||||
"encoding/xml"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"io"
|
||||
"net/http"
|
||||
"reflect"
|
||||
"runtime/debug"
|
||||
@@ -13,11 +13,11 @@ import (
|
||||
"strings"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/tidwall/gjson"
|
||||
|
||||
"github.com/silenceper/wechat/v2/officialaccount/context"
|
||||
"github.com/silenceper/wechat/v2/officialaccount/message"
|
||||
"github.com/silenceper/wechat/v2/util"
|
||||
"github.com/tidwall/gjson"
|
||||
)
|
||||
|
||||
// Server struct
|
||||
@@ -106,7 +106,7 @@ func (srv *Server) handleRequest() (reply *message.Reply, err error) {
|
||||
srv.isSafeMode = true
|
||||
}
|
||||
|
||||
//set request contentType
|
||||
// set request contentType
|
||||
contentType := srv.Request.Header.Get("Content-Type")
|
||||
srv.isJSONContent = strings.Contains(contentType, "application/json")
|
||||
|
||||
@@ -162,7 +162,7 @@ func (srv *Server) getMessage() (interface{}, error) {
|
||||
return nil, fmt.Errorf("消息解密失败, err=%v", err)
|
||||
}
|
||||
} else {
|
||||
rawXMLMsgBytes, err = ioutil.ReadAll(srv.Request.Body)
|
||||
rawXMLMsgBytes, err = io.ReadAll(srv.Request.Body)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("从body中解析xml失败, err=%v", err)
|
||||
}
|
||||
@@ -193,7 +193,7 @@ func (srv *Server) parseRequestMessage(rawXMLMsgBytes []byte) (msg *message.MixM
|
||||
err = xml.Unmarshal(rawXMLMsgBytes, msg)
|
||||
return
|
||||
}
|
||||
//parse json
|
||||
// parse json
|
||||
err = json.Unmarshal(rawXMLMsgBytes, msg)
|
||||
if err != nil {
|
||||
return
|
||||
|
||||
@@ -28,6 +28,7 @@ type AccountBasicInfo struct {
|
||||
}
|
||||
|
||||
// GetAccountBasicInfo 获取小程序基础信息
|
||||
//
|
||||
//reference:https://developers.weixin.qq.com/doc/oplatform/Third-party_Platforms/Mini_Programs/Mini_Program_Information_Settings.html
|
||||
func (basic *Basic) GetAccountBasicInfo() (*AccountBasicInfo, error) {
|
||||
ak, err := basic.GetAuthrAccessToken(basic.AppID)
|
||||
|
||||
17
util/http.go
17
util/http.go
@@ -9,7 +9,6 @@ import (
|
||||
"encoding/xml"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"mime/multipart"
|
||||
"net/http"
|
||||
@@ -38,7 +37,7 @@ func HTTPGetContext(ctx context.Context, uri string) ([]byte, error) {
|
||||
if response.StatusCode != http.StatusOK {
|
||||
return nil, fmt.Errorf("http get error : uri=%v , statusCode=%v", uri, response.StatusCode)
|
||||
}
|
||||
return ioutil.ReadAll(response.Body)
|
||||
return io.ReadAll(response.Body)
|
||||
}
|
||||
|
||||
// HTTPPost post 请求
|
||||
@@ -67,7 +66,7 @@ func HTTPPostContext(ctx context.Context, uri string, data []byte, header map[st
|
||||
if response.StatusCode != http.StatusOK {
|
||||
return nil, fmt.Errorf("http post error : uri=%v , statusCode=%v", uri, response.StatusCode)
|
||||
}
|
||||
return ioutil.ReadAll(response.Body)
|
||||
return io.ReadAll(response.Body)
|
||||
}
|
||||
|
||||
// PostJSON post json 数据请求
|
||||
@@ -88,7 +87,7 @@ func PostJSON(uri string, obj interface{}) ([]byte, error) {
|
||||
if response.StatusCode != http.StatusOK {
|
||||
return nil, fmt.Errorf("http get error : uri=%v , statusCode=%v", uri, response.StatusCode)
|
||||
}
|
||||
return ioutil.ReadAll(response.Body)
|
||||
return io.ReadAll(response.Body)
|
||||
}
|
||||
|
||||
// PostJSONWithRespContentType post json数据请求,且返回数据类型
|
||||
@@ -110,7 +109,7 @@ func PostJSONWithRespContentType(uri string, obj interface{}) ([]byte, string, e
|
||||
if response.StatusCode != http.StatusOK {
|
||||
return nil, "", fmt.Errorf("http get error : uri=%v , statusCode=%v", uri, response.StatusCode)
|
||||
}
|
||||
responseData, err := ioutil.ReadAll(response.Body)
|
||||
responseData, err := io.ReadAll(response.Body)
|
||||
contentType := response.Header.Get("Content-Type")
|
||||
return responseData, contentType, err
|
||||
}
|
||||
@@ -183,7 +182,7 @@ func PostMultipartForm(fields []MultipartFormField, uri string) (respBody []byte
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return nil, err
|
||||
}
|
||||
respBody, err = ioutil.ReadAll(resp.Body)
|
||||
respBody, err = io.ReadAll(resp.Body)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -204,13 +203,13 @@ func PostXML(uri string, obj interface{}) ([]byte, error) {
|
||||
if response.StatusCode != http.StatusOK {
|
||||
return nil, fmt.Errorf("http code error : uri=%v , statusCode=%v", uri, response.StatusCode)
|
||||
}
|
||||
return ioutil.ReadAll(response.Body)
|
||||
return io.ReadAll(response.Body)
|
||||
}
|
||||
|
||||
// httpWithTLS CA证书
|
||||
func httpWithTLS(rootCa, key string) (*http.Client, error) {
|
||||
var client *http.Client
|
||||
certData, err := ioutil.ReadFile(rootCa)
|
||||
certData, err := os.ReadFile(rootCa)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to find cert path=%s, error=%v", rootCa, err)
|
||||
}
|
||||
@@ -269,5 +268,5 @@ func PostXMLWithTLS(uri string, obj interface{}, ca, key string) ([]byte, error)
|
||||
if response.StatusCode != http.StatusOK {
|
||||
return nil, fmt.Errorf("http code error : uri=%v , statusCode=%v", uri, response.StatusCode)
|
||||
}
|
||||
return ioutil.ReadAll(response.Body)
|
||||
return io.ReadAll(response.Body)
|
||||
}
|
||||
|
||||
@@ -15,21 +15,22 @@ type SignatureOptions struct {
|
||||
}
|
||||
|
||||
// VerifyURL 验证请求参数是否合法并返回解密后的消息内容
|
||||
// //Gin框架的使用示例
|
||||
// r.GET("/v1/event/callback", func(c *gin.Context) {
|
||||
// options := kf.SignatureOptions{}
|
||||
// //获取回调的的校验参数
|
||||
// if = c.ShouldBindQuery(&options); err != nil {
|
||||
// c.String(http.StatusUnauthorized, "参数解析失败")
|
||||
// }
|
||||
// // 调用VerifyURL方法校验当前请求,如果合法则把解密后的内容作为响应返回给微信服务器
|
||||
// echo, err := kfClient.VerifyURL(options)
|
||||
// if err == nil {
|
||||
// c.String(http.StatusOK, echo)
|
||||
// } else {
|
||||
// c.String(http.StatusUnauthorized, "非法请求来源")
|
||||
// }
|
||||
// })
|
||||
//
|
||||
// //Gin框架的使用示例
|
||||
// r.GET("/v1/event/callback", func(c *gin.Context) {
|
||||
// options := kf.SignatureOptions{}
|
||||
// //获取回调的的校验参数
|
||||
// if = c.ShouldBindQuery(&options); err != nil {
|
||||
// c.String(http.StatusUnauthorized, "参数解析失败")
|
||||
// }
|
||||
// // 调用VerifyURL方法校验当前请求,如果合法则把解密后的内容作为响应返回给微信服务器
|
||||
// echo, err := kfClient.VerifyURL(options)
|
||||
// if err == nil {
|
||||
// c.String(http.StatusOK, echo)
|
||||
// } else {
|
||||
// c.String(http.StatusUnauthorized, "非法请求来源")
|
||||
// }
|
||||
// })
|
||||
func (r *Client) VerifyURL(options SignatureOptions) (string, error) {
|
||||
if options.Signature != util.Signature(r.ctx.Token, options.TimeStamp, options.Nonce, options.EchoStr) {
|
||||
return "", NewSDKErr(40015)
|
||||
@@ -59,27 +60,28 @@ type CallbackMessage struct {
|
||||
}
|
||||
|
||||
// GetCallbackMessage 获取回调事件中的消息内容
|
||||
// //Gin框架的使用示例
|
||||
// r.POST("/v1/event/callback", func(c *gin.Context) {
|
||||
// var (
|
||||
// message kf.CallbackMessage
|
||||
// body []byte
|
||||
// )
|
||||
// // 读取原始消息内容
|
||||
// body, err = c.GetRawData()
|
||||
// if err != nil {
|
||||
// c.String(http.StatusInternalServerError, err.Error())
|
||||
// return
|
||||
// }
|
||||
// // 解析原始数据
|
||||
// message, err = kfClient.GetCallbackMessage(body)
|
||||
// if err != nil {
|
||||
// c.String(http.StatusInternalServerError, "消息获取失败")
|
||||
// return
|
||||
// }
|
||||
// fmt.Println(message)
|
||||
// c.String(200, "ok")
|
||||
// })
|
||||
//
|
||||
// //Gin框架的使用示例
|
||||
// r.POST("/v1/event/callback", func(c *gin.Context) {
|
||||
// var (
|
||||
// message kf.CallbackMessage
|
||||
// body []byte
|
||||
// )
|
||||
// // 读取原始消息内容
|
||||
// body, err = c.GetRawData()
|
||||
// if err != nil {
|
||||
// c.String(http.StatusInternalServerError, err.Error())
|
||||
// return
|
||||
// }
|
||||
// // 解析原始数据
|
||||
// message, err = kfClient.GetCallbackMessage(body)
|
||||
// if err != nil {
|
||||
// c.String(http.StatusInternalServerError, "消息获取失败")
|
||||
// return
|
||||
// }
|
||||
// fmt.Println(message)
|
||||
// c.String(200, "ok")
|
||||
// })
|
||||
func (r *Client) GetCallbackMessage(encryptedMsg []byte) (msg CallbackMessage, err error) {
|
||||
var origin callbackOriginMessage
|
||||
if err = xml.Unmarshal(encryptedMsg, &origin); err != nil {
|
||||
|
||||
Reference in New Issue
Block a user