diff --git a/weixin-java-demo-with-spring/src/main/java/com/github/binarywang/demo/spring/service/BaseWxService.java b/weixin-java-demo-with-spring/src/main/java/com/github/binarywang/demo/spring/service/BaseWxService.java index a7d851d8..133c7445 100644 --- a/weixin-java-demo-with-spring/src/main/java/com/github/binarywang/demo/spring/service/BaseWxService.java +++ b/weixin-java-demo-with-spring/src/main/java/com/github/binarywang/demo/spring/service/BaseWxService.java @@ -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; /** * diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpKefuService.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpKefuService.java index ec9b7af3..37799d13 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpKefuService.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpKefuService.java @@ -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 { + + //*******************客服管理接口***********************// /** *
    * 获取客服基本信息
    * 详情请见:客服管理
-   * 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
    * 
*/ WxMpKfList kfList() throws WxErrorException; - + /** *
    * 获取在线客服接待信息
    * 详情请见:客服管理
-   * 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
    * 
*/ WxMpKfOnlineList kfOnlineList() throws WxErrorException; - + /** *
    * 添加客服账号
    * 详情请见:客服管理
-   * 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
    * 
*/ boolean kfAccountAdd(WxMpKfAccountRequest request) throws WxErrorException; - + /** *
    * 设置客服信息(更新)
    * 详情请见:客服管理
-   * 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
    * 
*/ boolean kfAccountUpdate(WxMpKfAccountRequest request) throws WxErrorException; - + /** *
    * 上传客服头像
    * 详情请见:客服管理
-   * 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
    * 
*/ - - boolean kfAccountUploadHeadImg(String kfAccount, File imgFile) throws WxErrorException; - + boolean kfAccountUploadHeadImg(String kfAccount, File imgFile) + throws WxErrorException; + /** *
    * 删除客服账号
    * 详情请见:客服管理
-   * 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
    * 
*/ boolean kfAccountDel(String kfAccount) throws WxErrorException; + + //*******************多客服会话控制接口***********************// + /** + *
+   * 创建会话
+   * 开发者可以使用本接口,为多客服的客服工号创建会话,将某个客户直接指定给客服工号接待,需要注意此接口不会受客服自动接入数以及自动接入开关限制。只能为在线的客服(PC客户端在线,或者已绑定多客服助手)创建会话。
+   * 详情请见:多客服会话控制接口
+   * 接口url格式: https://api.weixin.qq.com/customservice/kfsession/create?access_token=ACCESS_TOKEN
+   * 
+ */ + boolean kfSessionCreate(String openid, String kfAccount, String text) throws WxErrorException; + + /** + *
+   * 关闭会话
+   * 开发者可以使用本接口,关闭一个会话。
+   * 详情请见:多客服会话控制接口
+   * 接口url格式: https://api.weixin.qq.com/customservice/kfsession/close?access_token=ACCESS_TOKEN
+   * 
+ */ + boolean kfSessionClose(String openid, String kfAccount, String text) throws WxErrorException; + + /** + *
+   * 获取客户的会话状态
+   * 开发者可以通过本接口获取客户当前的会话状态。
+   * 详情请见:多客服会话控制接口
+   * 接口url格式: https://api.weixin.qq.com/customservice/kfsession/getsession?access_token=ACCESS_TOKEN&openid=OPENID
+   * 
+ */ + WxMpKfSessionGetResult kfSessionGet(String openid) throws WxErrorException; + + /** + *
+   * 获取客服的会话列表
+   * 开发者可以通过本接口获取某个客服正在接待的会话列表。
+   * 详情请见:多客服会话控制接口
+   * 接口url格式: https://api.weixin.qq.com/customservice/kfsession/getsessionlist?access_token=ACCESS_TOKEN&kf_account=KFACCOUNT
+   * 
+ */ + WxMpKfSessionList kfSessionList(String kfAccount) throws WxErrorException; + + /** + *
+   * 获取未接入会话列表
+   * 开发者可以通过本接口获取当前正在等待队列中的会话列表,此接口最多返回最早进入队列的100个未接入会话。
+   * 详情请见:多客服会话控制接口
+   * 接口url格式: https://api.weixin.qq.com/customservice/kfsession/getwaitcase?access_token=ACCESS_TOKEN
+   * 
+ */ + WxMpKfSessionWaitCaseList kfSessionGetWaitCase() throws WxErrorException; } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpServiceImpl.java index e79ded19..6ea190e4 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpServiceImpl.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpServiceImpl.java @@ -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); diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpKefuServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpKefuServiceImpl.java index 91afb731..19fdd508 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpKefuServiceImpl.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpKefuServiceImpl.java @@ -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); + } + } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/customerservice/request/WxMpKfAccountRequest.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/kefu/request/WxMpKfAccountRequest.java similarity index 98% rename from weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/customerservice/request/WxMpKfAccountRequest.java rename to weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/kefu/request/WxMpKfAccountRequest.java index a5d301da..fb5ac41b 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/customerservice/request/WxMpKfAccountRequest.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/kefu/request/WxMpKfAccountRequest.java @@ -1,4 +1,4 @@ -package me.chanjar.weixin.mp.bean.customerservice.request; +package me.chanjar.weixin.mp.bean.kefu.request; import java.io.Serializable; diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/kefu/request/WxMpKfSessionRequest.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/kefu/request/WxMpKfSessionRequest.java new file mode 100644 index 00000000..aaf9e98c --- /dev/null +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/kefu/request/WxMpKfSessionRequest.java @@ -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; + } + +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/customerservice/result/WxMpKfInfo.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/kefu/result/WxMpKfInfo.java similarity index 92% rename from weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/customerservice/result/WxMpKfInfo.java rename to weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/kefu/result/WxMpKfInfo.java index 95b3a96f..39e27f22 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/customerservice/result/WxMpKfInfo.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/kefu/result/WxMpKfInfo.java @@ -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); } } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/customerservice/result/WxMpKfList.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/kefu/result/WxMpKfList.java similarity index 78% rename from weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/customerservice/result/WxMpKfList.java rename to weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/kefu/result/WxMpKfList.java index 335204fb..062ff9ac 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/customerservice/result/WxMpKfList.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/kefu/result/WxMpKfList.java @@ -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 getKfList() { diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/customerservice/result/WxMpKfOnlineList.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/kefu/result/WxMpKfOnlineList.java similarity index 79% rename from weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/customerservice/result/WxMpKfOnlineList.java rename to weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/kefu/result/WxMpKfOnlineList.java index 949d8849..b4a418f6 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/customerservice/result/WxMpKfOnlineList.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/kefu/result/WxMpKfOnlineList.java @@ -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 getKfOnlineList() { diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/kefu/result/WxMpKfSession.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/kefu/result/WxMpKfSession.java new file mode 100644 index 00000000..9cc3d50f --- /dev/null +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/kefu/result/WxMpKfSession.java @@ -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; + } + +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/kefu/result/WxMpKfSessionGetResult.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/kefu/result/WxMpKfSessionGetResult.java new file mode 100644 index 00000000..22a6cf24 --- /dev/null +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/kefu/result/WxMpKfSessionGetResult.java @@ -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; + } + +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/kefu/result/WxMpKfSessionList.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/kefu/result/WxMpKfSessionList.java new file mode 100644 index 00000000..dea7e243 --- /dev/null +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/kefu/result/WxMpKfSessionList.java @@ -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 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 getKfSessionList() { + return this.kfSessionList; + } + + public void setKfSessionList(List kfSessionList) { + this.kfSessionList = kfSessionList; + } +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/kefu/result/WxMpKfSessionWaitCaseList.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/kefu/result/WxMpKfSessionWaitCaseList.java new file mode 100644 index 00000000..dc2ab06b --- /dev/null +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/kefu/result/WxMpKfSessionWaitCaseList.java @@ -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 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 getKfSessionWaitCaseList() { + return this.kfSessionWaitCaseList; + } + + public void setKfSessionWaitCaseList(List kfSessionWaitCaseList) { + this.kfSessionWaitCaseList = kfSessionWaitCaseList; + } + +} diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpKefuImplTest.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpKefuImplTest.java index f2045437..120a3c03 100644 --- a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpKefuImplTest.java +++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpKefuImplTest.java @@ -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); + } + } diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/result/kefu/WxMpKfListTest.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/result/kefu/WxMpKfListTest.java index 0d3841ef..cc782250 100644 --- a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/result/kefu/WxMpKfListTest.java +++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/result/kefu/WxMpKfListTest.java @@ -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 { diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/result/kefu/WxMpKfOnlineListTest.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/result/kefu/WxMpKfOnlineListTest.java index 052f8e25..ab04e8e0 100644 --- a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/result/kefu/WxMpKfOnlineListTest.java +++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/result/kefu/WxMpKfOnlineListTest.java @@ -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 {