fwq
2024-09-23 55334da20cff4dac840c320eda1d0ca53ba27eda
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
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
package com.hx.mp.util;
 
import com.hx.util.StringUtils;
import com.hz.util.http.HttpHzUtil;
import com.hz.util.http.dto.HttpHzResponse;
import net.sf.json.JSONArray;
import net.sf.json.JSONException;
import net.sf.json.JSONObject;
import org.apache.commons.io.IOUtils;
 
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.List;
 
/**
 * 企业微信客户工具
 */
public class CorpMpClientUtil {
 
    /**
     * 生成联系我按钮参数的链接(生成config_id)
     */
    public static final String CREATE_CONTACT_ID_URL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/add_contact_way?access_token=";
    /**
     * 获取企业客户详情链接
     */
    public static final String GET_CLIENT_DETAIL_URL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/get";
    /**
     * 获取获取企业标签库链接
     */
    public static final String GET_CORP_TAG_LIST = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/get_corp_tag_list?access_token=";
    /**
     * 添加客户联系人标签
     */
    public static final String ADD_TAG = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/add_corp_tag?access_token=";
    /**
     * 编辑企业客户标签
     */
    public static final String EDIT_TAG = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/edit_corp_tag?access_token=";
    /**
     * 删除客户联系人标签
     */
    public static final String DEL_TAG = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/del_corp_tag?access_token=";
    /**
     * 客户关联企业微信的标签url
     */
    public static final String RELATION_TAG = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/mark_tag?access_token=";
 
    /**
     * 获取员工客户列表url
     */
    public static final String EXTERNAL_CONTACT_LIST = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/list";
 
    /**
     * 创建获客链接url
     */
    public static final String CUSTOMER_ACQUISITION_CREATE_LINK = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/customer_acquisition/create_link?access_token=";
 
    /**
     * 获取获客客户列表
     */
    public static final String CUSTOMER_ACQUISITION_CUSTOMER_LIST = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/customer_acquisition/customer?access_token=";
 
    /**
     * 获取配置过客户群管理的客户群列表
     */
    public static final String GROUP_CHAT_LIST = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/groupchat/list?access_token=";
 
 
    /**
     * 通过客户群ID,获取详情。包括群名、群成员列表、群成员入群时间、入群方式。(客户群是由具有客户群使用权限的成员创建的外部群)
     */
    public static final String GROUP_CHAT_DETAIL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/groupchat/get?access_token=";
 
    /**
     * 企业微信发送普通邮件
     */
    public static final String GROUP_SENT_EMAIL = "https://qyapi.weixin.qq.com/cgi-bin/exmail/app/compose_send?access_token=";
 
    /**
     * 客户群「加入群聊」查看
     */
    public static final String GROUP_JOIN_WAY_SEE = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/groupchat/get_join_way?access_token=";
    /**
     * 客户群「加入群聊」新增
     * 企业可调用此接口来生成并配置「加入群聊」的二维码或者小程序按钮
     * 客户通过扫描二维码或点击小程序上的按钮,即可加入特定的客户群
     */
    public static final String GROUP_JOIN_WAY_ADD = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/groupchat/add_join_way?access_token=";
    /**
     * 客户群「加入群聊」修改
     */
    public static final String GROUP_JOIN_WAY_EDIT = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/groupchat/update_join_way?access_token=";
    /**
     * 客户群「加入群聊」删除
     */
    public static final String GROUP_JOIN_WAY_EDL= "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/groupchat/del_join_way?access_token=";
 
 
    /**
     * 生成企业成员联系我的id-单人
     *
     * @param accessToken 企业的accessToken
     * @param userId      企业成员的userId
     * @param state       企业自定义的state参数,用于区分不同的添加渠道,在调用“获取外部联系人详情”时会返回该参数值,不超过30个字符
     * @param remark      联系方式的备注信息,用于助记,不超过30个字符
     * @return 返回
     */
    public static JSONObject createContactId(String accessToken, String userId, String state, String remark) {
 
        String configId = null;
        JSONObject data = new JSONObject();
        data.put("type", 1);
        data.put("scene", 1);
        data.put("state", state);
        data.put("remark", remark);
        JSONArray userIds = new JSONArray();
        userIds.add(userId);
        data.put("user", userIds);
 
        //请求,返回格式
       /*{
           "errcode": 0,
               "errmsg": "ok",
               "config_id":"42b34949e138eb6e027c123cba77fAAA"  
       }*/
 
        return HttpURLUtil(CREATE_CONTACT_ID_URL + accessToken, data.toString());
    }
 
