mirror of
https://github.com/silenceper/wechat.git
synced 2026-02-08 14:42:26 +08:00
Compare commits
3 Commits
v2.0.5-rc.
...
v2.0.5
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e7fdcf9534 | ||
|
|
05907d152e | ||
|
|
398f2ec6ae |
52
officialaccount/basic/short_url.go
Normal file
52
officialaccount/basic/short_url.go
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
package basic
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/silenceper/wechat/v2/util"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// 将一条长链接转成短链接
|
||||||
|
// https://developers.weixin.qq.com/doc/offiaccount/Account_Management/URL_Shortener.html
|
||||||
|
long2shortURL = "https://api.weixin.qq.com/cgi-bin/shorturl?access_token=%s"
|
||||||
|
long2shortAction = "long2short"
|
||||||
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
reqLong2ShortURL struct {
|
||||||
|
Action string `json:"action"`
|
||||||
|
LongURL string `json:"long_url"`
|
||||||
|
}
|
||||||
|
resplong2ShortURL struct {
|
||||||
|
ShortURL string `json:"short_url"`
|
||||||
|
util.CommonError
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
// Long2ShortURL 将一条长链接转成短链接
|
||||||
|
func (basic *Basic) Long2ShortURL(longURL string) (shortURL string, err error) {
|
||||||
|
var (
|
||||||
|
req = &reqLong2ShortURL{
|
||||||
|
Action: long2shortAction,
|
||||||
|
LongURL: longURL,
|
||||||
|
}
|
||||||
|
resp = new(resplong2ShortURL)
|
||||||
|
ac, uri string
|
||||||
|
responseBytes []byte
|
||||||
|
)
|
||||||
|
ac, err = basic.GetAccessToken()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
uri = fmt.Sprintf(long2shortURL, ac)
|
||||||
|
responseBytes, err = util.PostJSON(uri, req)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err = util.DecodeWithError(responseBytes, resp, long2shortAction); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
shortURL = resp.ShortURL
|
||||||
|
return
|
||||||
|
}
|
||||||
@@ -225,3 +225,8 @@ func (msg *CommonToken) SetCreateTime(createTime int64) {
|
|||||||
func (msg *CommonToken) SetMsgType(msgType MsgType) {
|
func (msg *CommonToken) SetMsgType(msgType MsgType) {
|
||||||
msg.MsgType = msgType
|
msg.MsgType = msgType
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//GetOpenID get the FromUserName value
|
||||||
|
func (msg *CommonToken) GetOpenID() string {
|
||||||
|
return string(msg.FromUserName)
|
||||||
|
}
|
||||||
|
|||||||
87
officialaccount/user/migrate.go
Normal file
87
officialaccount/user/migrate.go
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
//Package user migrate 用于微信公众号账号迁移,获取openID变化
|
||||||
|
//参考文档:https://kf.qq.com/faq/1901177NrqMr190117nqYJze.html
|
||||||
|
package user
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/silenceper/wechat/v2/util"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
changeOpenIDURL = "https://api.weixin.qq.com/cgi-bin/changeopenid"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ChangeOpenIDResult OpenID迁移变化
|
||||||
|
type ChangeOpenIDResult struct {
|
||||||
|
OriOpenID string `json:"ori_openid"`
|
||||||
|
NewOpenID string `json:"new_openid"`
|
||||||
|
ErrMsg string `json:"err_msg,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ChangeOpenIDResultList OpenID迁移变化列表
|
||||||
|
type ChangeOpenIDResultList struct {
|
||||||
|
util.CommonError
|
||||||
|
List []ChangeOpenIDResult `json:"result_list"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListChangeOpenIDs 返回指定OpenID变化列表
|
||||||
|
// fromAppID 为老账号AppID
|
||||||
|
// openIDs 为老账号的openID,openIDs限100个以内
|
||||||
|
// AccessToken 为新账号的AccessToken
|
||||||
|
func (user *User) ListChangeOpenIDs(fromAppID string, openIDs ...string) (list *ChangeOpenIDResultList, err error) {
|
||||||
|
list = &ChangeOpenIDResultList{}
|
||||||
|
//list.List = make([]ChangeOpenIDResult, 0)
|
||||||
|
if len(openIDs) > 100 {
|
||||||
|
err = errors.New("openIDs length must be lt 100")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if fromAppID == "" {
|
||||||
|
err = errors.New("fromAppID is required")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
accessToken, err := user.GetAccessToken()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
uri := fmt.Sprintf("%s?access_token=%s", changeOpenIDURL, accessToken)
|
||||||
|
var resp []byte
|
||||||
|
var req struct {
|
||||||
|
FromAppID string `json:"from_appid"`
|
||||||
|
OpenidList []string `json:"openid_list"`
|
||||||
|
}
|
||||||
|
req.FromAppID = fromAppID
|
||||||
|
req.OpenidList = append(req.OpenidList, openIDs...)
|
||||||
|
resp, err = util.PostJSON(uri, req)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
err = util.DecodeWithError(resp, list, "ListChangeOpenIDs")
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListAllChangeOpenIDs 返回所有用户OpenID列表
|
||||||
|
// fromAppID 为老账号AppID
|
||||||
|
// openIDs 为老账号的openID
|
||||||
|
// AccessToken 为新账号的AccessToken
|
||||||
|
func (user *User) ListAllChangeOpenIDs(fromAppID string, openIDs ...string) (list []ChangeOpenIDResult, err error) {
|
||||||
|
list = make([]ChangeOpenIDResult, 0)
|
||||||
|
chunks := util.SliceChunk(openIDs, 100)
|
||||||
|
for _, chunk := range chunks {
|
||||||
|
result, err := user.ListChangeOpenIDs(fromAppID, chunk...)
|
||||||
|
if err != nil {
|
||||||
|
return list, err
|
||||||
|
}
|
||||||
|
list = append(list, result.List...)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
@@ -139,7 +139,7 @@ func (user *User) ListUserOpenIDs(nextOpenid ...string) (*OpenidList, error) {
|
|||||||
// ListAllUserOpenIDs 返回所有用户OpenID列表
|
// ListAllUserOpenIDs 返回所有用户OpenID列表
|
||||||
func (user *User) ListAllUserOpenIDs() ([]string, error) {
|
func (user *User) ListAllUserOpenIDs() ([]string, error) {
|
||||||
nextOpenid := ""
|
nextOpenid := ""
|
||||||
openids := []string{}
|
openids := make([]string, 0)
|
||||||
count := 0
|
count := 0
|
||||||
for {
|
for {
|
||||||
ul, err := user.ListUserOpenIDs(nextOpenid)
|
ul, err := user.ListUserOpenIDs(nextOpenid)
|
||||||
|
|||||||
41
util/util.go
Normal file
41
util/util.go
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
package util
|
||||||
|
|
||||||
|
//SliceChunk 用于将字符串切片分块
|
||||||
|
func SliceChunk(src []string, chunkSize int) (chunks [][]string) {
|
||||||
|
total := len(src)
|
||||||
|
chunks = make([][]string, 0)
|
||||||
|
if chunkSize < 1 {
|
||||||
|
chunkSize = 1
|
||||||
|
}
|
||||||
|
if total == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
chunkNum := total / chunkSize
|
||||||
|
if total%chunkSize != 0 {
|
||||||
|
chunkNum++
|
||||||
|
}
|
||||||
|
|
||||||
|
chunks = make([][]string, chunkNum)
|
||||||
|
|
||||||
|
for i := 0; i < chunkNum; i++ {
|
||||||
|
for j := 0; j < chunkSize; j++ {
|
||||||
|
offset := i*chunkSize + j
|
||||||
|
if offset >= total {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if chunks[i] == nil {
|
||||||
|
actualChunkSize := chunkSize
|
||||||
|
if i == chunkNum-1 && total%chunkSize != 0 {
|
||||||
|
actualChunkSize = total % chunkSize
|
||||||
|
}
|
||||||
|
chunks[i] = make([]string, actualChunkSize)
|
||||||
|
}
|
||||||
|
|
||||||
|
chunks[i][j] = src[offset]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
18
util/util_test.go
Normal file
18
util/util_test.go
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
package util
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestSliceChunk(t *testing.T) {
|
||||||
|
src1 := []string{"1", "2", "3", "4", "5"}
|
||||||
|
assert.Equal(t, [][]string{{"1", "2"}, {"3", "4"}, {"5"}}, SliceChunk(src1, 2))
|
||||||
|
assert.Equal(t, [][]string{{"1", "2", "3", "4", "5"}}, SliceChunk(src1, 5))
|
||||||
|
assert.Equal(t, [][]string{{"1", "2", "3", "4", "5"}}, SliceChunk(src1, 6))
|
||||||
|
assert.Equal(t, [][]string{{"1"}, {"2"}, {"3"}, {"4"}, {"5"}}, SliceChunk(src1, 1))
|
||||||
|
assert.Equal(t, [][]string{{"1"}, {"2"}, {"3"}, {"4"}, {"5"}}, SliceChunk(src1, 0))
|
||||||
|
assert.Equal(t, [][]string{{"1"}, {"2"}, {"3"}, {"4"}, {"5"}}, SliceChunk(src1, -100))
|
||||||
|
assert.Equal(t, [][]string{}, SliceChunk(nil, 5))
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user