Skip to content

Commit 4f5be60

Browse files
chutian0124hywr
authored andcommitted
🆕 binarywang#2150 【企业微信】补充完善部分客户联系接口,以及服务商模式外部联系人openid转换接口
1 parent d6d3625 commit 4f5be60

8 files changed

+486
-1
lines changed

weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpExternalContactService.java

+113
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import me.chanjar.weixin.cp.bean.external.*;
77
import me.chanjar.weixin.cp.bean.external.contact.WxCpExternalContactBatchInfo;
88
import me.chanjar.weixin.cp.bean.external.contact.WxCpExternalContactInfo;
9+
import org.jetbrains.annotations.NotNull;
910

1011
import java.util.Date;
1112
import java.util.List;
@@ -134,6 +135,14 @@ public interface WxCpExternalContactService {
134135
*/
135136
WxCpExternalContactInfo getContactDetail(String userId) throws WxErrorException;
136137

138+
/**
139+
* 企业和服务商可通过此接口,将微信外部联系人的userid转为微信openid,用于调用支付相关接口。暂不支持企业微信外部联系人(ExternalUserid为wo开头)的userid转openid。
140+
* @param externalUserid 微信外部联系人的userid
141+
* @return 该企业的外部联系人openid
142+
* @throws WxErrorException .
143+
*/
144+
String convertToOpenid(String externalUserid) throws WxErrorException;
145+
137146
/**
138147
* 批量获取客户详情.
139148
* <pre>
@@ -225,9 +234,85 @@ WxCpExternalContactBatchInfo getContactDetailBatch(String userId, String cursor,
225234
* @param takeOverUserid the take over userid
226235
* @return wx cp base resp
227236
* @throws WxErrorException the wx error exception
237+
* @deprecated 此后续将不再更新维护,建议使用 {@link #transferCustomer(WxCpUserTransferCustomerReq)}
228238
*/
239+
@Deprecated
229240
WxCpBaseResp transferExternalContact(String externalUserid, String handOverUserid, String takeOverUserid) throws WxErrorException;
230241

242+
/**
243+
* 企业可通过此接口,转接在职成员的客户给其他成员。
244+
* <per>
245+
* external_userid必须是handover_userid的客户(即配置了客户联系功能的成员所添加的联系人)。
246+
* 在职成员的每位客户最多被分配2次。客户被转接成功后,将有90个自然日的服务关系保护期,保护期内的客户无法再次被分配。
247+
*
248+
* 权限说明:
249+
* * 企业需要使用“客户联系”secret或配置到“可调用应用”列表中的自建应用secret所获取的accesstoken来调用(accesstoken如何获取?)。
250+
* 第三方应用需拥有“企业客户权限->客户联系->在职继承”权限
251+
* 接替成员必须在此第三方应用或自建应用的可见范围内。
252+
* 接替成员需要配置了客户联系功能。
253+
* 接替成员需要在企业微信激活且已经过实名认证。
254+
* </per>
255+
* @param req 转接在职成员的客户给其他成员请求实体
256+
* @return wx cp base resp
257+
* @throws WxErrorException the wx error exception
258+
*/
259+
WxCpUserTransferCustomerResp transferCustomer(WxCpUserTransferCustomerReq req) throws WxErrorException;
260+
261+
/**
262+
* 企业和第三方可通过此接口查询在职成员的客户转接情况。
263+
* <per>
264+
* 权限说明:
265+
*
266+
* 企业需要使用“客户联系”secret或配置到“可调用应用”列表中的自建应用secret所获取的accesstoken来调用(accesstoken如何获取?)。
267+
* 第三方应用需拥有“企业客户权限->客户联系->在职继承”权限
268+
* 接替成员必须在此第三方应用或自建应用的可见范围内。
269+
* </per>
270+
* @param handOverUserid 原添加成员的userid
271+
* @param takeOverUserid 接替成员的userid
272+
* @param cursor 分页查询的cursor,每个分页返回的数据不会超过1000条;不填或为空表示获取第一个分页;
273+
* @return 客户转接接口实体
274+
* @throws WxErrorException the wx error exception
275+
*/
276+
WxCpUserTransferResultResp transferResult(@NotNull String handOverUserid, @NotNull String takeOverUserid, String cursor) throws WxErrorException;
277+
278+
/**
279+
* 企业可通过此接口,分配离职成员的客户给其他成员。
280+
* <per>
281+
* handover_userid必须是已离职用户。
282+
* external_userid必须是handover_userid的客户(即配置了客户联系功能的成员所添加的联系人)。
283+
* 在职成员的每位客户最多被分配2次。客户被转接成功后,将有90个自然日的服务关系保护期,保护期内的客户无法再次被分配。
284+
*
285+
* 权限说明:
286+
*
287+
* 企业需要使用“客户联系”secret或配置到“可调用应用”列表中的自建应用secret所获取的accesstoken来调用(accesstoken如何获取?)。
288+
* 第三方应用需拥有“企业客户权限->客户联系->离职分配”权限
289+
* 接替成员必须在此第三方应用或自建应用的可见范围内。
290+
* 接替成员需要配置了客户联系功能。
291+
* 接替成员需要在企业微信激活且已经过实名认证。
292+
* </per>
293+
* @param req 转接在职成员的客户给其他成员请求实体
294+
* @return wx cp base resp
295+
* @throws WxErrorException the wx error exception
296+
*/
297+
WxCpUserTransferCustomerResp resignedTransferCustomer(WxCpUserTransferCustomerReq req) throws WxErrorException;
298+
299+
/**
300+
* 企业和第三方可通过此接口查询离职成员的客户分配情况。
301+
* <per>
302+
* 权限说明:
303+
*
304+
* 企业需要使用“客户联系”secret或配置到“可调用应用”列表中的自建应用secret所获取的accesstoken来调用(accesstoken如何获取?)。
305+
* 第三方应用需拥有“企业客户权限->客户联系->在职继承”权限
306+
* 接替成员必须在此第三方应用或自建应用的可见范围内。
307+
* </per>
308+
* @param handOverUserid 原添加成员的userid
309+
* @param takeOverUserid 接替成员的userid
310+
* @param cursor 分页查询的cursor,每个分页返回的数据不会超过1000条;不填或为空表示获取第一个分页;
311+
* @return 客户转接接口实体
312+
* @throws WxErrorException the wx error exception
313+
*/
314+
WxCpUserTransferResultResp resignedTransferResult(@NotNull String handOverUserid, @NotNull String takeOverUserid, String cursor) throws WxErrorException;
315+
231316
/**
232317
* <pre>
233318
* 该接口用于获取配置过客户群管理的客户群列表。
@@ -260,6 +345,32 @@ WxCpExternalContactBatchInfo getContactDetailBatch(String userId, String cursor,
260345
*/
261346
WxCpUserExternalGroupChatInfo getGroupChat(String chatId) throws WxErrorException;
262347

348+
/**
349+
*
350+
* 企业可通过此接口,将已离职成员为群主的群,分配给另一个客服成员。
351+
*
352+
* <per>
353+
* 注意::
354+
*
355+
* 群主离职了的客户群,才可继承
356+
* 继承给的新群主,必须是配置了客户联系功能的成员
357+
* 继承给的新群主,必须有设置实名
358+
* 继承给的新群主,必须有激活企业微信
359+
* 同一个人的群,限制每天最多分配300个给新群主
360+
*
361+
* 权限说明:
362+
*
363+
* 企业需要使用“客户联系”secret或配置到“可调用应用”列表中的自建应用secret所获取的accesstoken来调用(accesstoken如何获取?)。
364+
* 第三方应用需拥有“企业客户权限->客户联系->分配离职成员的客户群”权限
365+
* 对于第三方/自建应用,群主必须在应用的可见范围。
366+
* </per>
367+
* @param chatIds 需要转群主的客户群ID列表。取值范围: 1 ~ 100
368+
* @param newOwner 新群主ID
369+
* @return 分配结果,主要是分配失败的群列表
370+
* @throws WxErrorException the wx error exception
371+
*/
372+
WxCpUserExternalGroupChatTransferResp transferGroupChat(String[] chatIds, String newOwner) throws WxErrorException;
373+
263374
/**
264375
* <pre>
265376
* 企业可通过此接口获取成员联系客户的数据,包括发起申请数、新增客户数、聊天数、发送消息数和删除/拉黑成员的客户数等指标。
@@ -397,4 +508,6 @@ WxCpExternalContactBatchInfo getContactDetailBatch(String userId, String cursor,
397508
* @throws WxErrorException the wx error exception
398509
*/
399510
WxCpBaseResp markTag(String userid, String externalUserid, String[] addTag, String[] removeTag) throws WxErrorException;
511+
512+
400513
}

weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpExternalContactServiceImpl.java

+63
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
import me.chanjar.weixin.common.error.WxCpErrorMsgEnum;
88
import me.chanjar.weixin.common.error.WxErrorException;
99
import me.chanjar.weixin.common.error.WxRuntimeException;
10+
import me.chanjar.weixin.common.util.BeanUtils;
11+
import me.chanjar.weixin.common.util.json.GsonParser;
1012
import me.chanjar.weixin.cp.api.WxCpExternalContactService;
1113
import me.chanjar.weixin.cp.api.WxCpService;
1214
import me.chanjar.weixin.cp.bean.WxCpBaseResp;
@@ -15,6 +17,7 @@
1517
import me.chanjar.weixin.cp.bean.external.contact.WxCpExternalContactInfo;
1618
import org.apache.commons.lang3.ArrayUtils;
1719
import org.apache.commons.lang3.StringUtils;
20+
import org.jetbrains.annotations.NotNull;
1821

1922
import java.util.Collections;
2023
import java.util.Date;
@@ -106,6 +109,16 @@ public WxCpExternalContactInfo getContactDetail(String userId) throws WxErrorExc
106109
return WxCpExternalContactInfo.fromJson(responseContent);
107110
}
108111

112+
@Override
113+
public String convertToOpenid(@NotNull String externalUserId) throws WxErrorException {
114+
JsonObject json = new JsonObject();
115+
json.addProperty("external_userid", externalUserId);
116+
final String url = this.mainService.getWxCpConfigStorage().getApiUrl(CONVERT_TO_OPENID);
117+
String responseContent = this.mainService.post(url, json.toString());
118+
JsonObject tmpJson = GsonParser.parse(responseContent);
119+
return tmpJson.get("openid").getAsString();
120+
}
121+
109122
@Override
110123
public WxCpExternalContactBatchInfo getContactDetailBatch(String userId,
111124
String cursor,
@@ -176,6 +189,44 @@ public WxCpBaseResp transferExternalContact(String externalUserid, String handOv
176189
return WxCpBaseResp.fromJson(result);
177190
}
178191

192+
@Override
193+
public WxCpUserTransferCustomerResp transferCustomer(WxCpUserTransferCustomerReq req) throws WxErrorException {
194+
BeanUtils.checkRequiredFields(req);
195+
final String url = this.mainService.getWxCpConfigStorage().getApiUrl(TRANSFER_CUSTOMER);
196+
final String result = this.mainService.post(url, req.toJson());
197+
return WxCpUserTransferCustomerResp.fromJson(result);
198+
}
199+
200+
@Override
201+
public WxCpUserTransferResultResp transferResult(@NotNull String handOverUserid, @NotNull String takeOverUserid, String cursor) throws WxErrorException {
202+
JsonObject json = new JsonObject();
203+
json.addProperty("cursor", cursor);
204+
json.addProperty("handover_userid", handOverUserid);
205+
json.addProperty("takeover_userid", takeOverUserid);
206+
final String url = this.mainService.getWxCpConfigStorage().getApiUrl(TRANSFER_RESULT);
207+
final String result = this.mainService.post(url, json.toString());
208+
return WxCpUserTransferResultResp.fromJson(result);
209+
}
210+
211+
@Override
212+
public WxCpUserTransferCustomerResp resignedTransferCustomer(WxCpUserTransferCustomerReq req) throws WxErrorException {
213+
BeanUtils.checkRequiredFields(req);
214+
final String url = this.mainService.getWxCpConfigStorage().getApiUrl(RESIGNED_TRANSFER_CUSTOMER);
215+
final String result = this.mainService.post(url, req.toJson());
216+
return WxCpUserTransferCustomerResp.fromJson(result);
217+
}
218+
219+
@Override
220+
public WxCpUserTransferResultResp resignedTransferResult(@NotNull String handOverUserid, @NotNull String takeOverUserid, String cursor) throws WxErrorException {
221+
JsonObject json = new JsonObject();
222+
json.addProperty("cursor", cursor);
223+
json.addProperty("handover_userid", handOverUserid);
224+
json.addProperty("takeover_userid", takeOverUserid);
225+
final String url = this.mainService.getWxCpConfigStorage().getApiUrl(RESIGNED_TRANSFER_RESULT);
226+
final String result = this.mainService.post(url, json.toString());
227+
return WxCpUserTransferResultResp.fromJson(result);
228+
}
229+
179230
@Override
180231
public WxCpUserExternalGroupChatList listGroupChat(Integer pageIndex, Integer pageSize, int status, String[] userIds, String[] partyIds) throws WxErrorException {
181232
JsonObject json = new JsonObject();
@@ -206,6 +257,18 @@ public WxCpUserExternalGroupChatInfo getGroupChat(String chatId) throws WxErrorE
206257
return WxCpUserExternalGroupChatInfo.fromJson(result);
207258
}
208259

260+
@Override
261+
public WxCpUserExternalGroupChatTransferResp transferGroupChat(String[] chatIds, String newOwner) throws WxErrorException {
262+
JsonObject json = new JsonObject();
263+
if (ArrayUtils.isNotEmpty(chatIds)) {
264+
json.add("chat_id_list", new Gson().toJsonTree(chatIds).getAsJsonArray());
265+
}
266+
json.addProperty("new_owner", newOwner);
267+
final String url = this.mainService.getWxCpConfigStorage().getApiUrl(GROUP_CHAT_TRANSFER);
268+
final String result = this.mainService.post(url, json.toString());
269+
return WxCpUserExternalGroupChatTransferResp.fromJson(result);
270+
}
271+
209272
@Override
210273
public WxCpUserExternalUserBehaviorStatistic getUserBehaviorStatistic(Date startTime, Date endTime, String[] userIds, String[] partyIds) throws WxErrorException {
211274
JsonObject json = new JsonObject();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
package me.chanjar.weixin.cp.bean.external;
2+
3+
import com.google.gson.annotations.SerializedName;
4+
import lombok.Getter;
5+
import lombok.Setter;
6+
import me.chanjar.weixin.cp.bean.WxCpBaseResp;
7+
import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder;
8+
9+
import java.util.List;
10+
11+
/**
12+
* 分配离职成员的客户群结果
13+
* @author pg
14+
* @date 2021年6月21日
15+
*/
16+
@Getter
17+
@Setter
18+
public class WxCpUserExternalGroupChatTransferResp extends WxCpBaseResp {
19+
private static final long serialVersionUID = -943124579487821819L;
20+
/**
21+
* 没有成功继承的群列表
22+
*/
23+
@SerializedName("failed_chat_list")
24+
private List<GroupChatFailedTransfer> failedChatList;
25+
26+
public static WxCpUserExternalGroupChatTransferResp fromJson(String json) {
27+
return WxCpGsonBuilder.create().fromJson(json, WxCpUserExternalGroupChatTransferResp.class);
28+
}
29+
30+
public String toJson() {
31+
return WxCpGsonBuilder.create().toJson(this);
32+
}
33+
34+
@Getter
35+
@Setter
36+
public static class GroupChatFailedTransfer extends WxCpBaseResp {
37+
private static final long serialVersionUID = -5836775099634587239L;
38+
/**
39+
* 没能成功继承的群ID
40+
*/
41+
private String chatId;
42+
43+
public static WxCpUserExternalGroupChatTransferResp.GroupChatFailedTransfer fromJson(String json) {
44+
return WxCpGsonBuilder.create().fromJson(json, WxCpUserExternalGroupChatTransferResp.GroupChatFailedTransfer.class);
45+
}
46+
47+
public String toJson() {
48+
return WxCpGsonBuilder.create().toJson(this);
49+
}
50+
}
51+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package me.chanjar.weixin.cp.bean.external;
2+
3+
import com.google.gson.annotations.SerializedName;
4+
import lombok.Getter;
5+
import lombok.Setter;
6+
import me.chanjar.weixin.common.annotation.Required;
7+
import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder;
8+
9+
import java.io.Serializable;
10+
import java.util.List;
11+
12+
/**
13+
* 转接在职成员的客户给其他成员,请求对象
14+
*
15+
* @author pg
16+
* @date 2021年6月21日
17+
*/
18+
@Getter
19+
@Setter
20+
public class WxCpUserTransferCustomerReq implements Serializable {
21+
private static final long serialVersionUID = -309819538677411801L;
22+
/**
23+
* 原跟进成员的userid
24+
*/
25+
@SerializedName("handover_userid")
26+
@Required
27+
private String handOverUserid;
28+
/**
29+
* 接替成员的userid
30+
*/
31+
@SerializedName("takeover_userid")
32+
@Required
33+
private String takeOverUserid;
34+
/**
35+
* 客户的external_userid列表,每次最多分配100个客户
36+
*/
37+
@SerializedName("external_userid")
38+
@Required
39+
private List<String> externalUserid;
40+
/**
41+
* 转移成功后发给客户的消息,最多200个字符,不填则使用默认文案
42+
*/
43+
@SerializedName("transfer_success_msg")
44+
private String transferMsg;
45+
46+
public String toJson() {
47+
return WxCpGsonBuilder.create().toJson(this);
48+
}
49+
}

0 commit comments

Comments
 (0)