    /**
     * 获取客户列表
     * @param accessToken 企业的accessToken
     * @param userId 企业成员的userId
     * @return 返回
     */
    public static JSONObject getExternalContactList(String accessToken, String userId) {
        return HttpURLUtil(EXTERNAL_CONTACT_LIST + "?access_token=" + accessToken + "&userid=" + userId, null);
    }
 
    /**
     * 获取企业客户详情信息
     *
     * @param accessToken    企业的accessToken
     * @param externalUserId 外部人员的userId
     * @return 返回
     */
    public static JSONObject getClientData(String accessToken, String externalUserId) {
        return HttpURLUtil(GET_CLIENT_DETAIL_URL + "?access_token=" + accessToken + "&external_userid=" + externalUserId, null);
    }
 
    /**
     * 企业可通过此接口获取企业客户标签详情
     *
     * @param accessToken 企业的accessToken
     * @param tagId  标签id
     * @param groupId 标签组id
     * @return 返回
     */
    public static JSONObject getCorpTagList(String accessToken, JSONArray tagId, JSONArray groupId) {
        JSONObject data = new JSONObject();
        data.put("tag_id", tagId);
        data.put("group_id", groupId);
        return HttpURLUtil(GET_CORP_TAG_LIST + accessToken, data.toString());
    }
 
    /**
     * 添加客户联系人标签,
     * 如果要向指定的标签组下添加标签,需要填写group_id参数;如果要创建一个全新的标签组以及标签,
     * 则需要通过group_name参数指定新标签组名称,如果填写的groupname已经存在,则会在此标签组下新建标签
     *
     * @param accessToken 企业的accessToken
     * @param groupId     组id(组名称和组id必填一个)
     * @param groupName   组名称 组名称和组id必填一个)
     * @param groupOrder  组排序,不填默认企业微信生成规则
     * @param tagArray    数组,格式:[{ "name": "TAG_NAME_1", "order": 1 }]
     * @return 返回
     */
    public static JSONObject addTable(String accessToken, String groupId, String groupName, String groupOrder, JSONArray tagArray) {
        JSONObject data = new JSONObject();
        data.put("group_id", groupId);
        data.put("group_name", groupName);
        data.put("order", groupOrder);
        data.put("tag", tagArray);
        return HttpURLUtil(ADD_TAG + accessToken, data.toString());
    }
 
    /**
     * 编辑企业客户标签,
     * 注意:修改后的标签组不能和已有的标签组重名,标签也不能和同一标签组下的其他标签重名。
     *
     * @param accessToken 企业的accessToken
     * @param id     标签或标签组的id
     * @param name   新的标签或标签组名称,最长为30个字符
     * @param order  标签/标签组的次序值。order值大的排序靠前。有效的值范围是[0, 2^32)
     * @return 返回
     */
    public static JSONObject editTable(String accessToken, String id, String name, String order) {
        JSONObject data = new JSONObject();
        data.put("id", id);
        data.put("name", name);
        data.put("order", order);
        return HttpURLUtil(EDIT_TAG + accessToken, data.toString());
    }
 
    /**
     * 删除客户联系人标签
     * groupArr和tagArr不可同时为空。
     * 如果一个标签组下所有的标签均被删除,则标签组会被自动删除。
     *
     * @param accessToken 企业的accessToken
     * @param groupArr    组id数组
     * @param tagArr      标签id数组
     * @return 返回
     */
    public static JSONObject delTable(String accessToken, JSONArray groupArr, JSONArray tagArr) {
        JSONObject data = new JSONObject();
        data.put("tag_id", tagArr);
        data.put("group_id", groupArr);
        return HttpURLUtil(DEL_TAG + accessToken, data.toString());
    }
 
