实现多客服会话控制的接口

This commit is contained in:
BinaryWang 2016-07-12 09:09:46 +08:00
parent 065156e81b
commit 0c2768dfe7
16 changed files with 599 additions and 98 deletions

View File

@ -22,7 +22,7 @@ import me.chanjar.weixin.mp.api.WxMpMessageRouter;
import me.chanjar.weixin.mp.api.WxMpServiceImpl; import me.chanjar.weixin.mp.api.WxMpServiceImpl;
import me.chanjar.weixin.mp.bean.WxMpXmlMessage; import me.chanjar.weixin.mp.bean.WxMpXmlMessage;
import me.chanjar.weixin.mp.bean.WxMpXmlOutMessage; 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;
/** /**
* *

View File

@ -3,9 +3,12 @@ package me.chanjar.weixin.mp.api;
import java.io.File; import java.io.File;
import me.chanjar.weixin.common.exception.WxErrorException; import me.chanjar.weixin.common.exception.WxErrorException;
import me.chanjar.weixin.mp.bean.customerservice.request.WxMpKfAccountRequest; import me.chanjar.weixin.mp.bean.kefu.request.WxMpKfAccountRequest;
import me.chanjar.weixin.mp.bean.customerservice.result.WxMpKfList; import me.chanjar.weixin.mp.bean.kefu.result.WxMpKfList;
import me.chanjar.weixin.mp.bean.customerservice.result.WxMpKfOnlineList; 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 * @author Binary Wang
* *
*/ */
public interface WxMpKefuService { public interface WxMpKefuService {
//*******************客服管理接口***********************//
/** /**
* <pre> * <pre>
* 获取客服基本信息 * 获取客服基本信息
* 详情请见<a href="http://mp.weixin.qq.com/wiki/18/749901f4e123170fb8a4d447ae6040ba.html">客服管理</a> * 详情请见<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> * </pre>
*/ */
WxMpKfList kfList() throws WxErrorException; WxMpKfList kfList() throws WxErrorException;
/** /**
* <pre> * <pre>
* 获取在线客服接待信息 * 获取在线客服接待信息
* 详情请见<a href="http://mp.weixin.qq.com/wiki/18/749901f4e123170fb8a4d447ae6040ba.html">客服管理</a> * 详情请见<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> * </pre>
*/ */
WxMpKfOnlineList kfOnlineList() throws WxErrorException; WxMpKfOnlineList kfOnlineList() throws WxErrorException;
/** /**
* <pre> * <pre>
* 添加客服账号 * 添加客服账号
* 详情请见<a href="http://mp.weixin.qq.com/wiki/18/749901f4e123170fb8a4d447ae6040ba.html">客服管理</a> * 详情请见<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> * </pre>
*/ */
boolean kfAccountAdd(WxMpKfAccountRequest request) throws WxErrorException; boolean kfAccountAdd(WxMpKfAccountRequest request) throws WxErrorException;
/** /**
* <pre> * <pre>
* 设置客服信息更新 * 设置客服信息更新
* 详情请见<a href="http://mp.weixin.qq.com/wiki/18/749901f4e123170fb8a4d447ae6040ba.html">客服管理</a> * 详情请见<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> * </pre>
*/ */
boolean kfAccountUpdate(WxMpKfAccountRequest request) throws WxErrorException; boolean kfAccountUpdate(WxMpKfAccountRequest request) throws WxErrorException;
/** /**
* <pre> * <pre>
* 上传客服头像 * 上传客服头像
* 详情请见<a href="http://mp.weixin.qq.com/wiki/18/749901f4e123170fb8a4d447ae6040ba.html">客服管理</a> * 详情请见<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> * </pre>
*/ */
boolean kfAccountUploadHeadImg(String kfAccount, File imgFile)
boolean kfAccountUploadHeadImg(String kfAccount, File imgFile) throws WxErrorException; throws WxErrorException;
/** /**
* <pre> * <pre>
* 删除客服账号 * 删除客服账号
* 详情请见<a href="http://mp.weixin.qq.com/wiki/18/749901f4e123170fb8a4d447ae6040ba.html">客服管理</a> * 详情请见<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> * </pre>
*/ */
boolean kfAccountDel(String kfAccount) throws WxErrorException; 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;
} }

View File

