增加vendor

This commit is contained in:
hoteas
2022-05-24 13:49:25 +08:00
parent 77753a123f
commit b638d8bd65
742 changed files with 509206 additions and 0 deletions
+87
View 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 为老账号的openIDopenIDs限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
}
+241
View File
@@ -0,0 +1,241 @@
package user
import (
"encoding/json"
"fmt"
"github.com/silenceper/wechat/v2/util"
)
const (
tagCreateURL = "https://api.weixin.qq.com/cgi-bin/tags/create?access_token=%s"
tagGetURL = "https://api.weixin.qq.com/cgi-bin/tags/get?access_token=%s"
tagUpdateURL = "https://api.weixin.qq.com/cgi-bin/tags/update?access_token=%s"
tagDeleteURL = "https://api.weixin.qq.com/cgi-bin/tags/delete?access_token=%s"
tagUserListURL = "https://api.weixin.qq.com/cgi-bin/user/tag/get?access_token=%s"
tagBatchtaggingURL = "https://api.weixin.qq.com/cgi-bin/tags/members/batchtagging?access_token=%s"
tagBatchuntaggingURL = "https://api.weixin.qq.com/cgi-bin/tags/members/batchuntagging?access_token=%s"
tagUserTidListURL = "https://api.weixin.qq.com/cgi-bin/tags/getidlist?access_token=%s"
)
// TagInfo 标签信息
type TagInfo struct {
ID int32 `json:"id"`
Name string `json:"name"`
Count int64 `json:"count"`
}
// TagOpenIDList 标签用户列表
type TagOpenIDList struct {
Count int `json:"count"`
Data struct {
OpenIDs []string `json:"openid"`
} `json:"data"`
NextOpenID string `json:"next_openid"`
}
// CreateTag 创建标签
func (user *User) CreateTag(tagName string) (tagInfo *TagInfo, err error) {
var accessToken string
accessToken, err = user.GetAccessToken()
if err != nil {
return
}
uri := fmt.Sprintf(tagCreateURL, accessToken)
var response []byte
var request struct {
Tag struct {
Name string `json:"name"`
} `json:"tag"`
}
request.Tag.Name = tagName
response, err = util.PostJSON(uri, &request)
if err != nil {
return
}
var result struct {
util.CommonError
Tag *TagInfo `json:"tag"`
}
err = json.Unmarshal(response, &result)
if err != nil {
return
}
if result.ErrCode != 0 {
err = fmt.Errorf("CreateTag Error , errcode=%d , errmsg=%s", result.ErrCode, result.ErrMsg)
return
}
return result.Tag, nil
}
// DeleteTag 删除标签
func (user *User) DeleteTag(tagID int32) (err error) {
accessToken, err := user.GetAccessToken()
if err != nil {
return
}
url := fmt.Sprintf(tagDeleteURL, accessToken)
var request struct {
Tag struct {
ID int32 `json:"id"`
} `json:"tag"`
}
request.Tag.ID = tagID
resp, err := util.PostJSON(url, &request)
if err != nil {
return
}
return util.DecodeWithCommonError(resp, "DeleteTag")
}
// UpdateTag 编辑标签
func (user *User) UpdateTag(tagID int32, tagName string) (err error) {
accessToken, err := user.GetAccessToken()
if err != nil {
return
}
url := fmt.Sprintf(tagUpdateURL, accessToken)
var request struct {
Tag struct {
ID int32 `json:"id"`
Name string `json:"name"`
} `json:"tag"`
}
request.Tag.ID = tagID
request.Tag.Name = tagName
resp, err := util.PostJSON(url, &request)
if err != nil {
return
}
return util.DecodeWithCommonError(resp, "UpdateTag")
}
// GetTag 获取公众号已创建的标签
func (user *User) GetTag() (tags []*TagInfo, err error) {
accessToken, err := user.GetAccessToken()
if err != nil {
return nil, err
}
url := fmt.Sprintf(tagGetURL, accessToken)
response, err := util.HTTPGet(url)
if err != nil {
return
}
var result struct {
util.CommonError
Tags []*TagInfo `json:"tags"`
}
err = json.Unmarshal(response, &result)
if err != nil {
return
}
return result.Tags, nil
}
// OpenIDListByTag 获取标签下粉丝列表
func (user *User) OpenIDListByTag(tagID int32, nextOpenID ...string) (userList *TagOpenIDList, err error) {
accessToken, err := user.GetAccessToken()
if err != nil {
return nil, err
}
url := fmt.Sprintf(tagUserListURL, accessToken)
var request = struct {
ID int32 `json:"tagid"`
OpenID string `json:"next_openid"`
}{
ID: tagID,
}
if len(nextOpenID) > 0 {
request.OpenID = nextOpenID[0]
}
response, err := util.PostJSON(url, &request)
if err != nil {
return nil, err
}
userList = new(TagOpenIDList)
err = json.Unmarshal(response, &userList)
if err != nil {
return
}
return
}
// BatchTag 批量为用户打标签
func (user *User) BatchTag(openIDList []string, tagID int32) (err error) {
accessToken, err := user.GetAccessToken()
if err != nil {
return
}
if len(openIDList) == 0 {
return
}
var request = struct {
OpenIDList []string `json:"openid_list"`
TagID int32 `json:"tagid"`
}{
OpenIDList: openIDList,
TagID: tagID,
}
url := fmt.Sprintf(tagBatchtaggingURL, accessToken)
resp, err := util.PostJSON(url, &request)
if err != nil {
return
}
return util.DecodeWithCommonError(resp, "BatchTag")
}
// BatchUntag 批量为用户取消标签
func (user *User) BatchUntag(openIDList []string, tagID int32) (err error) {
if len(openIDList) == 0 {
return
}
accessToken, err := user.GetAccessToken()
if err != nil {
return
}
url := fmt.Sprintf(tagBatchuntaggingURL, accessToken)
var request = struct {
OpenIDList []string `json:"openid_list"`
TagID int32 `json:"tagid"`
}{
OpenIDList: openIDList,
TagID: tagID,
}
resp, err := util.PostJSON(url, &request)
if err != nil {
return
}
return util.DecodeWithCommonError(resp, "BatchUntag")
}
// UserTidList 获取用户身上的标签列表
func (user *User) UserTidList(openID string) (tagIDList []int32, err error) {
accessToken, err := user.GetAccessToken()
if err != nil {
return
}
url := fmt.Sprintf(tagUserTidListURL, accessToken)
var request = struct {
OpenID string `json:"openid"`
TagID int32 `json:"tagid"`
}{
OpenID: openID,
}
resp, err := util.PostJSON(url, &request)
if err != nil {
return
}
var result struct {
util.CommonError
TagIDList []int32 `json:"tagid_list"`
}
err = json.Unmarshal(resp, &result)
if err != nil {
return
}
if result.ErrCode != 0 {
err = fmt.Errorf("UserTidList Error , errcode=%d , errmsg=%s", result.ErrCode, result.ErrMsg)
return
}
return result.TagIDList, nil
}
+157
View File
@@ -0,0 +1,157 @@
package user
import (
"encoding/json"
"fmt"
"net/url"
"github.com/silenceper/wechat/v2/officialaccount/context"
"github.com/silenceper/wechat/v2/util"
)
const (
userInfoURL = "https://api.weixin.qq.com/cgi-bin/user/info?access_token=%s&openid=%s&lang=zh_CN"
updateRemarkURL = "https://api.weixin.qq.com/cgi-bin/user/info/updateremark?access_token=%s"
userListURL = "https://api.weixin.qq.com/cgi-bin/user/get"
)
// User 用户管理
type User struct {
*context.Context
}
// NewUser 实例化
func NewUser(context *context.Context) *User {
user := new(User)
user.Context = context
return user
}
// Info 用户基本信息
type Info struct {
util.CommonError
Subscribe int32 `json:"subscribe"`
OpenID string `json:"openid"`
Nickname string `json:"nickname"`
Sex int32 `json:"sex"`
City string `json:"city"`
Country string `json:"country"`
Province string `json:"province"`
Language string `json:"language"`
Headimgurl string `json:"headimgurl"`
SubscribeTime int32 `json:"subscribe_time"`
UnionID string `json:"unionid"`
Remark string `json:"remark"`
GroupID int32 `json:"groupid"`
TagIDList []int32 `json:"tagid_list"`
SubscribeScene string `json:"subscribe_scene"`
QrScene int `json:"qr_scene"`
QrSceneStr string `json:"qr_scene_str"`
}
// OpenidList 用户列表
type OpenidList struct {
util.CommonError
Total int `json:"total"`
Count int `json:"count"`
Data struct {
OpenIDs []string `json:"openid"`
} `json:"data"`
NextOpenID string `json:"next_openid"`
}
// GetUserInfo 获取用户基本信息
func (user *User) GetUserInfo(openID string) (userInfo *Info, err error) {
var accessToken string
accessToken, err = user.GetAccessToken()
if err != nil {
return
}
uri := fmt.Sprintf(userInfoURL, accessToken, openID)
var response []byte
response, err = util.HTTPGet(uri)
if err != nil {
return
}
userInfo = new(Info)
err = json.Unmarshal(response, userInfo)
if err != nil {
return
}
if userInfo.ErrCode != 0 {
err = fmt.Errorf("GetUserInfo Error , errcode=%d , errmsg=%s", userInfo.ErrCode, userInfo.ErrMsg)
return
}
return
}
// UpdateRemark 设置用户备注名
func (user *User) UpdateRemark(openID, remark string) (err error) {
var accessToken string
accessToken, err = user.GetAccessToken()
if err != nil {
return
}
uri := fmt.Sprintf(updateRemarkURL, accessToken)
var response []byte
response, err = util.PostJSON(uri, map[string]string{"openid": openID, "remark": remark})
if err != nil {
return
}
return util.DecodeWithCommonError(response, "UpdateRemark")
}
// ListUserOpenIDs 返回用户列表
func (user *User) ListUserOpenIDs(nextOpenid ...string) (*OpenidList, error) {
accessToken, err := user.GetAccessToken()
if err != nil {
return nil, err
}
uri, _ := url.Parse(userListURL)
q := uri.Query()
q.Set("access_token", accessToken)
if len(nextOpenid) > 0 && nextOpenid[0] != "" {
q.Set("next_openid", nextOpenid[0])
}
uri.RawQuery = q.Encode()
response, err := util.HTTPGet(uri.String())
if err != nil {
return nil, err
}
userlist := OpenidList{}
err = util.DecodeWithError(response, &userlist, "ListUserOpenIDs")
if err != nil {
return nil, err
}
return &userlist, nil
}
// ListAllUserOpenIDs 返回所有用户OpenID列表
func (user *User) ListAllUserOpenIDs() ([]string, error) {
nextOpenid := ""
openids := make([]string, 0)
count := 0
for {
ul, err := user.ListUserOpenIDs(nextOpenid)
if err != nil {
return nil, err
}
openids = append(openids, ul.Data.OpenIDs...)
count += ul.Count
if ul.Total > count {
nextOpenid = ul.NextOpenID
} else {
return openids, nil
}
}
}