@@ -22,7 +22,7 @@ import me.chanjar.weixin.mp.api.WxMpMessageRouter; | |||
import me.chanjar.weixin.mp.api.WxMpServiceImpl; | |||
import me.chanjar.weixin.mp.bean.WxMpXmlMessage; | |||
import me.chanjar.weixin.mp.bean.WxMpXmlOutMessage; | |||
import me.chanjar.weixin.mp.bean.customerservice.result.WxMpKfOnlineList; | |||
import me.chanjar.weixin.mp.bean.kefu.result.WxMpKfOnlineList; | |||
/** | |||
* | |||
@@ -3,9 +3,12 @@ package me.chanjar.weixin.mp.api; | |||
import java.io.File; | |||
import me.chanjar.weixin.common.exception.WxErrorException; | |||
import me.chanjar.weixin.mp.bean.customerservice.request.WxMpKfAccountRequest; | |||
import me.chanjar.weixin.mp.bean.customerservice.result.WxMpKfList; | |||
import me.chanjar.weixin.mp.bean.customerservice.result.WxMpKfOnlineList; | |||
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.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; | |||
/** | |||
* 客服接口 , | |||
@@ -15,59 +18,112 @@ import me.chanjar.weixin.mp.bean.customerservice.result.WxMpKfOnlineList; | |||
* @author Binary Wang | |||
* | |||
*/ | |||
public interface WxMpKefuService { | |||
public interface WxMpKefuService { | |||
//*******************客服管理接口***********************// | |||
/** | |||
* <pre> | |||
* 获取客服基本信息 | |||
* 详情请见:<a href="http://mp.weixin.qq.com/wiki/18/749901f4e123170fb8a4d447ae6040ba.html">客服管理</a> | |||
* https://api.weixin.qq.com/cgi-bin/customservice/getkflist?access_token=ACCESS_TOKEN | |||
* 接口url格式:https://api.weixin.qq.com/cgi-bin/customservice/getkflist?access_token=ACCESS_TOKEN | |||
* </pre> | |||
*/ | |||
WxMpKfList kfList() throws WxErrorException; | |||
/** | |||
* <pre> | |||
* 获取在线客服接待信息 | |||
* 详情请见:<a href="http://mp.weixin.qq.com/wiki/18/749901f4e123170fb8a4d447ae6040ba.html">客服管理</a> | |||
* https://api.weixin.qq.com/cgi-bin/customservice/getonlinekflist?access_token=ACCESS_TOKEN | |||
* 接口url格式:https://api.weixin.qq.com/cgi-bin/customservice/getonlinekflist?access_token=ACCESS_TOKEN | |||
* </pre> | |||
*/ | |||
WxMpKfOnlineList kfOnlineList() throws WxErrorException; | |||
/** | |||
* <pre> | |||
* 添加客服账号 | |||
* 详情请见:<a href="http://mp.weixin.qq.com/wiki/18/749901f4e123170fb8a4d447ae6040ba.html">客服管理</a> | |||
* https://api.weixin.qq.com/customservice/kfaccount/add?access_token=ACCESS_TOKEN | |||
* 接口url格式:https://api.weixin.qq.com/customservice/kfaccount/add?access_token=ACCESS_TOKEN | |||
* </pre> | |||
*/ | |||
boolean kfAccountAdd(WxMpKfAccountRequest request) throws WxErrorException; | |||
/** | |||
* <pre> | |||
* 设置客服信息(更新) | |||
* 详情请见:<a href="http://mp.weixin.qq.com/wiki/18/749901f4e123170fb8a4d447ae6040ba.html">客服管理</a> | |||
* https://api.weixin.qq.com/customservice/kfaccount/update?access_token=ACCESS_TOKEN | |||
* 接口url格式:https://api.weixin.qq.com/customservice/kfaccount/update?access_token=ACCESS_TOKEN | |||
* </pre> | |||
*/ | |||
boolean kfAccountUpdate(WxMpKfAccountRequest request) throws WxErrorException; | |||
/** | |||
* <pre> | |||
* 上传客服头像 | |||
* 详情请见:<a href="http://mp.weixin.qq.com/wiki/18/749901f4e123170fb8a4d447ae6040ba.html">客服管理</a> | |||
* http://api.weixin.qq.com/customservice/kfaccount/uploadheadimg?access_token=ACCESS_TOKEN&kf_account=KFACCOUNT | |||
* 接口url格式:http://api.weixin.qq.com/customservice/kfaccount/uploadheadimg?access_token=ACCESS_TOKEN&kf_account=KFACCOUNT | |||
* </pre> | |||
*/ | |||
boolean kfAccountUploadHeadImg(String kfAccount, File imgFile) throws WxErrorException; | |||
boolean kfAccountUploadHeadImg(String kfAccount, File imgFile) | |||
throws WxErrorException; | |||
/** | |||
* <pre> | |||
* 删除客服账号 | |||
* 详情请见:<a href="http://mp.weixin.qq.com/wiki/18/749901f4e123170fb8a4d447ae6040ba.html">客服管理</a> | |||
* https://api.weixin.qq.com/customservice/kfaccount/del?access_token=ACCESS_TOKEN&kf_account=KFACCOUNT | |||
* 接口url格式:https://api.weixin.qq.com/customservice/kfaccount/del?access_token=ACCESS_TOKEN&kf_account=KFACCOUNT | |||
* </pre> | |||
*/ | |||
boolean kfAccountDel(String kfAccount) throws WxErrorException; | |||
//*******************多客服会话控制接口***********************// | |||
/** | |||
* <pre> | |||
* 创建会话 | |||
* 开发者可以使用本接口,为多客服的客服工号创建会话,将某个客户直接指定给客服工号接待,需要注意此接口不会受客服自动接入数以及自动接入开关限制。只能为在线的客服(PC客户端在线,或者已绑定多客服助手)创建会话。 | |||
* 详情请见:<a href="http://mp.weixin.qq.com/wiki/4/4b256cfb246b22ad020e07cf8a61a738.html">多客服会话控制接口</a> | |||
* 接口url格式: https://api.weixin.qq.com/customservice/kfsession/create?access_token=ACCESS_TOKEN | |||
* </pre> | |||
*/ | |||
boolean kfSessionCreate(String openid, String kfAccount, String text) throws WxErrorException; | |||
/** | |||
* <pre> | |||
* 关闭会话 | |||
* 开发者可以使用本接口,关闭一个会话。 | |||
* 详情请见:<a href="http://mp.weixin.qq.com/wiki/4/4b256cfb246b22ad020e07cf8a61a738.html">多客服会话控制接口</a> | |||
* 接口url格式: https://api.weixin.qq.com/customservice/kfsession/close?access_token=ACCESS_TOKEN | |||
* </pre> | |||
*/ | |||
boolean kfSessionClose(String openid, String kfAccount, String text) throws WxErrorException; | |||
/** | |||
* <pre> | |||
* 获取客户的会话状态 | |||
* 开发者可以通过本接口获取客户当前的会话状态。 | |||
* 详情请见:<a href="http://mp.weixin.qq.com/wiki/4/4b256cfb246b22ad020e07cf8a61a738.html">多客服会话控制接口</a> | |||
* 接口url格式: https://api.weixin.qq.com/customservice/kfsession/getsession?access_token=ACCESS_TOKEN&openid=OPENID | |||
* </pre> | |||
*/ | |||
WxMpKfSessionGetResult kfSessionGet(String openid) throws WxErrorException; | |||
/** | |||
* <pre> | |||
* 获取客服的会话列表 | |||
* 开发者可以通过本接口获取某个客服正在接待的会话列表。 | |||
* 详情请见:<a href="http://mp.weixin.qq.com/wiki/4/4b256cfb246b22ad020e07cf8a61a738.html">多客服会话控制接口</a> | |||
* 接口url格式: https://api.weixin.qq.com/customservice/kfsession/getsessionlist?access_token=ACCESS_TOKEN&kf_account=KFACCOUNT | |||
* </pre> | |||
*/ | |||
WxMpKfSessionList kfSessionList(String kfAccount) throws WxErrorException; | |||
/** | |||
* <pre> | |||
* 获取未接入会话列表 | |||
* 开发者可以通过本接口获取当前正在等待队列中的会话列表,此接口最多返回最早进入队列的100个未接入会话。 | |||
* 详情请见:<a href="http://mp.weixin.qq.com/wiki/4/4b256cfb246b22ad020e07cf8a61a738.html">多客服会话控制接口</a> | |||
* 接口url格式: https://api.weixin.qq.com/customservice/kfsession/getwaitcase?access_token=ACCESS_TOKEN | |||
* </pre> | |||
*/ | |||
WxMpKfSessionWaitCaseList kfSessionGetWaitCase() throws WxErrorException; | |||
} |
@@ -1,10 +1,48 @@ | |||
package me.chanjar.weixin.mp.api; | |||
import com.google.gson.*; | |||
import java.io.File; | |||
import java.io.IOException; | |||
import java.io.InputStream; | |||
import java.io.StringReader; | |||
import java.io.UnsupportedEncodingException; | |||
import java.net.URLEncoder; | |||
import java.nio.charset.StandardCharsets; | |||
import java.security.NoSuchAlgorithmException; | |||
import java.util.Arrays; | |||
import java.util.Date; | |||
import java.util.HashMap; | |||
import java.util.List; | |||
import java.util.Map; | |||
import java.util.Map.Entry; | |||
import java.util.SortedMap; | |||
import java.util.TreeMap; | |||
import java.util.UUID; | |||
import org.apache.http.Consts; | |||
import org.apache.http.HttpHost; | |||
import org.apache.http.client.ClientProtocolException; | |||
import org.apache.http.client.config.RequestConfig; | |||
import org.apache.http.client.methods.CloseableHttpResponse; | |||
import org.apache.http.client.methods.HttpGet; | |||
import org.apache.http.client.methods.HttpPost; | |||
import org.apache.http.conn.ssl.SSLConnectionSocketFactory; | |||
import org.apache.http.entity.StringEntity; | |||
import org.apache.http.impl.client.BasicResponseHandler; | |||
import org.apache.http.impl.client.CloseableHttpClient; | |||
import org.slf4j.Logger; | |||
import org.slf4j.LoggerFactory; | |||
import org.slf4j.helpers.MessageFormatter; | |||
import com.google.gson.JsonArray; | |||
import com.google.gson.JsonElement; | |||
import com.google.gson.JsonObject; | |||
import com.google.gson.JsonParser; | |||
import com.google.gson.JsonPrimitive; | |||
import com.google.gson.internal.Streams; | |||
import com.google.gson.reflect.TypeToken; | |||
import com.google.gson.stream.JsonReader; | |||
import com.thoughtworks.xstream.XStream; | |||
import me.chanjar.weixin.common.api.WxConsts; | |||
import me.chanjar.weixin.common.bean.WxAccessToken; | |||
import me.chanjar.weixin.common.bean.WxCardApiSignature; | |||
@@ -19,43 +57,62 @@ import me.chanjar.weixin.common.util.RandomUtils; | |||
import me.chanjar.weixin.common.util.crypto.SHA1; | |||
import me.chanjar.weixin.common.util.crypto.WxCryptUtil; | |||
import me.chanjar.weixin.common.util.fs.FileUtils; | |||
import me.chanjar.weixin.common.util.http.*; | |||
import me.chanjar.weixin.common.util.http.ApacheHttpClientBuilder; | |||
import me.chanjar.weixin.common.util.http.DefaultApacheHttpHttpClientBuilder; | |||
import me.chanjar.weixin.common.util.http.MediaDownloadRequestExecutor; | |||
import me.chanjar.weixin.common.util.http.MediaUploadRequestExecutor; | |||
import me.chanjar.weixin.common.util.http.RequestExecutor; | |||
import me.chanjar.weixin.common.util.http.SimpleGetRequestExecutor; | |||
import me.chanjar.weixin.common.util.http.SimplePostRequestExecutor; | |||
import me.chanjar.weixin.common.util.http.URIUtil; | |||
import me.chanjar.weixin.common.util.http.Utf8ResponseHandler; | |||
import me.chanjar.weixin.common.util.json.GsonHelper; | |||
import me.chanjar.weixin.common.util.json.WxGsonBuilder; | |||
import me.chanjar.weixin.common.util.xml.XStreamInitializer; | |||
import me.chanjar.weixin.mp.api.impl.WxMpKefuServiceImpl; | |||
import me.chanjar.weixin.mp.bean.*; | |||
import me.chanjar.weixin.mp.bean.result.*; | |||
import me.chanjar.weixin.mp.util.http.*; | |||
import me.chanjar.weixin.mp.bean.WxMpCustomMessage; | |||
import me.chanjar.weixin.mp.bean.WxMpGroup; | |||
import me.chanjar.weixin.mp.bean.WxMpIndustry; | |||
import me.chanjar.weixin.mp.bean.WxMpMassGroupMessage; | |||
import me.chanjar.weixin.mp.bean.WxMpMassNews; | |||
import me.chanjar.weixin.mp.bean.WxMpMassOpenIdsMessage; | |||
import me.chanjar.weixin.mp.bean.WxMpMassPreviewMessage; | |||
import me.chanjar.weixin.mp.bean.WxMpMassVideo; | |||
import me.chanjar.weixin.mp.bean.WxMpMaterial; | |||
import me.chanjar.weixin.mp.bean.WxMpMaterialArticleUpdate; | |||
import me.chanjar.weixin.mp.bean.WxMpMaterialNews; | |||
import me.chanjar.weixin.mp.bean.WxMpSemanticQuery; | |||
import me.chanjar.weixin.mp.bean.WxMpTemplateMessage; | |||
import me.chanjar.weixin.mp.bean.result.WxMediaImgUploadResult; | |||
import me.chanjar.weixin.mp.bean.result.WxMpCardResult; | |||
import me.chanjar.weixin.mp.bean.result.WxMpMassSendResult; | |||
import me.chanjar.weixin.mp.bean.result.WxMpMassUploadResult; | |||
import me.chanjar.weixin.mp.bean.result.WxMpMaterialCountResult; | |||
import me.chanjar.weixin.mp.bean.result.WxMpMaterialFileBatchGetResult; | |||
import me.chanjar.weixin.mp.bean.result.WxMpMaterialNewsBatchGetResult; | |||
import me.chanjar.weixin.mp.bean.result.WxMpMaterialUploadResult; | |||
import me.chanjar.weixin.mp.bean.result.WxMpMaterialVideoInfoResult; | |||
import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken; | |||
import me.chanjar.weixin.mp.bean.result.WxMpPayCallback; | |||
import me.chanjar.weixin.mp.bean.result.WxMpPayRefundResult; | |||
import me.chanjar.weixin.mp.bean.result.WxMpPayResult; | |||
import me.chanjar.weixin.mp.bean.result.WxMpPrepayIdResult; | |||
import me.chanjar.weixin.mp.bean.result.WxMpQrCodeTicket; | |||
import me.chanjar.weixin.mp.bean.result.WxMpSemanticQueryResult; | |||
import me.chanjar.weixin.mp.bean.result.WxMpUser; | |||
import me.chanjar.weixin.mp.bean.result.WxMpUserCumulate; | |||
import me.chanjar.weixin.mp.bean.result.WxMpUserList; | |||
import me.chanjar.weixin.mp.bean.result.WxMpUserSummary; | |||
import me.chanjar.weixin.mp.bean.result.WxRedpackResult; | |||
import me.chanjar.weixin.mp.util.http.MaterialDeleteRequestExecutor; | |||
import me.chanjar.weixin.mp.util.http.MaterialNewsInfoRequestExecutor; | |||
import me.chanjar.weixin.mp.util.http.MaterialUploadRequestExecutor; | |||
import me.chanjar.weixin.mp.util.http.MaterialVideoInfoRequestExecutor; | |||
import me.chanjar.weixin.mp.util.http.MaterialVoiceAndImageDownloadRequestExecutor; | |||
import me.chanjar.weixin.mp.util.http.MediaImgUploadRequestExecutor; | |||
import me.chanjar.weixin.mp.util.http.QrCodeRequestExecutor; | |||
import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; | |||
import org.apache.commons.io.Charsets; | |||
import org.apache.http.Consts; | |||
import org.apache.http.HttpHost; | |||
import org.apache.http.client.ClientProtocolException; | |||
import org.apache.http.client.config.RequestConfig; | |||
import org.apache.http.client.methods.CloseableHttpResponse; | |||
import org.apache.http.client.methods.HttpGet; | |||
import org.apache.http.client.methods.HttpPost; | |||
import org.apache.http.conn.ssl.SSLConnectionSocketFactory; | |||
import org.apache.http.entity.StringEntity; | |||
import org.apache.http.impl.client.BasicResponseHandler; | |||
import org.apache.http.impl.client.CloseableHttpClient; | |||
import org.slf4j.Logger; | |||
import org.slf4j.LoggerFactory; | |||
import org.slf4j.helpers.MessageFormatter; | |||
import java.io.File; | |||
import java.io.IOException; | |||
import java.io.InputStream; | |||
import java.io.StringReader; | |||
import java.io.UnsupportedEncodingException; | |||
import java.net.URLEncoder; | |||
import java.nio.charset.StandardCharsets; | |||
import java.security.NoSuchAlgorithmException; | |||
import java.util.*; | |||
import java.util.Map.Entry; | |||
public class WxMpServiceImpl implements WxMpService { | |||
protected final Logger log = LoggerFactory.getLogger(WxMpServiceImpl.class); | |||
@@ -8,9 +8,13 @@ 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.customerservice.request.WxMpKfAccountRequest; | |||
import me.chanjar.weixin.mp.bean.customerservice.result.WxMpKfList; | |||
import me.chanjar.weixin.mp.bean.customerservice.result.WxMpKfOnlineList; | |||
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; | |||
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; | |||
/** | |||
* | |||
@@ -27,45 +31,103 @@ public class WxMpKefuServiceImpl implements WxMpKefuService { | |||
@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 responseContent = this.wxMpService | |||
.execute(new SimpleGetRequestExecutor(), url, null); | |||
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 responseContent = this.wxMpService | |||
.execute(new SimpleGetRequestExecutor(), url, null); | |||
return WxMpKfOnlineList.fromJson(responseContent); | |||
} | |||
@Override | |||
public boolean kfAccountAdd(WxMpKfAccountRequest request) throws WxErrorException { | |||
public boolean kfAccountAdd(WxMpKfAccountRequest request) | |||
throws WxErrorException { | |||
String url = "https://api.weixin.qq.com/customservice/kfaccount/add"; | |||
this.wxMpService.execute(new SimplePostRequestExecutor(), url, request.toJson()); | |||
this.wxMpService.execute(new SimplePostRequestExecutor(), url, | |||
request.toJson()); | |||
return true; | |||
} | |||
@Override | |||
public boolean kfAccountUpdate(WxMpKfAccountRequest request) throws WxErrorException { | |||
public boolean kfAccountUpdate(WxMpKfAccountRequest request) | |||
throws WxErrorException { | |||
String url = "https://api.weixin.qq.com/customservice/kfaccount/update"; | |||
this.wxMpService.execute(new SimplePostRequestExecutor(), url, request.toJson()); | |||
this.wxMpService.execute(new SimplePostRequestExecutor(), url, | |||
request.toJson()); | |||
return true; | |||
} | |||
@Override | |||
public boolean kfAccountUploadHeadImg(String kfAccount, File imgFile) throws WxErrorException { | |||
String url = "https://api.weixin.qq.com/customservice/kfaccount/uploadheadimg?kf_account=" + kfAccount ; | |||
public boolean kfAccountUploadHeadImg(String kfAccount, File imgFile) | |||
throws WxErrorException { | |||
String url = "https://api.weixin.qq.com/customservice/kfaccount/uploadheadimg?kf_account=" | |||
+ kfAccount; | |||
this.wxMpService.execute(new MediaUploadRequestExecutor(), url, imgFile); | |||
return true; | |||
} | |||
@Override | |||
public boolean kfAccountDel(String kfAccount) throws WxErrorException { | |||
String url = "https://api.weixin.qq.com/customservice/kfaccount/del?kf_account=" + kfAccount; | |||
String url = "https://api.weixin.qq.com/customservice/kfaccount/del?kf_account=" | |||
+ kfAccount; | |||
this.wxMpService.execute(new SimpleGetRequestExecutor(), url, null); | |||
return true; | |||
} | |||
@Override | |||
public boolean kfSessionCreate(String openid, String kfAccount, String text) | |||
throws WxErrorException { | |||
WxMpKfSessionRequest request = new WxMpKfSessionRequest(kfAccount, openid, | |||
text); | |||
String url = "https://api.weixin.qq.com/customservice/kfsession/create"; | |||
this.wxMpService.execute(new SimplePostRequestExecutor(), url, | |||
request.toJson()); | |||
return true; | |||
} | |||
@Override | |||
public boolean kfSessionClose(String openid, String kfAccount, String text) | |||
throws WxErrorException { | |||
WxMpKfSessionRequest request = new WxMpKfSessionRequest(kfAccount, openid, | |||
text); | |||
String url = "https://api.weixin.qq.com/customservice/kfsession/close"; | |||
this.wxMpService.execute(new SimplePostRequestExecutor(), url, | |||
request.toJson()); | |||
return true; | |||
} | |||
@Override | |||
public WxMpKfSessionGetResult kfSessionGet(String openid) | |||
throws WxErrorException { | |||
String url = "https://api.weixin.qq.com/customservice/kfsession/getsession?openid=" | |||
+ openid; | |||
String responseContent = this.wxMpService | |||
.execute(new SimpleGetRequestExecutor(), url, null); | |||
return WxMpKfSessionGetResult.fromJson(responseContent); | |||
} | |||
@Override | |||
public WxMpKfSessionList kfSessionList(String kfAccount) | |||
throws WxErrorException { | |||
String url = "https://api.weixin.qq.com/customservice/kfsession/getsessionlist?kf_account=" | |||
+ kfAccount; | |||
String responseContent = this.wxMpService | |||
.execute(new SimpleGetRequestExecutor(), url, null); | |||
return WxMpKfSessionList.fromJson(responseContent); | |||
} | |||
@Override | |||
public WxMpKfSessionWaitCaseList kfSessionGetWaitCase() | |||
throws WxErrorException { | |||
String url = "https://api.weixin.qq.com/customservice/kfsession/getwaitcase"; | |||
String responseContent = this.wxMpService | |||
.execute(new SimpleGetRequestExecutor(), url, null); | |||
return WxMpKfSessionWaitCaseList.fromJson(responseContent); | |||
} | |||
} |
@@ -1,4 +1,4 @@ | |||
package me.chanjar.weixin.mp.bean.customerservice.request; | |||
package me.chanjar.weixin.mp.bean.kefu.request; | |||
import java.io.Serializable; | |||
@@ -0,0 +1,66 @@ | |||
package me.chanjar.weixin.mp.bean.kefu.request; | |||
import java.io.Serializable; | |||
import org.apache.commons.lang3.builder.ToStringBuilder; | |||
import org.apache.commons.lang3.builder.ToStringStyle; | |||
import com.google.gson.annotations.SerializedName; | |||
import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; | |||
public class WxMpKfSessionRequest implements Serializable { | |||
private static final long serialVersionUID = -5451863610674856927L; | |||
/** | |||
* kf_account 完整客服账号,格式为:账号前缀@公众号微信号 | |||
*/ | |||
@SerializedName("kf_account") | |||
private String kfAccount; | |||
/** | |||
* openid 客户openid | |||
*/ | |||
@SerializedName("openid") | |||
private String openid; | |||
/** | |||
* text 附加信息,文本会展示在客服人员的多客服客户端 | |||
* 目前看起来无用,主要是老版的多客服客户端使用 | |||
*/ | |||
@SerializedName("text") | |||
@Deprecated | |||
private String text; | |||
public WxMpKfSessionRequest(String kfAccount, String openid, String text) { | |||
this.kfAccount = kfAccount; | |||
this.openid = openid; | |||
this.text = text; | |||
} | |||
@Override | |||
public String toString() { | |||
return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); | |||
} | |||
public String toJson() { | |||
return WxMpGsonBuilder.INSTANCE.create().toJson(this); | |||
} | |||
public String getKfAccount() { | |||
return this.kfAccount; | |||
} | |||
public void setKfAccount(String kfAccount) { | |||
this.kfAccount = kfAccount; | |||
} | |||
public String getText() { | |||
return this.text; | |||
} | |||
public void setText(String text) { | |||
this.text = text; | |||
} | |||
} |
@@ -1,8 +1,9 @@ | |||
package me.chanjar.weixin.mp.bean.customerservice.result; | |||
package me.chanjar.weixin.mp.bean.kefu.result; | |||
import java.io.Serializable; | |||
import org.apache.commons.lang3.builder.ToStringBuilder; | |||
import org.apache.commons.lang3.builder.ToStringStyle; | |||
import com.google.gson.annotations.Expose; | |||
import com.google.gson.annotations.SerializedName; | |||
@@ -20,38 +21,38 @@ public class WxMpKfInfo implements Serializable { | |||
*/ | |||
@SerializedName("kf_account") | |||
private String account; | |||
/** | |||
* kf_headimgurl 客服头像地址 | |||
*/ | |||
@SerializedName("kf_headimgurl") | |||
private String headImgUrl; | |||
/** | |||
* kf_id 客服工号 | |||
*/ | |||
@SerializedName("kf_id") | |||
private String id; | |||
/** | |||
* kf_nick 客服昵称 | |||
*/ | |||
@SerializedName("kf_nick") | |||
private String nick; | |||
/** | |||
* status 客服在线状态 1:pc在线,2:手机在线。若pc和手机同时在线则为 1+2=3 | |||
*/ | |||
@SerializedName("status") | |||
private Integer status; | |||
/** | |||
* auto_accept 客服设置的最大自动接入数 | |||
*/ | |||
@Expose | |||
@SerializedName("auto_accept") | |||
private Integer autoAccept; | |||
/** | |||
* accepted_case 客服当前正在接待的会话数 | |||
* @return | |||
@@ -118,6 +119,6 @@ public class WxMpKfInfo implements Serializable { | |||
@Override | |||
public String toString() { | |||
return ToStringBuilder.reflectionToString(this); | |||
return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); | |||
} | |||
} |
@@ -1,8 +1,9 @@ | |||
package me.chanjar.weixin.mp.bean.customerservice.result; | |||
package me.chanjar.weixin.mp.bean.kefu.result; | |||
import java.util.List; | |||
import org.apache.commons.lang3.builder.ToStringBuilder; | |||
import org.apache.commons.lang3.builder.ToStringStyle; | |||
import com.google.gson.annotations.SerializedName; | |||
@@ -18,7 +19,7 @@ public class WxMpKfList { | |||
@Override | |||
public String toString() { | |||
return ToStringBuilder.reflectionToString(this); | |||
return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); | |||
} | |||
public List<WxMpKfInfo> getKfList() { |
@@ -1,8 +1,9 @@ | |||
package me.chanjar.weixin.mp.bean.customerservice.result; | |||
package me.chanjar.weixin.mp.bean.kefu.result; | |||
import java.util.List; | |||
import org.apache.commons.lang3.builder.ToStringBuilder; | |||
import org.apache.commons.lang3.builder.ToStringStyle; | |||
import com.google.gson.annotations.SerializedName; | |||
@@ -18,7 +19,7 @@ public class WxMpKfOnlineList { | |||
@Override | |||
public String toString() { | |||
return ToStringBuilder.reflectionToString(this); | |||
return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); | |||
} | |||
public List<WxMpKfInfo> getKfOnlineList() { |
@@ -0,0 +1,61 @@ | |||
package me.chanjar.weixin.mp.bean.kefu.result; | |||
import org.apache.commons.lang3.builder.ToStringBuilder; | |||
import org.apache.commons.lang3.builder.ToStringStyle; | |||
import com.google.gson.annotations.SerializedName; | |||
/** | |||
* | |||
* @author Binary Wang | |||
* | |||
*/ | |||
public class WxMpKfSession { | |||
/** | |||
* kf_account 正在接待的客服,为空表示没有人在接待 | |||
*/ | |||
@SerializedName("kf_account") | |||
private String kfAccount; | |||
/** | |||
* createtime 会话接入的时间 或者 来访时间,UNIX时间戳 | |||
*/ | |||
@SerializedName("createtime") | |||
private long createTime; | |||
/** | |||
* openid 客户openid | |||
*/ | |||
@SerializedName("openid") | |||
private String openid; | |||
@Override | |||
public String toString() { | |||
return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); | |||
} | |||
public String getKfAccount() { | |||
return this.kfAccount; | |||
} | |||
public void setKfAccount(String kfAccount) { | |||
this.kfAccount = kfAccount; | |||
} | |||
public long getCreateTime() { | |||
return this.createTime; | |||
} | |||
public void setCreateTime(long createTime) { | |||
this.createTime = createTime; | |||
} | |||
public String getOpenid() { | |||
return this.openid; | |||
} | |||
public void setOpenid(String openid) { | |||
this.openid = openid; | |||
} | |||
} |
@@ -0,0 +1,53 @@ | |||
package me.chanjar.weixin.mp.bean.kefu.result; | |||
import org.apache.commons.lang3.builder.ToStringBuilder; | |||
import org.apache.commons.lang3.builder.ToStringStyle; | |||
import com.google.gson.annotations.SerializedName; | |||
import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; | |||
/** | |||
* | |||
* @author Binary Wang | |||
* | |||
*/ | |||
public class WxMpKfSessionGetResult { | |||
/** | |||
* kf_account 正在接待的客服,为空表示没有人在接待 | |||
*/ | |||
@SerializedName("kf_account") | |||
private String kfAccount; | |||
/** | |||
* createtime 会话接入的时间 ,UNIX时间戳 | |||
*/ | |||
@SerializedName("createtime") | |||
private long createTime; | |||
@Override | |||
public String toString() { | |||
return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); | |||
} | |||
public static WxMpKfSessionGetResult fromJson(String json) { | |||
return WxMpGsonBuilder.INSTANCE.create().fromJson(json, WxMpKfSessionGetResult.class); | |||
} | |||
public String getKfAccount() { | |||
return this.kfAccount; | |||
} | |||
public void setKfAccount(String kfAccount) { | |||
this.kfAccount = kfAccount; | |||
} | |||
public long getCreateTime() { | |||
return this.createTime; | |||
} | |||
public void setCreateTime(long createTime) { | |||
this.createTime = createTime; | |||
} | |||
} |
@@ -0,0 +1,41 @@ | |||
package me.chanjar.weixin.mp.bean.kefu.result; | |||
import java.util.List; | |||
import org.apache.commons.lang3.builder.ToStringBuilder; | |||
import org.apache.commons.lang3.builder.ToStringStyle; | |||
import com.google.gson.annotations.SerializedName; | |||
import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; | |||
/** | |||
* | |||
* @author Binary Wang | |||
* | |||
*/ | |||
public class WxMpKfSessionList { | |||
/** | |||
* 会话列表 | |||
*/ | |||
@SerializedName("sessionlist") | |||
private List<WxMpKfSession> kfSessionList; | |||
@Override | |||
public String toString() { | |||
return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); | |||
} | |||
public static WxMpKfSessionList fromJson(String json) { | |||
return WxMpGsonBuilder.INSTANCE.create().fromJson(json, | |||
WxMpKfSessionList.class); | |||
} | |||
public List<WxMpKfSession> getKfSessionList() { | |||
return this.kfSessionList; | |||
} | |||
public void setKfSessionList(List<WxMpKfSession> kfSessionList) { | |||
this.kfSessionList = kfSessionList; | |||
} | |||
} |
@@ -0,0 +1,48 @@ | |||
package me.chanjar.weixin.mp.bean.kefu.result; | |||
import java.util.List; | |||
import org.apache.commons.lang3.builder.ToStringBuilder; | |||
import org.apache.commons.lang3.builder.ToStringStyle; | |||
import com.google.gson.annotations.SerializedName; | |||
import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; | |||
/** | |||
* | |||
* @author Binary Wang | |||
* | |||
*/ | |||
public class WxMpKfSessionWaitCaseList { | |||
/** | |||
* count 未接入会话数量 | |||
*/ | |||
@SerializedName("count") | |||
private Long count; | |||
/** | |||
* waitcaselist 未接入会话列表,最多返回100条数据 | |||
*/ | |||
@SerializedName("waitcaselist") | |||
private List<WxMpKfSession> kfSessionWaitCaseList; | |||
@Override | |||
public String toString() { | |||
return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); | |||
} | |||
public static WxMpKfSessionWaitCaseList fromJson(String json) { | |||
return WxMpGsonBuilder.INSTANCE.create().fromJson(json, | |||
WxMpKfSessionWaitCaseList.class); | |||
} | |||
public List<WxMpKfSession> getKfSessionWaitCaseList() { | |||
return this.kfSessionWaitCaseList; | |||
} | |||
public void setKfSessionWaitCaseList(List<WxMpKfSession> kfSessionWaitCaseList) { | |||
this.kfSessionWaitCaseList = kfSessionWaitCaseList; | |||
} | |||
} |
@@ -1,5 +1,8 @@ | |||
package me.chanjar.weixin.mp.api.impl; | |||
import java.io.File; | |||
import org.testng.Assert; | |||
import org.testng.annotations.DataProvider; | |||
import org.testng.annotations.Guice; | |||
import org.testng.annotations.Test; | |||
@@ -9,15 +12,14 @@ import com.google.inject.Inject; | |||
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.api.WxMpConfigStorage; | |||
import me.chanjar.weixin.mp.api.WxMpServiceImpl; | |||
import me.chanjar.weixin.mp.bean.customerservice.request.WxMpKfAccountRequest; | |||
import me.chanjar.weixin.mp.bean.customerservice.result.WxMpKfList; | |||
import me.chanjar.weixin.mp.bean.customerservice.result.WxMpKfOnlineList; | |||
import java.io.File; | |||
import org.testng.Assert; | |||
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; | |||
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; | |||
/** | |||
* 测试客服相关接口 | |||
@@ -34,14 +36,18 @@ public class WxMpKefuImplTest { | |||
public void testKfList() throws WxErrorException { | |||
WxMpKfList kfList = this.wxService.getKefuService().kfList(); | |||
Assert.assertNotNull(kfList); | |||
System.err.println(kfList); | |||
for (WxMpKfInfo k : kfList.getKfList()) { | |||
System.err.println(k); | |||
} | |||
} | |||
public void testKfOnlineList() throws WxErrorException { | |||
WxMpKfOnlineList kfOnlineList = this.wxService.getKefuService() | |||
.kfOnlineList(); | |||
Assert.assertNotNull(kfOnlineList); | |||
System.err.println(kfOnlineList); | |||
for (WxMpKfInfo k : kfOnlineList.getKfOnlineList()) { | |||
System.err.println(k); | |||
} | |||
} | |||
@DataProvider | |||
@@ -76,11 +82,59 @@ public class WxMpKefuImplTest { | |||
Assert.assertTrue(result); | |||
} | |||
@Test(dependsOnMethods = { | |||
"testKfAccountUploadHeadImg" }, dataProvider = "getKfAccount") | |||
@Test(dataProvider = "getKfAccount") | |||
public void testKfAccountDel(String kfAccount) throws WxErrorException { | |||
boolean result = this.wxService.getKefuService().kfAccountDel(kfAccount); | |||
Assert.assertTrue(result); | |||
} | |||
@DataProvider | |||
public Object[][] getKfAccountAndOpenid() { | |||
WxXmlMpInMemoryConfigStorage configStorage = (WxXmlMpInMemoryConfigStorage) this.wxService | |||
.getWxMpConfigStorage(); | |||
return new Object[][] { | |||
{ configStorage.getKfAccount(), configStorage.getOpenId() } }; | |||
} | |||
@Test(dataProvider = "getKfAccountAndOpenid") | |||
public void testKfSessionCreate(String kfAccount, String openid) | |||
throws WxErrorException { | |||
boolean result = this.wxService.getKefuService().kfSessionCreate(openid, | |||
kfAccount, "welcome"); | |||
Assert.assertTrue(result); | |||
} | |||
@Test(dataProvider = "getKfAccountAndOpenid") | |||
public void testKfSessionClose(String kfAccount, String openid) | |||
throws WxErrorException { | |||
boolean result = this.wxService.getKefuService().kfSessionClose(openid, | |||
kfAccount, "bye bye"); | |||
Assert.assertTrue(result); | |||
} | |||
@Test(dataProvider = "getKfAccountAndOpenid") | |||
public void testKfSessionGet(@SuppressWarnings("unused") String kfAccount, | |||
String openid) throws WxErrorException { | |||
WxMpKfSessionGetResult result = this.wxService.getKefuService() | |||
.kfSessionGet(openid); | |||
Assert.assertNotNull(result); | |||
System.err.println(result); | |||
} | |||
@Test(dataProvider = "getKfAccount") | |||
public void testKfSessionList(String kfAccount) throws WxErrorException { | |||
WxMpKfSessionList result = this.wxService.getKefuService() | |||
.kfSessionList(kfAccount); | |||
Assert.assertNotNull(result); | |||
System.err.println(result); | |||
} | |||
@Test | |||
public void testKfSessionGetWaitCase() throws WxErrorException { | |||
WxMpKfSessionWaitCaseList result = this.wxService.getKefuService() | |||
.kfSessionGetWaitCase(); | |||
Assert.assertNotNull(result); | |||
System.err.println(result); | |||
} | |||
} |
@@ -4,7 +4,7 @@ import org.apache.commons.lang3.builder.ToStringBuilder; | |||
import org.testng.Assert; | |||
import org.testng.annotations.Test; | |||
import me.chanjar.weixin.mp.bean.customerservice.result.WxMpKfList; | |||
import me.chanjar.weixin.mp.bean.kefu.result.WxMpKfList; | |||
@Test | |||
public class WxMpKfListTest { | |||
@@ -4,7 +4,7 @@ import org.apache.commons.lang3.builder.ToStringBuilder; | |||
import org.testng.Assert; | |||
import org.testng.annotations.Test; | |||
import me.chanjar.weixin.mp.bean.customerservice.result.WxMpKfOnlineList; | |||
import me.chanjar.weixin.mp.bean.kefu.result.WxMpKfOnlineList; | |||
@Test | |||
public class WxMpKfOnlineListTest { | |||