    /**
     * 客户关联企业微信的标签
     * 注意:请确保external_userid是userid的外部联系人。
     * add_tag和remove_tag不可同时为空。
     *
     * @param accessToken    企业的accessToken
     * @param userId         企业成员的userid
     * @param externalUserId 外部联系人的id
     * @param addTag         新增的标签id(企业标签的id)数组
     * @param removeTag      删除的标签id(企业标签的id)数组
     * @return 返回
     */
    public static JSONObject relationTag(String accessToken, String userId, String externalUserId, JSONArray addTag, JSONArray removeTag) {
        JSONObject data = new JSONObject();
        data.put("userid", userId);
        data.put("external_userid", externalUserId);
        data.put("add_tag", addTag);
        data.put("remove_tag", removeTag);
        return HttpURLUtil(RELATION_TAG + accessToken, data.toString());
    }
 
    /**
     * 请求http协议 获取信息工具
     **/
    public static JSONObject HttpURLUtil(String url, String data) {
        HttpURLConnection con = null;
        URL u = null;
        String wxMsgXml = null;
        JSONObject obj = null;
        try {
            u = new URL(url);
            con = (HttpURLConnection) u.openConnection();
            con.setRequestMethod("POST");
            con.setDoOutput(true);
            con.setDoInput(true);
            con.setUseCaches(false);
            con.setReadTimeout(5000);
            con.setRequestProperty("Charset", "UTF-8");
            con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
 
            if (data != null) {
                OutputStream os = con.getOutputStream();
                os.write(data.getBytes("utf-8"));
            }
 
            if (con.getResponseCode() != 200)
                throw new RuntimeException("请求url失败");
            // 读取返回内容
            wxMsgXml = IOUtils.toString(con.getInputStream(), "utf-8");
            obj = JSONObject.fromObject(wxMsgXml);
            // //System.out.println("HttpURLUtil:"+wxMsgXml);
        } catch (Exception e) {
            e.printStackTrace();
            obj = new JSONObject();
            try {
                obj.put("status", 1);
                obj.put("errMsg", e.getMessage());
            } catch (JSONException e1) {
                e1.printStackTrace();
            }
        } finally {
            if (con != null) {
                con.disconnect();
            }
        }
        return obj;
    }
 
    /**生成企业成员联系我的id-单人
     * @param accessToken 企业的accessToken
     * @param userId 企业成员的userId
     * @param scene 场景,1-在小程序中联系,2-通过二维码联系
     * @param state 企业自定义的state参数,用于区分不同的添加渠道,在调用“获取外部联系人详情”时会返回该参数值,不超过30个字符
     * @param remark 联系方式的备注信息,用于助记,不超过30个字符
     * @return 返回
     */
    public static JSONObject createContactId(String accessToken,String userId,int scene,String state,String remark){
        String configId = null;
        JSONObject data = new JSONObject();
        data.put("type",1);
        data.put("scene",scene);
        data.put("state",state);
        data.put("remark",remark);
        JSONArray userIds = new JSONArray();
        userIds.add(userId);
        data.put("user",userIds);
 
        //请求,返回格式
       /*{
           "errcode": 0,
               "errmsg": "ok",
               "config_id":"42b34949e138eb6e027c123cba77fAAA"  
       }*/
 
        return HttpURLUtil(CREATE_CONTACT_ID_URL+accessToken,data.toString());
    }
 
