From 0ac6828d84ce6a66e2366489e75de3711fd950e9 Mon Sep 17 00:00:00 2001 From: jinyu Date: Mon, 28 Mar 2016 20:38:03 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E9=82=80=E8=AF=B7=E7=BB=91?= =?UTF-8?q?=E5=AE=9A=E5=AE=A2=E6=9C=8D=E5=B8=90=E5=8F=B7=E6=8E=A5=E5=8F=A3?= =?UTF-8?q?=E4=BB=A5=E5=8F=8A=E5=AE=A2=E6=9C=8D=E6=8E=A5=E5=8F=A3=E5=91=BD?= =?UTF-8?q?=E5=90=8D=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGE.md | 6 +- .../com/foxinmy/weixin4j/mp/WeixinProxy.java | 43 ++++++++--- .../foxinmy/weixin4j/mp/api/CustomApi.java | 74 +++++++++++++------ .../foxinmy/weixin4j/mp/api/weixin.properties | 24 +++--- .../{CustomRecord.java => KfChatRecord.java} | 6 +- .../foxinmy/weixin4j/mp/test/CustomTest.java | 22 +++--- 6 files changed, 115 insertions(+), 60 deletions(-) rename weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/model/{CustomRecord.java => KfChatRecord.java} (93%) diff --git a/CHANGE.md b/CHANGE.md index 2af9e97b..df71efe7 100644 --- a/CHANGE.md +++ b/CHANGE.md @@ -667,4 +667,8 @@ + weixin4j-base:新增海关接口 - + weixin4j-base:添加日志支持 \ No newline at end of file + + weixin4j-base:添加日志支持 + + * 2016-03-28 + + + weixin4j-mp:新增邀请绑定客服帐号接口以及客服接口命名调整 \ No newline at end of file diff --git a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/WeixinProxy.java b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/WeixinProxy.java index 357dfcb6..2fbb0423 100644 --- a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/WeixinProxy.java +++ b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/WeixinProxy.java @@ -29,10 +29,10 @@ import com.foxinmy.weixin4j.mp.api.UserApi; import com.foxinmy.weixin4j.mp.message.NotifyMessage; import com.foxinmy.weixin4j.mp.message.TemplateMessage; import com.foxinmy.weixin4j.mp.model.AutoReplySetting; -import com.foxinmy.weixin4j.mp.model.CustomRecord; import com.foxinmy.weixin4j.mp.model.Following; import com.foxinmy.weixin4j.mp.model.Group; import com.foxinmy.weixin4j.mp.model.KfAccount; +import com.foxinmy.weixin4j.mp.model.KfChatRecord; import com.foxinmy.weixin4j.mp.model.KfSession; import com.foxinmy.weixin4j.mp.model.Menu; import com.foxinmy.weixin4j.mp.model.MenuMatchRule; @@ -485,8 +485,8 @@ public class WeixinProxy { * 查询客服聊天记录 * @throws WeixinException */ - public List getCustomRecord(Date startTime, Date endTime, Pageable pageable) throws WeixinException { - return customApi.getCustomRecord(startTime, endTime, pageable); + public List getCustomRecord(Date startTime, Date endTime, Pageable pageable) throws WeixinException { + return customApi.getKfChatRecord(startTime, endTime, pageable); } /** @@ -532,8 +532,8 @@ public class WeixinProxy { * "http://mp.weixin.qq.com/wiki/9/6fff6f191ef92c126b043ada035cc935.html#.E6.B7.BB.E5.8A.A0.E5.AE.A2.E6.9C.8D.E8.B4.A6.E5.8F.B7"> * 新增客服账号 */ - public JsonResult createAccount(String id, String name, String pwd) throws WeixinException { - return customApi.createAccount(id, name, pwd); + public JsonResult createKfAccount(String id, String name, String pwd) throws WeixinException { + return customApi.createKfAccount(id, name, pwd); } /** @@ -556,8 +556,29 @@ public class WeixinProxy { * "http://mp.weixin.qq.com/wiki/9/6fff6f191ef92c126b043ada035cc935.html#.E8.AE.BE.E7.BD.AE.E5.AE.A2.E6.9C.8D.E4.BF.A1.E6.81.AF"> * 新增客服账号 */ - public JsonResult updateAccount(String id, String name, String pwd) throws WeixinException { - return customApi.updateAccount(id, name, pwd); + public JsonResult updateKfAccount(String id, String name, String pwd) throws WeixinException { + return customApi.updateKfAccount(id, name, pwd); + } + + /** + * 邀请绑定客服帐号 + * 新添加的客服帐号是不能直接使用的,只有客服人员用微信号绑定了客服账号后,方可登录Web客服进行操作。此接口发起一个绑定邀请到客服人员微信号 + * ,客服人员需要在微信客户端上用该微信号确认后帐号才可用。尚未绑定微信号的帐号可以进行绑定邀请操作,邀请未失效时不能对该帐号进行再次绑定微信号邀请。 + * + * @param kfAccount + * 完整客服帐号,格式为:帐号前缀@公众号微信号 + * @param inviteAccount + * 接收绑定邀请的客服微信号 + * @return 处理结果 + * @see com.foxinmy.weixin4j.mp.api.CustomApi + * @see 邀请绑定客服帐号 + * @throws WeixinException + */ + public JsonResult inviteKfAccount(String kfAccount, String inviteAccount) + throws WeixinException { + return customApi.inviteKfAccount(kfAccount, inviteAccount); } /** @@ -579,8 +600,8 @@ public class WeixinProxy { * "http://mp.weixin.qq.com/wiki/9/6fff6f191ef92c126b043ada035cc935.html#.E4.B8.8A.E4.BC.A0.E5.AE.A2.E6.9C.8D.E5.A4.B4.E5.83.8F"> * 上传客服头像 */ - public JsonResult uploadAccountHeadimg(String accountId, InputStream is, String fileName) throws WeixinException { - return customApi.uploadAccountHeadimg(accountId, is, fileName); + public JsonResult uploadKfAvatar(String accountId, InputStream is, String fileName) throws WeixinException { + return customApi.uploadKfAvatar(accountId, is, fileName); } /** @@ -598,8 +619,8 @@ public class WeixinProxy { * "http://mp.weixin.qq.com/wiki/9/6fff6f191ef92c126b043ada035cc935.html#.E5.88.A0.E9.99.A4.E5.AE.A2.E6.9C.8D.E8.B4.A6.E5.8F.B7"> * 删除客服账号 */ - public JsonResult deleteAccount(String id) throws WeixinException { - return customApi.deleteAccount(id); + public JsonResult deleteKfAccount(String id) throws WeixinException { + return customApi.deleteKfAccount(id); } /** diff --git a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/api/CustomApi.java b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/api/CustomApi.java index bbbfc9c3..ebc39385 100644 --- a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/api/CustomApi.java +++ b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/api/CustomApi.java @@ -16,8 +16,8 @@ import com.foxinmy.weixin4j.http.weixin.JsonResult; import com.foxinmy.weixin4j.http.weixin.WeixinResponse; import com.foxinmy.weixin4j.model.Pageable; import com.foxinmy.weixin4j.model.Token; -import com.foxinmy.weixin4j.mp.model.CustomRecord; import com.foxinmy.weixin4j.mp.model.KfAccount; +import com.foxinmy.weixin4j.mp.model.KfChatRecord; import com.foxinmy.weixin4j.mp.model.KfSession; import com.foxinmy.weixin4j.token.TokenHolder; import com.foxinmy.weixin4j.util.DigestUtil; @@ -55,15 +55,15 @@ public class CustomApi extends MpApi { * @param pageable * 分页数据 * @throws WeixinException - * @see com.foxinmy.weixin4j.mp.model.CustomRecord + * @see com.foxinmy.weixin4j.mp.model.KfChatRecord * @see 查询客服聊天记录 * @see 查询客服聊天记录 */ - public List getCustomRecord(Date startTime, Date endTime, + public List getKfChatRecord(Date startTime, Date endTime, Pageable pageable) throws WeixinException { - List records = new ArrayList(); - String custom_record_uri = getRequestUri("custom_record_uri"); + List records = new ArrayList(); + String kf_chatrecord_uri = getRequestUri("kf_chatrecord_uri"); Token token = tokenHolder.getToken(); JSONObject obj = new JSONObject(); obj.put("starttime", startTime.getTime() / 1000); @@ -72,14 +72,14 @@ public class CustomApi extends MpApi { obj.put("pagesize", Math.min(50, pageable.getPageSize())); obj.put("pageindex", pageable.getPageNumber()); WeixinResponse response = weixinExecutor.post( - String.format(custom_record_uri, token.getAccessToken()), + String.format(kf_chatrecord_uri, token.getAccessToken()), obj.toJSONString()); String text = response.getAsJson().getString("recordlist"); if (StringUtil.isBlank(text) || "[]".equals(text)) { break; } - records.addAll(JSON.parseArray(text, CustomRecord.class)); + records.addAll(JSON.parseArray(text, KfChatRecord.class)); pageable = new Pageable(pageable.getPageNumber() + 1, Math.min(50, Math.max(1, pageable.getPageSize() - ((i + 1) * 50)))); @@ -108,14 +108,14 @@ public class CustomApi extends MpApi { Token token = tokenHolder.getToken(); String text = ""; if (isOnline) { - String getonlinekflist_uri = getRequestUri("getonlinekflist_uri"); + String kf_onlinelist_uri = getRequestUri("kf_onlinelist_uri"); WeixinResponse response = weixinExecutor.get(String.format( - getonlinekflist_uri, token.getAccessToken())); + kf_onlinelist_uri, token.getAccessToken())); text = response.getAsJson().getString("kf_online_list"); } else { - String getkflist_uri = getRequestUri("getkflist_uri"); + String kf_list_uri = getRequestUri("kf_list_uri"); WeixinResponse response = weixinExecutor.get(String.format( - getkflist_uri, token.getAccessToken())); + kf_list_uri, token.getAccessToken())); text = response.getAsJson().getString("kf_list"); } return JSON.parseArray(text, KfAccount.class); @@ -138,16 +138,16 @@ public class CustomApi extends MpApi { * @see 新增客服账号 */ - public JsonResult createAccount(String id, String name, String pwd) + public JsonResult createKfAccount(String id, String name, String pwd) throws WeixinException { JSONObject obj = new JSONObject(); obj.put("kf_account", id); obj.put("nickname", name); obj.put("password", DigestUtil.MD5(pwd)); - String custom_add_uri = getRequestUri("custom_add_uri"); + String kf_create_uri = getRequestUri("kf_create_uri"); Token token = tokenHolder.getToken(); WeixinResponse response = weixinExecutor.post( - String.format(custom_add_uri, token.getAccessToken()), + String.format(kf_create_uri, token.getAccessToken()), obj.toJSONString()); return response.getAsJsonResult(); } @@ -169,16 +169,44 @@ public class CustomApi extends MpApi { * @see 新增客服账号 */ - public JsonResult updateAccount(String id, String name, String pwd) + public JsonResult updateKfAccount(String id, String name, String pwd) throws WeixinException { JSONObject obj = new JSONObject(); obj.put("kf_account", id); obj.put("nickname", name); obj.put("password", DigestUtil.MD5(pwd)); - String custom_update_uri = getRequestUri("custom_update_uri"); + String kf_update_uri = getRequestUri("kf_update_uri"); Token token = tokenHolder.getToken(); WeixinResponse response = weixinExecutor.post( - String.format(custom_update_uri, token.getAccessToken()), + String.format(kf_update_uri, token.getAccessToken()), + obj.toJSONString()); + return response.getAsJsonResult(); + } + + /** + * 邀请绑定客服帐号 + * 新添加的客服帐号是不能直接使用的,只有客服人员用微信号绑定了客服账号后,方可登录Web客服进行操作。此接口发起一个绑定邀请到客服人员微信号 + * ,客服人员需要在微信客户端上用该微信号确认后帐号才可用。尚未绑定微信号的帐号可以进行绑定邀请操作,邀请未失效时不能对该帐号进行再次绑定微信号邀请。 + * + * @param kfAccount + * 完整客服帐号,格式为:帐号前缀@公众号微信号 + * @param inviteAccount + * 接收绑定邀请的客服微信号 + * @return 处理结果 + * @see 邀请绑定客服帐号 + * @throws WeixinException + */ + public JsonResult inviteKfAccount(String kfAccount, String inviteAccount) + throws WeixinException { + JSONObject obj = new JSONObject(); + obj.put("kf_account", kfAccount); + obj.put("invite_wx", inviteAccount); + String kf_invite_uri = getRequestUri("kf_invite_uri"); + Token token = tokenHolder.getToken(); + WeixinResponse response = weixinExecutor.post( + String.format(kf_invite_uri, token.getAccessToken()), obj.toJSONString()); return response.getAsJsonResult(); } @@ -199,7 +227,7 @@ public class CustomApi extends MpApi { * @see 上传客服头像 */ - public JsonResult uploadAccountHeadimg(String accountId, InputStream is, + public JsonResult uploadKfAvatar(String accountId, InputStream is, String fileName) throws WeixinException { if (StringUtil.isBlank(fileName)) { fileName = ObjectId.get().toHexString(); @@ -208,9 +236,9 @@ public class CustomApi extends MpApi { fileName = String.format("%s.jpg", fileName); } Token token = tokenHolder.getToken(); - String custom_uploadheadimg_uri = getRequestUri("custom_uploadheadimg_uri"); + String kf_avatar_uri = getRequestUri("kf_avatar_uri"); WeixinResponse response = weixinExecutor.post(String.format( - custom_uploadheadimg_uri, token.getAccessToken(), accountId), + kf_avatar_uri, token.getAccessToken(), accountId), new FormBodyPart("media", new InputStreamBody(is, ContentType.IMAGE_JPG.getMimeType(), fileName))); @@ -229,11 +257,11 @@ public class CustomApi extends MpApi { * @see 删除客服账号 */ - public JsonResult deleteAccount(String id) throws WeixinException { + public JsonResult deleteKfAccount(String id) throws WeixinException { Token token = tokenHolder.getToken(); - String custom_delete_uri = getRequestUri("custom_delete_uri"); + String kf_delete_uri = getRequestUri("kf_delete_uri"); WeixinResponse response = weixinExecutor.get(String.format( - custom_delete_uri, token.getAccessToken(), id)); + kf_delete_uri, token.getAccessToken(), id)); return response.getAsJsonResult(); } diff --git a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/api/weixin.properties b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/api/weixin.properties index 088a9da5..b8b0026c 100644 --- a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/api/weixin.properties +++ b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/api/weixin.properties @@ -80,19 +80,21 @@ mass_preview_uri={api_cgi_url}/message/mass/preview?access_token=%s # \u67e5\u8be2\u7fa4\u53d1\u72b6\u6001 mass_get_uri={api_cgi_url}/message/mass/get?access_token=%s # \u5ba2\u670d\u804a\u5929\u8bb0\u5f55 -custom_record_uri={api_cgi_url}/customservice/getrecord?access_token=%s +kf_chatrecord_uri={api_cgi_url}/customservice/getrecord?access_token=%s # \u5ba2\u670d\u57fa\u672c\u4fe1\u606f -getkflist_uri={api_cgi_url}/customservice/getkflist?access_token=%s -# \u65b0\u589e\u591a\u5ba2\u670d\u8d26\u53f7 -custom_add_uri={api_base_url}/customservice/kfaccount/add?access_token=%s -# \u66f4\u65b0\u591a\u5ba2\u670d\u8d26\u53f7 -custom_update_uri={api_base_url}/customservice/kfaccount/update?access_token=%s -# \u4e0a\u4f20\u5ba2\u670d\u5934\u50cf -custom_uploadheadimg_uri={api_base_url}/customservice/kfacount/uploadheadimg?access_token=%s&kf_account=%s -# \u5220\u9664\u5ba2\u670d\u8d26\u53f7 -custom_delete_uri={api_base_url}/customservice/kfaccount/del?access_token=%s&kf_account=%s +kf_list_uri={api_cgi_url}/customservice/getkflist?access_token=%s # \u5728\u7ebf\u5ba2\u670d\u57fa\u672c\u4fe1\u606f -getonlinekflist_uri={api_cgi_url}/customservice/getonlinekflist?access_token=%s +kf_onlinelist_uri={api_cgi_url}/customservice/getonlinekflist?access_token=%s +# \u65b0\u589e\u591a\u5ba2\u670d\u8d26\u53f7 +kf_create_uri={api_base_url}/customservice/kfaccount/add?access_token=%s +# \u9080\u8bf7\u7ed1\u5b9a\u5ba2\u670d\u5e10\u53f7 +kf_invite_uri={api_base_url}customservice/kfaccount/inviteworker?access_token=%s +# \u66f4\u65b0\u591a\u5ba2\u670d\u8d26\u53f7 +kf_update_uri={api_base_url}/customservice/kfaccount/update?access_token=%s +# \u4e0a\u4f20\u5ba2\u670d\u5934\u50cf +kf_avatar_uri={api_base_url}/customservice/kfacount/uploadheadimg?access_token=%s&kf_account=%s +# \u5220\u9664\u5ba2\u670d\u8d26\u53f7 +kf_delete_uri={api_base_url}/customservice/kfaccount/del?access_token=%s&kf_account=%s # \u521b\u5efa\u5ba2\u670d\u4f1a\u8bdd kfsession_create_uri={api_base_url}/customservice/kfsession/create?access_token=%s # \u5173\u95ed\u5ba2\u670d\u4f1a\u8bdd diff --git a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/model/CustomRecord.java b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/model/KfChatRecord.java similarity index 93% rename from weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/model/CustomRecord.java rename to weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/model/KfChatRecord.java index 3da6c807..4c5f84d7 100644 --- a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/model/CustomRecord.java +++ b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/model/KfChatRecord.java @@ -9,12 +9,12 @@ import com.foxinmy.weixin4j.mp.type.CustomRecordOperCode; /** * 客服聊天记录 * - * @className CustomRecord + * @className KfChatRecord * @author jy * @date 2014年6月28日 * @since JDK 1.6 */ -public class CustomRecord implements Serializable { +public class KfChatRecord implements Serializable { private static final long serialVersionUID = -4024147769411601325L; @@ -94,7 +94,7 @@ public class CustomRecord implements Serializable { @Override public String toString() { StringBuilder sb = new StringBuilder(); - sb.append("[CustomRecord worker=").append(worker); + sb.append("[KfChatRecord worker=").append(worker); sb.append(" ,openId=").append(openId); sb.append(" ,operCode=").append(operCode); sb.append(" ,time=").append(time); diff --git a/weixin4j-mp/src/test/java/com/foxinmy/weixin4j/mp/test/CustomTest.java b/weixin4j-mp/src/test/java/com/foxinmy/weixin4j/mp/test/CustomTest.java index f90c8e14..87deef29 100644 --- a/weixin4j-mp/src/test/java/com/foxinmy/weixin4j/mp/test/CustomTest.java +++ b/weixin4j-mp/src/test/java/com/foxinmy/weixin4j/mp/test/CustomTest.java @@ -15,8 +15,8 @@ import com.foxinmy.weixin4j.exception.WeixinException; import com.foxinmy.weixin4j.http.weixin.JsonResult; import com.foxinmy.weixin4j.model.Pageable; import com.foxinmy.weixin4j.mp.api.CustomApi; -import com.foxinmy.weixin4j.mp.model.CustomRecord; import com.foxinmy.weixin4j.mp.model.KfAccount; +import com.foxinmy.weixin4j.mp.model.KfChatRecord; import com.foxinmy.weixin4j.mp.model.KfSession; /** @@ -38,14 +38,14 @@ public class CustomTest extends TokenTest { } @Test - public void customRecord() throws WeixinException { + public void kfChatRecord() throws WeixinException { Calendar calendar = Calendar.getInstance(); calendar.set(Calendar.HOUR_OF_DAY, 9); calendar.add(Calendar.DAY_OF_MONTH, -2); Date starttime = calendar.getTime(); calendar.set(Calendar.HOUR_OF_DAY, 21); Date endtime = calendar.getTime(); - List recordList = customApi.getCustomRecord(starttime, + List recordList = customApi.getKfChatRecord(starttime, endtime, new Pageable(1, 70)); System.out.println(recordList); } @@ -59,30 +59,30 @@ public class CustomTest extends TokenTest { } @Test - public void addAccount() throws WeixinException { - JsonResult result = customApi.createAccount("test@test", "test", + public void createKfAccount() throws WeixinException { + JsonResult result = customApi.createKfAccount("test@test", "test", "123456"); Assert.assertEquals(0, result.getCode()); } @Test - public void updateAccount() throws WeixinException { - JsonResult result = customApi.updateAccount("temp1@canyidianzhang", + public void updateKfAccount() throws WeixinException { + JsonResult result = customApi.updateKfAccount("temp1@canyidianzhang", "temp", "123456"); Assert.assertEquals(0, result.getCode()); } @Test - public void uploadAccountHeadimg() throws WeixinException, IOException { - JsonResult result = customApi.uploadAccountHeadimg( + public void uploadKfAvatar() throws WeixinException, IOException { + JsonResult result = customApi.uploadKfAvatar( "temp1@canyidianzhang", new FileInputStream(new File( "/Users/jy/Music/简谱/风动草.jpg")), "风动草.jpg"); Assert.assertEquals(0, result.getCode()); } @Test - public void deleteAccount() throws WeixinException, IOException { - JsonResult result = customApi.deleteAccount("temp@canyidianzhang"); + public void deleteKfAccount() throws WeixinException, IOException { + JsonResult result = customApi.deleteKfAccount("temp@canyidianzhang"); Assert.assertEquals(0, result.getCode()); }