| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489 |
- 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"
- // listCustomerStrategyURL 获取规则组列表
- listCustomerStrategyURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/customer_strategy/list?access_token=%s"
- // getCustomerStrategyURL 获取规则组详情
- getCustomerStrategyURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/customer_strategy/get?access_token=%s"
- // getRangeCustomerStrategyURL 获取规则组管理范围
- getRangeCustomerStrategyURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/customer_strategy/get_range?access_token=%s"
- // createCustomerStrategyURL 创建新的规则组
- createCustomerStrategyURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/customer_strategy/create?access_token=%s"
- // editCustomerStrategyURL 编辑规则组及其管理范围
- editCustomerStrategyURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/customer_strategy/edit?access_token=%s"
- // delCustomerStrategyURL 删除规则组
- delCustomerStrategyURL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/customer_strategy/del?access_token=%s"
- )
- // 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")
- return result.ExternalUserID, err
- }
- // 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 *ExternalProfile `json:"external_profile,omitempty"`
- }
- // FollowUser 跟进用户(指企业内部用户)
- type FollowUser struct {
- UserID string `json:"userid"`
- Remark string `json:"remark"`
- Description string `json:"description"`
- CreateTime int64 `json:"createtime"`
- 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 int `json:"source"`
- }
- // ExternalProfile 外部联系人的自定义展示信息,可以有多个字段和多种类型,包括文本,网页和小程序
- type ExternalProfile struct {
- ExternalCorpName string `json:"external_corp_name"`
- WechatChannels WechatChannels `json:"wechat_channels"`
- ExternalAttr []ExternalAttr `json:"external_attr"`
- }
- // WechatChannels 视频号属性。须从企业绑定到企业微信的视频号中选择,可在“我的企业”页中查看绑定的视频号
- type WechatChannels struct {
- Nickname string `json:"nickname"`
- Status int `json:"status"`
- }
- // ExternalAttr 属性列表,目前支持文本、网页、小程序三种类型
- type ExternalAttr struct {
- Type int `json:"type"`
- Name string `json:"name"`
- Text *Text `json:"text,omitempty"`
- Web *Web `json:"web,omitempty"`
- MiniProgram *MiniProgram `json:"miniprogram,omitempty"`
- }
- // Text 文本
- type Text struct {
- Value string `json:"value"`
- }
- // Web 网页
- type Web struct {
- URL string `json:"url"`
- Title string `json:"title"`
- }
- // MiniProgram 小程序
- type MiniProgram struct {
- AppID string `json:"appid"`
- Pagepath string `json:"pagepath"`
- Title string `json:"title"`
- }
- // 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")
- return result, err
- }
- // BatchGetExternalUserDetailsRequest 批量获取外部联系人详情请求
- type BatchGetExternalUserDetailsRequest struct {
- UserIDList []string `json:"userid_list"`
- Cursor string `json:"cursor"`
- Limit int `json:"limit,omitempty"`
- }
- // 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 int64 `json:"createtime"`
- 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")
- return result.ExternalContactList, err
- }
- // 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")
- }
- // ListCustomerStrategyRequest 获取规则组列表请求
- type ListCustomerStrategyRequest struct {
- Cursor string `json:"cursor"`
- Limit int `json:"limit"`
- }
- // ListCustomerStrategyResponse 获取规则组列表响应
- type ListCustomerStrategyResponse struct {
- util.CommonError
- Strategy []StrategyID `json:"strategy"`
- NextCursor string `json:"next_cursor"`
- }
- // StrategyID 规则组 ID
- type StrategyID struct {
- StrategyID int `json:"strategy_id"`
- }
- // ListCustomerStrategy 获取规则组列表
- // @see https://developer.work.weixin.qq.com/document/path/94883#%E8%8E%B7%E5%8F%96%E8%A7%84%E5%88%99%E7%BB%84%E5%88%97%E8%A1%A8
- func (r *Client) ListCustomerStrategy(req *ListCustomerStrategyRequest) (*ListCustomerStrategyResponse, 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(listCustomerStrategyURL, accessToken), req); err != nil {
- return nil, err
- }
- result := &ListCustomerStrategyResponse{}
- err = util.DecodeWithError(response, result, "ListCustomerStrategy")
- return result, err
- }
- // GetCustomerStrategyRequest 获取规则组详情请求
- type GetCustomerStrategyRequest struct {
- StrategyID int `json:"strategy_id"`
- }
- // GetCustomerStrategyResponse 获取规则组详情响应
- type GetCustomerStrategyResponse struct {
- util.CommonError
- Strategy Strategy `json:"strategy"`
- }
- // Strategy 规则组
- type Strategy struct {
- StrategyID int `json:"strategy_id"`
- ParentID int `json:"parent_id"`
- StrategyName string `json:"strategy_name"`
- CreateTime int64 `json:"create_time"`
- AdminList []string `json:"admin_list"`
- Privilege Privilege `json:"privilege"`
- }
- // Privilege 权限
- type Privilege struct {
- ViewCustomerList bool `json:"view_customer_list"`
- ViewCustomerData bool `json:"view_customer_data"`
- ViewRoomList bool `json:"view_room_list"`
- ContactMe bool `json:"contact_me"`
- JoinRoom bool `json:"join_room"`
- ShareCustomer bool `json:"share_customer"`
- OperResignCustomer bool `json:"oper_resign_customer"`
- OperResignGroup bool `json:"oper_resign_group"`
- SendCustomerMsg bool `json:"send_customer_msg"`
- EditWelcomeMsg bool `json:"edit_welcome_msg"`
- ViewBehaviorData bool `json:"view_behavior_data"`
- ViewRoomData bool `json:"view_room_data"`
- SendGroupMsg bool `json:"send_group_msg"`
- RoomDeduplication bool `json:"room_deduplication"`
- RapidReply bool `json:"rapid_reply"`
- OnjobCustomerTransfer bool `json:"onjob_customer_transfer"`
- EditAntiSpamRule bool `json:"edit_anti_spam_rule"`
- ExportCustomerList bool `json:"export_customer_list"`
- ExportCustomerData bool `json:"export_customer_data"`
- ExportCustomerGroupList bool `json:"export_customer_group_list"`
- ManageCustomerTag bool `json:"manage_customer_tag"`
- }
- // GetCustomerStrategy 获取规则组详情
- // @see https://developer.work.weixin.qq.com/document/path/94883#%E8%8E%B7%E5%8F%96%E8%A7%84%E5%88%99%E7%BB%84%E8%AF%A6%E6%83%85
- func (r *Client) GetCustomerStrategy(req *GetCustomerStrategyRequest) (*GetCustomerStrategyResponse, 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(getCustomerStrategyURL, accessToken), req); err != nil {
- return nil, err
- }
- result := &GetCustomerStrategyResponse{}
- err = util.DecodeWithError(response, result, "GetCustomerStrategy")
- return result, err
- }
- // GetRangeCustomerStrategyRequest 获取规则组管理范围请求
- type GetRangeCustomerStrategyRequest struct {
- StrategyID int `json:"strategy_id"`
- Cursor string `json:"cursor"`
- Limit int `json:"limit"`
- }
- // GetRangeCustomerStrategyResponse 获取规则组管理范围响应
- type GetRangeCustomerStrategyResponse struct {
- util.CommonError
- Range []Range `json:"range"`
- NextCursor string `json:"next_cursor"`
- }
- // Range 管理范围节点
- type Range struct {
- Type int `json:"type"`
- UserID string `json:"userid,omitempty"`
- PartyID int `json:"partyid,omitempty"`
- }
- // GetRangeCustomerStrategy 获取规则组管理范围
- // @see https://developer.work.weixin.qq.com/document/path/94883#%E8%8E%B7%E5%8F%96%E8%A7%84%E5%88%99%E7%BB%84%E7%AE%A1%E7%90%86%E8%8C%83%E5%9B%B4
- func (r *Client) GetRangeCustomerStrategy(req *GetRangeCustomerStrategyRequest) (*GetRangeCustomerStrategyResponse, 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(getRangeCustomerStrategyURL, accessToken), req); err != nil {
- return nil, err
- }
- result := &GetRangeCustomerStrategyResponse{}
- err = util.DecodeWithError(response, result, "GetRangeCustomerStrategy")
- return result, err
- }
- // CreateCustomerStrategyRequest 创建新的规则组请求
- type CreateCustomerStrategyRequest struct {
- ParentID int `json:"parent_id"`
- StrategyName string `json:"strategy_name"`
- AdminList []string `json:"admin_list"`
- Privilege Privilege `json:"privilege"`
- Range []Range `json:"range"`
- }
- // CreateCustomerStrategyResponse 创建新的规则组响应
- type CreateCustomerStrategyResponse struct {
- util.CommonError
- StrategyID int `json:"strategy_id"`
- }
- // CreateCustomerStrategy 创建新的规则组
- // @see https://developer.work.weixin.qq.com/document/path/94883#%E5%88%9B%E5%BB%BA%E6%96%B0%E7%9A%84%E8%A7%84%E5%88%99%E7%BB%84
- func (r *Client) CreateCustomerStrategy(req *CreateCustomerStrategyRequest) (*CreateCustomerStrategyResponse, 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(createCustomerStrategyURL, accessToken), req); err != nil {
- return nil, err
- }
- result := &CreateCustomerStrategyResponse{}
- err = util.DecodeWithError(response, result, "CreateCustomerStrategy")
- return result, err
- }
- // EditCustomerStrategyRequest 编辑规则组及其管理范围请求
- type EditCustomerStrategyRequest struct {
- StrategyID int `json:"strategy_id"`
- StrategyName string `json:"strategy_name"`
- AdminList []string `json:"admin_list"`
- Privilege Privilege `json:"privilege"`
- RangeAdd []Range `json:"range_add"`
- RangeDel []Range `json:"range_del"`
- }
- // EditCustomerStrategy 编辑规则组及其管理范围
- // see https://developer.work.weixin.qq.com/document/path/94883#%E7%BC%96%E8%BE%91%E8%A7%84%E5%88%99%E7%BB%84%E5%8F%8A%E5%85%B6%E7%AE%A1%E7%90%86%E8%8C%83%E5%9B%B4
- func (r *Client) EditCustomerStrategy(req *EditCustomerStrategyRequest) 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(editCustomerStrategyURL, accessToken), req); err != nil {
- return err
- }
- return util.DecodeWithCommonError(response, "EditCustomerStrategy")
- }
- // DelCustomerStrategyRequest 删除规则组请求
- type DelCustomerStrategyRequest struct {
- StrategyID int `json:"strategy_id"`
- }
- // DelCustomerStrategy 删除规则组
- // see https://developer.work.weixin.qq.com/document/path/94883#%E5%88%A0%E9%99%A4%E8%A7%84%E5%88%99%E7%BB%84
- func (r *Client) DelCustomerStrategy(req *DelCustomerStrategyRequest) 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(delCustomerStrategyURL, accessToken), req); err != nil {
- return err
- }
- return util.DecodeWithCommonError(response, "DelCustomerStrategy")
- }
|