    /**
     * 创建获客链接
     *
     * @param accessToken 企业的accessToken
     * @param linkName  链接名称
     * @param userList 员工用户userId
     * @return 返回
     */
    public static JSONObject createCustomerAcquisitionLink(String accessToken, String linkName, JSONArray userList) {
        JSONObject data = new JSONObject();
        data.put("link_name", linkName);
        JSONObject subData = new JSONObject();
        subData.accumulate("user_list", userList);
        data.put("range", subData);
        /** 返回数据
         * {
         *    "link_id":"LINK_ID",
         *    "link_name":"获客链接1号",
         *    "range":
         *    {
         *            "user_list":["zhangsan","lisi"],
         *         "department_list":[2,3]
         *    },
         *    "skip_verify":true
         * }
         */
        return HttpURLUtil(CUSTOMER_ACQUISITION_CREATE_LINK + accessToken, data.toString());
    }
 
    /**
     * 获取获客客户列表
     *
     * @param accessToken 企业的accessToken
     * @param linkId  链接id
     * @param cursor  分页游标
     * @return 返回
     */
    public static JSONObject getCustomerAcquisitionCustomerList(String accessToken, String linkId, String cursor) {
        JSONObject data = new JSONObject();
        data.put("link_id", linkId);
        data.put("limit", 1000);
        // 分页游标
        if (!StringUtils.isEmpty(cursor)) {
            data.put("cursor", cursor);
        }
        /** 返回数据
         * {
         *     "errcode": 0,
         *     "errmsg": "ok",
         *     "customer_list":
         *     [
         *                {
         *             "external_userid":"woAJ2GCAAAXtWyujaWJHDDGi0mACAAA",
         *             "userid":"zhangsan",
         *             "chat_status":0,
         *             "state":"CHANNEL_A"
         *        }
         *     ],
         *     "next_cursor":"CURSOR"
         * }
         */
        return HttpURLUtil(CUSTOMER_ACQUISITION_CUSTOMER_LIST + accessToken, data.toString());
    }
 
 
    /**
     * 该接口用于获取配置过客户群管理的客户群列表。
     *
     * @param accessToken  企业的accessToken
     * @param statusFilter 客户群跟进状态过滤。0 - 所有列表(即不过滤) 1 - 离职待继承 2 - 离职继承中 3 - 离职继承完成
     * @param userIdList   群主过滤 如果不填,表示获取应用可见范围内全部群主的数据可见范围人数超过1000人,为了防止数据包过大,会报错 81017 用户ID列表。最多100个
     * @param cursor       分页下标
     * @param limit        列表
     * @return 返回
     */
    public static HttpHzResponse getGroupChatList(String accessToken, Integer statusFilter, List<String> userIdList, String cursor, Integer limit) {
        JSONObject bodyData = new JSONObject();
        bodyData.put("status_filter", statusFilter);
        //分页下标
        if (StringUtils.noNull(cursor)) {
            bodyData.put("cursor", cursor);
        }
        //默认100条
        if (limit == null) {
            limit = 100;
        }
        bodyData.put("limit", limit);
        //过滤
        if (userIdList != null && userIdList.size() > 0) {
            JSONObject filter = new JSONObject();
            filter.put("userid_list", userIdList);
            bodyData.put("owner_filter", filter);
        }
        return HttpHzUtil.HttpURLUtilJson(GROUP_CHAT_LIST + accessToken, bodyData.toString(), null, null, "GET", null);
    }
 
    /**
     * 通过客户群ID,获取详情。包括群名、群成员列表、群成员入群时间、入群方式。(客户群是由具有客户群使用权限的成员创建的外部群)
     *
     * @param chatId   客户群ID
     * @param needName 是否需要返回群成员的名字0-不返回;1-返回
     */
    public static HttpHzResponse getGroupChatDetail(String accessToken, String chatId, Integer needName) {
        JSONObject bodyData = new JSONObject();
        bodyData.put("chat_id", chatId);
        if (needName == null) {
            needName = 0;
        }
        bodyData.put("need_name", needName);
        return HttpHzUtil.HttpURLUtilJson(GROUP_CHAT_DETAIL + accessToken, bodyData.toString(), null, null, "GET", null);
    }
 