@ -1,35 +1,23 @@
package me.chanjar.weixin.mp.api; package me.chanjar.weixin.mp.api;
import com.google.gson.*; import java.io.File;
import com.google.gson.internal.Streams; import java.io.IOException;
import com.google.gson.reflect.TypeToken; import java.io.InputStream;
import com.google.gson.stream.JsonReader; import java.io.StringReader;
import com.thoughtworks.xstream.XStream; import java.io.UnsupportedEncodingException;
import me.chanjar.weixin.common.api.WxConsts; import java.net.URLEncoder;
import me.chanjar.weixin.common.bean.WxAccessToken; import java.nio.charset.StandardCharsets;
import me.chanjar.weixin.common.bean.WxCardApiSignature; import java.security.NoSuchAlgorithmException;
import me.chanjar.weixin.common.bean.WxJsapiSignature; import java.util.Arrays;
import me.chanjar.weixin.common.bean.WxMenu; import java.util.Date;
import me.chanjar.weixin.common.bean.result.WxError; import java.util.HashMap;
import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; import java.util.List;
import me.chanjar.weixin.common.exception.WxErrorException; import java.util.Map;
import me.chanjar.weixin.common.session.StandardSessionManager; import java.util.Map.Entry;
import me.chanjar.weixin.common.session.WxSessionManager; import java.util.SortedMap;
import me.chanjar.weixin.common.util.RandomUtils; import java.util.TreeMap;
import me.chanjar.weixin.common.util.crypto.SHA1; import java.util.UUID;
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.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.util.json.WxMpGsonBuilder;
import org.apache.commons.io.Charsets;
import org.apache.http.Consts; import org.apache.http.Consts;
import org.apache.http.HttpHost; import org.apache.http.HttpHost;
import org.apache.http.client.ClientProtocolException; import org.apache.http.client.ClientProtocolException;
@ -45,16 +33,85 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.slf4j.helpers.MessageFormatter; import org.slf4j.helpers.MessageFormatter;
import java.io.File; import com.google.gson.JsonArray;
import java.io.IOException; import com.google.gson.JsonElement;
import java.io.InputStream; import com.google.gson.JsonObject;
import java.io.StringReader; import com.google.gson.JsonParser;
import java.io.UnsupportedEncodingException; import com.google.gson.JsonPrimitive;
import java.net.URLEncoder; import com.google.gson.internal.Streams;
import java.nio.charset.StandardCharsets; import com.google.gson.reflect.TypeToken;
import java.security.NoSuchAlgorithmException; import com.google.gson.stream.JsonReader;
import java.util.*; import com.thoughtworks.xstream.XStream;
import java.util.Map.Entry;
import me.chanjar.weixin.common.api.WxConsts;
import me.chanjar.weixin.common.bean.WxAccessToken;
import me.chanjar.weixin.common.bean.WxCardApiSignature;
import me.chanjar.weixin.common.bean.WxJsapiSignature;
import me.chanjar.weixin.common.bean.WxMenu;
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.session.StandardSessionManager;
import me.chanjar.weixin.common.session.WxSessionManager;
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.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.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;
public class WxMpServiceImpl implements WxMpService { public class WxMpServiceImpl implements WxMpService {

View File

@ -8,9 +8,13 @@ import me.chanjar.weixin.common.util.http.SimpleGetRequestExecutor;
import me.chanjar.weixin.common.util.http.SimplePostRequestExecutor; import me.chanjar.weixin.common.util.http.SimplePostRequestExecutor;
import me.chanjar.weixin.mp.api.WxMpKefuService; import me.chanjar.weixin.mp.api.WxMpKefuService;
import me.chanjar.weixin.mp.api.WxMpService; import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.customerservice.request.WxMpKfAccountRequest; import me.chanjar.weixin.mp.bean.kefu.request.WxMpKfAccountRequest;
import me.chanjar.weixin.mp.bean.customerservice.result.WxMpKfList; import me.chanjar.weixin.mp.bean.kefu.request.WxMpKfSessionRequest;
import me.chanjar.weixin.mp.bean.customerservice.result.WxMpKfOnlineList; 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 @Override
public WxMpKfList kfList() throws WxErrorException { public WxMpKfList kfList() throws WxErrorException {
String url = "https://api.weixin.qq.com/cgi-bin/customservice/getkflist"; String url = "https://api.weixin.qq.com/cgi-bin/customservice/getkflist";
String responseContent = this.wxMpService.execute( String responseContent = this.wxMpService
new SimpleGetRequestExecutor(), url, null); .execute(new SimpleGetRequestExecutor(), url, null);
return WxMpKfList.fromJson(responseContent); return WxMpKfList.fromJson(responseContent);
} }
@Override @Override
public WxMpKfOnlineList kfOnlineList() throws WxErrorException { public WxMpKfOnlineList kfOnlineList() throws WxErrorException {
String url = "https://api.weixin.qq.com/cgi-bin/customservice/getonlinekflist"; String url = "https://api.weixin.qq.com/cgi-bin/customservice/getonlinekflist";
String responseContent = this.wxMpService.execute( String responseContent = this.wxMpService
new SimpleGetRequestExecutor(), url, null); .execute(new SimpleGetRequestExecutor(), url, null);
return WxMpKfOnlineList.fromJson(responseContent); return WxMpKfOnlineList.fromJson(responseContent);
} }
@Override @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"; 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; return true;
} }
@Override @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"; 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; return true;
} }
@Override @Override
public boolean kfAccountUploadHeadImg(String kfAccount, File imgFile) throws WxErrorException { public boolean kfAccountUploadHeadImg(String kfAccount, File imgFile)
String url = "https://api.weixin.qq.com/customservice/kfaccount/uploadheadimg?kf_account=" + kfAccount ; throws WxErrorException {
String url = "https://api.weixin.qq.com/customservice/kfaccount/uploadheadimg?kf_account="
+ kfAccount;
this.wxMpService.execute(new MediaUploadRequestExecutor(), url, imgFile); this.wxMpService.execute(new MediaUploadRequestExecutor(), url, imgFile);
return true; return true;
} }
@Override @Override
public boolean kfAccountDel(String kfAccount) throws WxErrorException { 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); this.wxMpService.execute(new SimpleGetRequestExecutor(), url, null);
return true; 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);
}
} }

