/**
* Copyright (c) 2011-2015, Unas 小强哥 (unas@qq.com).
*
* Licensed under the Apache License, Version 2.0 (the "License");
*/
package com.jfinal.weixin.sdk.api;
import com.jfinal.weixin.sdk.kit.ParaMap;
import com.jfinal.weixin.sdk.utils.HttpUtils;
import com.jfinal.weixin.sdk.utils.JsonUtils;
import java.io.File;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 多客服功能
* 仅支持获取客服聊天记录接口,其他功能可以使用微信官方的多客服客户端软件来完成。
*
* 客服接口:http://mp.weixin.qq.com/wiki/1/70a29afed17f56d537c833f89be979c9.html
*/
public class CustomServiceApi {
private static String getRecordUrl = "https://api.weixin.qq.com/customservice/msgrecord/getrecord?access_token=";
/**
* 获取客服聊天记录
* @param jsonStr json字符串
* @return {ApiResult}
*/
public static ApiResult getRecord(String jsonStr) {
String jsonResult = HttpUtils.post(getRecordUrl + AccessTokenApi.getAccessTokenStr(), jsonStr);
return new ApiResult(jsonResult);
}
/**
* 获取客服聊天记录
* @param pageindex 查询第几页,从1开始
* @param pagesize 每页大小,每页最多拉取50条
* @param starttime 查询开始时间,UNIX时间戳
* @param endtime 查询结束时间,UNIX时间戳,每次查询不能跨日查询
* @return ApiResult
*/
public static ApiResult getRecord(int pageindex, int pagesize, long starttime, long endtime) {
if (pageindex < 1) { pageindex = 1; }
if (pagesize < 1 || pagesize > 50) { pagesize = 50; }
Map params = new HashMap();
params.put("pageindex", pageindex);
params.put("pagesize", pagesize);
params.put("starttime", starttime);
params.put("endtime", endtime);
return getRecord(JsonUtils.toJson(params));
}
private static String addKfAccountUrl = "https://api.weixin.qq.com/customservice/kfaccount/add?access_token=";
/**
* 添加客服帐号
* @param kf_account 完整客服账号,格式为:账号前缀@公众号微信号
* @param nickname 客服昵称,最长6个汉字或12个英文字符
* @param password 客服账号登录密码,格式为密码明文的32位加密MD5值。该密码仅用于在公众平台官网的多客服功能中使用,若不使用多客服功能,则不必设置密码
* @return ApiResult
*/
public static ApiResult addKfAccount(String kf_account, String nickname, String password) {
String accessToken = AccessTokenApi.getAccessTokenStr();
Map params = new HashMap();
params.put("kf_account", kf_account);
params.put("nickname", nickname);
params.put("password", password);
String jsonResult = HttpUtils.post(addKfAccountUrl + accessToken, JsonUtils.toJson(params));
return new ApiResult(jsonResult);
}
private static String updateKfAccountUrl = "https://api.weixin.qq.com/customservice/kfaccount/update?access_token=";
/**
* 修改客服帐号
* @param kf_account 完整客服账号,格式为:账号前缀@公众号微信号
* @param nickname 客服昵称,最长6个汉字或12个英文字符
* @param password 客服账号登录密码,格式为密码明文的32位加密MD5值。该密码仅用于在公众平台官网的多客服功能中使用,若不使用多客服功能,则不必设置密码
* @return ApiResult
*/
public static ApiResult updateKfAccount(String kf_account, String nickname, String password) {
String accessToken = AccessTokenApi.getAccessTokenStr();
Map params = new HashMap();
params.put("kf_account", kf_account);
params.put("nickname", nickname);
params.put("password", password);
String jsonResult = HttpUtils.post(updateKfAccountUrl + accessToken, JsonUtils.toJson(params));
return new ApiResult(jsonResult);
}
private static String delKfAccountUrl = "https://api.weixin.qq.com/customservice/kfaccount/del";
/**
* 删除客服帐号
* @param kf_account 完整客服账号,格式为:账号前缀@公众号微信号
* @return ApiResult
*/
public static ApiResult delKfAccount(String kf_account) {
String accessToken = AccessTokenApi.getAccessTokenStr();
String jsonResult = HttpUtils.get(delKfAccountUrl, ParaMap
.create("access_token", accessToken)
.put("kf_account", kf_account)
.getData());
return new ApiResult(jsonResult);
}
private static String uploadKfAccountHeadImgUrl = "https://api.weixin.qq.com/customservice/kfaccount/uploadheadimg?access_token=";
/**
* 设置客服帐号的头像
* @param kf_account 完整客服账号,格式为:账号前缀@公众号微信号
* @param headImg 客服人员的头像,头像图片文件必须是jpg格式,推荐使用640*640大小的图片以达到最佳效果
* @return ApiResult
*/
public static ApiResult uploadKfAccountHeadImg(String kf_account, File headImg) {
String accessToken = AccessTokenApi.getAccessTokenStr();
String url = uploadKfAccountHeadImgUrl + accessToken + "&kf_account=" + kf_account;
String jsonResult = HttpUtils.upload(url, headImg, null);
return new ApiResult(jsonResult);
}
private static String getKfListUrl = "https://api.weixin.qq.com/cgi-bin/customservice/getkflist?access_token=";
/**
* 获取所有客服账号
* @return ApiResult
*/
public static ApiResult getKfList() {
String accessToken = AccessTokenApi.getAccessTokenStr();
String jsonResult = HttpUtils.get(getKfListUrl + accessToken);
return new ApiResult(jsonResult);
}
private static String getOnlineKFListUrl = "https://api.weixin.qq.com/cgi-bin/customservice/getonlinekflist?access_token=";
/**
* 获取在线客服接待信息
* @return ApiResult
*/
public static ApiResult getOnlineKFList() {
String accessToken = AccessTokenApi.getAccessTokenStr();
String jsonResult = HttpUtils.get(getOnlineKFListUrl + accessToken);
return new ApiResult(jsonResult);
}
private static String customMessageUrl = "https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=";
/**
* 发送客服消息
* @param message 消息封装
* @return ApiResult
*/
private static ApiResult sendMsg(Map message) {
String accessToken = AccessTokenApi.getAccessTokenStr();
String jsonResult = HttpUtils.post(customMessageUrl + accessToken, JsonUtils.toJson(message));
return new ApiResult(jsonResult);
}
/**
* 发送文本客服消息
* @param openId openId
* @param text 文本消息
* @return ApiResult
*/
public static ApiResult sendText(String openId, String text) {
Map json = new HashMap();
json.put("touser", openId);
json.put("msgtype", "text");
Map textObj = new HashMap();
textObj.put("content", text);
json.put("text", textObj);
return sendMsg(json);
}
/**
* 发送图片消息
* @param openId openId
* @param media_id 图片媒体id
* @return ApiResult
*/
public static ApiResult sendImage(String openId, String media_id) {
Map json = new HashMap();
json.put("touser", openId);
json.put("msgtype", "image");
Map image = new HashMap();
image.put("media_id", media_id);
json.put("image", image);
return sendMsg(json);
}
/**
* 发送语言回复
* @param openId openId
* @param media_id 媒体id
* @return ApiResult
*/
public static ApiResult sendVoice(String openId, String media_id) {
Map json = new HashMap();
json.put("touser", openId);
json.put("msgtype", "voice");
Map voice = new HashMap();
voice.put("media_id", media_id);
json.put("voice", voice);
return sendMsg(json);
}
/**
* 发送视频回复
* @param openId openId
* @param media_id 媒体id
* @param title 视频标题
* @param description 视频描述
* @return {ApiResult}
*/
public static ApiResult sendVideo(String openId, String media_id, String title, String description) {
Map json = new HashMap();
json.put("touser", openId);
json.put("msgtype", "video");
Map video = new HashMap();
video.put("media_id", media_id);
video.put("title", title);
video.put("description", description);
json.put("video", video);
return sendMsg(json);
}
/**
* 发送音乐回复
* @param openId openId
* @param musicurl 音乐地址
* @param hqmusicurl 音乐高清地址
* @param thumb_media_id 音乐媒体id
* @param title 音乐标题
* @param description 音乐描述
* @return {ApiResult}
*/
public static ApiResult sendMusic(String openId, String musicurl, String hqmusicurl, String thumb_media_id, String title, String description) {
Map json = new HashMap();
json.put("touser", openId);
json.put("msgtype", "music");
Map music = new HashMap();
music.put("musicurl", musicurl);
music.put("hqmusicurl", hqmusicurl);
music.put("thumb_media_id", thumb_media_id);
music.put("title", title);
music.put("description", description);
json.put("music", music);
return sendMsg(json);
}
/**
* 发送图文回复,图文消息条数限制在8条以内
* @param openId openId
* @param articles 图文信息封装
* @return {ApiResult}
*/
public static ApiResult sendNews(String openId, List articles) {
Map json = new HashMap();
json.put("touser", openId);
json.put("msgtype", "news");
Map news = new HashMap();
news.put("articles", articles);
json.put("news", news);
return sendMsg(json);
}
/**
* 客户消息图文封装和 `News` 又略微区别,无法公用
*/
public static class Articles {
private String title;
private String description;
private String url;
private String picurl;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getPicurl() {
return picurl;
}
public void setPicurl(String picurl) {
this.picurl = picurl;
}
}
/**
* 发送图文消息(点击跳转到图文消息页面),图文消息条数限制在8条以内
* @param openId 普通用户openid
* @param mediaId 素材id
* @return ApiResult
*/
public static ApiResult sendMpNews(String openId, String mediaId) {
Map json = new HashMap();
json.put("touser", openId);
json.put("msgtype", "mpnews");
Map news = new HashMap();
news.put("media_id", mediaId);
json.put("mpnews", news);
return sendMsg(json);
}
/**
* 发送卡券
* @param openId 普通用户openid
* @param card_id 卡券id
* @param card_ext 详情及签名规则: http://mp.weixin.qq.com/wiki/7/aaa137b55fb2e0456bf8dd9148dd613f.html#.E9.99.84.E5.BD.954-.E5.8D.A1.E5.88.B8.E6.89.A9.E5.B1.95.E5.AD.97.E6.AE.B5.E5.8F.8A.E7.AD.BE.E5.90.8D.E7.94.9F.E6.88.90.E7.AE.97.E6.B3.95
* @return ApiResult
*/
public static ApiResult sendCoupon(String openId, String card_id, String card_ext) {
Map json = new HashMap();
json.put("touser", openId);
json.put("msgtype", "wxcard");
Map wxcard = new HashMap();
wxcard.put("card_id", card_id);
wxcard.put("card_ext", card_ext);
json.put("wxcard", wxcard);
return sendMsg(json);
}
private static String inviteWorkerUrl = "https://api.weixin.qq.com/customservice/kfaccount/inviteworker?access_token=";
/**
* 邀请绑定客服帐号
*
* 新添加的客服帐号是不能直接使用的,只有客服人员用微信号绑定了客服账号后,方可登录Web客服进行操作。
* 此接口发起一个绑定邀请到客服人员微信号,客服人员需要在微信客户端上用该微信号确认后帐号才可用。
* 尚未绑定微信号的帐号可以进行绑定邀请操作,邀请未失效时不能对该帐号进行再次绑定微信号邀请。
*
* @param kf_account 完整客服帐号,格式为:帐号前缀@公众号微信号
* @param invite_wx 接收绑定邀请的客服微信号
* @return ApiResult
*/
public static ApiResult inviteWorker(String kf_account, String invite_wx) {
String accessToken = AccessTokenApi.getAccessTokenStr();
Map params = new HashMap();
params.put("kf_account", kf_account);
params.put("invite_wx", invite_wx);
String jsonResult = HttpUtils.post(inviteWorkerUrl + accessToken, JsonUtils.toJson(params));
return new ApiResult(jsonResult);
}
//会话控制-----------------------------------------------------------------------------------
private static String createSession = "https://api.weixin.qq.com/customservice/kfsession/create?access_token=";
/**
* 创建会话
*
* 此接口在客服和用户之间创建一个会话,如果该客服和用户会话已存在,则直接返回0。指定的客服帐号必须已经绑定微信号且在线。
*
* @param kf_account 完整客服帐号,格式为:帐号前缀@公众号微信号
* @param openid 粉丝的openid
* @return ApiResult
*/
public static ApiResult createSession(String kf_account, String openid) {
String url = createSession + AccessTokenApi.getAccessTokenStr();
Map params = new HashMap();
params.put("kf_account", kf_account);
params.put("openid", openid);
String jsonResult = HttpUtils.post(url, JsonUtils.toJson(params));
return new ApiResult(jsonResult);
}
private static String closeSession = "https://api.weixin.qq.com/customservice/kfsession/close?access_token=";
/**
* 关闭会话
*
* 此接口在客服和用户之间创建一个会话,如果该客服和用户会话已存在,则直接返回0。指定的客服帐号必须已经绑定微信号且在线。
*
* @param kf_account 完整客服帐号,格式为:帐号前缀@公众号微信号
* @param openid 粉丝的openid
* @return ApiResult
*/
public static ApiResult closeSession(String kf_account, String openid) {
String url = closeSession + AccessTokenApi.getAccessTokenStr();
Map params = new HashMap();
params.put("kf_account", kf_account);
params.put("openid", openid);
String jsonResult = HttpUtils.post(url, JsonUtils.toJson(params));
return new ApiResult(jsonResult);
}
private static String getSession = "https://api.weixin.qq.com/customservice/kfsession/getsession";
/**
* 获取客户会话状态
* 此接口获取一个客户的会话,如果不存在,则kf_account为空
* @param openid 粉丝的openid
* @return ApiResult
*
* 不存在会话:
* {"createtime":0,"kf_account":""}
*
* 存在一个会话:
{
"createtime" : 123456789, //会话接入的时间
"kf_account" : "test1@test" //正在接待的客服,为空表示没有人在接待
}
*/
public static ApiResult getSession(String openid) {
String accessToken = AccessTokenApi.getAccessTokenStr();
String jsonResult = HttpUtils.get(getSession, ParaMap
.create("access_token", accessToken)
.put("openid", openid)
.getData());
return new ApiResult(jsonResult);
}
private static String getSessionList = "https://api.weixin.qq.com/customservice/kfsession/getsessionlist";
/**
* 获取客服会话列表
* 此接口获取一个客户的会话,如果不存在,则kf_account为空
* @param kf_account 完整客服帐号,格式为:帐号前缀@公众号微信号
* @return ApiResult
*
* 不存在会话:
* {"sessionlist":[]}
*
* 存在一个会话:
{
"sessionlist" : [
{
"createtime" : 123456789, //会话接入的时间
"openid" : "OPENID" //粉丝openid
},
{
"createtime" : 123456789,
"openid" : "OPENID"
}
]
}
*/
public static ApiResult getSessionList(String kf_account) {
String accessToken = AccessTokenApi.getAccessTokenStr();
String jsonResult = HttpUtils.get(getSessionList, ParaMap
.create("access_token", accessToken)
.put("kf_account", kf_account)
.getData());
return new ApiResult(jsonResult);
}
private static String getWaitCase = "https://api.weixin.qq.com/customservice/kfsession/getwaitcase";
/**
* 获取未接入会话列表
* 此接口获取一个客户的会话,如果不存在,则kf_account为空
* @return ApiResult
*
* 不存在会话:
* {"count":0,"waitcaselist":[]}
*
* 存在一个会话:
{
"count" : 1, //未接入会话数量
"waitcaselist" : [ //未接入会话列表,最多返回100条数据,按照来访顺序
{
"latest_time" : 1488784362, //粉丝的最后一条消息的时间
"openid" : "oC8JsuC61cKB_XMuh_Eb3Yk2yWsQ" //粉丝的openid
}
]
}
*/
public static ApiResult getWaitCase() {
String accessToken = AccessTokenApi.getAccessTokenStr();
String jsonResult = HttpUtils.get(getWaitCase, ParaMap
.create("access_token", accessToken)
.getData());
return new ApiResult(jsonResult);
}
//获取聊天记录-------------------------------------------------------------------------------------------
//获取聊记录
private static String getMsgList = "https://api.weixin.qq.com/customservice/msgrecord/getmsglist?access_token=";
/**
* 获取聊天记录
*
* 此接口返回的聊天记录中,对于图片、语音、视频,分别展示成文本格式的[image]、[voice]、[video]。
* 对于较可能包含重要信息的图片消息,后续将提供图片拉取URL,近期将上线。
*
* @param starttime 起始时间,unix时间戳
* @param endtime 结束时间,unix时间戳,每次查询时段不能超过24小时
* @param msgid 消息id顺序从小到大,从1开始
* @param number 每次获取条数,最多10000条
*
* @return ApiResult
*
{
"msgid" : 21957537, //下次请求的msgid
"number" : 24, //请求到的信息的总条数
"recordlist" : [ //消息列表
{
"openid" : "oC8JsuPnZTqSLImnbHfJBQYRgniI", //粉丝openid
"opercode" : 2002, //操作码, (2002: 客服发送信息, 2003: 客服接收消息)
"text" : "https://mp.weixin.qq.com", //聊天记录
"time" : 1488783439, //操作时间,unix时间戳
"worker" : "kf2001@ideal2002" //完整客服帐号,格式为:帐号前缀@公众号微信号
}
]
}
*/
public static ApiResult getMsgList(int starttime, int endtime, int msgid, int number) {
String url = getMsgList + AccessTokenApi.getAccessTokenStr();
Map params = new HashMap();
params.put("starttime", starttime);
params.put("endtime", endtime);
params.put("msgid", msgid);
params.put("number", number);
String jsonResult = HttpUtils.post(url, JsonUtils.toJson(params));
return new ApiResult(jsonResult);
}
}