diff --git a/officialaccount/user/tag.go b/officialaccount/user/tag.go new file mode 100644 index 0000000..7e2b348 --- /dev/null +++ b/officialaccount/user/tag.go @@ -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 +}