View File

@ -1,4 +1,4 @@
package me.chanjar.weixin.mp.bean.customerservice.request; package me.chanjar.weixin.mp.bean.kefu.request;
import java.io.Serializable; import java.io.Serializable;

View File

@ -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;
}
}

View File

@ -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 java.io.Serializable;
import org.apache.commons.lang3.builder.ToStringBuilder; 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.Expose;
import com.google.gson.annotations.SerializedName; import com.google.gson.annotations.SerializedName;
@ -20,38 +21,38 @@ public class WxMpKfInfo implements Serializable {
*/ */
@SerializedName("kf_account") @SerializedName("kf_account")
private String account; private String account;
/** /**
* kf_headimgurl 客服头像地址 * kf_headimgurl 客服头像地址
*/ */
@SerializedName("kf_headimgurl") @SerializedName("kf_headimgurl")
private String headImgUrl; private String headImgUrl;
/** /**
* kf_id 客服工号 * kf_id 客服工号
*/ */
@SerializedName("kf_id") @SerializedName("kf_id")
private String id; private String id;
/** /**
* kf_nick 客服昵称 * kf_nick 客服昵称
*/ */
@SerializedName("kf_nick") @SerializedName("kf_nick")
private String nick; private String nick;
/** /**
* status 客服在线状态 1pc在线2手机在线若pc和手机同时在线则为 1+2=3 * status 客服在线状态 1pc在线2手机在线若pc和手机同时在线则为 1+2=3
*/ */
@SerializedName("status") @SerializedName("status")
private Integer status; private Integer status;
/** /**
* auto_accept 客服设置的最大自动接入数 * auto_accept 客服设置的最大自动接入数
*/ */
@Expose @Expose
@SerializedName("auto_accept") @SerializedName("auto_accept")
private Integer autoAccept; private Integer autoAccept;
/** /**
* accepted_case 客服当前正在接待的会话数 * accepted_case 客服当前正在接待的会话数
* @return * @return
@ -118,6 +119,6 @@ public class WxMpKfInfo implements Serializable {
@Override @Override
public String toString() { public String toString() {
return ToStringBuilder.reflectionToString(this); return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE);
} }
} }

View File

@ -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 java.util.List;
import org.apache.commons.lang3.builder.ToStringBuilder; import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import com.google.gson.annotations.SerializedName; import com.google.gson.annotations.SerializedName;
@ -18,7 +19,7 @@ public class WxMpKfList {
@Override @Override
public String toString() { public String toString() {
return ToStringBuilder.reflectionToString(this); return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE);
} }
public List<WxMpKfInfo> getKfList() { public List<WxMpKfInfo> getKfList() {

View File

@ -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 java.util.List;
import org.apache.commons.lang3.builder.ToStringBuilder; import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import com.google.gson.annotations.SerializedName; import com.google.gson.annotations.SerializedName;
@ -18,7 +19,7 @@ public class WxMpKfOnlineList {
@Override @Override
public String toString() { public String toString() {
return ToStringBuilder.reflectionToString(this); return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE);
} }
public List<WxMpKfInfo> getKfOnlineList() { public List<WxMpKfInfo> getKfOnlineList() {

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -1,5 +1,8 @@
package me.chanjar.weixin.mp.api.impl; package me.chanjar.weixin.mp.api.impl;
import java.io.File;
import org.testng.Assert;
import org.testng.annotations.DataProvider; import org.testng.annotations.DataProvider;
import org.testng.annotations.Guice; import org.testng.annotations.Guice;
import org.testng.annotations.Test; 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.common.exception.WxErrorException;
import me.chanjar.weixin.mp.api.ApiTestModule; import me.chanjar.weixin.mp.api.ApiTestModule;
import me.chanjar.weixin.mp.api.ApiTestModule.WxXmlMpInMemoryConfigStorage; 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.api.WxMpServiceImpl;
import me.chanjar.weixin.mp.bean.customerservice.request.WxMpKfAccountRequest; import me.chanjar.weixin.mp.bean.kefu.request.WxMpKfAccountRequest;
import me.chanjar.weixin.mp.bean.customerservice.result.WxMpKfList; import me.chanjar.weixin.mp.bean.kefu.result.WxMpKfInfo;
import me.chanjar.weixin.mp.bean.customerservice.result.WxMpKfOnlineList; import me.chanjar.weixin.mp.bean.kefu.result.WxMpKfList;
import me.chanjar.weixin.mp.bean.kefu.result.WxMpKfOnlineList;
import java.io.File; import me.chanjar.weixin.mp.bean.kefu.result.WxMpKfSessionGetResult;
import me.chanjar.weixin.mp.bean.kefu.result.WxMpKfSessionList;
import org.testng.Assert; import me.chanjar.weixin.mp.bean.kefu.result.WxMpKfSessionWaitCaseList;
/** /**
* 测试客服相关接口 * 测试客服相关接口
@ -34,14 +36,18 @@ public class WxMpKefuImplTest {
public void testKfList() throws WxErrorException { public void testKfList() throws WxErrorException {
WxMpKfList kfList = this.wxService.getKefuService().kfList(); WxMpKfList kfList = this.wxService.getKefuService().kfList();
Assert.assertNotNull(kfList); Assert.assertNotNull(kfList);
System.err.println(kfList); for (WxMpKfInfo k : kfList.getKfList()) {
System.err.println(k);
}
} }
public void testKfOnlineList() throws WxErrorException { public void testKfOnlineList() throws WxErrorException {
WxMpKfOnlineList kfOnlineList = this.wxService.getKefuService() WxMpKfOnlineList kfOnlineList = this.wxService.getKefuService()
.kfOnlineList(); .kfOnlineList();
Assert.assertNotNull(kfOnlineList); Assert.assertNotNull(kfOnlineList);
System.err.println(kfOnlineList); for (WxMpKfInfo k : kfOnlineList.getKfOnlineList()) {
System.err.println(k);
}
} }
@DataProvider @DataProvider
@ -76,11 +82,59 @@ public class WxMpKefuImplTest {
Assert.assertTrue(result); Assert.assertTrue(result);
} }
@Test(dependsOnMethods = { @Test(dataProvider = "getKfAccount")
"testKfAccountUploadHeadImg" }, dataProvider = "getKfAccount")
public void testKfAccountDel(String kfAccount) throws WxErrorException { public void testKfAccountDel(String kfAccount) throws WxErrorException {
boolean result = this.wxService.getKefuService().kfAccountDel(kfAccount); boolean result = this.wxService.getKefuService().kfAccountDel(kfAccount);
Assert.assertTrue(result); 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);
}
} }

View File

@ -4,7 +4,7 @@ import org.apache.commons.lang3.builder.ToStringBuilder;
import org.testng.Assert; import org.testng.Assert;
import org.testng.annotations.Test; import org.testng.annotations.Test;
import me.chanjar.weixin.mp.bean.customerservice.result.WxMpKfList; import me.chanjar.weixin.mp.bean.kefu.result.WxMpKfList;
@Test @Test
public class WxMpKfListTest { public class WxMpKfListTest {

View File

@ -4,7 +4,7 @@ import org.apache.commons.lang3.builder.ToStringBuilder;
import org.testng.Assert; import org.testng.Assert;
import org.testng.annotations.Test; import org.testng.annotations.Test;
import me.chanjar.weixin.mp.bean.customerservice.result.WxMpKfOnlineList; import me.chanjar.weixin.mp.bean.kefu.result.WxMpKfOnlineList;
@Test @Test
public class WxMpKfOnlineListTest { public class WxMpKfOnlineListTest {