mirror of
https://github.com/silenceper/wechat.git
synced 2026-02-08 22:52:27 +08:00
Compare commits
4 Commits
feature/re
...
feature/go
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d8e3208ef2 | ||
|
|
d8fde54f2d | ||
|
|
ba0a1477eb | ||
|
|
01eedc4274 |
8
.github/workflows/go.yml
vendored
8
.github/workflows/go.yml
vendored
@@ -10,7 +10,7 @@ jobs:
|
|||||||
golangci:
|
golangci:
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
go-version: [ '1.16','1.17','1.18','1.19','1.20','1.21.4' ]
|
go-version: [ '1.18','1.19','1.20','1.21.4','1.22' ]
|
||||||
name: golangci-lint
|
name: golangci-lint
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
@@ -21,10 +21,10 @@ jobs:
|
|||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
- name: golangci-lint
|
- name: golangci-lint
|
||||||
uses: golangci/golangci-lint-action@v4
|
uses: golangci/golangci-lint-action@v6
|
||||||
with:
|
with:
|
||||||
# Required: the version of golangci-lint is required and must be specified without patch version: we always use the latest patch version.
|
# Required: the version of golangci-lint is required and must be specified without patch version: we always use the latest patch version.
|
||||||
version: v1.52.2
|
version: v1.58.2
|
||||||
build:
|
build:
|
||||||
name: Test
|
name: Test
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
@@ -42,7 +42,7 @@ jobs:
|
|||||||
# strategy set
|
# strategy set
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
go: [ '1.16','1.17','1.18','1.19','1.20','1.21','1.22' ]
|
go: [ '1.18','1.19','1.20','1.21','1.22' ]
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|||||||
@@ -4,36 +4,32 @@ linters:
|
|||||||
disable-all: true
|
disable-all: true
|
||||||
enable:
|
enable:
|
||||||
- bodyclose
|
- bodyclose
|
||||||
- deadcode
|
|
||||||
- depguard
|
- depguard
|
||||||
- dogsled
|
- dogsled
|
||||||
- dupl
|
- dupl
|
||||||
- errcheck
|
- errcheck
|
||||||
|
- exportloopref
|
||||||
- funlen
|
- funlen
|
||||||
- goconst
|
- goconst
|
||||||
# - gocritic
|
# - gocritic
|
||||||
- gocyclo
|
- gocyclo
|
||||||
- gofmt
|
- gofmt
|
||||||
- goimports
|
- goimports
|
||||||
- golint
|
|
||||||
- goprintffuncname
|
- goprintffuncname
|
||||||
- gosimple
|
- gosimple
|
||||||
- govet
|
- govet
|
||||||
- ineffassign
|
- ineffassign
|
||||||
- interfacer
|
|
||||||
- misspell
|
- misspell
|
||||||
- nolintlint
|
- nolintlint
|
||||||
- rowserrcheck
|
- rowserrcheck
|
||||||
- scopelint
|
|
||||||
- staticcheck
|
- staticcheck
|
||||||
- structcheck
|
|
||||||
- stylecheck
|
- stylecheck
|
||||||
- typecheck
|
# - typecheck
|
||||||
- unconvert
|
- unconvert
|
||||||
- unparam
|
- unparam
|
||||||
- unused
|
- unused
|
||||||
- varcheck
|
|
||||||
- whitespace
|
- whitespace
|
||||||
|
# - revive
|
||||||
|
|
||||||
issues:
|
issues:
|
||||||
include:
|
include:
|
||||||
@@ -57,10 +53,68 @@ linters-settings:
|
|||||||
lines: 66
|
lines: 66
|
||||||
statements: 50
|
statements: 50
|
||||||
|
|
||||||
#issues:
|
errcheck:
|
||||||
# include:
|
# Report about not checking of errors in type assertions: `a := b.(MyStruct)`.
|
||||||
# - EXC0002 # disable excluding of issues about comments from golint
|
# Such cases aren't reported by default.
|
||||||
# exclude-rules:
|
# Default: false
|
||||||
# - linters:
|
check-type-assertions: true
|
||||||
# - stylecheck
|
# report about assignment of errors to blank identifier: `num, _ := strconv.Atoi(numStr)`.
|
||||||
# text: "ST1000:"
|
# Such cases aren't reported by default.
|
||||||
|
# Default: false
|
||||||
|
check-blank: true
|
||||||
|
# To disable the errcheck built-in exclude list.
|
||||||
|
# See `-excludeonly` option in https://github.com/kisielk/errcheck#excluding-functions for details.
|
||||||
|
# Default: false
|
||||||
|
disable-default-exclusions: true
|
||||||
|
# List of functions to exclude from checking, where each entry is a single function to exclude.
|
||||||
|
# See https://github.com/kisielk/errcheck#excluding-functions for details.
|
||||||
|
exclude-functions:
|
||||||
|
- io/ioutil.ReadFile
|
||||||
|
- io.Copy(*bytes.Buffer)
|
||||||
|
- io.Copy(os.Stdout)
|
||||||
|
- (*bytes.Buffer).WriteString
|
||||||
|
- (*bytes.Buffer).Write
|
||||||
|
- url.Parse
|
||||||
|
- (*strings.Builder).WriteString
|
||||||
|
- io.WriteString
|
||||||
|
- (*bytes.Buffer).WriteByte
|
||||||
|
- (*hmac.New).Write
|
||||||
|
- (*int)
|
||||||
|
- (*string)
|
||||||
|
- (hash.Hash).Write
|
||||||
|
|
||||||
|
depguard:
|
||||||
|
# Rules to apply.
|
||||||
|
#
|
||||||
|
# Variables:
|
||||||
|
# - File Variables
|
||||||
|
# you can still use and exclamation mark ! in front of a variable to say not to use it.
|
||||||
|
# Example !$test will match any file that is not a go test file.
|
||||||
|
#
|
||||||
|
# `$all` - matches all go files
|
||||||
|
# `$test` - matches all go test files
|
||||||
|
#
|
||||||
|
# - Package Variables
|
||||||
|
#
|
||||||
|
# `$gostd` - matches all of go's standard library (Pulled from `GOROOT`)
|
||||||
|
#
|
||||||
|
# Default: Only allow $gostd in all files.
|
||||||
|
rules:
|
||||||
|
# Name of a rule.
|
||||||
|
main:
|
||||||
|
# Used to determine the package matching priority.
|
||||||
|
# There are three different modes: `original`, `strict`, and `lax`.
|
||||||
|
# Default: "original"
|
||||||
|
list-mode: lax
|
||||||
|
# List of file globs that will match this list of settings to compare against.
|
||||||
|
# Default: $all
|
||||||
|
files:
|
||||||
|
- "!**/*_a _file.go"
|
||||||
|
# List of allowed packages.
|
||||||
|
allow:
|
||||||
|
- $gostd
|
||||||
|
- github.com/OpenPeeDeeP
|
||||||
|
# Packages that are not allowed where the value is a suggestion.
|
||||||
|
deny:
|
||||||
|
- pkg: "github.com/pkg/errors"
|
||||||
|
desc: Should be replaced by standard lib errors package
|
||||||
6
cache/memcache_test.go
vendored
6
cache/memcache_test.go
vendored
@@ -22,12 +22,16 @@ func TestMemcache(t *testing.T) {
|
|||||||
exists := mem.IsExist("unknown-key")
|
exists := mem.IsExist("unknown-key")
|
||||||
assert.Equal(t, false, exists)
|
assert.Equal(t, false, exists)
|
||||||
|
|
||||||
name := mem.Get("username").(string)
|
name, ok := mem.Get("username").(string)
|
||||||
|
if !ok {
|
||||||
|
t.Error("get Error")
|
||||||
|
}
|
||||||
if name != "" {
|
if name != "" {
|
||||||
if name != "silenceper" {
|
if name != "silenceper" {
|
||||||
t.Error("get Error")
|
t.Error("get Error")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
data := mem.Get("unknown-key")
|
data := mem.Get("unknown-key")
|
||||||
assert.Nil(t, data)
|
assert.Nil(t, data)
|
||||||
|
|
||||||
|
|||||||
6
cache/redis.go
vendored
6
cache/redis.go
vendored
@@ -76,8 +76,10 @@ func (r *Redis) IsExist(key string) bool {
|
|||||||
|
|
||||||
// IsExistContext 判断 key 是否存在
|
// IsExistContext 判断 key 是否存在
|
||||||
func (r *Redis) IsExistContext(ctx context.Context, key string) bool {
|
func (r *Redis) IsExistContext(ctx context.Context, key string) bool {
|
||||||
result, _ := r.conn.Exists(ctx, key).Result()
|
result, err := r.conn.Exists(ctx, key).Result()
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
return result > 0
|
return result > 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
5
cache/redis_test.go
vendored
5
cache/redis_test.go
vendored
@@ -35,7 +35,10 @@ func TestRedis(t *testing.T) {
|
|||||||
t.Error("IsExist Error")
|
t.Error("IsExist Error")
|
||||||
}
|
}
|
||||||
|
|
||||||
name := redis.Get(key).(string)
|
name, ok := redis.Get(key).(string)
|
||||||
|
if !ok {
|
||||||
|
t.Error("get Error")
|
||||||
|
}
|
||||||
if name != val {
|
if name != val {
|
||||||
t.Error("get Error")
|
t.Error("get Error")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -57,18 +57,19 @@ type ResAccessToken struct {
|
|||||||
ExpiresIn int64 `json:"expires_in"`
|
ExpiresIn int64 `json:"expires_in"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetAccessToken 获取access_token,先从cache中获取,没有则从服务端获取
|
// GetAccessToken 获取 access_token,先从 cache 中获取,没有则从服务端获取
|
||||||
func (ak *DefaultAccessToken) GetAccessToken() (accessToken string, err error) {
|
func (ak *DefaultAccessToken) GetAccessToken() (accessToken string, err error) {
|
||||||
return ak.GetAccessTokenContext(context.Background())
|
return ak.GetAccessTokenContext(context.Background())
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetAccessTokenContext 获取access_token,先从cache中获取,没有则从服务端获取
|
// GetAccessTokenContext 获取 access_token,先从 cache 中获取,没有则从服务端获取
|
||||||
func (ak *DefaultAccessToken) GetAccessTokenContext(ctx context.Context) (accessToken string, err error) {
|
func (ak *DefaultAccessToken) GetAccessTokenContext(ctx context.Context) (accessToken string, err error) {
|
||||||
// 先从 cache 中取
|
// 先从 cache 中取
|
||||||
accessTokenCacheKey := fmt.Sprintf("%s_access_token_%s", ak.cacheKeyPrefix, ak.appID)
|
accessTokenCacheKey := fmt.Sprintf("%s_access_token_%s", ak.cacheKeyPrefix, ak.appID)
|
||||||
|
|
||||||
if val := ak.cache.Get(accessTokenCacheKey); val != nil {
|
if val := ak.cache.Get(accessTokenCacheKey); val != nil {
|
||||||
if accessToken = val.(string); accessToken != "" {
|
var ok bool
|
||||||
|
if accessToken, ok = val.(string); ok && accessToken != "" {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -79,7 +80,8 @@ func (ak *DefaultAccessToken) GetAccessTokenContext(ctx context.Context) (access
|
|||||||
|
|
||||||
// 双检,防止重复从微信服务器获取
|
// 双检,防止重复从微信服务器获取
|
||||||
if val := ak.cache.Get(accessTokenCacheKey); val != nil {
|
if val := ak.cache.Get(accessTokenCacheKey); val != nil {
|
||||||
if accessToken = val.(string); accessToken != "" {
|
var ok bool
|
||||||
|
if accessToken, ok = val.(string); ok && accessToken != "" {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -98,7 +100,7 @@ func (ak *DefaultAccessToken) GetAccessTokenContext(ctx context.Context) (access
|
|||||||
}
|
}
|
||||||
|
|
||||||
// StableAccessToken 获取稳定版接口调用凭据 (与 getAccessToken 获取的调用凭证完全隔离,互不影响)
|
// StableAccessToken 获取稳定版接口调用凭据 (与 getAccessToken 获取的调用凭证完全隔离,互不影响)
|
||||||
// 不强制更新access_token,可用于不同环境不同服务而不需要分布式锁以及公用缓存,避免access_token争抢
|
// 不强制更新 access_token,可用于不同环境不同服务而不需要分布式锁以及公用缓存,避免 access_token 争抢
|
||||||
// https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/mp-access-token/getStableAccessToken.html
|
// https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/mp-access-token/getStableAccessToken.html
|
||||||
type StableAccessToken struct {
|
type StableAccessToken struct {
|
||||||
appID string
|
appID string
|
||||||
@@ -120,12 +122,12 @@ func NewStableAccessToken(appID, appSecret, cacheKeyPrefix string, cache cache.C
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetAccessToken 获取access_token,先从cache中获取,没有则从服务端获取
|
// GetAccessToken 获取 access_token,先从 cache 中获取,没有则从服务端获取
|
||||||
func (ak *StableAccessToken) GetAccessToken() (accessToken string, err error) {
|
func (ak *StableAccessToken) GetAccessToken() (accessToken string, err error) {
|
||||||
return ak.GetAccessTokenContext(context.Background())
|
return ak.GetAccessTokenContext(context.Background())
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetAccessTokenContext 获取access_token,先从cache中获取,没有则从服务端获取
|
// GetAccessTokenContext 获取 access_token,先从 cache 中获取,没有则从服务端获取
|
||||||
func (ak *StableAccessToken) GetAccessTokenContext(ctx context.Context) (accessToken string, err error) {
|
func (ak *StableAccessToken) GetAccessTokenContext(ctx context.Context) (accessToken string, err error) {
|
||||||
// 先从 cache 中取
|
// 先从 cache 中取
|
||||||
accessTokenCacheKey := fmt.Sprintf("%s_stable_access_token_%s", ak.cacheKeyPrefix, ak.appID)
|
accessTokenCacheKey := fmt.Sprintf("%s_stable_access_token_%s", ak.cacheKeyPrefix, ak.appID)
|
||||||
@@ -193,12 +195,12 @@ func NewWorkAccessToken(corpID, corpSecret, cacheKeyPrefix string, cache cache.C
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetAccessToken 企业微信获取access_token,先从cache中获取,没有则从服务端获取
|
// GetAccessToken 企业微信获取 access_token,先从 cache 中获取,没有则从服务端获取
|
||||||
func (ak *WorkAccessToken) GetAccessToken() (accessToken string, err error) {
|
func (ak *WorkAccessToken) GetAccessToken() (accessToken string, err error) {
|
||||||
return ak.GetAccessTokenContext(context.Background())
|
return ak.GetAccessTokenContext(context.Background())
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetAccessTokenContext 企业微信获取access_token,先从cache中获取,没有则从服务端获取
|
// GetAccessTokenContext 企业微信获取 access_token,先从 cache 中获取,没有则从服务端获取
|
||||||
func (ak *WorkAccessToken) GetAccessTokenContext(ctx context.Context) (accessToken string, err error) {
|
func (ak *WorkAccessToken) GetAccessTokenContext(ctx context.Context) (accessToken string, err error) {
|
||||||
// 加上 lock,是为了防止在并发获取 token 时,cache 刚好失效,导致从微信服务器上获取到不同 token
|
// 加上 lock,是为了防止在并发获取 token 时,cache 刚好失效,导致从微信服务器上获取到不同 token
|
||||||
ak.accessTokenLock.Lock()
|
ak.accessTokenLock.Lock()
|
||||||
@@ -206,7 +208,10 @@ func (ak *WorkAccessToken) GetAccessTokenContext(ctx context.Context) (accessTok
|
|||||||
accessTokenCacheKey := fmt.Sprintf("%s_access_token_%s", ak.cacheKeyPrefix, ak.CorpID)
|
accessTokenCacheKey := fmt.Sprintf("%s_access_token_%s", ak.cacheKeyPrefix, ak.CorpID)
|
||||||
val := ak.cache.Get(accessTokenCacheKey)
|
val := ak.cache.Get(accessTokenCacheKey)
|
||||||
if val != nil {
|
if val != nil {
|
||||||
accessToken = val.(string)
|
var ok bool
|
||||||
|
if accessToken, ok = val.(string); !ok {
|
||||||
|
accessToken = ""
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
30
go.mod
30
go.mod
@@ -1,16 +1,30 @@
|
|||||||
module github.com/silenceper/wechat/v2
|
module github.com/silenceper/wechat/v2
|
||||||
|
|
||||||
go 1.16
|
go 1.18
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/alicebob/miniredis/v2 v2.30.0
|
github.com/alicebob/miniredis/v2 v2.33.0
|
||||||
github.com/bradfitz/gomemcache v0.0.0-20220106215444-fb4bf637b56d
|
github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874
|
||||||
github.com/fatih/structs v1.1.0
|
github.com/fatih/structs v1.1.0
|
||||||
github.com/go-redis/redis/v8 v8.11.5
|
github.com/go-redis/redis/v8 v8.11.5
|
||||||
github.com/sirupsen/logrus v1.9.0
|
github.com/sirupsen/logrus v1.9.3
|
||||||
github.com/spf13/cast v1.4.1
|
github.com/spf13/cast v1.6.0
|
||||||
github.com/stretchr/testify v1.7.1
|
github.com/stretchr/testify v1.9.0
|
||||||
github.com/tidwall/gjson v1.14.1
|
github.com/tidwall/gjson v1.17.1
|
||||||
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d
|
golang.org/x/crypto v0.25.0
|
||||||
gopkg.in/h2non/gock.v1 v1.1.2
|
gopkg.in/h2non/gock.v1 v1.1.2
|
||||||
)
|
)
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/alicebob/gopher-json v0.0.0-20200520072559-a9ecdc9d1d3a // indirect
|
||||||
|
github.com/cespare/xxhash/v2 v2.1.2 // indirect
|
||||||
|
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||||
|
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
|
||||||
|
github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542 // indirect
|
||||||
|
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||||
|
github.com/tidwall/match v1.1.1 // indirect
|
||||||
|
github.com/tidwall/pretty v1.2.0 // indirect
|
||||||
|
github.com/yuin/gopher-lua v1.1.1 // indirect
|
||||||
|
golang.org/x/sys v0.22.0 // indirect
|
||||||
|
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||||
|
)
|
||||||
|
|||||||
137
go.sum
137
go.sum
@@ -1,14 +1,11 @@
|
|||||||
github.com/alicebob/gopher-json v0.0.0-20200520072559-a9ecdc9d1d3a h1:HbKu58rmZpUGpz5+4FfNmIU+FmZg2P3Xaj2v2bfNWmk=
|
github.com/alicebob/gopher-json v0.0.0-20200520072559-a9ecdc9d1d3a h1:HbKu58rmZpUGpz5+4FfNmIU+FmZg2P3Xaj2v2bfNWmk=
|
||||||
github.com/alicebob/gopher-json v0.0.0-20200520072559-a9ecdc9d1d3a/go.mod h1:SGnFV6hVsYE877CKEZ6tDNTjaSXYUk6QqoIK6PrAtcc=
|
github.com/alicebob/gopher-json v0.0.0-20200520072559-a9ecdc9d1d3a/go.mod h1:SGnFV6hVsYE877CKEZ6tDNTjaSXYUk6QqoIK6PrAtcc=
|
||||||
github.com/alicebob/miniredis/v2 v2.30.0 h1:uA3uhDbCxfO9+DI/DuGeAMr9qI+noVWwGPNTFuKID5M=
|
github.com/alicebob/miniredis/v2 v2.33.0 h1:uvTF0EDeu9RLnUEG27Db5I68ESoIxTiXbNUiji6lZrA=
|
||||||
github.com/alicebob/miniredis/v2 v2.30.0/go.mod h1:84TWKZlxYkfgMucPBf5SOQBYJceZeQRFIaQgNMiCX6Q=
|
github.com/alicebob/miniredis/v2 v2.33.0/go.mod h1:MhP4a3EU7aENRi9aO+tHfTBZicLqQevyi/DJpoj6mi0=
|
||||||
github.com/bradfitz/gomemcache v0.0.0-20220106215444-fb4bf637b56d h1:pVrfxiGfwelyab6n21ZBkbkmbevaf+WvMIiR7sr97hw=
|
github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874 h1:N7oVaKyGp8bttX0bfZGmcGkjz7DLQXhAn3DNd3T0ous=
|
||||||
github.com/bradfitz/gomemcache v0.0.0-20220106215444-fb4bf637b56d/go.mod h1:H0wQNHz2YrLsuXOZozoeDmnHXkNCRmMW0gwFWDfEZDA=
|
github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874/go.mod h1:r5xuitiExdLAJ09PR7vBVENGvp4ZuTBeWTGtxuX3K+c=
|
||||||
github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE=
|
github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE=
|
||||||
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
|
||||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
|
||||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
@@ -16,132 +13,52 @@ github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/r
|
|||||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
|
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
|
||||||
github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo=
|
github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo=
|
||||||
github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
|
github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
|
||||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
|
||||||
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
|
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
|
||||||
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
|
||||||
github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI=
|
github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI=
|
||||||
github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo=
|
github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo=
|
||||||
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
|
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
||||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
|
||||||
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
|
|
||||||
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
|
|
||||||
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
|
|
||||||
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
|
|
||||||
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
|
||||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
|
||||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
|
||||||
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
|
||||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
|
||||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
|
||||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
|
||||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
|
||||||
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
|
||||||
github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542 h1:2VTzZjLZBgl62/EtslCrtky5vbi9dd7HrQPQIx6wqiw=
|
github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542 h1:2VTzZjLZBgl62/EtslCrtky5vbi9dd7HrQPQIx6wqiw=
|
||||||
github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542/go.mod h1:Ow0tF8D4Kplbc8s8sSb3V2oUCygFHVp8gC3Dn6U4MNI=
|
github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542/go.mod h1:Ow0tF8D4Kplbc8s8sSb3V2oUCygFHVp8gC3Dn6U4MNI=
|
||||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||||
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||||
github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32 h1:W6apQkHrMkS0Muv8G/TipAy/FJl/rCYT0+EuS8+Z0z4=
|
github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32 h1:W6apQkHrMkS0Muv8G/TipAy/FJl/rCYT0+EuS8+Z0z4=
|
||||||
github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32/go.mod h1:9wM+0iRr9ahx58uYLpLIr5fm8diHn0JbqRycJi6w0Ms=
|
github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32/go.mod h1:9wM+0iRr9ahx58uYLpLIr5fm8diHn0JbqRycJi6w0Ms=
|
||||||
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
|
|
||||||
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
|
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
|
||||||
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
|
|
||||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
|
||||||
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
|
|
||||||
github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0=
|
|
||||||
github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
|
github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
|
||||||
github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU=
|
|
||||||
github.com/onsi/ginkgo/v2 v2.0.0/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c=
|
|
||||||
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
|
|
||||||
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
|
|
||||||
github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
|
|
||||||
github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE=
|
github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE=
|
||||||
github.com/onsi/gomega v1.18.1/go.mod h1:0q+aL8jAiMXy9hbwj2mr5GziHiwhAIQpFmmtT5hitRs=
|
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0=
|
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
|
||||||
github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
|
||||||
github.com/spf13/cast v1.4.1 h1:s0hze+J0196ZfEMTs80N7UlFt0BDuQ7Q+JDnHiMWKdA=
|
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||||
github.com/spf13/cast v1.4.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0=
|
||||||
|
github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
|
||||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
|
||||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY=
|
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
||||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||||
github.com/tidwall/gjson v1.14.1 h1:iymTbGkQBhveq21bEvAQ81I0LEBork8BFe1CUZXdyuo=
|
github.com/tidwall/gjson v1.17.1 h1:wlYEnwqAHgzmhNUFfw7Xalt2JzQvsMx2Se4PcoFCT/U=
|
||||||
github.com/tidwall/gjson v1.14.1/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
github.com/tidwall/gjson v1.17.1/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
||||||
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
|
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
|
||||||
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
|
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
|
||||||
github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs=
|
github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs=
|
||||||
github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
|
github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
|
||||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
github.com/yuin/gopher-lua v1.1.1 h1:kYKnWBjvbNP4XLT3+bPEwAXJx262OhaHDWDVOPjL46M=
|
||||||
github.com/yuin/gopher-lua v0.0.0-20220504180219-658193537a64 h1:5mLPGnFdSsevFRFc9q3yYbBkB6tsm4aCwwQV/j1JQAQ=
|
github.com/yuin/gopher-lua v1.1.1/go.mod h1:GBR0iDaNXjAgGg9zfCvksxSRnQx76gclCIb7kdAd1Pw=
|
||||||
github.com/yuin/gopher-lua v0.0.0-20220504180219-658193537a64/go.mod h1:GBR0iDaNXjAgGg9zfCvksxSRnQx76gclCIb7kdAd1Pw=
|
golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30=
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M=
|
||||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4=
|
||||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
|
||||||
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d h1:sK3txAijHtOK88l68nt020reeT1ZdKLIYetKl95FzVY=
|
|
||||||
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
|
||||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
|
||||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
|
||||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
|
||||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
|
||||||
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
|
||||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
|
||||||
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
|
|
||||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 h1:CIJ76btIcR3eFI5EgSo6k1qKw9KJexJuRLI9G7Hp5wE=
|
|
||||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
|
||||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
|
||||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
|
||||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
|
||||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
|
||||||
golang.org/x/sys v0.0.0-20190204203706-41f3e6584952/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
|
||||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
|
||||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 h1:0A+M6Uqn+Eje4kHMK80dtF3JCXC4ykBgQG4Fe06QRhQ=
|
|
||||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
|
||||||
golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M=
|
|
||||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
|
||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
|
||||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
|
||||||
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
|
||||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
|
||||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
|
||||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
|
||||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
|
||||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
|
||||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
|
||||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
|
||||||
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
|
|
||||||
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
|
|
||||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
|
||||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
|
||||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
|
||||||
gopkg.in/h2non/gock.v1 v1.1.2 h1:jBbHXgGBK/AoPVfJh5x4r/WxIrElvbLel8TCZkkZJoY=
|
gopkg.in/h2non/gock.v1 v1.1.2 h1:jBbHXgGBK/AoPVfJh5x4r/WxIrElvbLel8TCZkkZJoY=
|
||||||
gopkg.in/h2non/gock.v1 v1.1.2/go.mod h1:n7UGz/ckNChHiK05rDoiC4MYSunEC/lyaUm2WWaDva0=
|
gopkg.in/h2non/gock.v1 v1.1.2/go.mod h1:n7UGz/ckNChHiK05rDoiC4MYSunEC/lyaUm2WWaDva0=
|
||||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
|
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
|
||||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
|
||||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
|
||||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
|
||||||
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
|
||||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
|
||||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
|
||||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
|||||||
@@ -93,10 +93,16 @@ func (o *OpenAPI) ClearQuotaByAppSecret() error {
|
|||||||
func (o *OpenAPI) getAppIDAndSecret() (string, string, error) {
|
func (o *OpenAPI) getAppIDAndSecret() (string, string, error) {
|
||||||
switch o.ctx.(type) {
|
switch o.ctx.(type) {
|
||||||
case *mpContext.Context:
|
case *mpContext.Context:
|
||||||
c := o.ctx.(*mpContext.Context)
|
c, ok := o.ctx.(*mpContext.Context)
|
||||||
|
if !ok {
|
||||||
|
return "", "", errors.New("invalid context type")
|
||||||
|
}
|
||||||
return c.AppID, c.AppSecret, nil
|
return c.AppID, c.AppSecret, nil
|
||||||
case *ocContext.Context:
|
case *ocContext.Context:
|
||||||
c := o.ctx.(*ocContext.Context)
|
c, ok := o.ctx.(*ocContext.Context)
|
||||||
|
if !ok {
|
||||||
|
return "", "", errors.New("invalid context type")
|
||||||
|
}
|
||||||
return c.AppID, c.AppSecret, nil
|
return c.AppID, c.AppSecret, nil
|
||||||
default:
|
default:
|
||||||
return "", "", errors.New("invalid context type")
|
return "", "", errors.New("invalid context type")
|
||||||
|
|||||||
@@ -183,7 +183,7 @@ type GetShippingOrderRequest struct {
|
|||||||
|
|
||||||
// ShippingItem 物流信息
|
// ShippingItem 物流信息
|
||||||
type ShippingItem struct {
|
type ShippingItem struct {
|
||||||
TrackingNo string `json:"tracking_no"` // 物流单号,示例值: "323244567777
|
TrackingNo string `json:"tracking_no"` // 物流单号,示例值:"323244567777
|
||||||
ExpressCompany string `json:"express_company"` // 物流公司编码,快递公司 ID,物流快递发货时必填;参见「查询物流公司编码列表」
|
ExpressCompany string `json:"express_company"` // 物流公司编码,快递公司 ID,物流快递发货时必填;参见「查询物流公司编码列表」
|
||||||
UploadTime int64 `json:"upload_time"` // 上传物流信息时间,时间戳形式
|
UploadTime int64 `json:"upload_time"` // 上传物流信息时间,时间戳形式
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ type Color struct {
|
|||||||
|
|
||||||
// QRCoder 小程序码参数
|
// QRCoder 小程序码参数
|
||||||
type QRCoder struct {
|
type QRCoder struct {
|
||||||
// page 必须是已经发布的小程序存在的页面,根路径前不要填加 /,不能携带参数(参数请放在scene字段里),如果不填写这个字段,默认跳主页面
|
// page 必须是已经发布的小程序存在的页面,根路径前不要填加 /,不能携带参数(参数请放在 scene 字段里),如果不填写这个字段,默认跳主页面
|
||||||
Page string `json:"page,omitempty"`
|
Page string `json:"page,omitempty"`
|
||||||
// path 扫码进入的小程序页面路径
|
// path 扫码进入的小程序页面路径
|
||||||
Path string `json:"path,omitempty"`
|
Path string `json:"path,omitempty"`
|
||||||
|
|||||||
@@ -43,8 +43,8 @@ func NewSubscribe(ctx *context.Context) *Subscribe {
|
|||||||
type Message struct {
|
type Message struct {
|
||||||
ToUser string `json:"touser"` // 必选,接收者(用户)的 openid
|
ToUser string `json:"touser"` // 必选,接收者(用户)的 openid
|
||||||
TemplateID string `json:"template_id"` // 必选,所需下发的订阅模板 id
|
TemplateID string `json:"template_id"` // 必选,所需下发的订阅模板 id
|
||||||
Page string `json:"page"` // 可选,点击模板卡片后的跳转页面,仅限本小程序内的页面。支持带参数,(示例index?foo=bar)。该字段不填则模板无跳转。
|
Page string `json:"page"` // 可选,点击模板卡片后的跳转页面,仅限本小程序内的页面。支持带参数,(示例 index?foo=bar)。该字段不填则模板无跳转。
|
||||||
Data map[string]*DataItem `json:"data"` // 必选, 模板内容
|
Data map[string]*DataItem `json:"data"` // 必选,模板内容
|
||||||
MiniprogramState string `json:"miniprogram_state"` // 可选,跳转小程序类型:developer 为开发版;trial 为体验版;formal 为正式版;默认为正式版
|
MiniprogramState string `json:"miniprogram_state"` // 可选,跳转小程序类型:developer 为开发版;trial 为体验版;formal 为正式版;默认为正式版
|
||||||
Lang string `json:"lang"` // 入小程序查看”的语言类型,支持 zh_CN(简体中文)、en_US(英文)、zh_HK(繁体中文)、zh_TW(繁体中文),默认为 zh_CN
|
Lang string `json:"lang"` // 入小程序查看”的语言类型,支持 zh_CN(简体中文)、en_US(英文)、zh_HK(繁体中文)、zh_TW(繁体中文),默认为 zh_CN
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -77,19 +77,27 @@ func ShowQRCode(tk *Ticket) string {
|
|||||||
|
|
||||||
// NewTmpQrRequest 新建临时二维码请求实例
|
// NewTmpQrRequest 新建临时二维码请求实例
|
||||||
func NewTmpQrRequest(exp time.Duration, scene interface{}) *Request {
|
func NewTmpQrRequest(exp time.Duration, scene interface{}) *Request {
|
||||||
tq := &Request{
|
var (
|
||||||
|
tq = &Request{
|
||||||
ExpireSeconds: int64(exp.Seconds()),
|
ExpireSeconds: int64(exp.Seconds()),
|
||||||
}
|
}
|
||||||
|
ok bool
|
||||||
|
)
|
||||||
switch reflect.ValueOf(scene).Kind() {
|
switch reflect.ValueOf(scene).Kind() {
|
||||||
case reflect.String:
|
case reflect.String:
|
||||||
tq.ActionName = actionStr
|
tq.ActionName = actionStr
|
||||||
tq.ActionInfo.Scene.SceneStr = scene.(string)
|
if tq.ActionInfo.Scene.SceneStr, ok = scene.(string); !ok {
|
||||||
|
panic("scene must be string")
|
||||||
|
}
|
||||||
case reflect.Int, reflect.Int8, reflect.Int16,
|
case reflect.Int, reflect.Int8, reflect.Int16,
|
||||||
reflect.Int32, reflect.Int64,
|
reflect.Int32, reflect.Int64,
|
||||||
reflect.Uint, reflect.Uint8, reflect.Uint16,
|
reflect.Uint, reflect.Uint8, reflect.Uint16,
|
||||||
reflect.Uint32, reflect.Uint64:
|
reflect.Uint32, reflect.Uint64:
|
||||||
tq.ActionName = actionID
|
tq.ActionName = actionID
|
||||||
tq.ActionInfo.Scene.SceneID = scene.(int)
|
if tq.ActionInfo.Scene.SceneID, ok = scene.(int); !ok {
|
||||||
|
panic("scene must be int")
|
||||||
|
}
|
||||||
|
default:
|
||||||
}
|
}
|
||||||
|
|
||||||
return tq
|
return tq
|
||||||
@@ -97,17 +105,25 @@ func NewTmpQrRequest(exp time.Duration, scene interface{}) *Request {
|
|||||||
|
|
||||||
// NewLimitQrRequest 新建永久二维码请求实例
|
// NewLimitQrRequest 新建永久二维码请求实例
|
||||||
func NewLimitQrRequest(scene interface{}) *Request {
|
func NewLimitQrRequest(scene interface{}) *Request {
|
||||||
tq := &Request{}
|
var (
|
||||||
|
tq = &Request{}
|
||||||
|
ok bool
|
||||||
|
)
|
||||||
switch reflect.ValueOf(scene).Kind() {
|
switch reflect.ValueOf(scene).Kind() {
|
||||||
case reflect.String:
|
case reflect.String:
|
||||||
tq.ActionName = actionLimitStr
|
tq.ActionName = actionLimitStr
|
||||||
tq.ActionInfo.Scene.SceneStr = scene.(string)
|
if tq.ActionInfo.Scene.SceneStr, ok = scene.(string); !ok {
|
||||||
|
panic("scene must be string")
|
||||||
|
}
|
||||||
case reflect.Int, reflect.Int8, reflect.Int16,
|
case reflect.Int, reflect.Int8, reflect.Int16,
|
||||||
reflect.Int32, reflect.Int64,
|
reflect.Int32, reflect.Int64,
|
||||||
reflect.Uint, reflect.Uint8, reflect.Uint16,
|
reflect.Uint, reflect.Uint8, reflect.Uint16,
|
||||||
reflect.Uint32, reflect.Uint64:
|
reflect.Uint32, reflect.Uint64:
|
||||||
tq.ActionName = actionLimitID
|
tq.ActionName = actionLimitID
|
||||||
tq.ActionInfo.Scene.SceneID = scene.(int)
|
if tq.ActionInfo.Scene.SceneID, ok = scene.(int); !ok {
|
||||||
|
panic("scene must be int")
|
||||||
|
}
|
||||||
|
default:
|
||||||
}
|
}
|
||||||
|
|
||||||
return tq
|
return tq
|
||||||
|
|||||||
@@ -11,13 +11,13 @@ import (
|
|||||||
type MediaType string
|
type MediaType string
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// MediaTypeImage 媒体文件:图片
|
// MediaTypeImage 媒体文件:图片
|
||||||
MediaTypeImage MediaType = "image"
|
MediaTypeImage MediaType = "image"
|
||||||
// MediaTypeVoice 媒体文件:声音
|
// MediaTypeVoice 媒体文件:声音
|
||||||
MediaTypeVoice MediaType = "voice"
|
MediaTypeVoice MediaType = "voice"
|
||||||
// MediaTypeVideo 媒体文件:视频
|
// MediaTypeVideo 媒体文件:视频
|
||||||
MediaTypeVideo MediaType = "video"
|
MediaTypeVideo MediaType = "video"
|
||||||
// MediaTypeThumb 媒体文件:缩略图
|
// MediaTypeThumb 媒体文件:缩略图
|
||||||
MediaTypeThumb MediaType = "thumb"
|
MediaTypeThumb MediaType = "thumb"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -31,14 +31,14 @@ func NewSubscribe(context *context.Context) *Subscribe {
|
|||||||
|
|
||||||
// SubscribeMessage 发送的订阅消息内容
|
// SubscribeMessage 发送的订阅消息内容
|
||||||
type SubscribeMessage struct {
|
type SubscribeMessage struct {
|
||||||
ToUser string `json:"touser"` // 必须, 接受者OpenID
|
ToUser string `json:"touser"` // 必须,接受者 OpenID
|
||||||
TemplateID string `json:"template_id"` // 必须, 模版ID
|
TemplateID string `json:"template_id"` // 必须,模版 ID
|
||||||
Page string `json:"page,omitempty"` // 可选, 跳转网页时填写
|
Page string `json:"page,omitempty"` // 可选,跳转网页时填写
|
||||||
Data map[string]*SubscribeDataItem `json:"data"` // 必须, 模板数据
|
Data map[string]*SubscribeDataItem `json:"data"` // 必须,模板数据
|
||||||
MiniProgram struct {
|
MiniProgram struct {
|
||||||
AppID string `json:"appid"` // 所需跳转到的小程序 appid(该小程序 appid 必须与发模板消息的公众号是绑定关联关系)
|
AppID string `json:"appid"` // 所需跳转到的小程序 appid(该小程序 appid 必须与发模板消息的公众号是绑定关联关系)
|
||||||
PagePath string `json:"pagepath"` // 所需跳转到小程序的具体页面路径,支持带参数,(示例index?foo=bar)
|
PagePath string `json:"pagepath"` // 所需跳转到小程序的具体页面路径,支持带参数,(示例 index?foo=bar)
|
||||||
} `json:"miniprogram"` // 可选,跳转至小程序地址
|
} `json:"miniprogram"` // 可选,跳转至小程序地址
|
||||||
}
|
}
|
||||||
|
|
||||||
// SubscribeDataItem 模版内某个 .DATA 的值
|
// SubscribeDataItem 模版内某个 .DATA 的值
|
||||||
|
|||||||
@@ -29,17 +29,17 @@ func NewTemplate(context *context.Context) *Template {
|
|||||||
|
|
||||||
// TemplateMessage 发送的模板消息内容
|
// TemplateMessage 发送的模板消息内容
|
||||||
type TemplateMessage struct {
|
type TemplateMessage struct {
|
||||||
ToUser string `json:"touser"` // 必须, 接受者OpenID
|
ToUser string `json:"touser"` // 必须,接受者 OpenID
|
||||||
TemplateID string `json:"template_id"` // 必须, 模版ID
|
TemplateID string `json:"template_id"` // 必须,模版 ID
|
||||||
URL string `json:"url,omitempty"` // 可选, 用户点击后跳转的URL, 该URL必须处于开发者在公众平台网站中设置的域中
|
URL string `json:"url,omitempty"` // 可选,用户点击后跳转的 URL, 该 URL 必须处于开发者在公众平台网站中设置的域中
|
||||||
Color string `json:"color,omitempty"` // 可选, 整个消息的颜色, 可以不设置
|
Color string `json:"color,omitempty"` // 可选,整个消息的颜色,可以不设置
|
||||||
Data map[string]*TemplateDataItem `json:"data"` // 必须, 模板数据
|
Data map[string]*TemplateDataItem `json:"data"` // 必须,模板数据
|
||||||
ClientMsgID string `json:"client_msg_id,omitempty"` // 可选, 防重入ID
|
ClientMsgID string `json:"client_msg_id,omitempty"` // 可选,防重入 ID
|
||||||
|
|
||||||
MiniProgram struct {
|
MiniProgram struct {
|
||||||
AppID string `json:"appid"` // 所需跳转到的小程序 appid(该小程序 appid 必须与发模板消息的公众号是绑定关联关系)
|
AppID string `json:"appid"` // 所需跳转到的小程序 appid(该小程序 appid 必须与发模板消息的公众号是绑定关联关系)
|
||||||
PagePath string `json:"pagepath"` // 所需跳转到小程序的具体页面路径,支持带参数,(示例index?foo=bar)
|
PagePath string `json:"pagepath"` // 所需跳转到小程序的具体页面路径,支持带参数,(示例 index?foo=bar)
|
||||||
} `json:"miniprogram"` // 可选,跳转至小程序地址
|
} `json:"miniprogram"` // 可选,跳转至小程序地址
|
||||||
}
|
}
|
||||||
|
|
||||||
// TemplateDataItem 模版内某个 .DATA 的值
|
// TemplateDataItem 模版内某个 .DATA 的值
|
||||||
@@ -80,7 +80,7 @@ func (tpl *Template) Send(msg *TemplateMessage) (msgID int64, err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// TemplateItem 模板消息.
|
// TemplateItem 模板消息。
|
||||||
type TemplateItem struct {
|
type TemplateItem struct {
|
||||||
TemplateID string `json:"template_id"`
|
TemplateID string `json:"template_id"`
|
||||||
Title string `json:"title"`
|
Title string `json:"title"`
|
||||||
@@ -121,7 +121,7 @@ type resTemplateAdd struct {
|
|||||||
TemplateID string `json:"template_id"`
|
TemplateID string `json:"template_id"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add 添加模板.
|
// Add 添加模板。
|
||||||
func (tpl *Template) Add(shortID string, keyNameList []string) (templateID string, err error) {
|
func (tpl *Template) Add(shortID string, keyNameList []string) (templateID string, err error) {
|
||||||
var accessToken string
|
var accessToken string
|
||||||
accessToken, err = tpl.GetAccessToken()
|
accessToken, err = tpl.GetAccessToken()
|
||||||
@@ -144,7 +144,7 @@ func (tpl *Template) Add(shortID string, keyNameList []string) (templateID strin
|
|||||||
return result.TemplateID, err
|
return result.TemplateID, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete 删除私有模板.
|
// Delete 删除私有模板。
|
||||||
func (tpl *Template) Delete(templateID string) (err error) {
|
func (tpl *Template) Delete(templateID string) (err error) {
|
||||||
var accessToken string
|
var accessToken string
|
||||||
accessToken, err = tpl.GetAccessToken()
|
accessToken, err = tpl.GetAccessToken()
|
||||||
|
|||||||
@@ -4,25 +4,23 @@ import (
|
|||||||
stdcontext "context"
|
stdcontext "context"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/silenceper/wechat/v2/internal/openapi"
|
|
||||||
"github.com/silenceper/wechat/v2/officialaccount/draft"
|
|
||||||
"github.com/silenceper/wechat/v2/officialaccount/freepublish"
|
|
||||||
"github.com/silenceper/wechat/v2/officialaccount/ocr"
|
|
||||||
|
|
||||||
"github.com/silenceper/wechat/v2/officialaccount/datacube"
|
|
||||||
|
|
||||||
"github.com/silenceper/wechat/v2/credential"
|
"github.com/silenceper/wechat/v2/credential"
|
||||||
|
"github.com/silenceper/wechat/v2/internal/openapi"
|
||||||
"github.com/silenceper/wechat/v2/officialaccount/basic"
|
"github.com/silenceper/wechat/v2/officialaccount/basic"
|
||||||
"github.com/silenceper/wechat/v2/officialaccount/broadcast"
|
"github.com/silenceper/wechat/v2/officialaccount/broadcast"
|
||||||
"github.com/silenceper/wechat/v2/officialaccount/config"
|
"github.com/silenceper/wechat/v2/officialaccount/config"
|
||||||
"github.com/silenceper/wechat/v2/officialaccount/context"
|
"github.com/silenceper/wechat/v2/officialaccount/context"
|
||||||
"github.com/silenceper/wechat/v2/officialaccount/customerservice"
|
"github.com/silenceper/wechat/v2/officialaccount/customerservice"
|
||||||
|
"github.com/silenceper/wechat/v2/officialaccount/datacube"
|
||||||
"github.com/silenceper/wechat/v2/officialaccount/device"
|
"github.com/silenceper/wechat/v2/officialaccount/device"
|
||||||
|
"github.com/silenceper/wechat/v2/officialaccount/draft"
|
||||||
|
"github.com/silenceper/wechat/v2/officialaccount/freepublish"
|
||||||
"github.com/silenceper/wechat/v2/officialaccount/js"
|
"github.com/silenceper/wechat/v2/officialaccount/js"
|
||||||
"github.com/silenceper/wechat/v2/officialaccount/material"
|
"github.com/silenceper/wechat/v2/officialaccount/material"
|
||||||
"github.com/silenceper/wechat/v2/officialaccount/menu"
|
"github.com/silenceper/wechat/v2/officialaccount/menu"
|
||||||
"github.com/silenceper/wechat/v2/officialaccount/message"
|
"github.com/silenceper/wechat/v2/officialaccount/message"
|
||||||
"github.com/silenceper/wechat/v2/officialaccount/oauth"
|
"github.com/silenceper/wechat/v2/officialaccount/oauth"
|
||||||
|
"github.com/silenceper/wechat/v2/officialaccount/ocr"
|
||||||
"github.com/silenceper/wechat/v2/officialaccount/server"
|
"github.com/silenceper/wechat/v2/officialaccount/server"
|
||||||
"github.com/silenceper/wechat/v2/officialaccount/user"
|
"github.com/silenceper/wechat/v2/officialaccount/user"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -161,7 +161,10 @@ func (user *User) ListUserOpenIDs(nextOpenid ...string) (*OpenidList, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
uri, _ := url.Parse(userListURL)
|
uri, err := url.Parse(userListURL)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
q := uri.Query()
|
q := uri.Query()
|
||||||
q.Set("access_token", accessToken)
|
q.Set("access_token", accessToken)
|
||||||
if len(nextOpenid) > 0 && nextOpenid[0] != "" {
|
if len(nextOpenid) > 0 && nextOpenid[0] != "" {
|
||||||
|
|||||||
@@ -221,7 +221,7 @@ func (basic *Basic) SetHeadImage(imgMediaID string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// SetHeadImageFull 修改小程序头像
|
// SetHeadImageFull 修改小程序头像
|
||||||
// 新增临时素材: https://developers.weixin.qq.com/doc/offiaccount/Asset_Management/New_temporary_materials.html
|
// 新增临时素材:https://developers.weixin.qq.com/doc/offiaccount/Asset_Management/New_temporary_materials.html
|
||||||
// ref: https://developers.weixin.qq.com/doc/oplatform/openApi/OpenApiDoc/miniprogram-management/basic-info-management/setHeadImage.html
|
// ref: https://developers.weixin.qq.com/doc/oplatform/openApi/OpenApiDoc/miniprogram-management/basic-info-management/setHeadImage.html
|
||||||
func (basic *Basic) SetHeadImageFull(param *SetHeadImageParam) error {
|
func (basic *Basic) SetHeadImageFull(param *SetHeadImageParam) error {
|
||||||
ak, err := basic.GetAuthrAccessToken(basic.AppID)
|
ak, err := basic.GetAuthrAccessToken(basic.AppID)
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ type GetRegistrationStatusParam struct {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetRegistrationStatus 查询创建任务状态.
|
// GetRegistrationStatus 查询创建任务状态。
|
||||||
func (component *Component) GetRegistrationStatus(param *GetRegistrationStatusParam) error {
|
func (component *Component) GetRegistrationStatus(param *GetRegistrationStatusParam) error {
|
||||||
componentAK, err := component.GetComponentAccessToken()
|
componentAK, err := component.GetComponentAccessToken()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ func EncryptMsg(random, rawXMLMsg []byte, appID, aesKey string) (encrtptMsg []by
|
|||||||
func AESEncryptMsg(random, rawXMLMsg []byte, appID string, aesKey []byte) (ciphertext []byte) {
|
func AESEncryptMsg(random, rawXMLMsg []byte, appID string, aesKey []byte) (ciphertext []byte) {
|
||||||
const (
|
const (
|
||||||
BlockSize = 32 // PKCS#7
|
BlockSize = 32 // PKCS#7
|
||||||
BlockMask = BlockSize - 1 // BLOCK_SIZE 为 2^n 时, 可以用 mask 获取针对 BLOCK_SIZE 的余数
|
BlockMask = BlockSize - 1 // BLOCK_SIZE 为 2^n 时,可以用 mask 获取针对 BLOCK_SIZE 的余数
|
||||||
)
|
)
|
||||||
|
|
||||||
appIDOffset := 20 + len(rawXMLMsg)
|
appIDOffset := 20 + len(rawXMLMsg)
|
||||||
@@ -127,7 +127,7 @@ func aesKeyDecode(encodedAESKey string) (key []byte, err error) {
|
|||||||
func AESDecryptMsg(ciphertext []byte, aesKey []byte) (random, rawXMLMsg, appID []byte, err error) {
|
func AESDecryptMsg(ciphertext []byte, aesKey []byte) (random, rawXMLMsg, appID []byte, err error) {
|
||||||
const (
|
const (
|
||||||
BlockSize = 32 // PKCS#7
|
BlockSize = 32 // PKCS#7
|
||||||
BlockMask = BlockSize - 1 // BLOCK_SIZE 为 2^n 时, 可以用 mask 获取针对 BLOCK_SIZE 的余数
|
BlockMask = BlockSize - 1 // BLOCK_SIZE 为 2^n 时,可以用 mask 获取针对 BLOCK_SIZE 的余数
|
||||||
)
|
)
|
||||||
|
|
||||||
if len(ciphertext) < BlockSize {
|
if len(ciphertext) < BlockSize {
|
||||||
|
|||||||
@@ -25,7 +25,10 @@ func RSADecrypt(privateKey string, ciphertext []byte) ([]byte, error) {
|
|||||||
}
|
}
|
||||||
switch t := key.(type) {
|
switch t := key.(type) {
|
||||||
case *rsa.PrivateKey:
|
case *rsa.PrivateKey:
|
||||||
priv = key.(*rsa.PrivateKey)
|
var ok bool
|
||||||
|
if priv, ok = key.(*rsa.PrivateKey); !ok {
|
||||||
|
return nil, fmt.Errorf(" ParsePKCS8PrivateKey error: Not supported privatekey format, should be *rsa.PrivateKey, got %T", t)
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
return nil, fmt.Errorf("ParsePKCS1PrivateKey error: %s, ParsePKCS8PrivateKey error: Not supported privatekey format, should be *rsa.PrivateKey, got %T", oldErr.Error(), t)
|
return nil, fmt.Errorf("ParsePKCS1PrivateKey error: %s, ParsePKCS8PrivateKey error: Not supported privatekey format, should be *rsa.PrivateKey, got %T", oldErr.Error(), t)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Template 对字符串中的和map的key相同的字符串进行模板替换 仅支持 形如: {name}
|
// Template 对字符串中的和 map 的 key 相同的字符串进行模板替换 仅支持 形如:{name}
|
||||||
func Template(source string, data map[string]interface{}) string {
|
func Template(source string, data map[string]interface{}) string {
|
||||||
sourceCopy := &source
|
sourceCopy := &source
|
||||||
for k, val := range data {
|
for k, val := range data {
|
||||||
|
|||||||
@@ -188,7 +188,7 @@ type UserGetResponse struct {
|
|||||||
} `json:"web,omitempty"`
|
} `json:"web,omitempty"`
|
||||||
} `json:"attrs"`
|
} `json:"attrs"`
|
||||||
} `json:"extattr"` // 扩展属性,代开发自建应用需要管理员授权才返回;第三方仅通讯录应用可获取;对于非第三方创建的成员,第三方通讯录应用也不可获取;上游企业不可获取下游企业成员该字段
|
} `json:"extattr"` // 扩展属性,代开发自建应用需要管理员授权才返回;第三方仅通讯录应用可获取;对于非第三方创建的成员,第三方通讯录应用也不可获取;上游企业不可获取下游企业成员该字段
|
||||||
Status int `json:"status"` // 激活状态: 1=已激活,2=已禁用,4=未激活,5=退出企业。 已激活代表已激活企业微信或已关注微信插件(原企业号)。未激活代表既未激活企业微信又未关注微信插件(原企业号)。
|
Status int `json:"status"` // 激活状态:1=已激活,2=已禁用,4=未激活,5=退出企业。已激活代表已激活企业微信或已关注微信插件(原企业号)。未激活代表既未激活企业微信又未关注微信插件(原企业号)。
|
||||||
QrCode string `json:"qr_code"` // 员工个人二维码,扫描可添加为外部联系人 (注意返回的是一个 url,可在浏览器上打开该 url 以展示二维码);代开发自建应用需要管理员授权且成员 oauth2 授权获取;第三方仅通讯录应用可获取;对于非第三方创建的成员,第三方通讯录应用也不可获取;上游企业不可获取下游企业成员该字段
|
QrCode string `json:"qr_code"` // 员工个人二维码,扫描可添加为外部联系人 (注意返回的是一个 url,可在浏览器上打开该 url 以展示二维码);代开发自建应用需要管理员授权且成员 oauth2 授权获取;第三方仅通讯录应用可获取;对于非第三方创建的成员,第三方通讯录应用也不可获取;上游企业不可获取下游企业成员该字段
|
||||||
ExternalPosition string `json:"external_position"` // 对外职务,如果设置了该值,则以此作为对外展示的职务,否则以 position 来展示。代开发自建应用需要管理员授权才返回;第三方仅通讯录应用可获取;对于非第三方创建的成员,第三方通讯录应用也不可获取;上游企业不可获取下游企业成员该字段
|
ExternalPosition string `json:"external_position"` // 对外职务,如果设置了该值,则以此作为对外展示的职务,否则以 position 来展示。代开发自建应用需要管理员授权才返回;第三方仅通讯录应用可获取;对于非第三方创建的成员,第三方通讯录应用也不可获取;上游企业不可获取下游企业成员该字段
|
||||||
ExternalProfile struct {
|
ExternalProfile struct {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// Package appchat 应用发送消息到群聊会话,企业微信接口:https://developer.work.weixin.qq.com/document/path/90248
|
// Package appchat 应用发送消息到群聊会话,企业微信接口:https://developer.work.weixin.qq.com/document/path/90248
|
||||||
package appchat
|
package appchat
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import (
|
|||||||
// Config for 企业微信
|
// Config for 企业微信
|
||||||
type Config struct {
|
type Config struct {
|
||||||
CorpID string `json:"corp_id"` // corp_id
|
CorpID string `json:"corp_id"` // corp_id
|
||||||
CorpSecret string `json:"corp_secret"` // corp_secret,如果需要获取会话存档实例,当前参数请填写聊天内容存档的Secret,可以在企业微信管理端--管理工具--聊天内容存档查看
|
CorpSecret string `json:"corp_secret"` // corp_secret,如果需要获取会话存档实例,当前参数请填写聊天内容存档的 Secret,可以在企业微信管理端--管理工具--聊天内容存档查看
|
||||||
AgentID string `json:"agent_id"` // agent_id
|
AgentID string `json:"agent_id"` // agent_id
|
||||||
Cache cache.Cache
|
Cache cache.Cache
|
||||||
RasPrivateKey string // 消息加密私钥,可以在企业微信管理端--管理工具--消息加密公钥查看对用公钥,私钥一般由自己保存
|
RasPrivateKey string // 消息加密私钥,可以在企业微信管理端--管理工具--消息加密公钥查看对用公钥,私钥一般由自己保存
|
||||||
|
|||||||
@@ -104,7 +104,7 @@ type WechatChannel struct {
|
|||||||
Source int `json:"source"`
|
Source int `json:"source"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// ExternalProfile 外部联系人的自定义展示信息,可以有多个字段和多种类型,包括文本,网页和小程序
|
// ExternalProfile 外部联系人的自定义展示信息,可以有多个字段和多种类型,包括文本,网页和小程序
|
||||||
type ExternalProfile struct {
|
type ExternalProfile struct {
|
||||||
ExternalCorpName string `json:"external_corp_name"`
|
ExternalCorpName string `json:"external_corp_name"`
|
||||||
WechatChannels WechatChannels `json:"wechat_channels"`
|
WechatChannels WechatChannels `json:"wechat_channels"`
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ const groupChatURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/groupc
|
|||||||
type (
|
type (
|
||||||
// AddJoinWayRequest 添加群配置请求参数
|
// AddJoinWayRequest 添加群配置请求参数
|
||||||
AddJoinWayRequest struct {
|
AddJoinWayRequest struct {
|
||||||
Scene int `json:"scene"` // 必填 1 - 群的小程序插件,2 - 群的二维码插件
|
Scene int `json:"scene"` // 必填 1 - 群的小程序插件,2 - 群的二维码插件
|
||||||
Remark string `json:"remark"` //非必填 联系方式的备注信息,用于助记,超过 30 个字符将被截断
|
Remark string `json:"remark"` //非必填 联系方式的备注信息,用于助记,超过 30 个字符将被截断
|
||||||
AutoCreateRoom int `json:"auto_create_room"` //非必填 当群满了后,是否自动新建群。0-否;1-是。默认为 1
|
AutoCreateRoom int `json:"auto_create_room"` //非必填 当群满了后,是否自动新建群。0-否;1-是。默认为 1
|
||||||
RoomBaseName string `json:"room_base_name"` //非必填 自动建群的群名前缀,当 auto_create_room 为 1 时有效。最长 40 个 utf8 字符
|
RoomBaseName string `json:"room_base_name"` //非必填 自动建群的群名前缀,当 auto_create_room 为 1 时有效。最长 40 个 utf8 字符
|
||||||
@@ -96,7 +96,7 @@ func (r *Client) GetJoinWay(req *JoinWayConfigRequest) (*GetJoinWayResponse, err
|
|||||||
// UpdateJoinWayRequest 更新群配置的请求参数
|
// UpdateJoinWayRequest 更新群配置的请求参数
|
||||||
type UpdateJoinWayRequest struct {
|
type UpdateJoinWayRequest struct {
|
||||||
ConfigID string `json:"config_id"`
|
ConfigID string `json:"config_id"`
|
||||||
Scene int `json:"scene"` // 必填 1 - 群的小程序插件,2 - 群的二维码插件
|
Scene int `json:"scene"` // 必填 1 - 群的小程序插件,2 - 群的二维码插件
|
||||||
Remark string `json:"remark"` //非必填 联系方式的备注信息,用于助记,超过 30 个字符将被截断
|
Remark string `json:"remark"` //非必填 联系方式的备注信息,用于助记,超过 30 个字符将被截断
|
||||||
AutoCreateRoom int `json:"auto_create_room"` //非必填 当群满了后,是否自动新建群。0-否;1-是。默认为 1
|
AutoCreateRoom int `json:"auto_create_room"` //非必填 当群满了后,是否自动新建群。0-否;1-是。默认为 1
|
||||||
RoomBaseName string `json:"room_base_name"` //非必填 自动建群的群名前缀,当 auto_create_room 为 1 时有效。最长 40 个 utf8 字符
|
RoomBaseName string `json:"room_base_name"` //非必填 自动建群的群名前缀,当 auto_create_room 为 1 时有效。最长 40 个 utf8 字符
|
||||||
|
|||||||
@@ -22,8 +22,8 @@ const (
|
|||||||
|
|
||||||
// AccountAddOptions 添加客服账号请求参数
|
// AccountAddOptions 添加客服账号请求参数
|
||||||
type AccountAddOptions struct {
|
type AccountAddOptions struct {
|
||||||
Name string `json:"name"` // 客服帐号名称, 不多于16个字符
|
Name string `json:"name"` // 客服帐号名称,不多于 16 个字符
|
||||||
MediaID string `json:"media_id"` // 客服头像临时素材。可以调用上传临时素材接口获取, 不多于128个字节
|
MediaID string `json:"media_id"` // 客服头像临时素材。可以调用上传临时素材接口获取,不多于 128 个字节
|
||||||
}
|
}
|
||||||
|
|
||||||
// AccountAddSchema 添加客服账号响应内容
|
// AccountAddSchema 添加客服账号响应内容
|
||||||
@@ -82,8 +82,8 @@ func (r *Client) AccountDel(options AccountDelOptions) (info util.CommonError, e
|
|||||||
// AccountUpdateOptions 修改客服账号请求参数
|
// AccountUpdateOptions 修改客服账号请求参数
|
||||||
type AccountUpdateOptions struct {
|
type AccountUpdateOptions struct {
|
||||||
OpenKFID string `json:"open_kfid"` // 客服帐号 ID, 不多于 64 字节
|
OpenKFID string `json:"open_kfid"` // 客服帐号 ID, 不多于 64 字节
|
||||||
Name string `json:"name"` // 客服帐号名称, 不多于16个字符
|
Name string `json:"name"` // 客服帐号名称,不多于 16 个字符
|
||||||
MediaID string `json:"media_id"` // 客服头像临时素材。可以调用上传临时素材接口获取, 不多于128个字节
|
MediaID string `json:"media_id"` // 客服头像临时素材。可以调用上传临时素材接口获取,不多于 128 个字节
|
||||||
}
|
}
|
||||||
|
|
||||||
// AccountUpdate 修复客服账号
|
// AccountUpdate 修复客服账号
|
||||||
@@ -148,7 +148,7 @@ func (r *Client) AccountList() (info AccountListSchema, err error) {
|
|||||||
// 3.返回的客服链接,不能修改或复制参数到其他链接使用。否则进入会话事件参数校验不通过,导致无法回调。
|
// 3.返回的客服链接,不能修改或复制参数到其他链接使用。否则进入会话事件参数校验不通过,导致无法回调。
|
||||||
type AddContactWayOptions struct {
|
type AddContactWayOptions struct {
|
||||||
OpenKFID string `json:"open_kfid"` // 客服帐号 ID, 不多于 64 字节
|
OpenKFID string `json:"open_kfid"` // 客服帐号 ID, 不多于 64 字节
|
||||||
Scene string `json:"scene"` // 场景值,字符串类型,由开发者自定义, 不多于32字节, 字符串取值范围(正则表达式):[0-9a-zA-Z_-]*
|
Scene string `json:"scene"` // 场景值,字符串类型,由开发者自定义,不多于 32 字节,字符串取值范围 (正则表达式):[0-9a-zA-Z_-]*
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddContactWaySchema 获取客服账号链接响应内容
|
// AddContactWaySchema 获取客服账号链接响应内容
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ type CustomerSchema struct {
|
|||||||
NickName string `json:"nickname"` // 微信昵称
|
NickName string `json:"nickname"` // 微信昵称
|
||||||
Avatar string `json:"avatar"` // 微信头像。第三方不可获取
|
Avatar string `json:"avatar"` // 微信头像。第三方不可获取
|
||||||
Gender int `json:"gender"` // 性别
|
Gender int `json:"gender"` // 性别
|
||||||
UnionID string `json:"unionid"` // unionid,需要绑定微信开发者帐号才能获取到,查看绑定方法: https://open.work.weixin.qq.com/kf/doc/92512/93143/94769#%E5%A6%82%E4%BD%95%E8%8E%B7%E5%8F%96%E5%BE%AE%E4%BF%A1%E5%AE%A2%E6%88%B7%E7%9A%84unionid
|
UnionID string `json:"unionid"` // unionid,需要绑定微信开发者帐号才能获取到,查看绑定方法:https://open.work.weixin.qq.com/kf/doc/92512/93143/94769#%E5%A6%82%E4%BD%95%E8%8E%B7%E5%8F%96%E5%BE%AE%E4%BF%A1%E5%AE%A2%E6%88%B7%E7%9A%84unionid
|
||||||
}
|
}
|
||||||
|
|
||||||
// CustomerBatchGetSchema 获取客户基本信息响应内容
|
// CustomerBatchGetSchema 获取客户基本信息响应内容
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ const (
|
|||||||
// SDKDecryptMSGFailed 错误码:40016
|
// SDKDecryptMSGFailed 错误码:40016
|
||||||
SDKDecryptMSGFailed Error = "消息解密失败"
|
SDKDecryptMSGFailed Error = "消息解密失败"
|
||||||
// SDKMediaIDExceedMinLength 错误码:40058
|
// SDKMediaIDExceedMinLength 错误码:40058
|
||||||
SDKMediaIDExceedMinLength Error = "不合法的参数, 请参照具体 API 接口说明进行传参"
|
SDKMediaIDExceedMinLength Error = "不合法的参数,请参照具体 API 接口说明进行传参"
|
||||||
// SDKContentContainsSensitiveInformation 错误码:40201
|
// SDKContentContainsSensitiveInformation 错误码:40201
|
||||||
SDKContentContainsSensitiveInformation Error = "当前客服账号由于涉及敏感信息,已被封禁,请联系企业微信客服处理"
|
SDKContentContainsSensitiveInformation Error = "当前客服账号由于涉及敏感信息,已被封禁,请联系企业微信客服处理"
|
||||||
// SDKAccessTokenMissing 错误码:41001
|
// SDKAccessTokenMissing 错误码:41001
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ const (
|
|||||||
// SendMsgSchema 发送消息响应内容
|
// SendMsgSchema 发送消息响应内容
|
||||||
type SendMsgSchema struct {
|
type SendMsgSchema struct {
|
||||||
util.CommonError
|
util.CommonError
|
||||||
MsgID string `json:"msgid"` // 消息ID。如果请求参数指定了msgid,则原样返回,否则系统自动生成并返回。不多于32字节, 字符串取值范围(正则表达式):[0-9a-zA-Z_-]*
|
MsgID string `json:"msgid"` // 消息 ID。如果请求参数指定了 msgid,则原样返回,否则系统自动生成并返回。不多于 32 字节,字符串取值范围 (正则表达式):[0-9a-zA-Z_-]*
|
||||||
}
|
}
|
||||||
|
|
||||||
// SendMsg 发送消息
|
// SendMsg 发送消息
|
||||||
|
|||||||
@@ -83,35 +83,35 @@ type Menu struct {
|
|||||||
MsgMenu struct {
|
MsgMenu struct {
|
||||||
HeadContent string `json:"head_content"` // 消息内容,不多于 1024 字节
|
HeadContent string `json:"head_content"` // 消息内容,不多于 1024 字节
|
||||||
List []interface{} `json:"list"` // 菜单项配置,不能多余 10 个
|
List []interface{} `json:"list"` // 菜单项配置,不能多余 10 个
|
||||||
TailContent string `json:"tail_content"` // 结束文本, 不多于1024字
|
TailContent string `json:"tail_content"` // 结束文本,不多于 1024 字
|
||||||
} `json:"msgmenu"`
|
} `json:"msgmenu"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// MenuClick 回复菜单
|
// MenuClick 回复菜单
|
||||||
type MenuClick struct {
|
type MenuClick struct {
|
||||||
Type string `json:"type"` // 菜单类型: click 回复菜单
|
Type string `json:"type"` // 菜单类型:click 回复菜单
|
||||||
Click struct {
|
Click struct {
|
||||||
ID string `json:"id"` // 菜单ID, 不少于1字节, 不多于64字节
|
ID string `json:"id"` // 菜单 ID, 不少于 1 字节,不多于 64 字节
|
||||||
Content string `json:"content"` // 菜单显示内容, 不少于1字节, 不多于128字节
|
Content string `json:"content"` // 菜单显示内容,不少于 1 字节,不多于 128 字节
|
||||||
} `json:"click"`
|
} `json:"click"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// MenuView 超链接菜单
|
// MenuView 超链接菜单
|
||||||
type MenuView struct {
|
type MenuView struct {
|
||||||
Type string `json:"type"` // 菜单类型: view 超链接菜单
|
Type string `json:"type"` // 菜单类型:view 超链接菜单
|
||||||
View struct {
|
View struct {
|
||||||
URL string `json:"url"` // 点击后跳转的链接, 不少于1字节, 不多于2048字节
|
URL string `json:"url"` // 点击后跳转的链接,不少于 1 字节,不多于 2048 字节
|
||||||
Content string `json:"content"` // 菜单显示内容, 不少于1字节, 不多于1024字节
|
Content string `json:"content"` // 菜单显示内容,不少于 1 字节,不多于 1024 字节
|
||||||
} `json:"view"`
|
} `json:"view"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// MenuMiniProgram 小程序菜单
|
// MenuMiniProgram 小程序菜单
|
||||||
type MenuMiniProgram struct {
|
type MenuMiniProgram struct {
|
||||||
Type string `json:"type"` // 菜单类型: miniprogram 小程序菜单
|
Type string `json:"type"` // 菜单类型:miniprogram 小程序菜单
|
||||||
MiniProgram struct {
|
MiniProgram struct {
|
||||||
AppID string `json:"appid"` // 小程序appid, 不少于1字节, 不多于32字节
|
AppID string `json:"appid"` // 小程序 appid, 不少于 1 字节,不多于 32 字节
|
||||||
PagePath string `json:"pagepath"` // 点击后进入的小程序页面, 不少于1字节, 不多于1024字节
|
PagePath string `json:"pagepath"` // 点击后进入的小程序页面,不少于 1 字节,不多于 1024 字节
|
||||||
Content string `json:"content"` // 菜单显示内容, 不少于1字节, 不多于1024字节
|
Content string `json:"content"` // 菜单显示内容,不少于 1 字节,不多于 1024 字节
|
||||||
} `json:"miniprogram"`
|
} `json:"miniprogram"`
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -120,8 +120,8 @@ type Location struct {
|
|||||||
Message
|
Message
|
||||||
MsgType string `json:"msgtype"` // 消息类型,此时固定为:location
|
MsgType string `json:"msgtype"` // 消息类型,此时固定为:location
|
||||||
Location struct {
|
Location struct {
|
||||||
Latitude float32 `json:"latitude"` // 纬度, 浮点数,范围为90 ~ -90
|
Latitude float32 `json:"latitude"` // 纬度,浮点数,范围为 90 ~ -90
|
||||||
Longitude float32 `json:"longitude"` // 经度, 浮点数,范围为180 ~ -180
|
Longitude float32 `json:"longitude"` // 经度,浮点数,范围为 180 ~ -180
|
||||||
Name string `json:"name"` // 位置名
|
Name string `json:"name"` // 位置名
|
||||||
Address string `json:"address"` // 地址详情说明
|
Address string `json:"address"` // 地址详情说明
|
||||||
} `json:"location"`
|
} `json:"location"`
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ const (
|
|||||||
// SendMsgOnEventSchema 发送事件响应消息
|
// SendMsgOnEventSchema 发送事件响应消息
|
||||||
type SendMsgOnEventSchema struct {
|
type SendMsgOnEventSchema struct {
|
||||||
util.CommonError
|
util.CommonError
|
||||||
MsgID string `json:"msgid"` // 消息ID。如果请求参数指定了msgid,则原样返回,否则系统自动生成并返回。不多于32字节, 字符串取值范围(正则表达式):[0-9a-zA-Z_-]*
|
MsgID string `json:"msgid"` // 消息 ID。如果请求参数指定了 msgid,则原样返回,否则系统自动生成并返回。不多于 32 字节,字符串取值范围 (正则表达式):[0-9a-zA-Z_-]*
|
||||||
}
|
}
|
||||||
|
|
||||||
// SendMsgOnEvent 发送事件响应消息
|
// SendMsgOnEvent 发送事件响应消息
|
||||||
|
|||||||
@@ -22,34 +22,34 @@ type Menu struct {
|
|||||||
MsgMenu struct {
|
MsgMenu struct {
|
||||||
HeadContent string `json:"head_content"` // 消息内容,不多于 1024 字节
|
HeadContent string `json:"head_content"` // 消息内容,不多于 1024 字节
|
||||||
List []interface{} `json:"list"` // 菜单项配置,不能多余 10 个
|
List []interface{} `json:"list"` // 菜单项配置,不能多余 10 个
|
||||||
TailContent string `json:"tail_content"` // 结束文本, 不多于1024字
|
TailContent string `json:"tail_content"` // 结束文本,不多于 1024 字
|
||||||
} `json:"msgmenu"`
|
} `json:"msgmenu"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// MenuClick 回复菜单
|
// MenuClick 回复菜单
|
||||||
type MenuClick struct {
|
type MenuClick struct {
|
||||||
Type string `json:"type"` // 菜单类型: click 回复菜单
|
Type string `json:"type"` // 菜单类型:click 回复菜单
|
||||||
Click struct {
|
Click struct {
|
||||||
ID string `json:"id"` // 菜单ID, 不少于1字节, 不多于64字节
|
ID string `json:"id"` // 菜单 ID, 不少于 1 字节,不多于 64 字节
|
||||||
Content string `json:"content"` // 菜单显示内容, 不少于1字节, 不多于128字节
|
Content string `json:"content"` // 菜单显示内容,不少于 1 字节,不多于 128 字节
|
||||||
} `json:"click"`
|
} `json:"click"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// MenuView 超链接菜单
|
// MenuView 超链接菜单
|
||||||
type MenuView struct {
|
type MenuView struct {
|
||||||
Type string `json:"type"` // 菜单类型: view 超链接菜单
|
Type string `json:"type"` // 菜单类型:view 超链接菜单
|
||||||
View struct {
|
View struct {
|
||||||
URL string `json:"url"` // 点击后跳转的链接, 不少于1字节, 不多于2048字节
|
URL string `json:"url"` // 点击后跳转的链接,不少于 1 字节,不多于 2048 字节
|
||||||
Content string `json:"content"` // 菜单显示内容, 不少于1字节, 不多于1024字节
|
Content string `json:"content"` // 菜单显示内容,不少于 1 字节,不多于 1024 字节
|
||||||
} `json:"view"`
|
} `json:"view"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// MenuMiniProgram 小程序菜单
|
// MenuMiniProgram 小程序菜单
|
||||||
type MenuMiniProgram struct {
|
type MenuMiniProgram struct {
|
||||||
Type string `json:"type"` // 菜单类型: miniprogram 小程序菜单
|
Type string `json:"type"` // 菜单类型:miniprogram 小程序菜单
|
||||||
MiniProgram struct {
|
MiniProgram struct {
|
||||||
AppID string `json:"appid"` // 小程序appid, 不少于1字节, 不多于32字节
|
AppID string `json:"appid"` // 小程序 appid, 不少于 1 字节,不多于 32 字节
|
||||||
PagePath string `json:"pagepath"` // 点击后进入的小程序页面, 不少于1字节, 不多于1024字节
|
PagePath string `json:"pagepath"` // 点击后进入的小程序页面,不少于 1 字节,不多于 1024 字节
|
||||||
Content string `json:"content"` // 菜单显示内容, 不少于1字节, 不多于1024字节
|
Content string `json:"content"` // 菜单显示内容,不少于 1 字节,不多于 1024 字节
|
||||||
} `json:"miniprogram"`
|
} `json:"miniprogram"`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ type ReceptionistListSchema struct {
|
|||||||
util.CommonError
|
util.CommonError
|
||||||
ReceptionistList []struct {
|
ReceptionistList []struct {
|
||||||
UserID string `json:"userid"` // 接待人员的 userid。第三方应用获取到的为密文 userid,即 open_userid
|
UserID string `json:"userid"` // 接待人员的 userid。第三方应用获取到的为密文 userid,即 open_userid
|
||||||
Status int `json:"status"` // 接待人员的接待状态。0:接待中,1:停止接待。第三方应用需具有“管理帐号、分配会话和收发消息”权限才可获取
|
Status int `json:"status"` // 接待人员的接待状态。0:接待中,1:停止接待。第三方应用需具有“管理帐号、分配会话和收发消息”权限才可获取
|
||||||
} `json:"servicer_list"`
|
} `json:"servicer_list"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,8 +16,8 @@ const (
|
|||||||
|
|
||||||
// SyncMsgOptions 获取消息查询参数
|
// SyncMsgOptions 获取消息查询参数
|
||||||
type SyncMsgOptions struct {
|
type SyncMsgOptions struct {
|
||||||
Cursor string `json:"cursor"` // 上一次调用时返回的next_cursor,第一次拉取可以不填, 不多于64字节
|
Cursor string `json:"cursor"` // 上一次调用时返回的 next_cursor,第一次拉取可以不填,不多于 64 字节
|
||||||
Token string `json:"token"` // 回调事件返回的token字段,10分钟内有效;可不填,如果不填接口有严格的频率限制, 不多于128字节
|
Token string `json:"token"` // 回调事件返回的 token 字段,10 分钟内有效;可不填,如果不填接口有严格的频率限制,不多于 128 字节
|
||||||
Limit uint `json:"limit"` // 期望请求的数据量,默认值和最大值都为 1000, 注意:可能会出现返回条数少于 limit 的情况,需结合返回的 has_more 字段判断是否继续请求。
|
Limit uint `json:"limit"` // 期望请求的数据量,默认值和最大值都为 1000, 注意:可能会出现返回条数少于 limit 的情况,需结合返回的 has_more 字段判断是否继续请求。
|
||||||
VoiceFormat uint `json:"voice_format,omitempty"` // 语音消息类型,0-Amr 1-Silk,默认 0。可通过该参数控制返回的语音格式,开发者可按需选择自己程序支持的一种格式
|
VoiceFormat uint `json:"voice_format,omitempty"` // 语音消息类型,0-Amr 1-Silk,默认 0。可通过该参数控制返回的语音格式,开发者可按需选择自己程序支持的一种格式
|
||||||
OpenKfID string `json:"open_kfid,omitempty"` // 指定拉取某个客服帐号的消息,否则默认返回有权限的客服帐号的消息。当客服帐号较多,建议按 open_kfid 来拉取以获取更好的性能。
|
OpenKfID string `json:"open_kfid,omitempty"` // 指定拉取某个客服帐号的消息,否则默认返回有权限的客服帐号的消息。当客服帐号较多,建议按 open_kfid 来拉取以获取更好的性能。
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// Package message 消息推送,实现企业微信消息推送相关接口:https://developer.work.weixin.qq.com/document/path/90235
|
// Package message 消息推送,实现企业微信消息推送相关接口:https://developer.work.weixin.qq.com/document/path/90235
|
||||||
package message
|
package message
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ type ChatData struct {
|
|||||||
MsgID string `json:"msgid,omitempty"` // 消息 id,消息的唯一标识,企业可以使用此字段进行消息去重。
|
MsgID string `json:"msgid,omitempty"` // 消息 id,消息的唯一标识,企业可以使用此字段进行消息去重。
|
||||||
PublickeyVer uint32 `json:"publickey_ver,omitempty"` // 加密此条消息使用的公钥版本号。
|
PublickeyVer uint32 `json:"publickey_ver,omitempty"` // 加密此条消息使用的公钥版本号。
|
||||||
EncryptRandomKey string `json:"encrypt_random_key,omitempty"` // 使用 publickey_ver 指定版本的公钥进行非对称加密后 base64 加密的内容,需要业务方先 base64 decode 处理后,再使用指定版本的私钥进行解密,得出内容。
|
EncryptRandomKey string `json:"encrypt_random_key,omitempty"` // 使用 publickey_ver 指定版本的公钥进行非对称加密后 base64 加密的内容,需要业务方先 base64 decode 处理后,再使用指定版本的私钥进行解密,得出内容。
|
||||||
EncryptChatMsg string `json:"encrypt_chat_msg,omitempty"` // 消息密文。需要业务方使用将encrypt_random_key解密得到的内容,与encrypt_chat_msg,传入sdk接口DecryptData,得到消息明文。
|
EncryptChatMsg string `json:"encrypt_chat_msg,omitempty"` // 消息密文。需要业务方使用将 encrypt_random_key 解密得到的内容,与 encrypt_chat_msg,传入 sdk 接口 DecryptData,得到消息明文。
|
||||||
}
|
}
|
||||||
|
|
||||||
// ChatMessage 会话存档消息
|
// ChatMessage 会话存档消息
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ func (s *Client) Free() {
|
|||||||
* @param [in] proxy 使用代理的请求,需要传入代理的链接。如:socks5://10.0.0.1:8081 或者 http://10.0.0.1:8081
|
* @param [in] proxy 使用代理的请求,需要传入代理的链接。如:socks5://10.0.0.1:8081 或者 http://10.0.0.1:8081
|
||||||
* @param [in] passwd 代理账号密码,需要传入代理的账号密码。如 user_name:passwd_123
|
* @param [in] passwd 代理账号密码,需要传入代理的账号密码。如 user_name:passwd_123
|
||||||
* @param [in] timeout 超时时间,单位秒
|
* @param [in] timeout 超时时间,单位秒
|
||||||
* @return chatDatas 返回本次拉取消息的数据,slice结构体.内容包括errcode/errmsg,以及每条消息内容。示例如下:
|
* @return chatDatas 返回本次拉取消息的数据,slice 结构体。内容包括 errcode/errmsg,以及每条消息内容。示例如下:
|
||||||
|
|
||||||
{"errcode":0,"errmsg":"ok","chatdata":[{"seq":196,"msgid":"CAQQ2fbb4QUY0On2rYSAgAMgip/yzgs=","publickey_ver":3,"encrypt_random_key":"ftJ+uz3n/z1DsxlkwxNgE+mL38H42/KCvN8T60gbbtPD+Rta1hKTuQPzUzO6Hzne97MgKs7FfdDxDck/v8cDT6gUVjA2tZ/M7euSD0L66opJ/IUeBtpAtvgVSD5qhlaQjvfKJc/zPMGNK2xCLFYqwmQBZXbNT7uA69Fflm512nZKW/piK2RKdYJhRyvQnA1ISxK097sp9WlEgDg250fM5tgwMjujdzr7ehK6gtVBUFldNSJS7ndtIf6aSBfaLktZgwHZ57ONewWq8GJe7WwQf1hwcDbCh7YMG8nsweEwhDfUz+u8rz9an+0lgrYMZFRHnmzjgmLwrR7B/32Qxqd79A==","encrypt_chat_msg":"898WSfGMnIeytTsea7Rc0WsOocs0bIAerF6de0v2cFwqo9uOxrW9wYe5rCjCHHH5bDrNvLxBE/xOoFfcwOTYX0HQxTJaH0ES9OHDZ61p8gcbfGdJKnq2UU4tAEgGb8H+Q9n8syRXIjaI3KuVCqGIi4QGHFmxWenPFfjF/vRuPd0EpzUNwmqfUxLBWLpGhv+dLnqiEOBW41Zdc0OO0St6E+JeIeHlRZAR+E13Isv9eS09xNbF0qQXWIyNUi+ucLr5VuZnPGXBrSfvwX8f0QebTwpy1tT2zvQiMM2MBugKH6NuMzzuvEsXeD+6+3VRqL"}]}
|
{"errcode":0,"errmsg":"ok","chatdata":[{"seq":196,"msgid":"CAQQ2fbb4QUY0On2rYSAgAMgip/yzgs=","publickey_ver":3,"encrypt_random_key":"ftJ+uz3n/z1DsxlkwxNgE+mL38H42/KCvN8T60gbbtPD+Rta1hKTuQPzUzO6Hzne97MgKs7FfdDxDck/v8cDT6gUVjA2tZ/M7euSD0L66opJ/IUeBtpAtvgVSD5qhlaQjvfKJc/zPMGNK2xCLFYqwmQBZXbNT7uA69Fflm512nZKW/piK2RKdYJhRyvQnA1ISxK097sp9WlEgDg250fM5tgwMjujdzr7ehK6gtVBUFldNSJS7ndtIf6aSBfaLktZgwHZ57ONewWq8GJe7WwQf1hwcDbCh7YMG8nsweEwhDfUz+u8rz9an+0lgrYMZFRHnmzjgmLwrR7B/32Qxqd79A==","encrypt_chat_msg":"898WSfGMnIeytTsea7Rc0WsOocs0bIAerF6de0v2cFwqo9uOxrW9wYe5rCjCHHH5bDrNvLxBE/xOoFfcwOTYX0HQxTJaH0ES9OHDZ61p8gcbfGdJKnq2UU4tAEgGb8H+Q9n8syRXIjaI3KuVCqGIi4QGHFmxWenPFfjF/vRuPd0EpzUNwmqfUxLBWLpGhv+dLnqiEOBW41Zdc0OO0St6E+JeIeHlRZAR+E13Isv9eS09xNbF0qQXWIyNUi+ucLr5VuZnPGXBrSfvwX8f0QebTwpy1tT2zvQiMM2MBugKH6NuMzzuvEsXeD+6+3VRqL"}]}
|
||||||
*/
|
*/
|
||||||
@@ -122,7 +122,7 @@ func (s *Client) GetChatData(seq uint64, limit uint64, proxy string, passwd stri
|
|||||||
* @param [in] proxy 使用代理的请求,需要传入代理的链接。如:socks5://10.0.0.1:8081 或者 http://10.0.0.1:8081
|
* @param [in] proxy 使用代理的请求,需要传入代理的链接。如:socks5://10.0.0.1:8081 或者 http://10.0.0.1:8081
|
||||||
* @param [in] passwd 代理账号密码,需要传入代理的账号密码。如 user_name:passwd_123
|
* @param [in] passwd 代理账号密码,需要传入代理的账号密码。如 user_name:passwd_123
|
||||||
* @param [in] timeout 超时时间,单位秒
|
* @param [in] timeout 超时时间,单位秒
|
||||||
* @return chatDatas 返回本次拉取消息的数据,slice结构体.内容包括errcode/errmsg,以及每条消息内容。示例如下:
|
* @return chatDatas 返回本次拉取消息的数据,slice 结构体。内容包括 errcode/errmsg,以及每条消息内容。示例如下:
|
||||||
|
|
||||||
{"errcode":0,"errmsg":"ok","chatdata":[{"seq":196,"msgid":"CAQQ2fbb4QUY0On2rYSAgAMgip/yzgs=","publickey_ver":3,"encrypt_random_key":"ftJ+uz3n/z1DsxlkwxNgE+mL38H42/KCvN8T60gbbtPD+Rta1hKTuQPzUzO6Hzne97MgKs7FfdDxDck/v8cDT6gUVjA2tZ/M7euSD0L66opJ/IUeBtpAtvgVSD5qhlaQjvfKJc/zPMGNK2xCLFYqwmQBZXbNT7uA69Fflm512nZKW/piK2RKdYJhRyvQnA1ISxK097sp9WlEgDg250fM5tgwMjujdzr7ehK6gtVBUFldNSJS7ndtIf6aSBfaLktZgwHZ57ONewWq8GJe7WwQf1hwcDbCh7YMG8nsweEwhDfUz+u8rz9an+0lgrYMZFRHnmzjgmLwrR7B/32Qxqd79A==","encrypt_chat_msg":"898WSfGMnIeytTsea7Rc0WsOocs0bIAerF6de0v2cFwqo9uOxrW9wYe5rCjCHHH5bDrNvLxBE/xOoFfcwOTYX0HQxTJaH0ES9OHDZ61p8gcbfGdJKnq2UU4tAEgGb8H+Q9n8syRXIjaI3KuVCqGIi4QGHFmxWenPFfjF/vRuPd0EpzUNwmqfUxLBWLpGhv+dLnqiEOBW41Zdc0OO0St6E+JeIeHlRZAR+E13Isv9eS09xNbF0qQXWIyNUi+ucLr5VuZnPGXBrSfvwX8f0QebTwpy1tT2zvQiMM2MBugKH6NuMzzuvEsXeD+6+3VRqL"}]}
|
{"errcode":0,"errmsg":"ok","chatdata":[{"seq":196,"msgid":"CAQQ2fbb4QUY0On2rYSAgAMgip/yzgs=","publickey_ver":3,"encrypt_random_key":"ftJ+uz3n/z1DsxlkwxNgE+mL38H42/KCvN8T60gbbtPD+Rta1hKTuQPzUzO6Hzne97MgKs7FfdDxDck/v8cDT6gUVjA2tZ/M7euSD0L66opJ/IUeBtpAtvgVSD5qhlaQjvfKJc/zPMGNK2xCLFYqwmQBZXbNT7uA69Fflm512nZKW/piK2RKdYJhRyvQnA1ISxK097sp9WlEgDg250fM5tgwMjujdzr7ehK6gtVBUFldNSJS7ndtIf6aSBfaLktZgwHZ57ONewWq8GJe7WwQf1hwcDbCh7YMG8nsweEwhDfUz+u8rz9an+0lgrYMZFRHnmzjgmLwrR7B/32Qxqd79A==","encrypt_chat_msg":"898WSfGMnIeytTsea7Rc0WsOocs0bIAerF6de0v2cFwqo9uOxrW9wYe5rCjCHHH5bDrNvLxBE/xOoFfcwOTYX0HQxTJaH0ES9OHDZ61p8gcbfGdJKnq2UU4tAEgGb8H+Q9n8syRXIjaI3KuVCqGIi4QGHFmxWenPFfjF/vRuPd0EpzUNwmqfUxLBWLpGhv+dLnqiEOBW41Zdc0OO0St6E+JeIeHlRZAR+E13Isv9eS09xNbF0qQXWIyNUi+ucLr5VuZnPGXBrSfvwX8f0QebTwpy1tT2zvQiMM2MBugKH6NuMzzuvEsXeD+6+3VRqL"}]}
|
||||||
*/
|
*/
|
||||||
@@ -152,10 +152,10 @@ func (s *Client) GetRawChatData(seq uint64, limit uint64, proxy string, passwd s
|
|||||||
return data, err
|
return data, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// DecryptData 解析密文.企业微信自有解密内容
|
// DecryptData 解析密文。企业微信自有解密内容
|
||||||
/**
|
/**
|
||||||
* @brief 解析密文.企业微信自有解密内容
|
* @brief 解析密文。企业微信自有解密内容
|
||||||
* @param [in] encrypt_key, getchatdata返回的encrypt_random_key,使用企业自持对应版本秘钥RSA解密后的内容
|
* @param [in] encrypt_key, getchatdata 返回的 encrypt_random_key,使用企业自持对应版本秘钥 RSA 解密后的内容
|
||||||
* @param [in] encrypt_msg, getchatdata 返回的 encrypt_chat_msg
|
* @param [in] encrypt_msg, getchatdata 返回的 encrypt_chat_msg
|
||||||
* @param [out] msg, 解密的消息明文
|
* @param [out] msg, 解密的消息明文
|
||||||
* @return 返回是否调用成功
|
* @return 返回是否调用成功
|
||||||
@@ -219,7 +219,7 @@ func (s *Client) DecryptData(encryptRandomKey string, encryptMsg string) (msg Ch
|
|||||||
* @param [in] passwd 代理账号密码,需要传入代理的账号密码。如 user_name:passwd_123
|
* @param [in] passwd 代理账号密码,需要传入代理的账号密码。如 user_name:passwd_123
|
||||||
* @param [in] indexbuf 媒体消息分片拉取,需要填入每次拉取的索引信息。首次不需要填写,默认拉取 512k,后续每次调用只需要将上次调用返回的 outindexbuf 填入即可。
|
* @param [in] indexbuf 媒体消息分片拉取,需要填入每次拉取的索引信息。首次不需要填写,默认拉取 512k,后续每次调用只需要将上次调用返回的 outindexbuf 填入即可。
|
||||||
* @param [in] timeout 超时时间,单位秒
|
* @param [in] timeout 超时时间,单位秒
|
||||||
* @param [out] media_data 返回本次拉取的媒体数据.MediaData结构体.内容包括data(数据内容)/outindexbuf(下次索引)/is_finish(拉取完成标记)
|
* @param [out] media_data 返回本次拉取的媒体数据.MediaData 结构体。内容包括 data(数据内容)/outindexbuf(下次索引)/is_finish(拉取完成标记)
|
||||||
|
|
||||||
*
|
*
|
||||||
* @return 返回是否调用成功
|
* @return 返回是否调用成功
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ type WebhookSendResponse struct {
|
|||||||
|
|
||||||
// WebhookSendTextOption 机器人发送文本消息请求参数
|
// WebhookSendTextOption 机器人发送文本消息请求参数
|
||||||
type WebhookSendTextOption struct {
|
type WebhookSendTextOption struct {
|
||||||
MsgType string `json:"msgtype"` // 消息类型,此时固定为text
|
MsgType string `json:"msgtype"` // 消息类型,此时固定为 text
|
||||||
Text struct {
|
Text struct {
|
||||||
Content string `json:"content"` // 文本内容,最长不超过 2048 个字节,必须是 utf8 编码
|
Content string `json:"content"` // 文本内容,最长不超过 2048 个字节,必须是 utf8 编码
|
||||||
MentionedList []string `json:"mentioned_list"` // userid 的列表,提醒群中的指定成员 (@某个成员),@all 表示提醒所有人,如果开发者获取不到 userid,可以使用 mentioned_mobile_list
|
MentionedList []string `json:"mentioned_list"` // userid 的列表,提醒群中的指定成员 (@某个成员),@all 表示提醒所有人,如果开发者获取不到 userid,可以使用 mentioned_mobile_list
|
||||||
@@ -20,7 +20,7 @@ type WebhookSendTextOption struct {
|
|||||||
// WebhookSendMarkdownOption 机器人发送 markdown 消息请求参数
|
// WebhookSendMarkdownOption 机器人发送 markdown 消息请求参数
|
||||||
// 支持语法参考 https://developer.work.weixin.qq.com/document/path/91770
|
// 支持语法参考 https://developer.work.weixin.qq.com/document/path/91770
|
||||||
type WebhookSendMarkdownOption struct {
|
type WebhookSendMarkdownOption struct {
|
||||||
MsgType string `json:"msgtype"` // 消息类型,此时固定为markdown
|
MsgType string `json:"msgtype"` // 消息类型,此时固定为 markdown
|
||||||
Markdown struct {
|
Markdown struct {
|
||||||
Content string `json:"content"` // markdown 内容,最长不超过 4096 个字节,必须是 utf8 编码
|
Content string `json:"content"` // markdown 内容,最长不超过 4096 个字节,必须是 utf8 编码
|
||||||
} `json:"markdown"` // markdown 消息内容
|
} `json:"markdown"` // markdown 消息内容
|
||||||
@@ -28,7 +28,7 @@ type WebhookSendMarkdownOption struct {
|
|||||||
|
|
||||||
// WebhookSendImageOption 机器人发送图片消息请求参数
|
// WebhookSendImageOption 机器人发送图片消息请求参数
|
||||||
type WebhookSendImageOption struct {
|
type WebhookSendImageOption struct {
|
||||||
MsgType string `json:"msgtype"` // 消息类型,此时固定为image
|
MsgType string `json:"msgtype"` // 消息类型,此时固定为 image
|
||||||
Image struct {
|
Image struct {
|
||||||
Base64 string `json:"base64"` // 图片内容的 base64 编码
|
Base64 string `json:"base64"` // 图片内容的 base64 编码
|
||||||
MD5 string `json:"md5"` // 图片内容(base64 编码前)的 md5 值
|
MD5 string `json:"md5"` // 图片内容(base64 编码前)的 md5 值
|
||||||
@@ -37,7 +37,7 @@ type WebhookSendImageOption struct {
|
|||||||
|
|
||||||
// WebhookSendNewsOption 机器人发送图文消息请求参数
|
// WebhookSendNewsOption 机器人发送图文消息请求参数
|
||||||
type WebhookSendNewsOption struct {
|
type WebhookSendNewsOption struct {
|
||||||
MsgType string `json:"msgtype"` // 消息类型,此时固定为news
|
MsgType string `json:"msgtype"` // 消息类型,此时固定为 news
|
||||||
News struct {
|
News struct {
|
||||||
Articles []struct {
|
Articles []struct {
|
||||||
Title string `json:"title"` // 标题,不超过 128 个字节,超过会自动截断
|
Title string `json:"title"` // 标题,不超过 128 个字节,超过会自动截断
|
||||||
|
|||||||
Reference in New Issue
Block a user