    /**
     * 企业微信发送普通邮件
     * 接口地址: https://developer.work.weixin.qq.com/document/path/97445
     * @param bodyData  参数
     */
    public static JSONObject sentEmail(String accessToken, JSONObject bodyData) {
        return HttpURLUtil(GROUP_SENT_EMAIL + accessToken, bodyData.toString());
    }
 
    /**
     * 客户群「加入群聊」查看详情
     * @param config_id 联系方式配置ID
     * */
    public static HttpHzResponse groupJoinSee(String accessToken, String config_id) {
        JSONObject bodyData = new JSONObject();
        bodyData.put("config_id", config_id);
        return HttpHzUtil.HttpURLUtilJson(GROUP_JOIN_WAY_SEE + accessToken, bodyData.toString(), null, null, "POST", null);
    }
 
    /**
     * 客户群「加入群聊」新增
     * @param scene 场景。1 - 群的小程序插件, 2 - 群的二维码插件
     * @param remark 联系方式的备注信息,用于助记,超过30个字符将被截断
     * @param auto_create_room 当群满了后,是否自动新建群。0-否;1-是。 默认为1
     * @param room_base_name 自动建群的群名前缀,当auto_create_room为1时有效。最长40个utf8字符
     * @param room_base_id 自动建群的群起始序号,当auto_create_room为1时有效
     * @param chat_id_list 使用该配置的客户群ID列表,最多支持5个
     * */
    public static HttpHzResponse groupJoinAdd(String accessToken, Integer scene, String remark
            ,Integer auto_create_room,String room_base_name,Integer room_base_id,List<String> chat_id_list,String state) {
        JSONObject bodyData = new JSONObject();
        bodyData.put("scene", scene);
        bodyData.put("remark", remark);
        bodyData.put("auto_create_room", auto_create_room);
        bodyData.put("room_base_name", room_base_name);
        bodyData.put("room_base_id", room_base_id);
        bodyData.put("chat_id_list", chat_id_list);
        bodyData.put("state", state);
        return HttpHzUtil.HttpURLUtilJson(GROUP_JOIN_WAY_ADD + accessToken, bodyData.toString(), null, null, "POST", null);
    }
 
    /**
     * 客户群「加入群聊」修改
     * @param config_id 联系方式配置ID
     * @param scene 场景。1 - 群的小程序插件, 2 - 群的二维码插件
     * @param remark 联系方式的备注信息,用于助记,超过30个字符将被截断
     * @param auto_create_room 当群满了后,是否自动新建群。0-否;1-是。 默认为1
     * @param room_base_name 自动建群的群名前缀,当auto_create_room为1时有效。最长40个utf8字符
     * @param room_base_id 自动建群的群起始序号,当auto_create_room为1时有效
     * @param chat_id_list 使用该配置的客户群ID列表,最多支持5个
     * */
    public static HttpHzResponse groupJoinEdit(String accessToken,String config_id, Integer scene, String remark
            ,Integer auto_create_room,String room_base_name,Integer room_base_id,List<String> chat_id_list,String state) {
        JSONObject bodyData = new JSONObject();
        bodyData.put("config_id", config_id);
        bodyData.put("scene", scene);
        bodyData.put("remark", remark);
        bodyData.put("auto_create_room", auto_create_room);
        bodyData.put("room_base_name", room_base_name);
        bodyData.put("room_base_id", room_base_id);
        bodyData.put("chat_id_list", chat_id_list);
        bodyData.put("state", state);
        return HttpHzUtil.HttpURLUtilJson(GROUP_JOIN_WAY_EDIT + accessToken, bodyData.toString(), null, null, "POST", null);
    }
 
    /**
     * 客户群「加入群聊」删除
     * @param config_id 联系方式配置ID
     * */
    public static HttpHzResponse groupJoinDel(String accessToken, String config_id) {
        JSONObject bodyData = new JSONObject();
        bodyData.put("config_id", config_id);
        return HttpHzUtil.HttpURLUtilJson(GROUP_JOIN_WAY_EDL + accessToken, bodyData.toString(), null, null, "POST", null);
    }
 
 
 
}