@@ -1,12 +1,18 @@ | |||
package me.chanjar.weixin.mp.api; | |||
import me.chanjar.weixin.common.exception.WxErrorException; | |||
import me.chanjar.weixin.mp.bean.kefu.request.WxMpKfAccountRequest; | |||
import me.chanjar.weixin.mp.bean.kefu.result.*; | |||
import java.io.File; | |||
import java.util.Date; | |||
import me.chanjar.weixin.common.exception.WxErrorException; | |||
import me.chanjar.weixin.mp.bean.WxMpCustomMessage; | |||
import me.chanjar.weixin.mp.bean.kefu.request.WxMpKfAccountRequest; | |||
import me.chanjar.weixin.mp.bean.kefu.result.WxMpKfList; | |||
import me.chanjar.weixin.mp.bean.kefu.result.WxMpKfMsgList; | |||
import me.chanjar.weixin.mp.bean.kefu.result.WxMpKfOnlineList; | |||
import me.chanjar.weixin.mp.bean.kefu.result.WxMpKfSessionGetResult; | |||
import me.chanjar.weixin.mp.bean.kefu.result.WxMpKfSessionList; | |||
import me.chanjar.weixin.mp.bean.kefu.result.WxMpKfSessionWaitCaseList; | |||
/** | |||
* 客服接口 , | |||
* 命名采用kefu拼音的原因是: | |||
@@ -17,6 +23,14 @@ import java.util.Date; | |||
*/ | |||
public interface WxMpKefuService { | |||
/** | |||
* <pre> | |||
* 发送客服消息 | |||
* 详情请见: <a href="http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140547&token=&lang=zh_CN">发送客服消息</a> | |||
* </pre> | |||
*/ | |||
boolean customMessageSend(WxMpCustomMessage message) throws WxErrorException; | |||
//*******************客服管理接口***********************// | |||
/** | |||
@@ -3,7 +3,6 @@ package me.chanjar.weixin.mp.api; | |||
import me.chanjar.weixin.common.bean.WxJsapiSignature; | |||
import me.chanjar.weixin.common.exception.WxErrorException; | |||
import me.chanjar.weixin.common.util.http.RequestExecutor; | |||
import me.chanjar.weixin.mp.bean.WxMpCustomMessage; | |||
import me.chanjar.weixin.mp.bean.WxMpIndustry; | |||
import me.chanjar.weixin.mp.bean.WxMpMassGroupMessage; | |||
import me.chanjar.weixin.mp.bean.WxMpMassNews; | |||
@@ -82,14 +81,6 @@ public interface WxMpService { | |||
*/ | |||
WxJsapiSignature createJsapiSignature(String url) throws WxErrorException; | |||
/** | |||
* <pre> | |||
* 发送客服消息 | |||
* 详情请见: http://mp.weixin.qq.com/wiki/index.php?title=发送客服消息 | |||
* </pre> | |||
*/ | |||
void customMessageSend(WxMpCustomMessage message) throws WxErrorException; | |||
/** | |||
* <pre> | |||
* 上传群发用的图文消息,上传后才能群发图文消息 | |||
@@ -3,15 +3,18 @@ package me.chanjar.weixin.mp.api.impl; | |||
import java.io.File; | |||
import java.util.Date; | |||
import org.slf4j.Logger; | |||
import org.slf4j.LoggerFactory; | |||
import com.google.gson.JsonObject; | |||
import me.chanjar.weixin.common.bean.result.WxError; | |||
import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; | |||
import me.chanjar.weixin.common.exception.WxErrorException; | |||
import me.chanjar.weixin.common.util.http.MediaUploadRequestExecutor; | |||
import me.chanjar.weixin.common.util.http.SimpleGetRequestExecutor; | |||
import me.chanjar.weixin.common.util.http.SimplePostRequestExecutor; | |||
import me.chanjar.weixin.mp.api.WxMpKefuService; | |||
import me.chanjar.weixin.mp.api.WxMpService; | |||
import me.chanjar.weixin.mp.bean.WxMpCustomMessage; | |||
import me.chanjar.weixin.mp.bean.kefu.request.WxMpKfAccountRequest; | |||
import me.chanjar.weixin.mp.bean.kefu.request.WxMpKfSessionRequest; | |||
import me.chanjar.weixin.mp.bean.kefu.result.WxMpKfList; | |||
@@ -27,6 +30,8 @@ import me.chanjar.weixin.mp.bean.kefu.result.WxMpKfSessionWaitCaseList; | |||
* | |||
*/ | |||
public class WxMpKefuServiceImpl implements WxMpKefuService { | |||
protected final Logger log = LoggerFactory | |||
.getLogger(WxMpKefuServiceImpl.class); | |||
private static final String API_URL_PREFIX = "https://api.weixin.qq.com/customservice"; | |||
private WxMpService wxMpService; | |||
@@ -34,19 +39,31 @@ public class WxMpKefuServiceImpl implements WxMpKefuService { | |||
this.wxMpService = wxMpService; | |||
} | |||
@Override | |||
public boolean customMessageSend(WxMpCustomMessage message) | |||
throws WxErrorException { | |||
String url = "https://api.weixin.qq.com/cgi-bin/message/custom/send"; | |||
String responseContent = this.wxMpService.post(url, message.toJson()); | |||
this.log.debug("\nurl:{}\nparams:{}\nresponse:{}", url, message.toJson(), | |||
responseContent); | |||
return true; | |||
} | |||
@Override | |||
public WxMpKfList kfList() throws WxErrorException { | |||
String url = "https://api.weixin.qq.com/cgi-bin/customservice/getkflist"; | |||
String responseContent = this.wxMpService | |||
.execute(new SimpleGetRequestExecutor(), url, null); | |||
String url = API_URL_PREFIX + "/getkflist"; | |||
String responseContent = this.wxMpService.get(url, null); | |||
this.log.debug("\nurl:{}\nparams:{}\nresponse:{}", url, null, | |||
responseContent); | |||
return WxMpKfList.fromJson(responseContent); | |||
} | |||
@Override | |||
public WxMpKfOnlineList kfOnlineList() throws WxErrorException { | |||
String url = "https://api.weixin.qq.com/cgi-bin/customservice/getonlinekflist"; | |||
String responseContent = this.wxMpService | |||
.execute(new SimpleGetRequestExecutor(), url, null); | |||
String url = API_URL_PREFIX + "/getonlinekflist"; | |||
String responseContent = this.wxMpService.get(url, null); | |||
this.log.debug("\nurl:{}\nparams:{}\nresponse:{}", url, null, | |||
responseContent); | |||
return WxMpKfOnlineList.fromJson(responseContent); | |||
} | |||
@@ -54,8 +71,9 @@ public class WxMpKefuServiceImpl implements WxMpKefuService { | |||
public boolean kfAccountAdd(WxMpKfAccountRequest request) | |||
throws WxErrorException { | |||
String url = API_URL_PREFIX + "/kfaccount/add"; | |||
this.wxMpService.execute(new SimplePostRequestExecutor(), url, | |||
request.toJson()); | |||
String responseContent = this.wxMpService.post(url, request.toJson()); | |||
this.log.debug("\nurl:{}\nparams:{}\nresponse:{}", url, request.toJson(), | |||
responseContent); | |||
return true; | |||
} | |||
@@ -63,16 +81,18 @@ public class WxMpKefuServiceImpl implements WxMpKefuService { | |||
public boolean kfAccountUpdate(WxMpKfAccountRequest request) | |||
throws WxErrorException { | |||
String url = API_URL_PREFIX + "/kfaccount/update"; | |||
this.wxMpService.execute(new SimplePostRequestExecutor(), url, | |||
request.toJson()); | |||
String responseContent = this.wxMpService.post(url, request.toJson()); | |||
this.log.debug("\nurl:{}\nparams:{}\nresponse:{}", url, request.toJson(), | |||
responseContent); | |||
return true; | |||
} | |||
@Override | |||
public boolean kfAccountInviteWorker(WxMpKfAccountRequest request) throws WxErrorException { | |||
String url = API_URL_PREFIX + "/kfaccount/inviteworker"; | |||
this.wxMpService.execute(new SimplePostRequestExecutor(), url, | |||
request.toJson()); | |||
String responseContent = this.wxMpService.post(url, request.toJson()); | |||
this.log.debug("\nurl:{}\nparams:{}\nresponse:{}", url, request.toJson(), | |||
responseContent); | |||
return true; | |||
} | |||
@@ -80,14 +100,20 @@ public class WxMpKefuServiceImpl implements WxMpKefuService { | |||
public boolean kfAccountUploadHeadImg(String kfAccount, File imgFile) | |||
throws WxErrorException { | |||
String url = API_URL_PREFIX + "/kfaccount/uploadheadimg?kf_account=" + kfAccount; | |||
this.wxMpService.execute(new MediaUploadRequestExecutor(), url, imgFile); | |||
WxMediaUploadResult responseContent = this.wxMpService | |||
.execute(new MediaUploadRequestExecutor(), url, imgFile); | |||
this.log.debug("\nurl:{}\nparams:{}&file:{}\nresponse:{}", url, kfAccount, | |||
imgFile.getAbsolutePath(), | |||
responseContent); | |||
return true; | |||
} | |||
@Override | |||
public boolean kfAccountDel(String kfAccount) throws WxErrorException { | |||
String url = API_URL_PREFIX + "/kfaccount/del?kf_account=" + kfAccount; | |||
this.wxMpService.execute(new SimpleGetRequestExecutor(), url, null); | |||
String responseContent = this.wxMpService.get(url, null); | |||
this.log.debug("\nurl:{}\nparams:{}\nresponse:{}", url, null, | |||
responseContent); | |||
return true; | |||
} | |||
@@ -96,8 +122,9 @@ public class WxMpKefuServiceImpl implements WxMpKefuService { | |||
throws WxErrorException { | |||
WxMpKfSessionRequest request = new WxMpKfSessionRequest(kfAccount, openid); | |||
String url = API_URL_PREFIX + "/kfsession/create"; | |||
this.wxMpService.execute(new SimplePostRequestExecutor(), url, | |||
request.toJson()); | |||
String responseContent = this.wxMpService.post(url, request.toJson()); | |||
this.log.debug("\nurl:{}\nparams:{}\nresponse:{}", url, request.toJson(), | |||
responseContent); | |||
return true; | |||
} | |||
@@ -106,8 +133,9 @@ public class WxMpKefuServiceImpl implements WxMpKefuService { | |||
throws WxErrorException { | |||
WxMpKfSessionRequest request = new WxMpKfSessionRequest(kfAccount, openid); | |||
String url = API_URL_PREFIX + "/kfsession/close"; | |||
this.wxMpService.execute(new SimplePostRequestExecutor(), url, | |||
request.toJson()); | |||
String responseContent = this.wxMpService.post(url, request.toJson()); | |||
this.log.debug("\nurl:{}\nparams:{}\nresponse:{}", url, request.toJson(), | |||
responseContent); | |||
return true; | |||
} | |||
@@ -115,8 +143,9 @@ public class WxMpKefuServiceImpl implements WxMpKefuService { | |||
public WxMpKfSessionGetResult kfSessionGet(String openid) | |||
throws WxErrorException { | |||
String url = API_URL_PREFIX + "/kfsession/getsession?openid=" + openid; | |||
String responseContent = this.wxMpService | |||
.execute(new SimpleGetRequestExecutor(), url, null); | |||
String responseContent = this.wxMpService.get(url, null); | |||
this.log.debug("\nurl:{}\nparams:{}\nresponse:{}", url, null, | |||
responseContent); | |||
return WxMpKfSessionGetResult.fromJson(responseContent); | |||
} | |||
@@ -124,8 +153,9 @@ public class WxMpKefuServiceImpl implements WxMpKefuService { | |||
public WxMpKfSessionList kfSessionList(String kfAccount) | |||
throws WxErrorException { | |||
String url = API_URL_PREFIX + "/kfsession/getsessionlist?kf_account=" + kfAccount; | |||
String responseContent = this.wxMpService | |||
.execute(new SimpleGetRequestExecutor(), url, null); | |||
String responseContent = this.wxMpService.get(url, null); | |||
this.log.debug("\nurl:{}\nparams:{}\nresponse:{}", url, null, | |||
responseContent); | |||
return WxMpKfSessionList.fromJson(responseContent); | |||
} | |||
@@ -133,8 +163,9 @@ public class WxMpKefuServiceImpl implements WxMpKefuService { | |||
public WxMpKfSessionWaitCaseList kfSessionGetWaitCase() | |||
throws WxErrorException { | |||
String url = API_URL_PREFIX + "/kfsession/getwaitcase"; | |||
String responseContent = this.wxMpService | |||
.execute(new SimpleGetRequestExecutor(), url, null); | |||
String responseContent = this.wxMpService.get(url, null); | |||
this.log.debug("\nurl:{}\nparams:{}\nresponse:{}", url, null, | |||
responseContent); | |||
return WxMpKfSessionWaitCaseList.fromJson(responseContent); | |||
} | |||
@@ -156,7 +187,9 @@ public class WxMpKefuServiceImpl implements WxMpKefuService { | |||
param.addProperty("msgid", msgId); //msgid 消息id顺序从小到大,从1开始 | |||
param.addProperty("number", number); //number 每次获取条数,最多10000条 | |||
String responseContent = this.wxMpService.execute(new SimplePostRequestExecutor(), url, param.toString()); | |||
String responseContent = this.wxMpService.post(url, param.toString()); | |||
this.log.debug("\nurl:{}\nparams:{}\nresponse:{}", url, param.toString(), | |||
responseContent); | |||
return WxMpKfMsgList.fromJson(responseContent); | |||
} | |||
@@ -44,7 +44,6 @@ import me.chanjar.weixin.mp.api.WxMpQrcodeService; | |||
import me.chanjar.weixin.mp.api.WxMpService; | |||
import me.chanjar.weixin.mp.api.WxMpUserService; | |||
import me.chanjar.weixin.mp.api.WxMpUserTagService; | |||
import me.chanjar.weixin.mp.bean.WxMpCustomMessage; | |||
import me.chanjar.weixin.mp.bean.WxMpIndustry; | |||
import me.chanjar.weixin.mp.bean.WxMpMassGroupMessage; | |||
import me.chanjar.weixin.mp.bean.WxMpMassNews; | |||
@@ -203,12 +202,6 @@ public class WxMpServiceImpl implements WxMpService { | |||
return jsapiSignature; | |||
} | |||
@Override | |||
public void customMessageSend(WxMpCustomMessage message) throws WxErrorException { | |||
String url = "https://api.weixin.qq.com/cgi-bin/message/custom/send"; | |||
execute(new SimplePostRequestExecutor(), url, message.toJson()); | |||
} | |||
@Override | |||
public WxMpMassUploadResult massNewsUpload(WxMpMassNews news) throws WxErrorException { | |||
String url = "https://api.weixin.qq.com/cgi-bin/media/uploadnews"; | |||
@@ -1,44 +0,0 @@ | |||
package me.chanjar.weixin.mp.api; | |||
import com.google.inject.Inject; | |||
import me.chanjar.weixin.common.api.WxConsts; | |||
import me.chanjar.weixin.common.exception.WxErrorException; | |||
import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl; | |||
import me.chanjar.weixin.mp.bean.WxMpCustomMessage; | |||
import org.testng.annotations.Guice; | |||
import org.testng.annotations.Test; | |||
/*** | |||
* 测试发送客服消息 | |||
* @author chanjarster | |||
* | |||
*/ | |||
@Test(groups="customMessageAPI") | |||
@Guice(modules = ApiTestModule.class) | |||
public class WxMpCustomMessageAPITest { | |||
@Inject | |||
protected WxMpServiceImpl wxService; | |||
public void testSendCustomMessage() throws WxErrorException { | |||
ApiTestModule.WxXmlMpInMemoryConfigStorage configStorage = (ApiTestModule.WxXmlMpInMemoryConfigStorage) this.wxService.getWxMpConfigStorage(); | |||
WxMpCustomMessage message = new WxMpCustomMessage(); | |||
message.setMsgType(WxConsts.CUSTOM_MSG_TEXT); | |||
message.setToUser(configStorage.getOpenId()); | |||
message.setContent("欢迎欢迎,热烈欢迎\n换行测试\n超链接:<a href=\"http://www.baidu.com\">Hello World</a>"); | |||
this.wxService.customMessageSend(message); | |||
} | |||
public void testSendCustomMessageWithKfAccount() throws WxErrorException { | |||
ApiTestModule.WxXmlMpInMemoryConfigStorage configStorage = (ApiTestModule.WxXmlMpInMemoryConfigStorage) this.wxService.getWxMpConfigStorage(); | |||
WxMpCustomMessage message = new WxMpCustomMessage(); | |||
message.setMsgType(WxConsts.CUSTOM_MSG_TEXT); | |||
message.setToUser(configStorage.getOpenId()); | |||
message.setKfAccount(configStorage.getKfAccount()); | |||
message.setContent("欢迎欢迎,热烈欢迎\n换行测试\n超链接:<a href=\"http://www.baidu.com\">Hello World</a>"); | |||
this.wxService.customMessageSend(message); | |||
} | |||
} |
@@ -11,9 +11,11 @@ import org.testng.annotations.Test; | |||
import com.google.inject.Inject; | |||
import me.chanjar.weixin.common.api.WxConsts; | |||
import me.chanjar.weixin.common.exception.WxErrorException; | |||
import me.chanjar.weixin.mp.api.ApiTestModule; | |||
import me.chanjar.weixin.mp.api.ApiTestModule.WxXmlMpInMemoryConfigStorage; | |||
import me.chanjar.weixin.mp.bean.WxMpCustomMessage; | |||
import me.chanjar.weixin.mp.bean.kefu.request.WxMpKfAccountRequest; | |||
import me.chanjar.weixin.mp.bean.kefu.result.WxMpKfInfo; | |||
import me.chanjar.weixin.mp.bean.kefu.result.WxMpKfList; | |||
@@ -35,6 +37,31 @@ public class WxMpKefuServiceImplTest { | |||
@Inject | |||
protected WxMpServiceImpl wxService; | |||
public void testSendCustomMessage() throws WxErrorException { | |||
ApiTestModule.WxXmlMpInMemoryConfigStorage configStorage = (ApiTestModule.WxXmlMpInMemoryConfigStorage) this.wxService | |||
.getWxMpConfigStorage(); | |||
WxMpCustomMessage message = new WxMpCustomMessage(); | |||
message.setMsgType(WxConsts.CUSTOM_MSG_TEXT); | |||
message.setToUser(configStorage.getOpenId()); | |||
message.setContent( | |||
"欢迎欢迎,热烈欢迎\n换行测试\n超链接:<a href=\"http://www.baidu.com\">Hello World</a>"); | |||
this.wxService.getKefuService().customMessageSend(message); | |||
} | |||
public void testSendCustomMessageWithKfAccount() throws WxErrorException { | |||
ApiTestModule.WxXmlMpInMemoryConfigStorage configStorage = (ApiTestModule.WxXmlMpInMemoryConfigStorage) this.wxService | |||
.getWxMpConfigStorage(); | |||
WxMpCustomMessage message = new WxMpCustomMessage(); | |||
message.setMsgType(WxConsts.CUSTOM_MSG_TEXT); | |||
message.setToUser(configStorage.getOpenId()); | |||
message.setKfAccount(configStorage.getKfAccount()); | |||
message.setContent( | |||
"欢迎欢迎,热烈欢迎\n换行测试\n超链接:<a href=\"http://www.baidu.com\">Hello World</a>"); | |||
this.wxService.getKefuService().customMessageSend(message); | |||
} | |||
public void testKfList() throws WxErrorException { | |||
WxMpKfList kfList = this.wxService.getKefuService().kfList(); | |||
Assert.assertNotNull(kfList); | |||
@@ -123,7 +150,7 @@ public class WxMpKefuServiceImplTest { | |||
} | |||
@Test(dataProvider = "getKfAccountAndOpenid") | |||
public void testKfSessionGet(String kfAccount, | |||
public void testKfSessionGet(@SuppressWarnings("unused") String kfAccount, | |||
String openid) throws WxErrorException { | |||
WxMpKfSessionGetResult result = this.wxService.getKefuService() | |||
.kfSessionGet(openid); | |||
@@ -1,5 +1,9 @@ | |||
package me.chanjar.weixin.mp.demo; | |||
import java.util.Map; | |||
import java.util.Random; | |||
import java.util.regex.Pattern; | |||
import me.chanjar.weixin.common.exception.WxErrorException; | |||
import me.chanjar.weixin.common.session.WxSession; | |||
import me.chanjar.weixin.common.session.WxSessionManager; | |||
@@ -10,10 +14,6 @@ import me.chanjar.weixin.mp.bean.WxMpCustomMessage; | |||
import me.chanjar.weixin.mp.bean.WxMpXmlMessage; | |||
import me.chanjar.weixin.mp.bean.WxMpXmlOutMessage; | |||
import java.util.Map; | |||
import java.util.Random; | |||
import java.util.regex.Pattern; | |||
public class DemoGuessNumberHandler implements WxMpMessageHandler, WxMpMessageMatcher { | |||
private Random random = new Random(); | |||
@@ -57,14 +57,14 @@ public class DemoGuessNumberHandler implements WxMpMessageHandler, WxMpMessageMa | |||
.toUser(wxMessage.getFromUserName()) | |||
.content("请猜一个100以内的数字") | |||
.build(); | |||
wxMpService.customMessageSend(m); | |||
wxMpService.getKefuService().customMessageSend(m); | |||
} else { | |||
WxMpCustomMessage m = WxMpCustomMessage | |||
.TEXT() | |||
.toUser(wxMessage.getFromUserName()) | |||
.content("放弃了吗?那请重新猜一个100以内的数字") | |||
.build(); | |||
wxMpService.customMessageSend(m); | |||
wxMpService.getKefuService().customMessageSend(m); | |||
} | |||
session.setAttribute("guessing", Boolean.TRUE); | |||
@@ -92,7 +92,7 @@ public class DemoGuessNumberHandler implements WxMpMessageHandler, WxMpMessageMa | |||
.toUser(wxMessage.getFromUserName()) | |||
.content("小了") | |||
.build(); | |||
wxMpService.customMessageSend(m); | |||
wxMpService.getKefuService().customMessageSend(m); | |||
} else if (guessNumber > answer) { | |||
WxMpCustomMessage m = WxMpCustomMessage | |||
@@ -100,7 +100,7 @@ public class DemoGuessNumberHandler implements WxMpMessageHandler, WxMpMessageMa | |||
.toUser(wxMessage.getFromUserName()) | |||
.content("大了") | |||
.build(); | |||
wxMpService.customMessageSend(m); | |||
wxMpService.getKefuService().customMessageSend(m); | |||
} else { | |||
WxMpCustomMessage m = WxMpCustomMessage | |||
.TEXT() | |||
@@ -108,7 +108,7 @@ public class DemoGuessNumberHandler implements WxMpMessageHandler, WxMpMessageMa | |||
.content("Bingo!") | |||
.build(); | |||
session.removeAttribute("guessing"); | |||
wxMpService.customMessageSend(m); | |||
wxMpService.getKefuService().customMessageSend(m); | |||
} | |||
} | |||