forked from silenceper/wechat
-
Notifications
You must be signed in to change notification settings - Fork 0
/
external_user.go
489 lines (444 loc) · 17.5 KB
/
external_user.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
package externalcontact
import (
"encoding/json"
"fmt"
"github.com/bbang94/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")
}