mirror of
https://github.com/silenceper/wechat.git
synced 2026-02-08 22:52:27 +08:00
Merge branch 'release-2.0' of github.com:hb1707/wechat into release-2.0
# Conflicts: # work/externalcontact/client.go # work/oauth/oauth.go # work/work.go
This commit is contained in:
3
work/externalcontact/README.md
Normal file
3
work/externalcontact/README.md
Normal file
@@ -0,0 +1,3 @@
|
||||
### 企业微信 客户联系部分
|
||||
|
||||
相关文档正在梳理中...
|
||||
45
work/externalcontact/callback.go
Normal file
45
work/externalcontact/callback.go
Normal file
@@ -0,0 +1,45 @@
|
||||
package externalcontact
|
||||
|
||||
import (
|
||||
"encoding/xml"
|
||||
|
||||
"github.com/silenceper/wechat/v2/util"
|
||||
)
|
||||
|
||||
// 原始回调消息内容
|
||||
type callbackOriginMessage struct {
|
||||
ToUserName string // 企业微信的CorpID,当为第三方套件回调事件时,CorpID的内容为suiteid
|
||||
AgentID string // 接收的应用id,可在应用的设置页面获取
|
||||
Encrypt string // 消息结构体加密后的字符串
|
||||
}
|
||||
|
||||
// EventCallbackMessage 微信客户联系回调消息
|
||||
// https://developer.work.weixin.qq.com/document/path/92130
|
||||
type EventCallbackMessage struct {
|
||||
ToUserName string `json:"to_user_name"`
|
||||
FromUserName string `json:"from_user_name"`
|
||||
CreateTime int64 `json:"create_time"`
|
||||
MsgType string `json:"msg_type"`
|
||||
Event string `json:"event"`
|
||||
ChangeType string `json:"change_type"`
|
||||
UserID string `json:"user_id"`
|
||||
ExternalUserID string `json:"external_user_id"`
|
||||
State string `json:"state"`
|
||||
WelcomeCode string `json:"welcome_code"`
|
||||
}
|
||||
|
||||
// GetCallbackMessage 获取联系客户回调事件中的消息内容
|
||||
func (r *Client) GetCallbackMessage(encryptedMsg []byte) (msg EventCallbackMessage, err error) {
|
||||
var origin callbackOriginMessage
|
||||
if err = xml.Unmarshal(encryptedMsg, &origin); err != nil {
|
||||
return
|
||||
}
|
||||
_, bData, err := util.DecryptMsg(r.CorpID, origin.Encrypt, r.EncodingAESKey)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if err = xml.Unmarshal(bData, &msg); err != nil {
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
275
work/externalcontact/contact_way.go
Normal file
275
work/externalcontact/contact_way.go
Normal file
@@ -0,0 +1,275 @@
|
||||
package externalcontact
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/silenceper/wechat/v2/util"
|
||||
)
|
||||
|
||||
const (
|
||||
// AddContactWayURL 配置客户联系「联系我」方式
|
||||
AddContactWayURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/add_contact_way?access_token=%s"
|
||||
// GetContactWayURL 获取企业已配置的「联系我」方式
|
||||
GetContactWayURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/get_contact_way?access_token=%s"
|
||||
// UpdateContactWayURL 更新企业已配置的「联系我」方式
|
||||
UpdateContactWayURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/update_contact_way?access_token=%s"
|
||||
// ListContactWayURL 获取企业已配置的「联系我」列表
|
||||
ListContactWayURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/list_contact_way?access_token=%s"
|
||||
// DelContactWayURL 删除企业已配置的「联系我」方式
|
||||
DelContactWayURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/del_contact_way?access_token=%s"
|
||||
)
|
||||
|
||||
type (
|
||||
// ConclusionsRequest 结束语请求
|
||||
ConclusionsRequest struct {
|
||||
Text ConclusionsText `json:"text"`
|
||||
Image ConclusionsImageRequest `json:"image"`
|
||||
Link ConclusionsLink `json:"link"`
|
||||
MiniProgram ConclusionsMiniProgram `json:"miniprogram"`
|
||||
}
|
||||
// ConclusionsText 文本格式结束语
|
||||
ConclusionsText struct {
|
||||
Content string `json:"content"`
|
||||
}
|
||||
// ConclusionsImageRequest 图片格式结束语请求
|
||||
ConclusionsImageRequest struct {
|
||||
MediaID string `json:"media_id"`
|
||||
}
|
||||
// ConclusionsLink 链接格式结束语
|
||||
ConclusionsLink struct {
|
||||
Title string `json:"title"`
|
||||
PicURL string `json:"picurl"`
|
||||
Desc string `json:"desc"`
|
||||
URL string `json:"url"`
|
||||
}
|
||||
// ConclusionsMiniProgram 小程序格式结束语
|
||||
ConclusionsMiniProgram struct {
|
||||
Title string `json:"title"`
|
||||
PicMediaID string `json:"pic_media_id"`
|
||||
AppID string `json:"appid"`
|
||||
Page string `json:"page"`
|
||||
}
|
||||
// ConclusionsResponse 结束语响应
|
||||
ConclusionsResponse struct {
|
||||
Text ConclusionsText `json:"text"`
|
||||
Image ConclusionsImageResponse `json:"image"`
|
||||
Link ConclusionsLink `json:"link"`
|
||||
MiniProgram ConclusionsMiniProgram `json:"miniprogram"`
|
||||
}
|
||||
// ConclusionsImageResponse 图片格式结束语响应
|
||||
ConclusionsImageResponse struct {
|
||||
PicURL string `json:"pic_url"`
|
||||
}
|
||||
)
|
||||
|
||||
type (
|
||||
// AddContactWayRequest 配置客户联系「联系我」方式请求
|
||||
AddContactWayRequest struct {
|
||||
Type int `json:"type"`
|
||||
Scene int `json:"scene"`
|
||||
Style int `json:"style"`
|
||||
Remark string `json:"remark"`
|
||||
SkipVerify bool `json:"skip_verify"`
|
||||
State string `json:"state"`
|
||||
User []string `json:"user"`
|
||||
Party []int `json:"party"`
|
||||
IsTemp bool `json:"is_temp"`
|
||||
ExpiresIn int `json:"expires_in"`
|
||||
ChatExpiresIn int `json:"chat_expires_in"`
|
||||
UnionID string `json:"unionid"`
|
||||
Conclusions ConclusionsRequest `json:"conclusions"`
|
||||
}
|
||||
// AddContactWayResponse 配置客户联系「联系我」方式响应
|
||||
AddContactWayResponse struct {
|
||||
util.CommonError
|
||||
ConfigID string `json:"config_id"`
|
||||
QrCode string `json:"qr_code"`
|
||||
}
|
||||
)
|
||||
|
||||
// AddContactWay 配置客户联系「联系我」方式
|
||||
// see https://developer.work.weixin.qq.com/document/path/92228
|
||||
func (r *Client) AddContactWay(req *AddContactWayRequest) (*AddContactWayResponse, error) {
|
||||
var (
|
||||
accessToken string
|
||||
err error
|
||||
)
|
||||
if accessToken, err = r.GetAccessToken(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var response []byte
|
||||
if response, err = util.PostJSON(fmt.Sprintf(AddContactWayURL, accessToken), req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := &AddContactWayResponse{}
|
||||
if err = util.DecodeWithError(response, result, "AddContactWay"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
type (
|
||||
// GetContactWayRequest 获取企业已配置的「联系我」方式请求
|
||||
GetContactWayRequest struct {
|
||||
ConfigID string `json:"config_id"`
|
||||
}
|
||||
// GetContactWayResponse 获取企业已配置的「联系我」方式响应
|
||||
GetContactWayResponse struct {
|
||||
util.CommonError
|
||||
ContactWay ContactWay `json:"contact_way"`
|
||||
}
|
||||
// ContactWay 「联系我」配置
|
||||
ContactWay struct {
|
||||
ConfigID string `json:"config_id"`
|
||||
Type int `json:"type"`
|
||||
Scene int `json:"scene"`
|
||||
Style int `json:"style"`
|
||||
Remark string `json:"remark"`
|
||||
SkipVerify bool `json:"skip_verify"`
|
||||
State string `json:"state"`
|
||||
QrCode string `json:"qr_code"`
|
||||
User []string `json:"user"`
|
||||
Party []int `json:"party"`
|
||||
IsTemp bool `json:"is_temp"`
|
||||
ExpiresIn int `json:"expires_in"`
|
||||
ChatExpiresIn int `json:"chat_expires_in"`
|
||||
UnionID string `json:"unionid"`
|
||||
Conclusions ConclusionsResponse `json:"conclusions"`
|
||||
}
|
||||
)
|
||||
|
||||
// GetContactWay 获取企业已配置的「联系我」方式
|
||||
// see https://developer.work.weixin.qq.com/document/path/92228
|
||||
func (r *Client) GetContactWay(req *GetContactWayRequest) (*GetContactWayResponse, error) {
|
||||
var (
|
||||
accessToken string
|
||||
err error
|
||||
)
|
||||
if accessToken, err = r.GetAccessToken(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var response []byte
|
||||
if response, err = util.PostJSON(fmt.Sprintf(GetContactWayURL, accessToken), req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := &GetContactWayResponse{}
|
||||
if err = util.DecodeWithError(response, result, "GetContactWay"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
type (
|
||||
// UpdateContactWayRequest 更新企业已配置的「联系我」方式请求
|
||||
UpdateContactWayRequest struct {
|
||||
ConfigID string `json:"config_id"`
|
||||
Remark string `json:"remark"`
|
||||
SkipVerify bool `json:"skip_verify"`
|
||||
Style int `json:"style"`
|
||||
State string `json:"state"`
|
||||
User []string `json:"user"`
|
||||
Party []int `json:"party"`
|
||||
ExpiresIn int `json:"expires_in"`
|
||||
ChatExpiresIn int `json:"chat_expires_in"`
|
||||
UnionID string `json:"unionid"`
|
||||
Conclusions ConclusionsRequest `json:"conclusions"`
|
||||
}
|
||||
// UpdateContactWayResponse 更新企业已配置的「联系我」方式响应
|
||||
UpdateContactWayResponse struct {
|
||||
util.CommonError
|
||||
}
|
||||
)
|
||||
|
||||
// UpdateContactWay 更新企业已配置的「联系我」方式
|
||||
// see https://developer.work.weixin.qq.com/document/path/92228
|
||||
func (r *Client) UpdateContactWay(req *UpdateContactWayRequest) (*UpdateContactWayResponse, error) {
|
||||
var (
|
||||
accessToken string
|
||||
err error
|
||||
)
|
||||
if accessToken, err = r.GetAccessToken(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var response []byte
|
||||
if response, err = util.PostJSON(fmt.Sprintf(UpdateContactWayURL, accessToken), req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := &UpdateContactWayResponse{}
|
||||
if err = util.DecodeWithError(response, result, "UpdateContactWay"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
type (
|
||||
//ListContactWayRequest 获取企业已配置的「联系我」列表请求
|
||||
ListContactWayRequest struct {
|
||||
StartTime int `json:"start_time"`
|
||||
EndTime int `json:"end_time"`
|
||||
Cursor string `json:"cursor"`
|
||||
Limit int `json:"limit"`
|
||||
}
|
||||
//ListContactWayResponse 获取企业已配置的「联系我」列表响应
|
||||
ListContactWayResponse struct {
|
||||
util.CommonError
|
||||
ContactWay []*ContactWayForList `json:"contact_way"`
|
||||
NextCursor string `json:"next_cursor"`
|
||||
}
|
||||
// ContactWayForList 「联系我」配置
|
||||
ContactWayForList struct {
|
||||
ConfigID string `json:"config_id"`
|
||||
}
|
||||
)
|
||||
|
||||
// ListContactWay 获取企业已配置的「联系我」列表
|
||||
// see https://developer.work.weixin.qq.com/document/path/92228
|
||||
func (r *Client) ListContactWay(req *ListContactWayRequest) (*ListContactWayResponse, error) {
|
||||
var (
|
||||
accessToken string
|
||||
err error
|
||||
)
|
||||
if accessToken, err = r.GetAccessToken(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var response []byte
|
||||
if response, err = util.PostJSON(fmt.Sprintf(ListContactWayURL, accessToken), req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := &ListContactWayResponse{}
|
||||
if err = util.DecodeWithError(response, result, "ListContactWay"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
type (
|
||||
// DelContactWayRequest 删除企业已配置的「联系我」方式请求
|
||||
DelContactWayRequest struct {
|
||||
ConfigID string `json:"config_id"`
|
||||
}
|
||||
// DelContactWayResponse 删除企业已配置的「联系我」方式响应
|
||||
DelContactWayResponse struct {
|
||||
util.CommonError
|
||||
}
|
||||
)
|
||||
|
||||
// DelContactWay 删除企业已配置的「联系我」方式
|
||||
// see https://developer.work.weixin.qq.com/document/path/92228
|
||||
func (r *Client) DelContactWay(req *DelContactWayRequest) (*DelContactWayResponse, error) {
|
||||
var (
|
||||
accessToken string
|
||||
err error
|
||||
)
|
||||
if accessToken, err = r.GetAccessToken(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var response []byte
|
||||
if response, err = util.PostJSON(fmt.Sprintf(DelContactWayURL, accessToken), req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := &DelContactWayResponse{}
|
||||
if err = util.DecodeWithError(response, result, "DelContactWay"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
220
work/externalcontact/external_user.go
Normal file
220
work/externalcontact/external_user.go
Normal file
@@ -0,0 +1,220 @@
|
||||
package externalcontact
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/silenceper/wechat/v2/util"
|
||||
)
|
||||
|
||||
const (
|
||||
// FetchExternalContactUserListURL 获取客户列表
|
||||
FetchExternalContactUserListURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/list"
|
||||
// FetchExternalContactUserDetailURL 获取客户详情
|
||||
FetchExternalContactUserDetailURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/get"
|
||||
// FetchBatchExternalContactUserDetailURL 批量获取客户详情
|
||||
FetchBatchExternalContactUserDetailURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/batch/get_by_user"
|
||||
// UpdateUserRemarkURL 更新客户备注信息
|
||||
UpdateUserRemarkURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/remark"
|
||||
)
|
||||
|
||||
// ExternalUserListResponse 外部联系人列表响应
|
||||
type ExternalUserListResponse struct {
|
||||
util.CommonError
|
||||
ExternalUserID []string `json:"external_userid"`
|
||||
}
|
||||
|
||||
// GetExternalUserList 获取客户列表
|
||||
// @see https://developer.work.weixin.qq.com/document/path/92113
|
||||
func (r *Client) GetExternalUserList(userID string) ([]string, error) {
|
||||
accessToken, err := r.GetAccessToken()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var response []byte
|
||||
response, err = util.HTTPGet(fmt.Sprintf("%s?access_token=%v&userid=%v", FetchExternalContactUserListURL, accessToken, userID))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var result ExternalUserListResponse
|
||||
err = util.DecodeWithError(response, &result, "GetExternalUserList")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result.ExternalUserID, nil
|
||||
}
|
||||
|
||||
// ExternalUserDetailResponse 外部联系人详情响应
|
||||
type ExternalUserDetailResponse struct {
|
||||
util.CommonError
|
||||
ExternalContact ExternalUser `json:"external_contact"`
|
||||
FollowUser []FollowUser `json:"follow_user"`
|
||||
NextCursor string `json:"next_cursor"`
|
||||
}
|
||||
|
||||
// ExternalUser 外部联系人
|
||||
type ExternalUser struct {
|
||||
ExternalUserID string `json:"external_userid"`
|
||||
Name string `json:"name"`
|
||||
Avatar string `json:"avatar"`
|
||||
Type int64 `json:"type"`
|
||||
Gender int64 `json:"gender"`
|
||||
UnionID string `json:"unionid"`
|
||||
Position string `json:"position"`
|
||||
CorpName string `json:"corp_name"`
|
||||
CorpFullName string `json:"corp_full_name"`
|
||||
ExternalProfile string `json:"external_profile"`
|
||||
}
|
||||
|
||||
// FollowUser 跟进用户(指企业内部用户)
|
||||
type FollowUser struct {
|
||||
UserID string `json:"userid"`
|
||||
Remark string `json:"remark"`
|
||||
Description string `json:"description"`
|
||||
CreateTime string `json:"create_time"`
|
||||
Tags []Tag `json:"tags"`
|
||||
RemarkCorpName string `json:"remark_corp_name"`
|
||||
RemarkMobiles []string `json:"remark_mobiles"`
|
||||
OperUserID string `json:"oper_userid"`
|
||||
AddWay int64 `json:"add_way"`
|
||||
WeChatChannels WechatChannel `json:"wechat_channels"`
|
||||
State string `json:"state"`
|
||||
}
|
||||
|
||||
// Tag 已绑定在外部联系人的标签
|
||||
type Tag struct {
|
||||
GroupName string `json:"group_name"`
|
||||
TagName string `json:"tag_name"`
|
||||
Type int64 `json:"type"`
|
||||
TagID string `json:"tag_id"`
|
||||
}
|
||||
|
||||
// WechatChannel 视频号添加的场景
|
||||
type WechatChannel struct {
|
||||
NickName string `json:"nickname"`
|
||||
Source string `json:"source"`
|
||||
}
|
||||
|
||||
// GetExternalUserDetail 获取外部联系人详情
|
||||
// @see https://developer.work.weixin.qq.com/document/path/92114
|
||||
func (r *Client) GetExternalUserDetail(externalUserID string, nextCursor ...string) (*ExternalUserDetailResponse, error) {
|
||||
accessToken, err := r.GetAccessToken()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var response []byte
|
||||
var cursor string
|
||||
if len(nextCursor) > 0 {
|
||||
cursor = nextCursor[0]
|
||||
}
|
||||
response, err = util.HTTPGet(fmt.Sprintf("%s?access_token=%v&external_userid=%v&cursor=%v", FetchExternalContactUserDetailURL, accessToken, externalUserID, cursor))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := &ExternalUserDetailResponse{}
|
||||
err = util.DecodeWithError(response, result, "get_external_user_detail")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// BatchGetExternalUserDetailsRequest 批量获取外部联系人详情请求
|
||||
type BatchGetExternalUserDetailsRequest struct {
|
||||
UserIDList []string `json:"userid_list"`
|
||||
Cursor string `json:"cursor"`
|
||||
}
|
||||
|
||||
// ExternalUserDetailListResponse 批量获取外部联系人详情响应
|
||||
type ExternalUserDetailListResponse struct {
|
||||
util.CommonError
|
||||
ExternalContactList []ExternalUserForBatch `json:"external_contact_list"`
|
||||
}
|
||||
|
||||
// ExternalUserForBatch 批量获取外部联系人客户列表
|
||||
type ExternalUserForBatch struct {
|
||||
ExternalContact ExternalContact `json:"external_contact"`
|
||||
FollowInfo FollowInfo `json:"follow_info"`
|
||||
}
|
||||
|
||||
// ExternalContact 批量获取外部联系人用户信息
|
||||
type ExternalContact struct {
|
||||
ExternalUserID string `json:"external_userid"`
|
||||
Name string `json:"name"`
|
||||
Position string `json:"position"`
|
||||
Avatar string `json:"avatar"`
|
||||
CorpName string `json:"corp_name"`
|
||||
CorpFullName string `json:"corp_full_name"`
|
||||
Type int64 `json:"type"`
|
||||
Gender int64 `json:"gender"`
|
||||
UnionID string `json:"unionid"`
|
||||
ExternalProfile string `json:"external_profile"`
|
||||
}
|
||||
|
||||
// FollowInfo 批量获取外部联系人跟进人信息
|
||||
type FollowInfo struct {
|
||||
UserID string `json:"userid"`
|
||||
Remark string `json:"remark"`
|
||||
Description string `json:"description"`
|
||||
CreateTime int `json:"create_time"`
|
||||
TagID []string `json:"tag_id"`
|
||||
RemarkCorpName string `json:"remark_corp_name"`
|
||||
RemarkMobiles []string `json:"remark_mobiles"`
|
||||
OperUserID string `json:"oper_userid"`
|
||||
AddWay int64 `json:"add_way"`
|
||||
WeChatChannels WechatChannel `json:"wechat_channels"`
|
||||
}
|
||||
|
||||
// BatchGetExternalUserDetails 批量获取外部联系人详情
|
||||
// @see https://developer.work.weixin.qq.com/document/path/92994
|
||||
func (r *Client) BatchGetExternalUserDetails(request BatchGetExternalUserDetailsRequest) ([]ExternalUserForBatch, error) {
|
||||
accessToken, err := r.GetAccessToken()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var response []byte
|
||||
jsonData, err := json.Marshal(request)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
response, err = util.HTTPPost(fmt.Sprintf("%s?access_token=%v", FetchBatchExternalContactUserDetailURL, accessToken), string(jsonData))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var result ExternalUserDetailListResponse
|
||||
err = util.DecodeWithError(response, &result, "BatchGetExternalUserDetails")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result.ExternalContactList, nil
|
||||
}
|
||||
|
||||
// UpdateUserRemarkRequest 修改客户备注信息请求体
|
||||
type UpdateUserRemarkRequest struct {
|
||||
UserID string `json:"userid"`
|
||||
ExternalUserID string `json:"external_userid"`
|
||||
Remark string `json:"remark"`
|
||||
Description string `json:"description"`
|
||||
RemarkCompany string `json:"remark_company"`
|
||||
RemarkMobiles []string `json:"remark_mobiles"`
|
||||
RemarkPicMediaID string `json:"remark_pic_mediaid"`
|
||||
}
|
||||
|
||||
// UpdateUserRemark 修改客户备注信息
|
||||
// @see https://developer.work.weixin.qq.com/document/path/92115
|
||||
func (r *Client) UpdateUserRemark(request UpdateUserRemarkRequest) error {
|
||||
accessToken, err := r.GetAccessToken()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var response []byte
|
||||
jsonData, err := json.Marshal(request)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
response, err = util.HTTPPost(fmt.Sprintf("%s?access_token=%v", UpdateUserRemarkURL, accessToken), string(jsonData))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return util.DecodeWithCommonError(response, "UpdateUserRemark")
|
||||
}
|
||||
38
work/externalcontact/follow_user.go
Normal file
38
work/externalcontact/follow_user.go
Normal file
@@ -0,0 +1,38 @@
|
||||
package externalcontact
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/silenceper/wechat/v2/util"
|
||||
)
|
||||
|
||||
const (
|
||||
// FetchFollowUserListURL 获取配置了客户联系功能的成员列表
|
||||
FetchFollowUserListURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/get_follow_user_list"
|
||||
)
|
||||
|
||||
// followerUserResponse 客户联系功能的成员列表响应
|
||||
type followerUserResponse struct {
|
||||
util.CommonError
|
||||
FollowUser []string `json:"follow_user"`
|
||||
}
|
||||
|
||||
// GetFollowUserList 获取配置了客户联系功能的成员列表
|
||||
// @see https://developer.work.weixin.qq.com/document/path/92571
|
||||
func (r *Client) GetFollowUserList() ([]string, error) {
|
||||
accessToken, err := r.GetAccessToken()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var response []byte
|
||||
response, err = util.HTTPGet(fmt.Sprintf("%s?access_token=%s", FetchFollowUserListURL, accessToken))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var result followerUserResponse
|
||||
err = util.DecodeWithError(response, &result, "GetFollowUserList")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result.FollowUser, nil
|
||||
}
|
||||
143
work/externalcontact/groupchat.go
Normal file
143
work/externalcontact/groupchat.go
Normal file
@@ -0,0 +1,143 @@
|
||||
package externalcontact
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/silenceper/wechat/v2/util"
|
||||
)
|
||||
|
||||
// OpengIDToChatIDURL 客户群opengid转换URL
|
||||
const OpengIDToChatIDURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/opengid_to_chatid"
|
||||
|
||||
type (
|
||||
//GroupChatListRequest 获取客户群列表的请求参数
|
||||
GroupChatListRequest struct {
|
||||
StatusFilter int `json:"status_filter"` // 非必填 客户群跟进状态过滤。0 - 所有列表(即不过滤) 1 - 离职待继承 2 - 离职继承中 3 - 离职继承完成
|
||||
OwnerFilter OwnerFilter `json:"owner_filter"` //非必填 群主过滤。如果不填,表示获取应用可见范围内全部群主的数据(但是不建议这么用,如果可见范围人数超过1000人,为了防止数据包过大,会报错 81017)
|
||||
Cursor string `json:"cursor"` //非必填 用于分页查询的游标,字符串类型,由上一次调用返回,首次调用不填
|
||||
Limit int `json:"limit"` //必填 分页,预期请求的数据量,取值范围 1 ~ 1000
|
||||
}
|
||||
|
||||
//GroupChatList 客户群列表
|
||||
GroupChatList struct {
|
||||
ChatID string `json:"chat_id"`
|
||||
Status int `json:"status"`
|
||||
}
|
||||
//GroupChatListResponse 获取客户群列表的返回值
|
||||
GroupChatListResponse struct {
|
||||
util.CommonError
|
||||
GroupChatList []GroupChatList `json:"group_chat_list"`
|
||||
NextCursor string `json:"next_cursor"` //游标
|
||||
}
|
||||
)
|
||||
|
||||
// GetGroupChatList 获取客户群列表
|
||||
// @see https://developer.work.weixin.qq.com/document/path/92120
|
||||
func (r *Client) GetGroupChatList(req *GroupChatListRequest) (*GroupChatListResponse, error) {
|
||||
accessToken, err := r.GetAccessToken()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var response []byte
|
||||
response, err = util.PostJSON(fmt.Sprintf("%s/list?access_token=%s", GroupChatURL, accessToken), req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := &GroupChatListResponse{}
|
||||
if err = util.DecodeWithError(response, result, "GetGroupChatList"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
type (
|
||||
//GroupChatDetailRequest 客户群详情 请求参数
|
||||
GroupChatDetailRequest struct {
|
||||
ChatID string `json:"chat_id"`
|
||||
NeedName int `json:"need_name"`
|
||||
}
|
||||
//Invitor 邀请者
|
||||
Invitor struct {
|
||||
UserID string `json:"userid"` //邀请者的userid
|
||||
}
|
||||
//GroupChatMember 群成员
|
||||
GroupChatMember struct {
|
||||
UserID string `json:"userid"` //群成员id
|
||||
Type int `json:"type"` //成员类型。 1 - 企业成员 2 - 外部联系人
|
||||
JoinTime int `json:"join_time"` //入群时间
|
||||
JoinScene int `json:"join_scene"` //入群方式 1 - 由群成员邀请入群(直接邀请入群) 2 - 由群成员邀请入群(通过邀请链接入群) 3 - 通过扫描群二维码入群
|
||||
Invitor Invitor `json:"invitor,omitempty"` //邀请者。目前仅当是由本企业内部成员邀请入群时会返回该值
|
||||
GroupNickname string `json:"group_nickname"` //在群里的昵称
|
||||
Name string `json:"name"` //名字。仅当 need_name = 1 时返回 如果是微信用户,则返回其在微信中设置的名字 如果是企业微信联系人,则返回其设置对外展示的别名或实名
|
||||
UnionID string `json:"unionid,omitempty"` //外部联系人在微信开放平台的唯一身份标识(微信unionid),通过此字段企业可将外部联系人与公众号/小程序用户关联起来。仅当群成员类型是微信用户(包括企业成员未添加好友),且企业绑定了微信开发者ID有此字段(查看绑定方法)。第三方不可获取,上游企业不可获取下游企业客户的unionid字段
|
||||
}
|
||||
//GroupChatAdmin 群管理员
|
||||
GroupChatAdmin struct {
|
||||
UserID string `json:"userid"` //群管理员userid
|
||||
}
|
||||
//GroupChat 客户群详情
|
||||
GroupChat struct {
|
||||
ChatID string `json:"chat_id"` //客户群ID
|
||||
Name string `json:"name"` //群名
|
||||
Owner string `json:"owner"` //群主ID
|
||||
CreateTime int `json:"create_time"` //群的创建时间
|
||||
Notice string `json:"notice"` //群公告
|
||||
MemberList []GroupChatMember `json:"member_list"` //群成员列表
|
||||
AdminList []GroupChatAdmin `json:"admin_list"` //群管理员列表
|
||||
}
|
||||
//GroupChatDetailResponse 客户群详情 返回值
|
||||
GroupChatDetailResponse struct {
|
||||
util.CommonError
|
||||
GroupChat GroupChat `json:"group_chat"` //客户群详情
|
||||
}
|
||||
)
|
||||
|
||||
// GetGroupChatDetail 获取客户群详情
|
||||
// @see https://developer.work.weixin.qq.com/document/path/92122
|
||||
func (r *Client) GetGroupChatDetail(req *GroupChatDetailRequest) (*GroupChatDetailResponse, error) {
|
||||
accessToken, err := r.GetAccessToken()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var response []byte
|
||||
response, err = util.PostJSON(fmt.Sprintf("%s/get?access_token=%s", GroupChatURL, accessToken), req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := &GroupChatDetailResponse{}
|
||||
if err = util.DecodeWithError(response, result, "GetGroupChatDetail"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
type (
|
||||
//OpengIDToChatIDRequest 客户群opengid转换 请求参数
|
||||
OpengIDToChatIDRequest struct {
|
||||
OpengID string `json:"opengid"`
|
||||
}
|
||||
//OpengIDToChatIDResponse 客户群opengid转换 返回值
|
||||
OpengIDToChatIDResponse struct {
|
||||
util.CommonError
|
||||
ChatID string `json:"chat_id"` //客户群ID
|
||||
}
|
||||
)
|
||||
|
||||
// OpengIDToChatID 客户群opengid转换
|
||||
// @see https://developer.work.weixin.qq.com/document/path/94828
|
||||
func (r *Client) OpengIDToChatID(req *OpengIDToChatIDRequest) (*OpengIDToChatIDResponse, error) {
|
||||
accessToken, err := r.GetAccessToken()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var response []byte
|
||||
response, err = util.PostJSON(fmt.Sprintf("%s?access_token=%s", OpengIDToChatIDURL, accessToken), req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := &OpengIDToChatIDResponse{}
|
||||
if err = util.DecodeWithError(response, result, "GetGroupChatDetail"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
146
work/externalcontact/join_way.go
Normal file
146
work/externalcontact/join_way.go
Normal file
@@ -0,0 +1,146 @@
|
||||
package externalcontact
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/silenceper/wechat/v2/util"
|
||||
)
|
||||
|
||||
// GroupChatURL 客户群
|
||||
const GroupChatURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/groupchat"
|
||||
|
||||
type (
|
||||
// AddJoinWayRequest 添加群配置请求参数
|
||||
AddJoinWayRequest struct {
|
||||
Scene int `json:"scene"` // 必填 1 - 群的小程序插件,2 - 群的二维码插件
|
||||
Remark string `json:"remark"` //非必填 联系方式的备注信息,用于助记,超过30个字符将被截断
|
||||
AutoCreateRoom int `json:"auto_create_room"` //非必填 当群满了后,是否自动新建群。0-否;1-是。 默认为1
|
||||
RoomBaseName string `json:"room_base_name"` //非必填 自动建群的群名前缀,当auto_create_room为1时有效。最长40个utf8字符
|
||||
RoomBaseID int `json:"room_base_id"` //非必填 自动建群的群起始序号,当auto_create_room为1时有效
|
||||
ChatIDList []string `json:"chat_id_list"` //必填 使用该配置的客户群ID列表,支持5个。见客户群ID获取方法
|
||||
State string `json:"state"` //非必填 企业自定义的state参数,用于区分不同的入群渠道。不超过30个UTF-8字符
|
||||
}
|
||||
|
||||
// AddJoinWayResponse 添加群配置返回值
|
||||
AddJoinWayResponse struct {
|
||||
util.CommonError
|
||||
ConfigID string `json:"config_id"`
|
||||
}
|
||||
)
|
||||
|
||||
// AddJoinWay 加入群聊
|
||||
// @see https://developer.work.weixin.qq.com/document/path/92229
|
||||
func (r *Client) AddJoinWay(req *AddJoinWayRequest) (*AddJoinWayResponse, error) {
|
||||
var (
|
||||
accessToken string
|
||||
err error
|
||||
response []byte
|
||||
)
|
||||
if accessToken, err = r.GetAccessToken(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
response, err = util.PostJSON(fmt.Sprintf("%s/add_join_way?access_token=%s", GroupChatURL, accessToken), req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := &AddJoinWayResponse{}
|
||||
if err = util.DecodeWithError(response, result, "AddJoinWay"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
type (
|
||||
//JoinWayConfigRequest 获取或删除群配置的请求参数
|
||||
JoinWayConfigRequest struct {
|
||||
ConfigID string `json:"config_id"`
|
||||
}
|
||||
|
||||
//JoinWay 群配置
|
||||
JoinWay struct {
|
||||
ConfigID string `json:"config_id"`
|
||||
Scene int `json:"scene"`
|
||||
Remark string `json:"remark"`
|
||||
AutoCreateRoom int `json:"auto_create_room"`
|
||||
RoomBaseName string `json:"room_base_name"`
|
||||
RoomBaseID int `json:"room_base_id"`
|
||||
ChatIDList []string `json:"chat_id_list"`
|
||||
QrCode string `json:"qr_code"`
|
||||
State string `json:"state"`
|
||||
}
|
||||
//GetJoinWayResponse 获取群配置的返回值
|
||||
GetJoinWayResponse struct {
|
||||
util.CommonError
|
||||
JoinWay JoinWay `json:"join_way"`
|
||||
}
|
||||
)
|
||||
|
||||
// GetJoinWay 获取客户群进群方式配置
|
||||
// @see https://developer.work.weixin.qq.com/document/path/92229
|
||||
func (r *Client) GetJoinWay(req *JoinWayConfigRequest) (*GetJoinWayResponse, error) {
|
||||
var (
|
||||
accessToken string
|
||||
err error
|
||||
response []byte
|
||||
)
|
||||
if accessToken, err = r.GetAccessToken(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
response, err = util.PostJSON(fmt.Sprintf("%s/get_join_way?access_token=%s", GroupChatURL, accessToken), req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := &GetJoinWayResponse{}
|
||||
if err = util.DecodeWithError(response, result, "GetJoinWay"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// UpdateJoinWayRequest 更新群配置的请求参数
|
||||
type UpdateJoinWayRequest struct {
|
||||
ConfigID string `json:"config_id"`
|
||||
Scene int `json:"scene"` // 必填 1 - 群的小程序插件,2 - 群的二维码插件
|
||||
Remark string `json:"remark"` //非必填 联系方式的备注信息,用于助记,超过30个字符将被截断
|
||||
AutoCreateRoom int `json:"auto_create_room"` //非必填 当群满了后,是否自动新建群。0-否;1-是。 默认为1
|
||||
RoomBaseName string `json:"room_base_name"` //非必填 自动建群的群名前缀,当auto_create_room为1时有效。最长40个utf8字符
|
||||
RoomBaseID int `json:"room_base_id"` //非必填 自动建群的群起始序号,当auto_create_room为1时有效
|
||||
ChatIDList []string `json:"chat_id_list"` //必填 使用该配置的客户群ID列表,支持5个。见客户群ID获取方法
|
||||
State string `json:"state"` //非必填 企业自定义的state参数,用于区分不同的入群渠道。不超过30个UTF-8字符
|
||||
}
|
||||
|
||||
// UpdateJoinWay 更新客户群进群方式配置
|
||||
// @see https://developer.work.weixin.qq.com/document/path/92229
|
||||
func (r *Client) UpdateJoinWay(req *UpdateJoinWayRequest) error {
|
||||
var (
|
||||
accessToken string
|
||||
err error
|
||||
response []byte
|
||||
)
|
||||
if accessToken, err = r.GetAccessToken(); err != nil {
|
||||
return err
|
||||
}
|
||||
response, err = util.PostJSON(fmt.Sprintf("%s/update_join_way?access_token=%s", GroupChatURL, accessToken), req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return util.DecodeWithCommonError(response, "UpdateJoinWay")
|
||||
}
|
||||
|
||||
// DelJoinWay 删除客户群进群方式配置
|
||||
// @see https://developer.work.weixin.qq.com/document/path/92229
|
||||
func (r *Client) DelJoinWay(req *JoinWayConfigRequest) error {
|
||||
var (
|
||||
accessToken string
|
||||
err error
|
||||
response []byte
|
||||
)
|
||||
if accessToken, err = r.GetAccessToken(); err != nil {
|
||||
return err
|
||||
}
|
||||
response, err = util.PostJSON(fmt.Sprintf("%s/del_join_way?access_token=%s", GroupChatURL, accessToken), req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return util.DecodeWithCommonError(response, "DelJoinWay")
|
||||
}
|
||||
424
work/externalcontact/msg.go
Normal file
424
work/externalcontact/msg.go
Normal file
@@ -0,0 +1,424 @@
|
||||
package externalcontact
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/silenceper/wechat/v2/util"
|
||||
)
|
||||
|
||||
const (
|
||||
// AddMsgTemplateURL 创建企业群发
|
||||
AddMsgTemplateURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/add_msg_template?access_token=%s"
|
||||
// GetGroupMsgListV2URL 获取群发记录列表
|
||||
GetGroupMsgListV2URL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/get_groupmsg_list_v2?access_token=%s"
|
||||
// GetGroupMsgTaskURL 获取群发成员发送任务列表
|
||||
GetGroupMsgTaskURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/get_groupmsg_task?access_token=%s"
|
||||
// GetGroupMsgSendResultURL 获取企业群发成员执行结果
|
||||
GetGroupMsgSendResultURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/get_groupmsg_send_result?access_token=%s"
|
||||
// SendWelcomeMsgURL 发送新客户欢迎语
|
||||
SendWelcomeMsgURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/send_welcome_msg?access_token=%s"
|
||||
// AddGroupWelcomeTemplateURL 添加入群欢迎语素材
|
||||
AddGroupWelcomeTemplateURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/group_welcome_template/add?access_token=%s"
|
||||
// EditGroupWelcomeTemplateURL 编辑入群欢迎语素材
|
||||
EditGroupWelcomeTemplateURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/group_welcome_template/edit?access_token=%s"
|
||||
// GetGroupWelcomeTemplateURL 获取入群欢迎语素材
|
||||
GetGroupWelcomeTemplateURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/group_welcome_template/get?access_token=%s"
|
||||
// DelGroupWelcomeTemplateURL 删除入群欢迎语素材
|
||||
DelGroupWelcomeTemplateURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/group_welcome_template/del?access_token=%s"
|
||||
)
|
||||
|
||||
// AddMsgTemplateRequest 创建企业群发请求
|
||||
type AddMsgTemplateRequest struct {
|
||||
ChatType string `json:"chat_type"`
|
||||
ExternalUserID []string `json:"external_userid"`
|
||||
Sender string `json:"sender,omitempty"`
|
||||
Text MsgText `json:"text"`
|
||||
Attachments []*Attachment `json:"attachments"`
|
||||
}
|
||||
|
||||
// MsgText 文本消息
|
||||
type MsgText struct {
|
||||
Content string `json:"content"`
|
||||
}
|
||||
|
||||
type (
|
||||
// Attachment 附件
|
||||
Attachment struct {
|
||||
MsgType string `json:"msgtype"`
|
||||
Image AttachmentImg `json:"image,omitempty"`
|
||||
Link AttachmentLink `json:"link,omitempty"`
|
||||
MiniProgram AttachmentMiniProgram `json:"miniprogram,omitempty"`
|
||||
Video AttachmentVideo `json:"video,omitempty"`
|
||||
File AttachmentFile `json:"file,omitempty"`
|
||||
}
|
||||
// AttachmentImg 图片消息
|
||||
AttachmentImg struct {
|
||||
MediaID string `json:"media_id"`
|
||||
PicURL string `json:"pic_url"`
|
||||
}
|
||||
// AttachmentLink 图文消息
|
||||
AttachmentLink struct {
|
||||
Title string `json:"title"`
|
||||
PicURL string `json:"picurl"`
|
||||
Desc string `json:"desc"`
|
||||
URL string `json:"url"`
|
||||
}
|
||||
// AttachmentMiniProgram 小程序消息
|
||||
AttachmentMiniProgram struct {
|
||||
Title string `json:"title"`
|
||||
PicMediaID string `json:"pic_media_id"`
|
||||
AppID string `json:"appid"`
|
||||
Page string `json:"page"`
|
||||
}
|
||||
// AttachmentVideo 视频消息
|
||||
AttachmentVideo struct {
|
||||
MediaID string `json:"media_id"`
|
||||
}
|
||||
// AttachmentFile 文件消息
|
||||
AttachmentFile struct {
|
||||
MediaID string `json:"media_id"`
|
||||
}
|
||||
)
|
||||
|
||||
// AddMsgTemplateResponse 创建企业群发响应
|
||||
type AddMsgTemplateResponse struct {
|
||||
util.CommonError
|
||||
FailList []string `json:"fail_list"`
|
||||
MsgID string `json:"msgid"`
|
||||
}
|
||||
|
||||
// AddMsgTemplate 创建企业群发
|
||||
// see https://developer.work.weixin.qq.com/document/path/92135
|
||||
func (r *Client) AddMsgTemplate(req *AddMsgTemplateRequest) (*AddMsgTemplateResponse, error) {
|
||||
var (
|
||||
accessToken string
|
||||
err error
|
||||
)
|
||||
if accessToken, err = r.GetAccessToken(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var response []byte
|
||||
if response, err = util.PostJSON(fmt.Sprintf(AddMsgTemplateURL, accessToken), req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := &AddMsgTemplateResponse{}
|
||||
if err = util.DecodeWithError(response, result, "AddMsgTemplate"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// GetGroupMsgListV2Request 获取群发记录列表请求
|
||||
type GetGroupMsgListV2Request struct {
|
||||
ChatType string `json:"chat_type"`
|
||||
StartTime int `json:"start_time"`
|
||||
EndTime int `json:"end_time"`
|
||||
Creator string `json:"creator,omitempty"`
|
||||
FilterType int `json:"filter_type"`
|
||||
Limit int `json:"limit"`
|
||||
Cursor string `json:"cursor"`
|
||||
}
|
||||
|
||||
// GetGroupMsgListV2Response 获取群发记录列表响应
|
||||
type GetGroupMsgListV2Response struct {
|
||||
util.CommonError
|
||||
NextCursor string `json:"next_cursor"`
|
||||
GroupMsgList []*GroupMsg `json:"group_msg_list"`
|
||||
}
|
||||
|
||||
// GroupMsg 群发消息
|
||||
type GroupMsg struct {
|
||||
MsgID string `json:"msgid"`
|
||||
Creator string `json:"creator"`
|
||||
CreateTime int `json:"create_time"`
|
||||
CreateType int `json:"create_type"`
|
||||
Text MsgText `json:"text"`
|
||||
Attachments []*Attachment `json:"attachments"`
|
||||
}
|
||||
|
||||
// GetGroupMsgListV2 获取群发记录列表
|
||||
// see https://developer.work.weixin.qq.com/document/path/93338#%E8%8E%B7%E5%8F%96%E7%BE%A4%E5%8F%91%E8%AE%B0%E5%BD%95%E5%88%97%E8%A1%A8
|
||||
func (r *Client) GetGroupMsgListV2(req *GetGroupMsgListV2Request) (*GetGroupMsgListV2Response, error) {
|
||||
var (
|
||||
accessToken string
|
||||
err error
|
||||
)
|
||||
if accessToken, err = r.GetAccessToken(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var response []byte
|
||||
if response, err = util.PostJSON(fmt.Sprintf(GetGroupMsgListV2URL, accessToken), req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := &GetGroupMsgListV2Response{}
|
||||
if err = util.DecodeWithError(response, result, "GetGroupMsgListV2"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// GetGroupMsgTaskRequest 获取群发成员发送任务列表请求
|
||||
type GetGroupMsgTaskRequest struct {
|
||||
MsgID string `json:"msgid"`
|
||||
Limit int `json:"limit"`
|
||||
Cursor string `json:"cursor"`
|
||||
}
|
||||
|
||||
// GetGroupMsgTaskResponse 获取群发成员发送任务列表响应
|
||||
type GetGroupMsgTaskResponse struct {
|
||||
util.CommonError
|
||||
NextCursor string `json:"next_cursor"`
|
||||
TaskList []*Task `json:"task_list"`
|
||||
}
|
||||
|
||||
// Task 获取群发成员发送任务列表任务
|
||||
type Task struct {
|
||||
UserID string `json:"userid"`
|
||||
Status int `json:"status"`
|
||||
SendTime int `json:"send_time"`
|
||||
}
|
||||
|
||||
// GetGroupMsgTask 获取群发成员发送任务列表
|
||||
// see https://developer.work.weixin.qq.com/document/path/93338#%E8%8E%B7%E5%8F%96%E7%BE%A4%E5%8F%91%E6%88%90%E5%91%98%E5%8F%91%E9%80%81%E4%BB%BB%E5%8A%A1%E5%88%97%E8%A1%A8
|
||||
func (r *Client) GetGroupMsgTask(req *GetGroupMsgTaskRequest) (*GetGroupMsgTaskResponse, error) {
|
||||
var (
|
||||
accessToken string
|
||||
err error
|
||||
)
|
||||
if accessToken, err = r.GetAccessToken(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var response []byte
|
||||
if response, err = util.PostJSON(fmt.Sprintf(GetGroupMsgTaskURL, accessToken), req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := &GetGroupMsgTaskResponse{}
|
||||
if err = util.DecodeWithError(response, result, "GetGroupMsgTask"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// GetGroupMsgSendResultRequest 获取企业群发成员执行结果请求
|
||||
type GetGroupMsgSendResultRequest struct {
|
||||
MsgID string `json:"msgid"`
|
||||
UserID string `json:"userid"`
|
||||
Limit int `json:"limit"`
|
||||
Cursor string `json:"cursor"`
|
||||
}
|
||||
|
||||
// GetGroupMsgSendResultResponse 获取企业群发成员执行结果响应
|
||||
type GetGroupMsgSendResultResponse struct {
|
||||
util.CommonError
|
||||
NextCursor string `json:"next_cursor"`
|
||||
SendList []*Send `json:"send_list"`
|
||||
}
|
||||
|
||||
// Send 企业群发成员执行结果
|
||||
type Send struct {
|
||||
ExternalUserID string `json:"external_userid"`
|
||||
ChatID string `json:"chat_id"`
|
||||
UserID string `json:"userid"`
|
||||
Status int `json:"status"`
|
||||
SendTime int `json:"send_time"`
|
||||
}
|
||||
|
||||
// GetGroupMsgSendResult 获取企业群发成员执行结果
|
||||
// see https://developer.work.weixin.qq.com/document/path/93338#%E8%8E%B7%E5%8F%96%E4%BC%81%E4%B8%9A%E7%BE%A4%E5%8F%91%E6%88%90%E5%91%98%E6%89%A7%E8%A1%8C%E7%BB%93%E6%9E%9C
|
||||
func (r *Client) GetGroupMsgSendResult(req *GetGroupMsgSendResultRequest) (*GetGroupMsgSendResultResponse, error) {
|
||||
var (
|
||||
accessToken string
|
||||
err error
|
||||
)
|
||||
if accessToken, err = r.GetAccessToken(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var response []byte
|
||||
if response, err = util.PostJSON(fmt.Sprintf(GetGroupMsgSendResultURL, accessToken), req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := &GetGroupMsgSendResultResponse{}
|
||||
if err = util.DecodeWithError(response, result, "GetGroupMsgSendResult"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// SendWelcomeMsgRequest 发送新客户欢迎语请求
|
||||
type SendWelcomeMsgRequest struct {
|
||||
WelcomeCode string `json:"welcome_code"`
|
||||
Text MsgText `json:"text"`
|
||||
Attachments []*Attachment `json:"attachments"`
|
||||
}
|
||||
|
||||
// SendWelcomeMsgResponse 发送新客户欢迎语响应
|
||||
type SendWelcomeMsgResponse struct {
|
||||
util.CommonError
|
||||
}
|
||||
|
||||
// SendWelcomeMsg 发送新客户欢迎语
|
||||
// see https://developer.work.weixin.qq.com/document/path/92137
|
||||
func (r *Client) SendWelcomeMsg(req *SendWelcomeMsgRequest) error {
|
||||
var (
|
||||
accessToken string
|
||||
err error
|
||||
)
|
||||
if accessToken, err = r.GetAccessToken(); err != nil {
|
||||
return err
|
||||
}
|
||||
var response []byte
|
||||
if response, err = util.PostJSON(fmt.Sprintf(SendWelcomeMsgURL, accessToken), req); err != nil {
|
||||
return err
|
||||
}
|
||||
result := &SendWelcomeMsgResponse{}
|
||||
if err = util.DecodeWithError(response, result, "SendWelcomeMsg"); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// AddGroupWelcomeTemplateRequest 添加入群欢迎语素材请求
|
||||
type AddGroupWelcomeTemplateRequest struct {
|
||||
Text MsgText `json:"text"`
|
||||
Image AttachmentImg `json:"image"`
|
||||
Link AttachmentLink `json:"link"`
|
||||
MiniProgram AttachmentMiniProgram `json:"miniprogram"`
|
||||
File AttachmentFile `json:"file"`
|
||||
Video AttachmentVideo `json:"video"`
|
||||
AgentID int `json:"agentid"`
|
||||
Notify int `json:"notify"`
|
||||
}
|
||||
|
||||
// AddGroupWelcomeTemplateResponse 添加入群欢迎语素材响应
|
||||
type AddGroupWelcomeTemplateResponse struct {
|
||||
util.CommonError
|
||||
TemplateID string `json:"template_id"`
|
||||
}
|
||||
|
||||
// AddGroupWelcomeTemplate 添加入群欢迎语素材
|
||||
// see https://developer.work.weixin.qq.com/document/path/92366#%E6%B7%BB%E5%8A%A0%E5%85%A5%E7%BE%A4%E6%AC%A2%E8%BF%8E%E8%AF%AD%E7%B4%A0%E6%9D%90
|
||||
func (r *Client) AddGroupWelcomeTemplate(req *AddGroupWelcomeTemplateRequest) (*AddGroupWelcomeTemplateResponse, error) {
|
||||
var (
|
||||
accessToken string
|
||||
err error
|
||||
)
|
||||
if accessToken, err = r.GetAccessToken(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var response []byte
|
||||
if response, err = util.PostJSON(fmt.Sprintf(AddGroupWelcomeTemplateURL, accessToken), req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := &AddGroupWelcomeTemplateResponse{}
|
||||
if err = util.DecodeWithError(response, result, "AddGroupWelcomeTemplate"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// EditGroupWelcomeTemplateRequest 编辑入群欢迎语素材请求
|
||||
type EditGroupWelcomeTemplateRequest struct {
|
||||
TemplateID string `json:"template_id"`
|
||||
Text MsgText `json:"text"`
|
||||
Image AttachmentImg `json:"image"`
|
||||
Link AttachmentLink `json:"link"`
|
||||
MiniProgram AttachmentMiniProgram `json:"miniprogram"`
|
||||
File AttachmentFile `json:"file"`
|
||||
Video AttachmentVideo `json:"video"`
|
||||
AgentID int `json:"agentid"`
|
||||
}
|
||||
|
||||
// EditGroupWelcomeTemplateResponse 编辑入群欢迎语素材响应
|
||||
type EditGroupWelcomeTemplateResponse struct {
|
||||
util.CommonError
|
||||
}
|
||||
|
||||
// EditGroupWelcomeTemplate 编辑入群欢迎语素材
|
||||
// see https://developer.work.weixin.qq.com/document/path/92366#%E7%BC%96%E8%BE%91%E5%85%A5%E7%BE%A4%E6%AC%A2%E8%BF%8E%E8%AF%AD%E7%B4%A0%E6%9D%90
|
||||
func (r *Client) EditGroupWelcomeTemplate(req *EditGroupWelcomeTemplateRequest) error {
|
||||
var (
|
||||
accessToken string
|
||||
err error
|
||||
)
|
||||
if accessToken, err = r.GetAccessToken(); err != nil {
|
||||
return err
|
||||
}
|
||||
var response []byte
|
||||
if response, err = util.PostJSON(fmt.Sprintf(EditGroupWelcomeTemplateURL, accessToken), req); err != nil {
|
||||
return err
|
||||
}
|
||||
result := &EditGroupWelcomeTemplateResponse{}
|
||||
if err = util.DecodeWithError(response, result, "EditGroupWelcomeTemplate"); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetGroupWelcomeTemplateRequest 获取入群欢迎语素材请求
|
||||
type GetGroupWelcomeTemplateRequest struct {
|
||||
TemplateID string `json:"template_id"`
|
||||
}
|
||||
|
||||
// GetGroupWelcomeTemplateResponse 获取入群欢迎语素材响应
|
||||
type GetGroupWelcomeTemplateResponse struct {
|
||||
util.CommonError
|
||||
Text MsgText `json:"text"`
|
||||
Image AttachmentImg `json:"image"`
|
||||
Link AttachmentLink `json:"link"`
|
||||
MiniProgram AttachmentMiniProgram `json:"miniprogram"`
|
||||
File AttachmentFile `json:"file"`
|
||||
Video AttachmentVideo `json:"video"`
|
||||
}
|
||||
|
||||
// GetGroupWelcomeTemplate 获取入群欢迎语素材
|
||||
// see https://developer.work.weixin.qq.com/document/path/92366#%E8%8E%B7%E5%8F%96%E5%85%A5%E7%BE%A4%E6%AC%A2%E8%BF%8E%E8%AF%AD%E7%B4%A0%E6%9D%90
|
||||
func (r *Client) GetGroupWelcomeTemplate(req *GetGroupWelcomeTemplateRequest) (*GetGroupWelcomeTemplateResponse, error) {
|
||||
var (
|
||||
accessToken string
|
||||
err error
|
||||
)
|
||||
if accessToken, err = r.GetAccessToken(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var response []byte
|
||||
if response, err = util.PostJSON(fmt.Sprintf(GetGroupWelcomeTemplateURL, accessToken), req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := &GetGroupWelcomeTemplateResponse{}
|
||||
if err = util.DecodeWithError(response, result, "GetGroupWelcomeTemplate"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// DelGroupWelcomeTemplateRequest 删除入群欢迎语素材请求
|
||||
type DelGroupWelcomeTemplateRequest struct {
|
||||
TemplateID string `json:"template_id"`
|
||||
AgentID int `json:"agentid"`
|
||||
}
|
||||
|
||||
// DelGroupWelcomeTemplateResponse 删除入群欢迎语素材响应
|
||||
type DelGroupWelcomeTemplateResponse struct {
|
||||
util.CommonError
|
||||
}
|
||||
|
||||
// DelGroupWelcomeTemplate 删除入群欢迎语素材
|
||||
// see https://developer.work.weixin.qq.com/document/path/92366#%E5%88%A0%E9%99%A4%E5%85%A5%E7%BE%A4%E6%AC%A2%E8%BF%8E%E8%AF%AD%E7%B4%A0%E6%9D%90
|
||||
func (r *Client) DelGroupWelcomeTemplate(req *DelGroupWelcomeTemplateRequest) error {
|
||||
var (
|
||||
accessToken string
|
||||
err error
|
||||
)
|
||||
if accessToken, err = r.GetAccessToken(); err != nil {
|
||||
return err
|
||||
}
|
||||
var response []byte
|
||||
if response, err = util.PostJSON(fmt.Sprintf(DelGroupWelcomeTemplateURL, accessToken), req); err != nil {
|
||||
return err
|
||||
}
|
||||
result := &DelGroupWelcomeTemplateResponse{}
|
||||
if err = util.DecodeWithError(response, result, "DelGroupWelcomeTemplate"); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
176
work/externalcontact/statistic.go
Normal file
176
work/externalcontact/statistic.go
Normal file
@@ -0,0 +1,176 @@
|
||||
package externalcontact
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/silenceper/wechat/v2/util"
|
||||
)
|
||||
|
||||
const (
|
||||
// GetUserBehaviorDataURL 获取「联系客户统计」数据
|
||||
GetUserBehaviorDataURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/get_user_behavior_data"
|
||||
// GetGroupChatStatURL 获取「群聊数据统计」数据 按群主聚合的方式
|
||||
GetGroupChatStatURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/groupchat/statistic"
|
||||
// GetGroupChatStatByDayURL 获取「群聊数据统计」数据 按自然日聚合的方式
|
||||
GetGroupChatStatByDayURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/groupchat/statistic_group_by_day"
|
||||
)
|
||||
|
||||
type (
|
||||
// GetUserBehaviorRequest 获取「联系客户统计」数据请求
|
||||
GetUserBehaviorRequest struct {
|
||||
UserID []string `json:"userid"`
|
||||
PartyID []int `json:"partyid"`
|
||||
StartTime int `json:"start_time"`
|
||||
EndTime int `json:"end_time"`
|
||||
}
|
||||
// GetUserBehaviorResponse 获取「联系客户统计」数据响应
|
||||
GetUserBehaviorResponse struct {
|
||||
util.CommonError
|
||||
BehaviorData []BehaviorData `json:"behavior_data"`
|
||||
}
|
||||
// BehaviorData 联系客户统计数据
|
||||
BehaviorData struct {
|
||||
StatTime int `json:"stat_time"`
|
||||
ChatCnt int `json:"chat_cnt"`
|
||||
MessageCnt int `json:"message_cnt"`
|
||||
ReplyPercentage float64 `json:"reply_percentage"`
|
||||
AvgReplyTime int `json:"avg_reply_time"`
|
||||
NegativeFeedbackCnt int `json:"negative_feedback_cnt"`
|
||||
NewApplyCnt int `json:"new_apply_cnt"`
|
||||
NewContactCnt int `json:"new_contact_cnt"`
|
||||
}
|
||||
)
|
||||
|
||||
// GetUserBehaviorData 获取「联系客户统计」数据
|
||||
// @see https://developer.work.weixin.qq.com/document/path/92132
|
||||
func (r *Client) GetUserBehaviorData(req *GetUserBehaviorRequest) ([]BehaviorData, error) {
|
||||
accessToken, err := r.GetAccessToken()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var response []byte
|
||||
jsonData, err := json.Marshal(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
response, err = util.HTTPPost(fmt.Sprintf("%s?access_token=%v", GetUserBehaviorDataURL, accessToken), string(jsonData))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var result GetUserBehaviorResponse
|
||||
err = util.DecodeWithError(response, &result, "GetUserBehaviorData")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result.BehaviorData, nil
|
||||
}
|
||||
|
||||
type (
|
||||
// GetGroupChatStatRequest 获取「群聊数据统计」数据 按群主聚合的方式 请求
|
||||
GetGroupChatStatRequest struct {
|
||||
DayBeginTime int `json:"day_begin_time"`
|
||||
DayEndTime int `json:"day_end_time"`
|
||||
OwnerFilter OwnerFilter `json:"owner_filter"`
|
||||
OrderBy int `json:"order_by"`
|
||||
OrderAsc int `json:"order_asc"`
|
||||
Offset int `json:"offset"`
|
||||
Limit int `json:"limit"`
|
||||
}
|
||||
// GetGroupChatStatResponse 获取「群聊数据统计」数据 按群主聚合的方式 响应
|
||||
GetGroupChatStatResponse struct {
|
||||
util.CommonError
|
||||
Total int `json:"total"`
|
||||
NextOffset int `json:"next_offset"`
|
||||
Items []GroupChatStatItem `json:"items"`
|
||||
}
|
||||
// GroupChatStatItem 群聊数据统计(按群主聚合)条目
|
||||
GroupChatStatItem struct {
|
||||
Owner string `json:"owner"`
|
||||
Data GroupChatStatItemData `json:"data"`
|
||||
}
|
||||
)
|
||||
|
||||
// OwnerFilter 群主过滤
|
||||
type OwnerFilter struct {
|
||||
UseridList []string `json:"userid_list"`
|
||||
}
|
||||
|
||||
// GroupChatStatItemData 群聊数据统计条目数据
|
||||
type GroupChatStatItemData struct {
|
||||
NewChatCnt int `json:"new_chat_cnt"`
|
||||
ChatTotal int `json:"chat_total"`
|
||||
ChatHasMsg int `json:"chat_has_msg"`
|
||||
NewMemberCnt int `json:"new_member_cnt"`
|
||||
MemberTotal int `json:"member_total"`
|
||||
MemberHasMsg int `json:"member_has_msg"`
|
||||
MsgTotal int `json:"msg_total"`
|
||||
MigrateTraineeChatCnt int `json:"migrate_trainee_chat_cnt"`
|
||||
}
|
||||
|
||||
// GetGroupChatStat 获取「群聊数据统计」数据 按群主聚合的方式
|
||||
// @see https://developer.work.weixin.qq.com/document/path/92133
|
||||
func (r *Client) GetGroupChatStat(req *GetGroupChatStatRequest) (*GetGroupChatStatResponse, error) {
|
||||
accessToken, err := r.GetAccessToken()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var response []byte
|
||||
jsonData, err := json.Marshal(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
response, err = util.HTTPPost(fmt.Sprintf("%s?access_token=%v", GetGroupChatStatURL, accessToken), string(jsonData))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := &GetGroupChatStatResponse{}
|
||||
err = util.DecodeWithError(response, result, "GetGroupChatStat")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
type (
|
||||
// GetGroupChatStatByDayRequest 获取「群聊数据统计」数据 按自然日聚合的方式 请求
|
||||
GetGroupChatStatByDayRequest struct {
|
||||
DayBeginTime int `json:"day_begin_time"`
|
||||
DayEndTime int `json:"day_end_time"`
|
||||
OwnerFilter OwnerFilter `json:"owner_filter"`
|
||||
}
|
||||
// GetGroupChatStatByDayResponse 获取「群聊数据统计」数据 按自然日聚合的方式 响应
|
||||
GetGroupChatStatByDayResponse struct {
|
||||
util.CommonError
|
||||
Items []GetGroupChatStatByDayItem `json:"items"`
|
||||
}
|
||||
// GetGroupChatStatByDayItem 群聊数据统计(按自然日聚合)条目
|
||||
GetGroupChatStatByDayItem struct {
|
||||
StatTime int `json:"stat_time"`
|
||||
Data GroupChatStatItemData `json:"data"`
|
||||
}
|
||||
)
|
||||
|
||||
// GetGroupChatStatByDay 获取「群聊数据统计」数据 按自然日聚合的方式
|
||||
// @see https://developer.work.weixin.qq.com/document/path/92133
|
||||
func (r *Client) GetGroupChatStatByDay(req *GetGroupChatStatByDayRequest) ([]GetGroupChatStatByDayItem, error) {
|
||||
accessToken, err := r.GetAccessToken()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var response []byte
|
||||
jsonData, err := json.Marshal(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
response, err = util.HTTPPost(fmt.Sprintf("%s?access_token=%v", GetGroupChatStatByDayURL, accessToken), string(jsonData))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var result GetGroupChatStatByDayResponse
|
||||
err = util.DecodeWithError(response, &result, "GetGroupChatStatByDay")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result.Items, nil
|
||||
}
|
||||
203
work/externalcontact/tag.go
Normal file
203
work/externalcontact/tag.go
Normal file
@@ -0,0 +1,203 @@
|
||||
package externalcontact
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/silenceper/wechat/v2/util"
|
||||
)
|
||||
|
||||
const (
|
||||
// GetCropTagURL 获取标签列表
|
||||
GetCropTagURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/get_corp_tag_list"
|
||||
// AddCropTagURL 添加标签
|
||||
AddCropTagURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/add_corp_tag"
|
||||
// EditCropTagURL 修改标签
|
||||
EditCropTagURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/edit_corp_tag"
|
||||
// DelCropTagURL 删除标签
|
||||
DelCropTagURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/del_corp_tag"
|
||||
// MarkCropTagURL 为客户打上、删除标签
|
||||
MarkCropTagURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/mark_tag"
|
||||
)
|
||||
|
||||
// GetCropTagRequest 获取企业标签请求
|
||||
type GetCropTagRequest struct {
|
||||
TagID []string `json:"tag_id"`
|
||||
GroupID []string `json:"group_id"`
|
||||
}
|
||||
|
||||
// GetCropTagListResponse 获取企业标签列表响应
|
||||
type GetCropTagListResponse struct {
|
||||
util.CommonError
|
||||
TagGroup []TagGroup `json:"tag_group"`
|
||||
}
|
||||
|
||||
// TagGroup 企业标签组
|
||||
type TagGroup struct {
|
||||
GroupID string `json:"group_id"`
|
||||
GroupName string `json:"group_name"`
|
||||
CreateTime int `json:"create_time"`
|
||||
GroupOrder int `json:"group_order"`
|
||||
Deleted bool `json:"deleted"`
|
||||
Tag []TagGroupTagItem `json:"tag"`
|
||||
}
|
||||
|
||||
// TagGroupTagItem 企业标签内的子项
|
||||
type TagGroupTagItem struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
CreateTime int `json:"create_time"`
|
||||
Order int `json:"order"`
|
||||
Deleted bool `json:"deleted"`
|
||||
}
|
||||
|
||||
// GetCropTagList 获取企业标签库
|
||||
// @see https://developer.work.weixin.qq.com/document/path/92117
|
||||
func (r *Client) GetCropTagList(req GetCropTagRequest) ([]TagGroup, error) {
|
||||
accessToken, err := r.GetAccessToken()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var response []byte
|
||||
jsonData, err := json.Marshal(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
response, err = util.HTTPPost(fmt.Sprintf("%s?access_token=%v", GetCropTagURL, accessToken), string(jsonData))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var result GetCropTagListResponse
|
||||
err = util.DecodeWithError(response, &result, "GetCropTagList")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result.TagGroup, nil
|
||||
}
|
||||
|
||||
// AddCropTagRequest 添加企业标签请求
|
||||
type AddCropTagRequest struct {
|
||||
GroupID string `json:"group_id,omitempty"`
|
||||
GroupName string `json:"group_name"`
|
||||
Order int `json:"order"`
|
||||
Tag []AddCropTagItem `json:"tag"`
|
||||
AgentID int `json:"agentid"`
|
||||
}
|
||||
|
||||
// AddCropTagItem 添加企业标签子项
|
||||
type AddCropTagItem struct {
|
||||
Name string `json:"name"`
|
||||
Order int `json:"order"`
|
||||
}
|
||||
|
||||
// AddCropTagResponse 添加企业标签响应
|
||||
type AddCropTagResponse struct {
|
||||
util.CommonError
|
||||
TagGroup TagGroup `json:"tag_group"`
|
||||
}
|
||||
|
||||
// AddCropTag 添加企业客户标签
|
||||
// @see https://developer.work.weixin.qq.com/document/path/92117
|
||||
func (r *Client) AddCropTag(req AddCropTagRequest) (*TagGroup, error) {
|
||||
var accessToken string
|
||||
accessToken, err := r.GetAccessToken()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var response []byte
|
||||
jsonData, err := json.Marshal(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
response, err = util.HTTPPost(fmt.Sprintf("%s?access_token=%v", AddCropTagURL, accessToken), string(jsonData))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var result AddCropTagResponse
|
||||
err = util.DecodeWithError(response, &result, "AddCropTag")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &result.TagGroup, nil
|
||||
}
|
||||
|
||||
// EditCropTagRequest 编辑客户企业标签请求
|
||||
type EditCropTagRequest struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Order int `json:"order"`
|
||||
AgentID string `json:"agent_id"`
|
||||
}
|
||||
|
||||
// EditCropTag 修改企业客户标签
|
||||
// @see https://developer.work.weixin.qq.com/document/path/92117
|
||||
func (r *Client) EditCropTag(req EditCropTagRequest) error {
|
||||
accessToken, err := r.GetAccessToken()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var response []byte
|
||||
jsonData, err := json.Marshal(req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
response, err = util.HTTPPost(fmt.Sprintf("%s?access_token=%v", EditCropTagURL, accessToken), string(jsonData))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return util.DecodeWithCommonError(response, "EditCropTag")
|
||||
}
|
||||
|
||||
// DeleteCropTagRequest 删除企业标签请求
|
||||
type DeleteCropTagRequest struct {
|
||||
TagID []string `json:"tag_id"`
|
||||
GroupID []string `json:"group_id"`
|
||||
AgentID string `json:"agent_id"`
|
||||
}
|
||||
|
||||
// DeleteCropTag 删除企业客户标签
|
||||
// @see https://developer.work.weixin.qq.com/document/path/92117
|
||||
func (r *Client) DeleteCropTag(req DeleteCropTagRequest) error {
|
||||
accessToken, err := r.GetAccessToken()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var response []byte
|
||||
jsonData, err := json.Marshal(req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
response, err = util.HTTPPost(fmt.Sprintf("%s?access_token=%v", DelCropTagURL, accessToken), string(jsonData))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return util.DecodeWithCommonError(response, "DeleteCropTag")
|
||||
}
|
||||
|
||||
// MarkTagRequest 给客户打标签请求
|
||||
// 相关文档地址:https://developer.work.weixin.qq.com/document/path/92118
|
||||
type MarkTagRequest struct {
|
||||
UserID string `json:"userid"`
|
||||
ExternalUserID string `json:"external_userid"`
|
||||
AddTag []string `json:"add_tag"`
|
||||
RemoveTag []string `json:"remove_tag"`
|
||||
}
|
||||
|
||||
// MarkTag 为客户打上标签
|
||||
// @see https://developer.work.weixin.qq.com/document/path/92118
|
||||
func (r *Client) MarkTag(request MarkTagRequest) error {
|
||||
accessToken, err := r.GetAccessToken()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var response []byte
|
||||
jsonData, err := json.Marshal(request)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
response, err = util.HTTPPost(fmt.Sprintf("%s?access_token=%v", MarkCropTagURL, accessToken), string(jsonData))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return util.DecodeWithCommonError(response, "MarkTag")
|
||||
}
|
||||
Reference in New Issue
Block a user