mirror of
https://github.com/silenceper/wechat.git
synced 2026-03-01 00:35:26 +08:00
Compare commits
4 Commits
fbda048f62
...
07b7dc40fc
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
07b7dc40fc | ||
|
|
01784c2a4a | ||
|
|
8bc1474777 | ||
|
|
ca0b74e082 |
46
cache/cache.go
vendored
46
cache/cache.go
vendored
@@ -1,6 +1,9 @@
|
|||||||
package cache
|
package cache
|
||||||
|
|
||||||
import "time"
|
import (
|
||||||
|
"context"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
// Cache interface
|
// Cache interface
|
||||||
type Cache interface {
|
type Cache interface {
|
||||||
@@ -9,3 +12,44 @@ type Cache interface {
|
|||||||
IsExist(key string) bool
|
IsExist(key string) bool
|
||||||
Delete(key string) error
|
Delete(key string) error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ContextCache interface
|
||||||
|
type ContextCache interface {
|
||||||
|
Cache
|
||||||
|
GetContext(ctx context.Context, key string) interface{}
|
||||||
|
SetContext(ctx context.Context, key string, val interface{}, timeout time.Duration) error
|
||||||
|
IsExistContext(ctx context.Context, key string) bool
|
||||||
|
DeleteContext(ctx context.Context, key string) error
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetContext get value from cache
|
||||||
|
func GetContext(ctx context.Context, cache Cache, key string) interface{} {
|
||||||
|
if cache, ok := cache.(ContextCache); ok {
|
||||||
|
return cache.GetContext(ctx, key)
|
||||||
|
}
|
||||||
|
return cache.Get(key)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetContext set value to cache
|
||||||
|
func SetContext(ctx context.Context, cache Cache, key string, val interface{}, timeout time.Duration) error {
|
||||||
|
if cache, ok := cache.(ContextCache); ok {
|
||||||
|
return cache.SetContext(ctx, key, val, timeout)
|
||||||
|
}
|
||||||
|
return cache.Set(key, val, timeout)
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsExistContext check value exists in cache.
|
||||||
|
func IsExistContext(ctx context.Context, cache Cache, key string) bool {
|
||||||
|
if cache, ok := cache.(ContextCache); ok {
|
||||||
|
return cache.IsExistContext(ctx, key)
|
||||||
|
}
|
||||||
|
return cache.IsExist(key)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteContext delete value in cache.
|
||||||
|
func DeleteContext(ctx context.Context, cache Cache, key string) error {
|
||||||
|
if cache, ok := cache.(ContextCache); ok {
|
||||||
|
return cache.DeleteContext(ctx, key)
|
||||||
|
}
|
||||||
|
return cache.Delete(key)
|
||||||
|
}
|
||||||
|
|||||||
28
cache/redis.go
vendored
28
cache/redis.go
vendored
@@ -47,7 +47,12 @@ func (r *Redis) SetRedisCtx(ctx context.Context) {
|
|||||||
|
|
||||||
// Get 获取一个值
|
// Get 获取一个值
|
||||||
func (r *Redis) Get(key string) interface{} {
|
func (r *Redis) Get(key string) interface{} {
|
||||||
result, err := r.conn.Do(r.ctx, "GET", key).Result()
|
return r.GetContext(r.ctx, key)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetContext 获取一个值
|
||||||
|
func (r *Redis) GetContext(ctx context.Context, key string) interface{} {
|
||||||
|
result, err := r.conn.Do(ctx, "GET", key).Result()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -56,17 +61,32 @@ func (r *Redis) Get(key string) interface{} {
|
|||||||
|
|
||||||
// Set 设置一个值
|
// Set 设置一个值
|
||||||
func (r *Redis) Set(key string, val interface{}, timeout time.Duration) error {
|
func (r *Redis) Set(key string, val interface{}, timeout time.Duration) error {
|
||||||
return r.conn.SetEX(r.ctx, key, val, timeout).Err()
|
return r.SetContext(r.ctx, key, val, timeout)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetContext 设置一个值
|
||||||
|
func (r *Redis) SetContext(ctx context.Context, key string, val interface{}, timeout time.Duration) error {
|
||||||
|
return r.conn.SetEX(ctx, key, val, timeout).Err()
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsExist 判断key是否存在
|
// IsExist 判断key是否存在
|
||||||
func (r *Redis) IsExist(key string) bool {
|
func (r *Redis) IsExist(key string) bool {
|
||||||
result, _ := r.conn.Exists(r.ctx, key).Result()
|
return r.IsExistContext(r.ctx, key)
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsExistContext 判断key是否存在
|
||||||
|
func (r *Redis) IsExistContext(ctx context.Context, key string) bool {
|
||||||
|
result, _ := r.conn.Exists(ctx, key).Result()
|
||||||
|
|
||||||
return result > 0
|
return result > 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete 删除
|
// Delete 删除
|
||||||
func (r *Redis) Delete(key string) error {
|
func (r *Redis) Delete(key string) error {
|
||||||
return r.conn.Del(r.ctx, key).Err()
|
return r.DeleteContext(r.ctx, key)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteContext 删除
|
||||||
|
func (r *Redis) DeleteContext(ctx context.Context, key string) error {
|
||||||
|
return r.conn.Del(ctx, key).Err()
|
||||||
}
|
}
|
||||||
|
|||||||
10
cache/redis_test.go
vendored
10
cache/redis_test.go
vendored
@@ -4,17 +4,23 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/alicebob/miniredis/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestRedis(t *testing.T) {
|
func TestRedis(t *testing.T) {
|
||||||
|
server, err := miniredis.Run()
|
||||||
|
if err != nil {
|
||||||
|
t.Error("miniredis.Run Error", err)
|
||||||
|
}
|
||||||
|
t.Cleanup(server.Close)
|
||||||
var (
|
var (
|
||||||
timeoutDuration = time.Second
|
timeoutDuration = time.Second
|
||||||
ctx = context.Background()
|
ctx = context.Background()
|
||||||
opts = &RedisOpts{
|
opts = &RedisOpts{
|
||||||
Host: "127.0.0.1:6379",
|
Host: server.Addr(),
|
||||||
}
|
}
|
||||||
redis = NewRedis(ctx, opts)
|
redis = NewRedis(ctx, opts)
|
||||||
err error
|
|
||||||
val = "silenceper"
|
val = "silenceper"
|
||||||
key = "username"
|
key = "username"
|
||||||
)
|
)
|
||||||
|
|||||||
1
go.mod
1
go.mod
@@ -3,6 +3,7 @@ module github.com/silenceper/wechat/v2
|
|||||||
go 1.16
|
go 1.16
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
github.com/alicebob/miniredis/v2 v2.30.0
|
||||||
github.com/bradfitz/gomemcache v0.0.0-20220106215444-fb4bf637b56d
|
github.com/bradfitz/gomemcache v0.0.0-20220106215444-fb4bf637b56d
|
||||||
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
|
||||||
|
|||||||
7
go.sum
7
go.sum
@@ -1,3 +1,7 @@
|
|||||||
|
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/miniredis/v2 v2.30.0 h1:uA3uhDbCxfO9+DI/DuGeAMr9qI+noVWwGPNTFuKID5M=
|
||||||
|
github.com/alicebob/miniredis/v2 v2.30.0/go.mod h1:84TWKZlxYkfgMucPBf5SOQBYJceZeQRFIaQgNMiCX6Q=
|
||||||
github.com/bradfitz/gomemcache v0.0.0-20220106215444-fb4bf637b56d h1:pVrfxiGfwelyab6n21ZBkbkmbevaf+WvMIiR7sr97hw=
|
github.com/bradfitz/gomemcache v0.0.0-20220106215444-fb4bf637b56d h1:pVrfxiGfwelyab6n21ZBkbkmbevaf+WvMIiR7sr97hw=
|
||||||
github.com/bradfitz/gomemcache v0.0.0-20220106215444-fb4bf637b56d/go.mod h1:H0wQNHz2YrLsuXOZozoeDmnHXkNCRmMW0gwFWDfEZDA=
|
github.com/bradfitz/gomemcache v0.0.0-20220106215444-fb4bf637b56d/go.mod h1:H0wQNHz2YrLsuXOZozoeDmnHXkNCRmMW0gwFWDfEZDA=
|
||||||
github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE=
|
github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE=
|
||||||
@@ -71,6 +75,8 @@ github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JT
|
|||||||
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/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||||
|
github.com/yuin/gopher-lua v0.0.0-20220504180219-658193537a64 h1:5mLPGnFdSsevFRFc9q3yYbBkB6tsm4aCwwQV/j1JQAQ=
|
||||||
|
github.com/yuin/gopher-lua v0.0.0-20220504180219-658193537a64/go.mod h1:GBR0iDaNXjAgGg9zfCvksxSRnQx76gclCIb7kdAd1Pw=
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
@@ -89,6 +95,7 @@ golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJ
|
|||||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/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/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-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-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-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-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ type CustomerMessage struct {
|
|||||||
Wxcard *MediaWxcard `json:"wxcard,omitempty"` // 可选
|
Wxcard *MediaWxcard `json:"wxcard,omitempty"` // 可选
|
||||||
Msgmenu *MediaMsgmenu `json:"msgmenu,omitempty"` // 可选
|
Msgmenu *MediaMsgmenu `json:"msgmenu,omitempty"` // 可选
|
||||||
Miniprogrampage *MediaMiniprogrampage `json:"miniprogrampage,omitempty"` // 可选
|
Miniprogrampage *MediaMiniprogrampage `json:"miniprogrampage,omitempty"` // 可选
|
||||||
|
Mpnewsarticle *MediaArticle `json:"mpnewsarticle,omitempty"` // 可选
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewCustomerTextMessage 文本消息结构体构造方法
|
// NewCustomerTextMessage 文本消息结构体构造方法
|
||||||
@@ -97,6 +98,11 @@ type MediaResource struct {
|
|||||||
MediaID string `json:"media_id"`
|
MediaID string `json:"media_id"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MediaArticle 消息使用的已发布文章id
|
||||||
|
type MediaArticle struct {
|
||||||
|
ArticleID string `json:"article_id"`
|
||||||
|
}
|
||||||
|
|
||||||
// MediaVideo 视频消息包含的内容
|
// MediaVideo 视频消息包含的内容
|
||||||
type MediaVideo struct {
|
type MediaVideo struct {
|
||||||
MediaID string `json:"media_id"`
|
MediaID string `json:"media_id"`
|
||||||
|
|||||||
@@ -2,11 +2,13 @@
|
|||||||
package context
|
package context
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/url"
|
"net/url"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/silenceper/wechat/v2/cache"
|
||||||
"github.com/silenceper/wechat/v2/util"
|
"github.com/silenceper/wechat/v2/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -31,24 +33,29 @@ type ComponentAccessToken struct {
|
|||||||
ExpiresIn int64 `json:"expires_in"`
|
ExpiresIn int64 `json:"expires_in"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetComponentAccessToken 获取 ComponentAccessToken
|
// GetComponentAccessTokenContext 获取 ComponentAccessToken
|
||||||
func (ctx *Context) GetComponentAccessToken() (string, error) {
|
func (ctx *Context) GetComponentAccessTokenContext(stdCtx context.Context) (string, error) {
|
||||||
accessTokenCacheKey := fmt.Sprintf("component_access_token_%s", ctx.AppID)
|
accessTokenCacheKey := fmt.Sprintf("component_access_token_%s", ctx.AppID)
|
||||||
val := ctx.Cache.Get(accessTokenCacheKey)
|
val := cache.GetContext(stdCtx, ctx.Cache, accessTokenCacheKey)
|
||||||
if val == nil {
|
if val == nil {
|
||||||
return "", fmt.Errorf("cann't get component access token")
|
return "", fmt.Errorf("cann't get component access token")
|
||||||
}
|
}
|
||||||
return val.(string), nil
|
return val.(string), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetComponentAccessToken 通过component_verify_ticket 获取 ComponentAccessToken
|
// GetComponentAccessToken 获取 ComponentAccessToken
|
||||||
func (ctx *Context) SetComponentAccessToken(verifyTicket string) (*ComponentAccessToken, error) {
|
func (ctx *Context) GetComponentAccessToken() (string, error) {
|
||||||
|
return ctx.GetComponentAccessTokenContext(context.Background())
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetComponentAccessTokenContext 通过component_verify_ticket 获取 ComponentAccessToken
|
||||||
|
func (ctx *Context) SetComponentAccessTokenContext(stdCtx context.Context, verifyTicket string) (*ComponentAccessToken, error) {
|
||||||
body := map[string]string{
|
body := map[string]string{
|
||||||
"component_appid": ctx.AppID,
|
"component_appid": ctx.AppID,
|
||||||
"component_appsecret": ctx.AppSecret,
|
"component_appsecret": ctx.AppSecret,
|
||||||
"component_verify_ticket": verifyTicket,
|
"component_verify_ticket": verifyTicket,
|
||||||
}
|
}
|
||||||
respBody, err := util.PostJSON(componentAccessTokenURL, body)
|
respBody, err := util.PostJSONContext(stdCtx, componentAccessTokenURL, body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -64,15 +71,20 @@ func (ctx *Context) SetComponentAccessToken(verifyTicket string) (*ComponentAcce
|
|||||||
|
|
||||||
accessTokenCacheKey := fmt.Sprintf("component_access_token_%s", ctx.AppID)
|
accessTokenCacheKey := fmt.Sprintf("component_access_token_%s", ctx.AppID)
|
||||||
expires := at.ExpiresIn - 1500
|
expires := at.ExpiresIn - 1500
|
||||||
if err := ctx.Cache.Set(accessTokenCacheKey, at.AccessToken, time.Duration(expires)*time.Second); err != nil {
|
if err := cache.SetContext(stdCtx, ctx.Cache, accessTokenCacheKey, at.AccessToken, time.Duration(expires)*time.Second); err != nil {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
return at, nil
|
return at, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetPreCode 获取预授权码
|
// SetComponentAccessToken 通过component_verify_ticket 获取 ComponentAccessToken
|
||||||
func (ctx *Context) GetPreCode() (string, error) {
|
func (ctx *Context) SetComponentAccessToken(stdCtx context.Context, verifyTicket string) (*ComponentAccessToken, error) {
|
||||||
cat, err := ctx.GetComponentAccessToken()
|
return ctx.SetComponentAccessTokenContext(stdCtx, verifyTicket)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetPreCodeContext 获取预授权码
|
||||||
|
func (ctx *Context) GetPreCodeContext(stdCtx context.Context) (string, error) {
|
||||||
|
cat, err := ctx.GetComponentAccessTokenContext(stdCtx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
@@ -80,7 +92,7 @@ func (ctx *Context) GetPreCode() (string, error) {
|
|||||||
"component_appid": ctx.AppID,
|
"component_appid": ctx.AppID,
|
||||||
}
|
}
|
||||||
uri := fmt.Sprintf(getPreCodeURL, cat)
|
uri := fmt.Sprintf(getPreCodeURL, cat)
|
||||||
body, err := util.PostJSON(uri, req)
|
body, err := util.PostJSONContext(stdCtx, uri, req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
@@ -95,24 +107,39 @@ func (ctx *Context) GetPreCode() (string, error) {
|
|||||||
return ret.PreCode, nil
|
return ret.PreCode, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetComponentLoginPage 获取第三方公众号授权链接(扫码授权)
|
// GetPreCode 获取预授权码
|
||||||
func (ctx *Context) GetComponentLoginPage(redirectURI string, authType int, bizAppID string) (string, error) {
|
func (ctx *Context) GetPreCode() (string, error) {
|
||||||
code, err := ctx.GetPreCode()
|
return ctx.GetPreCodeContext(context.Background())
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetComponentLoginPageContext 获取第三方公众号授权链接(扫码授权)
|
||||||
|
func (ctx *Context) GetComponentLoginPageContext(stdCtx context.Context, redirectURI string, authType int, bizAppID string) (string, error) {
|
||||||
|
code, err := ctx.GetPreCodeContext(stdCtx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
return fmt.Sprintf(componentLoginURL, ctx.AppID, code, url.QueryEscape(redirectURI), authType, bizAppID), nil
|
return fmt.Sprintf(componentLoginURL, ctx.AppID, code, url.QueryEscape(redirectURI), authType, bizAppID), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetBindComponentURL 获取第三方公众号授权链接(链接跳转,适用移动端)
|
// GetComponentLoginPage 获取第三方公众号授权链接(扫码授权)
|
||||||
func (ctx *Context) GetBindComponentURL(redirectURI string, authType int, bizAppID string) (string, error) {
|
func (ctx *Context) GetComponentLoginPage(redirectURI string, authType int, bizAppID string) (string, error) {
|
||||||
code, err := ctx.GetPreCode()
|
return ctx.GetComponentLoginPageContext(context.Background(), redirectURI, authType, bizAppID)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetBindComponentURLContext 获取第三方公众号授权链接(链接跳转,适用移动端)
|
||||||
|
func (ctx *Context) GetBindComponentURLContext(stdCtx context.Context, redirectURI string, authType int, bizAppID string) (string, error) {
|
||||||
|
code, err := ctx.GetPreCodeContext(stdCtx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
return fmt.Sprintf(bindComponentURL, authType, ctx.AppID, code, url.QueryEscape(redirectURI), bizAppID), nil
|
return fmt.Sprintf(bindComponentURL, authType, ctx.AppID, code, url.QueryEscape(redirectURI), bizAppID), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetBindComponentURL 获取第三方公众号授权链接(链接跳转,适用移动端)
|
||||||
|
func (ctx *Context) GetBindComponentURL(redirectURI string, authType int, bizAppID string) (string, error) {
|
||||||
|
return ctx.GetBindComponentURLContext(context.Background(), redirectURI, authType, bizAppID)
|
||||||
|
}
|
||||||
|
|
||||||
// ID 微信返回接口中各种类型字段
|
// ID 微信返回接口中各种类型字段
|
||||||
type ID struct {
|
type ID struct {
|
||||||
ID int `json:"id"`
|
ID int `json:"id"`
|
||||||
@@ -137,9 +164,9 @@ type AuthrAccessToken struct {
|
|||||||
RefreshToken string `json:"authorizer_refresh_token"`
|
RefreshToken string `json:"authorizer_refresh_token"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// QueryAuthCode 使用授权码换取公众号或小程序的接口调用凭据和授权信息
|
// QueryAuthCodeContext 使用授权码换取公众号或小程序的接口调用凭据和授权信息
|
||||||
func (ctx *Context) QueryAuthCode(authCode string) (*AuthBaseInfo, error) {
|
func (ctx *Context) QueryAuthCodeContext(stdCtx context.Context, authCode string) (*AuthBaseInfo, error) {
|
||||||
cat, err := ctx.GetComponentAccessToken()
|
cat, err := ctx.GetComponentAccessTokenContext(stdCtx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -149,7 +176,7 @@ func (ctx *Context) QueryAuthCode(authCode string) (*AuthBaseInfo, error) {
|
|||||||
"authorization_code": authCode,
|
"authorization_code": authCode,
|
||||||
}
|
}
|
||||||
uri := fmt.Sprintf(queryAuthURL, cat)
|
uri := fmt.Sprintf(queryAuthURL, cat)
|
||||||
body, err := util.PostJSON(uri, req)
|
body, err := util.PostJSONContext(stdCtx, uri, req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -169,9 +196,14 @@ func (ctx *Context) QueryAuthCode(authCode string) (*AuthBaseInfo, error) {
|
|||||||
return ret.Info, nil
|
return ret.Info, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// RefreshAuthrToken 获取(刷新)授权公众号或小程序的接口调用凭据(令牌)
|
// QueryAuthCode 使用授权码换取公众号或小程序的接口调用凭据和授权信息
|
||||||
func (ctx *Context) RefreshAuthrToken(appid, refreshToken string) (*AuthrAccessToken, error) {
|
func (ctx *Context) QueryAuthCode(authCode string) (*AuthBaseInfo, error) {
|
||||||
cat, err := ctx.GetComponentAccessToken()
|
return ctx.QueryAuthCodeContext(context.Background(), authCode)
|
||||||
|
}
|
||||||
|
|
||||||
|
// RefreshAuthrTokenContext 获取(刷新)授权公众号或小程序的接口调用凭据(令牌)
|
||||||
|
func (ctx *Context) RefreshAuthrTokenContext(stdCtx context.Context, appid, refreshToken string) (*AuthrAccessToken, error) {
|
||||||
|
cat, err := ctx.GetComponentAccessTokenContext(stdCtx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -182,7 +214,7 @@ func (ctx *Context) RefreshAuthrToken(appid, refreshToken string) (*AuthrAccessT
|
|||||||
"authorizer_refresh_token": refreshToken,
|
"authorizer_refresh_token": refreshToken,
|
||||||
}
|
}
|
||||||
uri := fmt.Sprintf(refreshTokenURL, cat)
|
uri := fmt.Sprintf(refreshTokenURL, cat)
|
||||||
body, err := util.PostJSON(uri, req)
|
body, err := util.PostJSONContext(stdCtx, uri, req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -193,22 +225,32 @@ func (ctx *Context) RefreshAuthrToken(appid, refreshToken string) (*AuthrAccessT
|
|||||||
}
|
}
|
||||||
|
|
||||||
authrTokenKey := "authorizer_access_token_" + appid
|
authrTokenKey := "authorizer_access_token_" + appid
|
||||||
if err := ctx.Cache.Set(authrTokenKey, ret.AccessToken, time.Second*time.Duration(ret.ExpiresIn-30)); err != nil {
|
if err := cache.SetContext(stdCtx, ctx.Cache, authrTokenKey, ret.AccessToken, time.Second*time.Duration(ret.ExpiresIn-30)); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return ret, nil
|
return ret, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetAuthrAccessToken 获取授权方AccessToken
|
// RefreshAuthrToken 获取(刷新)授权公众号或小程序的接口调用凭据(令牌)
|
||||||
func (ctx *Context) GetAuthrAccessToken(appid string) (string, error) {
|
func (ctx *Context) RefreshAuthrToken(appid, refreshToken string) (*AuthrAccessToken, error) {
|
||||||
|
return ctx.RefreshAuthrTokenContext(context.Background(), appid, refreshToken)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetAuthrAccessTokenContext 获取授权方AccessToken
|
||||||
|
func (ctx *Context) GetAuthrAccessTokenContext(stdCtx context.Context, appid string) (string, error) {
|
||||||
authrTokenKey := "authorizer_access_token_" + appid
|
authrTokenKey := "authorizer_access_token_" + appid
|
||||||
val := ctx.Cache.Get(authrTokenKey)
|
val := cache.GetContext(stdCtx, ctx.Cache, authrTokenKey)
|
||||||
if val == nil {
|
if val == nil {
|
||||||
return "", fmt.Errorf("cannot get authorizer %s access token", appid)
|
return "", fmt.Errorf("cannot get authorizer %s access token", appid)
|
||||||
}
|
}
|
||||||
return val.(string), nil
|
return val.(string), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetAuthrAccessToken 获取授权方AccessToken
|
||||||
|
func (ctx *Context) GetAuthrAccessToken(appid string) (string, error) {
|
||||||
|
return ctx.GetAuthrAccessTokenContext(context.Background(), appid)
|
||||||
|
}
|
||||||
|
|
||||||
// AuthorizerInfo 授权方详细信息
|
// AuthorizerInfo 授权方详细信息
|
||||||
type AuthorizerInfo struct {
|
type AuthorizerInfo struct {
|
||||||
NickName string `json:"nick_name"`
|
NickName string `json:"nick_name"`
|
||||||
@@ -258,9 +300,9 @@ type CategoriesInfo struct {
|
|||||||
Second string `wx:"second"`
|
Second string `wx:"second"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetAuthrInfo 获取授权方的帐号基本信息
|
// GetAuthrInfoContext 获取授权方的帐号基本信息
|
||||||
func (ctx *Context) GetAuthrInfo(appid string) (*AuthorizerInfo, *AuthBaseInfo, error) {
|
func (ctx *Context) GetAuthrInfoContext(stdCtx context.Context, appid string) (*AuthorizerInfo, *AuthBaseInfo, error) {
|
||||||
cat, err := ctx.GetComponentAccessToken()
|
cat, err := ctx.GetComponentAccessTokenContext(stdCtx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
@@ -271,7 +313,7 @@ func (ctx *Context) GetAuthrInfo(appid string) (*AuthorizerInfo, *AuthBaseInfo,
|
|||||||
}
|
}
|
||||||
|
|
||||||
uri := fmt.Sprintf(getComponentInfoURL, cat)
|
uri := fmt.Sprintf(getComponentInfoURL, cat)
|
||||||
body, err := util.PostJSON(uri, req)
|
body, err := util.PostJSONContext(stdCtx, uri, req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
@@ -286,3 +328,8 @@ func (ctx *Context) GetAuthrInfo(appid string) (*AuthorizerInfo, *AuthBaseInfo,
|
|||||||
|
|
||||||
return ret.AuthorizerInfo, ret.AuthorizationInfo, nil
|
return ret.AuthorizerInfo, ret.AuthorizationInfo, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetAuthrInfo 获取授权方的帐号基本信息
|
||||||
|
func (ctx *Context) GetAuthrInfo(appid string) (*AuthorizerInfo, *AuthBaseInfo, error) {
|
||||||
|
return ctx.GetAuthrInfoContext(context.Background(), appid)
|
||||||
|
}
|
||||||
|
|||||||
16
util/http.go
16
util/http.go
@@ -69,8 +69,8 @@ func HTTPPostContext(ctx context.Context, uri string, data []byte, header map[st
|
|||||||
return io.ReadAll(response.Body)
|
return io.ReadAll(response.Body)
|
||||||
}
|
}
|
||||||
|
|
||||||
// PostJSON post json 数据请求
|
// PostJSONContext post json 数据请求
|
||||||
func PostJSON(uri string, obj interface{}) ([]byte, error) {
|
func PostJSONContext(ctx context.Context, uri string, obj interface{}) ([]byte, error) {
|
||||||
jsonBuf := new(bytes.Buffer)
|
jsonBuf := new(bytes.Buffer)
|
||||||
enc := json.NewEncoder(jsonBuf)
|
enc := json.NewEncoder(jsonBuf)
|
||||||
enc.SetEscapeHTML(false)
|
enc.SetEscapeHTML(false)
|
||||||
@@ -78,7 +78,12 @@ func PostJSON(uri string, obj interface{}) ([]byte, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
response, err := http.Post(uri, "application/json;charset=utf-8", jsonBuf)
|
req, err := http.NewRequestWithContext(ctx, "POST", uri, jsonBuf)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
req.Header.Set("Content-Type", "application/json;charset=utf-8")
|
||||||
|
response, err := http.DefaultClient.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -90,6 +95,11 @@ func PostJSON(uri string, obj interface{}) ([]byte, error) {
|
|||||||
return io.ReadAll(response.Body)
|
return io.ReadAll(response.Body)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PostJSON post json 数据请求
|
||||||
|
func PostJSON(uri string, obj interface{}) ([]byte, error) {
|
||||||
|
return PostJSONContext(context.Background(), uri, obj)
|
||||||
|
}
|
||||||
|
|
||||||
// PostJSONWithRespContentType post json数据请求,且返回数据类型
|
// PostJSONWithRespContentType post json数据请求,且返回数据类型
|
||||||
func PostJSONWithRespContentType(uri string, obj interface{}) ([]byte, string, error) {
|
func PostJSONWithRespContentType(uri string, obj interface{}) ([]byte, string, error) {
|
||||||
jsonBuf := new(bytes.Buffer)
|
jsonBuf := new(bytes.Buffer)
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// DepartmentSimpleListURL 获取子部门ID列表
|
// departmentSimpleListURL 获取子部门ID列表
|
||||||
DepartmentSimpleListURL = "https://qyapi.weixin.qq.com/cgi-bin/department/simplelist?access_token=%s&id=%d"
|
departmentSimpleListURL = "https://qyapi.weixin.qq.com/cgi-bin/department/simplelist?access_token=%s&id=%d"
|
||||||
)
|
)
|
||||||
|
|
||||||
type (
|
type (
|
||||||
@@ -36,7 +36,7 @@ func (r *Client) DepartmentSimpleList(departmentID int) ([]*DepartmentID, error)
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
var response []byte
|
var response []byte
|
||||||
if response, err = util.HTTPGet(fmt.Sprintf(DepartmentSimpleListURL, accessToken, departmentID)); err != nil {
|
if response, err = util.HTTPGet(fmt.Sprintf(departmentSimpleListURL, accessToken, departmentID)); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
result := &DepartmentSimpleListResponse{}
|
result := &DepartmentSimpleListResponse{}
|
||||||
|
|||||||
@@ -7,12 +7,12 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// UserSimpleListURL 获取部门成员
|
// userSimpleListURL 获取部门成员
|
||||||
UserSimpleListURL = "https://qyapi.weixin.qq.com/cgi-bin/user/simplelist?access_token=%s&department_id=%d"
|
userSimpleListURL = "https://qyapi.weixin.qq.com/cgi-bin/user/simplelist?access_token=%s&department_id=%d"
|
||||||
// UserGetURL 读取成员
|
// userGetURL 读取成员
|
||||||
UserGetURL = "https://qyapi.weixin.qq.com/cgi-bin/user/get?access_token=%s&userid=%s"
|
userGetURL = "https://qyapi.weixin.qq.com/cgi-bin/user/get?access_token=%s&userid=%s"
|
||||||
// UserListIDURL 获取成员ID列表
|
// userListIDURL 获取成员ID列表
|
||||||
UserListIDURL = "https://qyapi.weixin.qq.com/cgi-bin/user/list_id?access_token=%s"
|
userListIDURL = "https://qyapi.weixin.qq.com/cgi-bin/user/list_id?access_token=%s"
|
||||||
)
|
)
|
||||||
|
|
||||||
type (
|
type (
|
||||||
@@ -41,7 +41,7 @@ func (r *Client) UserSimpleList(departmentID int) ([]*UserList, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
var response []byte
|
var response []byte
|
||||||
if response, err = util.HTTPGet(fmt.Sprintf(UserSimpleListURL, accessToken, departmentID)); err != nil {
|
if response, err = util.HTTPGet(fmt.Sprintf(userSimpleListURL, accessToken, departmentID)); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
result := &UserSimpleListResponse{}
|
result := &UserSimpleListResponse{}
|
||||||
@@ -125,7 +125,7 @@ func (r *Client) UserGet(UserID string) (*UserGetResponse, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
var response []byte
|
var response []byte
|
||||||
if response, err = util.HTTPGet(fmt.Sprintf(UserGetURL, accessToken, UserID)); err != nil {
|
if response, err = util.HTTPGet(fmt.Sprintf(userGetURL, accessToken, UserID)); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
result := &UserGetResponse{}
|
result := &UserGetResponse{}
|
||||||
@@ -166,7 +166,7 @@ func (r *Client) UserListID(req *UserListIDRequest) (*UserListIDResponse, error)
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
var response []byte
|
var response []byte
|
||||||
if response, err = util.PostJSON(fmt.Sprintf(UserListIDURL, accessToken), req); err != nil {
|
if response, err = util.PostJSON(fmt.Sprintf(userListIDURL, accessToken), req); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
result := &UserListIDResponse{}
|
result := &UserListIDResponse{}
|
||||||
|
|||||||
@@ -7,16 +7,16 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// AddContactWayURL 配置客户联系「联系我」方式
|
// addContactWayURL 配置客户联系「联系我」方式
|
||||||
AddContactWayURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/add_contact_way?access_token=%s"
|
addContactWayURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/add_contact_way?access_token=%s"
|
||||||
// GetContactWayURL 获取企业已配置的「联系我」方式
|
// getContactWayURL 获取企业已配置的「联系我」方式
|
||||||
GetContactWayURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/get_contact_way?access_token=%s"
|
getContactWayURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/get_contact_way?access_token=%s"
|
||||||
// UpdateContactWayURL 更新企业已配置的「联系我」方式
|
// updateContactWayURL 更新企业已配置的「联系我」方式
|
||||||
UpdateContactWayURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/update_contact_way?access_token=%s"
|
updateContactWayURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/update_contact_way?access_token=%s"
|
||||||
// ListContactWayURL 获取企业已配置的「联系我」列表
|
// listContactWayURL 获取企业已配置的「联系我」列表
|
||||||
ListContactWayURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/list_contact_way?access_token=%s"
|
listContactWayURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/list_contact_way?access_token=%s"
|
||||||
// DelContactWayURL 删除企业已配置的「联系我」方式
|
// delContactWayURL 删除企业已配置的「联系我」方式
|
||||||
DelContactWayURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/del_contact_way?access_token=%s"
|
delContactWayURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/del_contact_way?access_token=%s"
|
||||||
)
|
)
|
||||||
|
|
||||||
type (
|
type (
|
||||||
@@ -98,7 +98,7 @@ func (r *Client) AddContactWay(req *AddContactWayRequest) (*AddContactWayRespons
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
var response []byte
|
var response []byte
|
||||||
if response, err = util.PostJSON(fmt.Sprintf(AddContactWayURL, accessToken), req); err != nil {
|
if response, err = util.PostJSON(fmt.Sprintf(addContactWayURL, accessToken), req); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
result := &AddContactWayResponse{}
|
result := &AddContactWayResponse{}
|
||||||
@@ -149,7 +149,7 @@ func (r *Client) GetContactWay(req *GetContactWayRequest) (*GetContactWayRespons
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
var response []byte
|
var response []byte
|
||||||
if response, err = util.PostJSON(fmt.Sprintf(GetContactWayURL, accessToken), req); err != nil {
|
if response, err = util.PostJSON(fmt.Sprintf(getContactWayURL, accessToken), req); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
result := &GetContactWayResponse{}
|
result := &GetContactWayResponse{}
|
||||||
@@ -191,7 +191,7 @@ func (r *Client) UpdateContactWay(req *UpdateContactWayRequest) (*UpdateContactW
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
var response []byte
|
var response []byte
|
||||||
if response, err = util.PostJSON(fmt.Sprintf(UpdateContactWayURL, accessToken), req); err != nil {
|
if response, err = util.PostJSON(fmt.Sprintf(updateContactWayURL, accessToken), req); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
result := &UpdateContactWayResponse{}
|
result := &UpdateContactWayResponse{}
|
||||||
@@ -232,7 +232,7 @@ func (r *Client) ListContactWay(req *ListContactWayRequest) (*ListContactWayResp
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
var response []byte
|
var response []byte
|
||||||
if response, err = util.PostJSON(fmt.Sprintf(ListContactWayURL, accessToken), req); err != nil {
|
if response, err = util.PostJSON(fmt.Sprintf(listContactWayURL, accessToken), req); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
result := &ListContactWayResponse{}
|
result := &ListContactWayResponse{}
|
||||||
@@ -264,7 +264,7 @@ func (r *Client) DelContactWay(req *DelContactWayRequest) (*DelContactWayRespons
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
var response []byte
|
var response []byte
|
||||||
if response, err = util.PostJSON(fmt.Sprintf(DelContactWayURL, accessToken), req); err != nil {
|
if response, err = util.PostJSON(fmt.Sprintf(delContactWayURL, accessToken), req); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
result := &DelContactWayResponse{}
|
result := &DelContactWayResponse{}
|
||||||
|
|||||||
@@ -8,14 +8,14 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// FetchExternalContactUserListURL 获取客户列表
|
// fetchExternalContactUserListURL 获取客户列表
|
||||||
FetchExternalContactUserListURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/list"
|
fetchExternalContactUserListURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/list"
|
||||||
// FetchExternalContactUserDetailURL 获取客户详情
|
// fetchExternalContactUserDetailURL 获取客户详情
|
||||||
FetchExternalContactUserDetailURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/get"
|
fetchExternalContactUserDetailURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/get"
|
||||||
// FetchBatchExternalContactUserDetailURL 批量获取客户详情
|
// fetchBatchExternalContactUserDetailURL 批量获取客户详情
|
||||||
FetchBatchExternalContactUserDetailURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/batch/get_by_user"
|
fetchBatchExternalContactUserDetailURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/batch/get_by_user"
|
||||||
// UpdateUserRemarkURL 更新客户备注信息
|
// updateUserRemarkURL 更新客户备注信息
|
||||||
UpdateUserRemarkURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/remark"
|
updateUserRemarkURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/remark"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ExternalUserListResponse 外部联系人列表响应
|
// ExternalUserListResponse 外部联系人列表响应
|
||||||
@@ -32,7 +32,7 @@ func (r *Client) GetExternalUserList(userID string) ([]string, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
var response []byte
|
var response []byte
|
||||||
response, err = util.HTTPGet(fmt.Sprintf("%s?access_token=%v&userid=%v", FetchExternalContactUserListURL, accessToken, userID))
|
response, err = util.HTTPGet(fmt.Sprintf("%s?access_token=%v&userid=%v", fetchExternalContactUserListURL, accessToken, userID))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -107,7 +107,7 @@ func (r *Client) GetExternalUserDetail(externalUserID string, nextCursor ...stri
|
|||||||
if len(nextCursor) > 0 {
|
if len(nextCursor) > 0 {
|
||||||
cursor = nextCursor[0]
|
cursor = nextCursor[0]
|
||||||
}
|
}
|
||||||
response, err = util.HTTPGet(fmt.Sprintf("%s?access_token=%v&external_userid=%v&cursor=%v", FetchExternalContactUserDetailURL, accessToken, externalUserID, cursor))
|
response, err = util.HTTPGet(fmt.Sprintf("%s?access_token=%v&external_userid=%v&cursor=%v", fetchExternalContactUserDetailURL, accessToken, externalUserID, cursor))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -178,7 +178,7 @@ func (r *Client) BatchGetExternalUserDetails(request BatchGetExternalUserDetails
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
response, err = util.HTTPPost(fmt.Sprintf("%s?access_token=%v", FetchBatchExternalContactUserDetailURL, accessToken), string(jsonData))
|
response, err = util.HTTPPost(fmt.Sprintf("%s?access_token=%v", fetchBatchExternalContactUserDetailURL, accessToken), string(jsonData))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -213,7 +213,7 @@ func (r *Client) UpdateUserRemark(request UpdateUserRemarkRequest) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
response, err = util.HTTPPost(fmt.Sprintf("%s?access_token=%v", UpdateUserRemarkURL, accessToken), string(jsonData))
|
response, err = util.HTTPPost(fmt.Sprintf("%s?access_token=%v", updateUserRemarkURL, accessToken), string(jsonData))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// FetchFollowUserListURL 获取配置了客户联系功能的成员列表
|
// fetchFollowUserListURL 获取配置了客户联系功能的成员列表
|
||||||
FetchFollowUserListURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/get_follow_user_list"
|
fetchFollowUserListURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/get_follow_user_list"
|
||||||
)
|
)
|
||||||
|
|
||||||
// followerUserResponse 客户联系功能的成员列表响应
|
// followerUserResponse 客户联系功能的成员列表响应
|
||||||
@@ -25,7 +25,7 @@ func (r *Client) GetFollowUserList() ([]string, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
var response []byte
|
var response []byte
|
||||||
response, err = util.HTTPGet(fmt.Sprintf("%s?access_token=%s", FetchFollowUserListURL, accessToken))
|
response, err = util.HTTPGet(fmt.Sprintf("%s?access_token=%s", fetchFollowUserListURL, accessToken))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ import (
|
|||||||
"github.com/silenceper/wechat/v2/util"
|
"github.com/silenceper/wechat/v2/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
// OpengIDToChatIDURL 客户群opengid转换URL
|
// opengIDToChatIDURL 客户群opengid转换URL
|
||||||
const OpengIDToChatIDURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/opengid_to_chatid"
|
const opengIDToChatIDURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/opengid_to_chatid"
|
||||||
|
|
||||||
type (
|
type (
|
||||||
//GroupChatListRequest 获取客户群列表的请求参数
|
//GroupChatListRequest 获取客户群列表的请求参数
|
||||||
@@ -39,7 +39,7 @@ func (r *Client) GetGroupChatList(req *GroupChatListRequest) (*GroupChatListResp
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
var response []byte
|
var response []byte
|
||||||
response, err = util.PostJSON(fmt.Sprintf("%s/list?access_token=%s", GroupChatURL, accessToken), req)
|
response, err = util.PostJSON(fmt.Sprintf("%s/list?access_token=%s", groupChatURL, accessToken), req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -100,7 +100,7 @@ func (r *Client) GetGroupChatDetail(req *GroupChatDetailRequest) (*GroupChatDeta
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
var response []byte
|
var response []byte
|
||||||
response, err = util.PostJSON(fmt.Sprintf("%s/get?access_token=%s", GroupChatURL, accessToken), req)
|
response, err = util.PostJSON(fmt.Sprintf("%s/get?access_token=%s", groupChatURL, accessToken), req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -131,7 +131,7 @@ func (r *Client) OpengIDToChatID(req *OpengIDToChatIDRequest) (*OpengIDToChatIDR
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
var response []byte
|
var response []byte
|
||||||
response, err = util.PostJSON(fmt.Sprintf("%s?access_token=%s", OpengIDToChatIDURL, accessToken), req)
|
response, err = util.PostJSON(fmt.Sprintf("%s?access_token=%s", opengIDToChatIDURL, accessToken), req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ import (
|
|||||||
"github.com/silenceper/wechat/v2/util"
|
"github.com/silenceper/wechat/v2/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
// GroupChatURL 客户群
|
// groupChatURL 客户群
|
||||||
const GroupChatURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/groupchat"
|
const groupChatURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/groupchat"
|
||||||
|
|
||||||
type (
|
type (
|
||||||
// AddJoinWayRequest 添加群配置请求参数
|
// AddJoinWayRequest 添加群配置请求参数
|
||||||
@@ -39,7 +39,7 @@ func (r *Client) AddJoinWay(req *AddJoinWayRequest) (*AddJoinWayResponse, error)
|
|||||||
if accessToken, err = r.GetAccessToken(); err != nil {
|
if accessToken, err = r.GetAccessToken(); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
response, err = util.PostJSON(fmt.Sprintf("%s/add_join_way?access_token=%s", GroupChatURL, accessToken), req)
|
response, err = util.PostJSON(fmt.Sprintf("%s/add_join_way?access_token=%s", groupChatURL, accessToken), req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -86,7 +86,7 @@ func (r *Client) GetJoinWay(req *JoinWayConfigRequest) (*GetJoinWayResponse, err
|
|||||||
if accessToken, err = r.GetAccessToken(); err != nil {
|
if accessToken, err = r.GetAccessToken(); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
response, err = util.PostJSON(fmt.Sprintf("%s/get_join_way?access_token=%s", GroupChatURL, accessToken), req)
|
response, err = util.PostJSON(fmt.Sprintf("%s/get_join_way?access_token=%s", groupChatURL, accessToken), req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -120,7 +120,7 @@ func (r *Client) UpdateJoinWay(req *UpdateJoinWayRequest) error {
|
|||||||
if accessToken, err = r.GetAccessToken(); err != nil {
|
if accessToken, err = r.GetAccessToken(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
response, err = util.PostJSON(fmt.Sprintf("%s/update_join_way?access_token=%s", GroupChatURL, accessToken), req)
|
response, err = util.PostJSON(fmt.Sprintf("%s/update_join_way?access_token=%s", groupChatURL, accessToken), req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -138,7 +138,7 @@ func (r *Client) DelJoinWay(req *JoinWayConfigRequest) error {
|
|||||||
if accessToken, err = r.GetAccessToken(); err != nil {
|
if accessToken, err = r.GetAccessToken(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
response, err = util.PostJSON(fmt.Sprintf("%s/del_join_way?access_token=%s", GroupChatURL, accessToken), req)
|
response, err = util.PostJSON(fmt.Sprintf("%s/del_join_way?access_token=%s", groupChatURL, accessToken), req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,24 +7,24 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// AddMsgTemplateURL 创建企业群发
|
// addMsgTemplateURL 创建企业群发
|
||||||
AddMsgTemplateURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/add_msg_template?access_token=%s"
|
addMsgTemplateURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/add_msg_template?access_token=%s"
|
||||||
// GetGroupMsgListV2URL 获取群发记录列表
|
// getGroupMsgListV2URL 获取群发记录列表
|
||||||
GetGroupMsgListV2URL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/get_groupmsg_list_v2?access_token=%s"
|
getGroupMsgListV2URL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/get_groupmsg_list_v2?access_token=%s"
|
||||||
// GetGroupMsgTaskURL 获取群发成员发送任务列表
|
// getGroupMsgTaskURL 获取群发成员发送任务列表
|
||||||
GetGroupMsgTaskURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/get_groupmsg_task?access_token=%s"
|
getGroupMsgTaskURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/get_groupmsg_task?access_token=%s"
|
||||||
// GetGroupMsgSendResultURL 获取企业群发成员执行结果
|
// getGroupMsgSendResultURL 获取企业群发成员执行结果
|
||||||
GetGroupMsgSendResultURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/get_groupmsg_send_result?access_token=%s"
|
getGroupMsgSendResultURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/get_groupmsg_send_result?access_token=%s"
|
||||||
// SendWelcomeMsgURL 发送新客户欢迎语
|
// sendWelcomeMsgURL 发送新客户欢迎语
|
||||||
SendWelcomeMsgURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/send_welcome_msg?access_token=%s"
|
sendWelcomeMsgURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/send_welcome_msg?access_token=%s"
|
||||||
// AddGroupWelcomeTemplateURL 添加入群欢迎语素材
|
// addGroupWelcomeTemplateURL 添加入群欢迎语素材
|
||||||
AddGroupWelcomeTemplateURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/group_welcome_template/add?access_token=%s"
|
addGroupWelcomeTemplateURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/group_welcome_template/add?access_token=%s"
|
||||||
// EditGroupWelcomeTemplateURL 编辑入群欢迎语素材
|
// editGroupWelcomeTemplateURL 编辑入群欢迎语素材
|
||||||
EditGroupWelcomeTemplateURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/group_welcome_template/edit?access_token=%s"
|
editGroupWelcomeTemplateURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/group_welcome_template/edit?access_token=%s"
|
||||||
// GetGroupWelcomeTemplateURL 获取入群欢迎语素材
|
// getGroupWelcomeTemplateURL 获取入群欢迎语素材
|
||||||
GetGroupWelcomeTemplateURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/group_welcome_template/get?access_token=%s"
|
getGroupWelcomeTemplateURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/group_welcome_template/get?access_token=%s"
|
||||||
// DelGroupWelcomeTemplateURL 删除入群欢迎语素材
|
// delGroupWelcomeTemplateURL 删除入群欢迎语素材
|
||||||
DelGroupWelcomeTemplateURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/group_welcome_template/del?access_token=%s"
|
delGroupWelcomeTemplateURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/group_welcome_template/del?access_token=%s"
|
||||||
)
|
)
|
||||||
|
|
||||||
// AddMsgTemplateRequest 创建企业群发请求
|
// AddMsgTemplateRequest 创建企业群发请求
|
||||||
@@ -98,7 +98,7 @@ func (r *Client) AddMsgTemplate(req *AddMsgTemplateRequest) (*AddMsgTemplateResp
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
var response []byte
|
var response []byte
|
||||||
if response, err = util.PostJSON(fmt.Sprintf(AddMsgTemplateURL, accessToken), req); err != nil {
|
if response, err = util.PostJSON(fmt.Sprintf(addMsgTemplateURL, accessToken), req); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
result := &AddMsgTemplateResponse{}
|
result := &AddMsgTemplateResponse{}
|
||||||
@@ -147,7 +147,7 @@ func (r *Client) GetGroupMsgListV2(req *GetGroupMsgListV2Request) (*GetGroupMsgL
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
var response []byte
|
var response []byte
|
||||||
if response, err = util.PostJSON(fmt.Sprintf(GetGroupMsgListV2URL, accessToken), req); err != nil {
|
if response, err = util.PostJSON(fmt.Sprintf(getGroupMsgListV2URL, accessToken), req); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
result := &GetGroupMsgListV2Response{}
|
result := &GetGroupMsgListV2Response{}
|
||||||
@@ -189,7 +189,7 @@ func (r *Client) GetGroupMsgTask(req *GetGroupMsgTaskRequest) (*GetGroupMsgTaskR
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
var response []byte
|
var response []byte
|
||||||
if response, err = util.PostJSON(fmt.Sprintf(GetGroupMsgTaskURL, accessToken), req); err != nil {
|
if response, err = util.PostJSON(fmt.Sprintf(getGroupMsgTaskURL, accessToken), req); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
result := &GetGroupMsgTaskResponse{}
|
result := &GetGroupMsgTaskResponse{}
|
||||||
@@ -234,7 +234,7 @@ func (r *Client) GetGroupMsgSendResult(req *GetGroupMsgSendResultRequest) (*GetG
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
var response []byte
|
var response []byte
|
||||||
if response, err = util.PostJSON(fmt.Sprintf(GetGroupMsgSendResultURL, accessToken), req); err != nil {
|
if response, err = util.PostJSON(fmt.Sprintf(getGroupMsgSendResultURL, accessToken), req); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
result := &GetGroupMsgSendResultResponse{}
|
result := &GetGroupMsgSendResultResponse{}
|
||||||
@@ -267,7 +267,7 @@ func (r *Client) SendWelcomeMsg(req *SendWelcomeMsgRequest) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
var response []byte
|
var response []byte
|
||||||
if response, err = util.PostJSON(fmt.Sprintf(SendWelcomeMsgURL, accessToken), req); err != nil {
|
if response, err = util.PostJSON(fmt.Sprintf(sendWelcomeMsgURL, accessToken), req); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
result := &SendWelcomeMsgResponse{}
|
result := &SendWelcomeMsgResponse{}
|
||||||
@@ -306,7 +306,7 @@ func (r *Client) AddGroupWelcomeTemplate(req *AddGroupWelcomeTemplateRequest) (*
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
var response []byte
|
var response []byte
|
||||||
if response, err = util.PostJSON(fmt.Sprintf(AddGroupWelcomeTemplateURL, accessToken), req); err != nil {
|
if response, err = util.PostJSON(fmt.Sprintf(addGroupWelcomeTemplateURL, accessToken), req); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
result := &AddGroupWelcomeTemplateResponse{}
|
result := &AddGroupWelcomeTemplateResponse{}
|
||||||
@@ -344,7 +344,7 @@ func (r *Client) EditGroupWelcomeTemplate(req *EditGroupWelcomeTemplateRequest)
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
var response []byte
|
var response []byte
|
||||||
if response, err = util.PostJSON(fmt.Sprintf(EditGroupWelcomeTemplateURL, accessToken), req); err != nil {
|
if response, err = util.PostJSON(fmt.Sprintf(editGroupWelcomeTemplateURL, accessToken), req); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
result := &EditGroupWelcomeTemplateResponse{}
|
result := &EditGroupWelcomeTemplateResponse{}
|
||||||
@@ -381,7 +381,7 @@ func (r *Client) GetGroupWelcomeTemplate(req *GetGroupWelcomeTemplateRequest) (*
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
var response []byte
|
var response []byte
|
||||||
if response, err = util.PostJSON(fmt.Sprintf(GetGroupWelcomeTemplateURL, accessToken), req); err != nil {
|
if response, err = util.PostJSON(fmt.Sprintf(getGroupWelcomeTemplateURL, accessToken), req); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
result := &GetGroupWelcomeTemplateResponse{}
|
result := &GetGroupWelcomeTemplateResponse{}
|
||||||
@@ -413,7 +413,7 @@ func (r *Client) DelGroupWelcomeTemplate(req *DelGroupWelcomeTemplateRequest) er
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
var response []byte
|
var response []byte
|
||||||
if response, err = util.PostJSON(fmt.Sprintf(DelGroupWelcomeTemplateURL, accessToken), req); err != nil {
|
if response, err = util.PostJSON(fmt.Sprintf(delGroupWelcomeTemplateURL, accessToken), req); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
result := &DelGroupWelcomeTemplateResponse{}
|
result := &DelGroupWelcomeTemplateResponse{}
|
||||||
|
|||||||
@@ -8,12 +8,12 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// GetUserBehaviorDataURL 获取「联系客户统计」数据
|
// getUserBehaviorDataURL 获取「联系客户统计」数据
|
||||||
GetUserBehaviorDataURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/get_user_behavior_data"
|
getUserBehaviorDataURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/get_user_behavior_data"
|
||||||
// GetGroupChatStatURL 获取「群聊数据统计」数据 按群主聚合的方式
|
// getGroupChatStatURL 获取「群聊数据统计」数据 按群主聚合的方式
|
||||||
GetGroupChatStatURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/groupchat/statistic"
|
getGroupChatStatURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/groupchat/statistic"
|
||||||
// GetGroupChatStatByDayURL 获取「群聊数据统计」数据 按自然日聚合的方式
|
// getGroupChatStatByDayURL 获取「群聊数据统计」数据 按自然日聚合的方式
|
||||||
GetGroupChatStatByDayURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/groupchat/statistic_group_by_day"
|
getGroupChatStatByDayURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/groupchat/statistic_group_by_day"
|
||||||
)
|
)
|
||||||
|
|
||||||
type (
|
type (
|
||||||
@@ -54,7 +54,7 @@ func (r *Client) GetUserBehaviorData(req *GetUserBehaviorRequest) ([]BehaviorDat
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
response, err = util.HTTPPost(fmt.Sprintf("%s?access_token=%v", GetUserBehaviorDataURL, accessToken), string(jsonData))
|
response, err = util.HTTPPost(fmt.Sprintf("%s?access_token=%v", getUserBehaviorDataURL, accessToken), string(jsonData))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -120,7 +120,7 @@ func (r *Client) GetGroupChatStat(req *GetGroupChatStatRequest) (*GetGroupChatSt
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
response, err = util.HTTPPost(fmt.Sprintf("%s?access_token=%v", GetGroupChatStatURL, accessToken), string(jsonData))
|
response, err = util.HTTPPost(fmt.Sprintf("%s?access_token=%v", getGroupChatStatURL, accessToken), string(jsonData))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -163,7 +163,7 @@ func (r *Client) GetGroupChatStatByDay(req *GetGroupChatStatByDayRequest) ([]Get
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
response, err = util.HTTPPost(fmt.Sprintf("%s?access_token=%v", GetGroupChatStatByDayURL, accessToken), string(jsonData))
|
response, err = util.HTTPPost(fmt.Sprintf("%s?access_token=%v", getGroupChatStatByDayURL, accessToken), string(jsonData))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,16 +8,16 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// GetCropTagURL 获取标签列表
|
// getCropTagURL 获取标签列表
|
||||||
GetCropTagURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/get_corp_tag_list"
|
getCropTagURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/get_corp_tag_list"
|
||||||
// AddCropTagURL 添加标签
|
// addCropTagURL 添加标签
|
||||||
AddCropTagURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/add_corp_tag"
|
addCropTagURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/add_corp_tag"
|
||||||
// EditCropTagURL 修改标签
|
// editCropTagURL 修改标签
|
||||||
EditCropTagURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/edit_corp_tag"
|
editCropTagURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/edit_corp_tag"
|
||||||
// DelCropTagURL 删除标签
|
// delCropTagURL 删除标签
|
||||||
DelCropTagURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/del_corp_tag"
|
delCropTagURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/del_corp_tag"
|
||||||
// MarkCropTagURL 为客户打上、删除标签
|
// markCropTagURL 为客户打上、删除标签
|
||||||
MarkCropTagURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/mark_tag"
|
markCropTagURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/mark_tag"
|
||||||
)
|
)
|
||||||
|
|
||||||
// GetCropTagRequest 获取企业标签请求
|
// GetCropTagRequest 获取企业标签请求
|
||||||
@@ -63,7 +63,7 @@ func (r *Client) GetCropTagList(req GetCropTagRequest) ([]TagGroup, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
response, err = util.HTTPPost(fmt.Sprintf("%s?access_token=%v", GetCropTagURL, accessToken), string(jsonData))
|
response, err = util.HTTPPost(fmt.Sprintf("%s?access_token=%v", getCropTagURL, accessToken), string(jsonData))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -109,7 +109,7 @@ func (r *Client) AddCropTag(req AddCropTagRequest) (*TagGroup, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
response, err = util.HTTPPost(fmt.Sprintf("%s?access_token=%v", AddCropTagURL, accessToken), string(jsonData))
|
response, err = util.HTTPPost(fmt.Sprintf("%s?access_token=%v", addCropTagURL, accessToken), string(jsonData))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -141,7 +141,7 @@ func (r *Client) EditCropTag(req EditCropTagRequest) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
response, err = util.HTTPPost(fmt.Sprintf("%s?access_token=%v", EditCropTagURL, accessToken), string(jsonData))
|
response, err = util.HTTPPost(fmt.Sprintf("%s?access_token=%v", editCropTagURL, accessToken), string(jsonData))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -167,7 +167,7 @@ func (r *Client) DeleteCropTag(req DeleteCropTagRequest) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
response, err = util.HTTPPost(fmt.Sprintf("%s?access_token=%v", DelCropTagURL, accessToken), string(jsonData))
|
response, err = util.HTTPPost(fmt.Sprintf("%s?access_token=%v", delCropTagURL, accessToken), string(jsonData))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -195,7 +195,7 @@ func (r *Client) MarkTag(request MarkTagRequest) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
response, err = util.HTTPPost(fmt.Sprintf("%s?access_token=%v", MarkCropTagURL, accessToken), string(jsonData))
|
response, err = util.HTTPPost(fmt.Sprintf("%s?access_token=%v", markCropTagURL, accessToken), string(jsonData))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,11 +7,10 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// UploadImgURL 上传图片
|
// uploadImgURL 上传图片
|
||||||
UploadImgURL = "https://qyapi.weixin.qq.com/cgi-bin/media/uploadimg?access_token=%s"
|
uploadImgURL = "https://qyapi.weixin.qq.com/cgi-bin/media/uploadimg?access_token=%s"
|
||||||
|
// uploadTempFile 上传临时素材
|
||||||
// UploadTempFile 上传临时素材
|
uploadTempFile = "https://qyapi.weixin.qq.com/cgi-bin/media/upload?access_token=%s&type=%s"
|
||||||
UploadTempFile = "https://qyapi.weixin.qq.com/cgi-bin/media/upload?access_token=%s&type=%s"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// UploadImgResponse 上传图片响应
|
// UploadImgResponse 上传图片响应
|
||||||
@@ -39,7 +38,7 @@ func (r *Client) UploadImg(filename string) (*UploadImgResponse, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
var response []byte
|
var response []byte
|
||||||
if response, err = util.PostFile("media", filename, fmt.Sprintf(UploadImgURL, accessToken)); err != nil {
|
if response, err = util.PostFile("media", filename, fmt.Sprintf(uploadImgURL, accessToken)); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
result := &UploadImgResponse{}
|
result := &UploadImgResponse{}
|
||||||
@@ -61,7 +60,7 @@ func (r *Client) UploadTempFile(filename string, mediaType string) (*UploadTempF
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
var response []byte
|
var response []byte
|
||||||
if response, err = util.PostFile("media", filename, fmt.Sprintf(UploadTempFile, accessToken, mediaType)); err != nil {
|
if response, err = util.PostFile("media", filename, fmt.Sprintf(uploadTempFile, accessToken, mediaType)); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
result := &UploadTempFileResponse{}
|
result := &UploadTempFileResponse{}
|
||||||
|
|||||||
@@ -150,7 +150,7 @@ type TodoMessage struct {
|
|||||||
BaseMessage
|
BaseMessage
|
||||||
Todo struct {
|
Todo struct {
|
||||||
Title string `json:"title,omitempty"` // 代办的来源文本
|
Title string `json:"title,omitempty"` // 代办的来源文本
|
||||||
Content string `json:"content,omitempty"` // 代办的具体内容
|
Content string `json:"content,omitempty"` // 代办的具体内容
|
||||||
} `json:"todo,omitempty"`
|
} `json:"todo,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -266,10 +266,10 @@ type VoipDocShareMessage struct {
|
|||||||
type ExternalRedPacketMessage struct {
|
type ExternalRedPacketMessage struct {
|
||||||
BaseMessage
|
BaseMessage
|
||||||
RedPacket struct {
|
RedPacket struct {
|
||||||
Type int32 `json:"type,omitempty"` // 红包消息类型。1 普通红包、2 拼手气群红包。Uint32类型
|
Type uint32 `json:"type,omitempty"` // 红包消息类型。1 普通红包、2 拼手气群红包。Uint32类型
|
||||||
Wish int32 `json:"wish,omitempty"` // 红包祝福语。String类型
|
Wish string `json:"wish,omitempty"` // 红包祝福语。String类型
|
||||||
TotalCnt int32 `json:"totalcnt,omitempty"` // 红包总个数。Uint32类型
|
TotalCnt uint32 `json:"totalcnt,omitempty"` // 红包总个数。Uint32类型
|
||||||
TotalAmount int32 `json:"totalamount,omitempty"` // 红包消息类型。1 普通红包、2 拼手气群红包。Uint32类型
|
TotalAmount uint32 `json:"totalamount,omitempty"` // 红包总金额。Uint32类型,单位为分。
|
||||||
} `json:"redpacket,omitempty"`
|
} `json:"redpacket,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -277,9 +277,9 @@ type ExternalRedPacketMessage struct {
|
|||||||
type SphFeedMessage struct {
|
type SphFeedMessage struct {
|
||||||
BaseMessage
|
BaseMessage
|
||||||
SphFeed struct {
|
SphFeed struct {
|
||||||
FeedType string `json:"feed_type,omitempty"` // 视频号消息类型
|
FeedType uint32 `json:"feed_type,omitempty"` // 视频号消息类型。2 图片、4 视频、9 直播。Uint32类型
|
||||||
SphName string `json:"sph_name,omitempty"` // 视频号账号名称
|
SphName string `json:"sph_name,omitempty"` // 视频号账号名称。String类型
|
||||||
FeedDesc uint64 `json:"feed_desc,omitempty"` // 视频号账号名称
|
FeedDesc string `json:"feed_desc,omitempty"` // 视频号消息描述。String类型
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,15 +8,15 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// WebhookSendURL 机器人发送群组消息
|
// webhookSendURL 机器人发送群组消息
|
||||||
WebhookSendURL = "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=%s"
|
webhookSendURL = "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=%s"
|
||||||
)
|
)
|
||||||
|
|
||||||
// RobotBroadcast 群机器人消息发送
|
// RobotBroadcast 群机器人消息发送
|
||||||
// @see https://developer.work.weixin.qq.com/document/path/91770
|
// @see https://developer.work.weixin.qq.com/document/path/91770
|
||||||
func (r *Client) RobotBroadcast(webhookKey string, options interface{}) (info util.CommonError, err error) {
|
func (r *Client) RobotBroadcast(webhookKey string, options interface{}) (info util.CommonError, err error) {
|
||||||
var data []byte
|
var data []byte
|
||||||
if data, err = util.PostJSON(fmt.Sprintf(WebhookSendURL, webhookKey), options); err != nil {
|
if data, err = util.PostJSON(fmt.Sprintf(webhookSendURL, webhookKey), options); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if err = json.Unmarshal(data, &info); err != nil {
|
if err = json.Unmarshal(data, &info); err != nil {
|
||||||
|
|||||||
Reference in New Issue
Block a user