diff --git a/CHANGE.md b/CHANGE.md
index c8374def..c7fac4f6 100644
--- a/CHANGE.md
+++ b/CHANGE.md
@@ -491,4 +491,8 @@
+ weixin4j-[mp|qy]:version upgrade to 1.6.3
- + weixin4j-server:version upgrade to 1.1.3
\ No newline at end of file
+ + weixin4j-server:version upgrade to 1.1.3
+
+* 2015-11-20
+
+ + weixin4j-qy:新增客服消息
\ No newline at end of file
diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/weixin/error.xml b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/weixin/error.xml
index 397bb7e4..b6111df5 100644
--- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/weixin/error.xml
+++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/weixin/error.xml
@@ -638,6 +638,10 @@
too many group now, no need to add new
组数量过多
+
+ 45022
+ 应用名字长度不合法,合法长度为2-16个字
+
45024
账号数量超过上限
@@ -1058,6 +1062,70 @@
86222
不允许消息服务访问的API
+
+ 86304
+ 不合法的消息类型
+
+
+ 86305
+ 客服服务未启用
+
+
+ 86306
+ 缺少发送人
+
+
+ 86307
+ 缺少发送人类型
+
+
+ 86308
+ 缺少发送人id
+
+
+ 86309
+ 缺少接收人
+
+
+ 86310
+ 缺少接收人类型
+
+
+ 86311
+ 缺少接收人id
+
+
+ 86312
+ 缺少消息类型
+
+
+ 86313
+ 缺少客服,发送人或接收人类型,必须有一个为kf
+
+
+ 86314
+ 客服不唯一,发送人或接收人类型,必须只有一个为kf
+
+
+ 86315
+ 不合法的发送人类型
+
+
+ 86316
+ 不合法的发送人id。Userid不存在、openid不存在、kf不存在
+
+
+ 86317
+ 不合法的接收人类型
+
+
+ 86318
+ 不合法的接收人id。Userid不存在、openid不存在、kf不存在
+
+
+ 86319
+ 不合法的客服,kf不在客服列表中
+
90001
未开通摇一摇周边
diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/payment/mch/Order.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/payment/mch/Order.java
index c51729e1..e88ad51a 100644
--- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/payment/mch/Order.java
+++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/payment/mch/Order.java
@@ -34,7 +34,7 @@ public class Order extends ApiResult {
/**
* 交易状态
*
- * @see com.foxinmy.weixin4j.mp.type.TradeState
+ * @see com.foxinmy.weixin4j.type.TradeState
*/
@XmlElement(name = "trade_state")
@JSONField(name = "trade_state")
@@ -54,7 +54,7 @@ public class Order extends ApiResult {
/**
* 交易类型
*
- * @see com.foxinmy.weixin4j.mp.type.TradeType
+ * @see com.foxinmy.weixin4j.type.TradeType
*/
@XmlElement(name = "trade_type")
@JSONField(name = "trade_type")
diff --git a/weixin4j-mp/src/test/java/com/foxinmy/weixin4j/mp/test/MenuTest.java b/weixin4j-mp/src/test/java/com/foxinmy/weixin4j/mp/test/MenuTest.java
index 7635dc08..9ea35ba9 100644
--- a/weixin4j-mp/src/test/java/com/foxinmy/weixin4j/mp/test/MenuTest.java
+++ b/weixin4j-mp/src/test/java/com/foxinmy/weixin4j/mp/test/MenuTest.java
@@ -34,20 +34,12 @@ public class MenuTest extends TokenTest {
@Test
public void create() throws WeixinException {
btnList = new ArrayList
*
* @param message
- * 客服消息对象
+ * 普通消息对象
* @return 如果无权限,则本次发送失败;如果收件人不存在或未关注,发送仍然执行。两种情况下均返回无效的部分 { "errcode":
* 0, "errmsg": "ok", "invaliduser": "UserID1",
* "invalidparty":"PartyID1", "invalidtag":"TagID1" }
@@ -86,4 +88,35 @@ public class NotifyApi extends QyApi {
return response.getAsJson();
}
+
+ /**
+ * 发送客服消息
+ *
+ * @param message
+ * 客服消息对象
+ * @return 发送结果
+ * @see 客服接口说明
+ * @see com.foxinmy.weixin4j.tuple.Text
+ * @see com.foxinmy.weixin4j.tuple.Image
+ * @see com.foxinmy.weixin4j.tuple.Voice
+ * @see com.foxinmy.weixin4j.tuple.Video
+ * @see com.foxinmy.weixin4j.tuple.File
+ * @see com.foxinmy.weixin4j.qy.message.CustomeMessage
+ * @throws WeixinException
+ */
+ public JsonResult sendCustomeMessage(CustomeMessage message)
+ throws WeixinException {
+ NotifyTuple tuple = message.getTuple();
+ String msgtype = tuple.getMessageType();
+ JSONObject obj = (JSONObject) JSON.toJSON(message);
+ obj.put("msgtype", msgtype);
+ obj.put(msgtype, tuple);
+ String message_kf_send_uri = getRequestUri("message_kf_send_uri");
+ Token token = tokenHolder.getToken();
+ WeixinResponse response = weixinExecutor.post(
+ String.format(message_kf_send_uri, token.getAccessToken()),
+ obj.toJSONString());
+ return response.getAsJsonResult();
+ }
}
diff --git a/weixin4j-qy/src/main/java/com/foxinmy/weixin4j/qy/api/weixin.properties b/weixin4j-qy/src/main/java/com/foxinmy/weixin4j/qy/api/weixin.properties
index d374d8a6..ada62c28 100644
--- a/weixin4j-qy/src/main/java/com/foxinmy/weixin4j/qy/api/weixin.properties
+++ b/weixin4j-qy/src/main/java/com/foxinmy/weixin4j/qy/api/weixin.properties
@@ -57,8 +57,10 @@ menu_create_uri={api_base_url}/menu/create?access_token=%s&agentid=%d
menu_delete_uri={api_base_url}/menu/delete?access_token=%s&agentid=%d
# \u67e5\u8be2\u83dc\u5355
menu_get_uri={api_base_url}/menu/get?access_token=%s&agentid=%d
-# \u53d1\u9001\u6d88\u606f
+# \u53d1\u9001\u666e\u901a\u6d88\u606f
message_send_uri={api_base_url}/message/send?access_token=%s
+# \u53d1\u9001\u5ba2\u670d\u6d88\u606f
+message_kf_send_uri={api_base_url}/kf/send?access_token=%s
# \u83b7\u53d6\u5fae\u4fe1IP\u5730\u5740
getcallbackip_uri={api_base_url}/getcallbackip?access_token=%s
# \u83b7\u53d6\u4f01\u4e1a\u53f7\u5e94\u7528\u4fe1\u606f
diff --git a/weixin4j-qy/src/main/java/com/foxinmy/weixin4j/qy/message/CustomeMessage.java b/weixin4j-qy/src/main/java/com/foxinmy/weixin4j/qy/message/CustomeMessage.java
new file mode 100644
index 00000000..b0514bf9
--- /dev/null
+++ b/weixin4j-qy/src/main/java/com/foxinmy/weixin4j/qy/message/CustomeMessage.java
@@ -0,0 +1,113 @@
+package com.foxinmy.weixin4j.qy.message;
+
+import java.io.Serializable;
+
+import com.alibaba.fastjson.annotation.JSONField;
+import com.foxinmy.weixin4j.tuple.NotifyTuple;
+
+/**
+ * 客服消息对象
+ *
+ * @className CustomeMessage
+ * @author jy
+ * @date 2015年11月20日
+ * @since JDK 1.7
+ * @see com.foxinmy.weixin4j.tuple.Text
+ * @see com.foxinmy.weixin4j.tuple.Image
+ * @see com.foxinmy.weixin4j.tuple.Voice
+ * @see com.foxinmy.weixin4j.tuple.Video
+ * @see com.foxinmy.weixin4j.tuple.File
+ * @see 客服消息
+ */
+public class CustomeMessage implements Serializable {
+
+ private static final long serialVersionUID = -3620361273175868681L;
+
+ private CustomeTarget sender;
+ private CustomeTarget receiver;
+ /**
+ * 消息对象
+ */
+ @JSONField(serialize = false)
+ private NotifyTuple tuple;
+
+ public CustomeMessage(CustomeTarget sender, CustomeTarget receiver,
+ NotifyTuple tuple) {
+ this.sender = sender;
+ this.receiver = receiver;
+ this.tuple = tuple;
+ }
+
+ public CustomeTarget getSender() {
+ return sender;
+ }
+
+ public CustomeTarget getReceiver() {
+ return receiver;
+ }
+
+ public NotifyTuple getTuple() {
+ return tuple;
+ }
+
+ /**
+ * 用户类型
+ *
+ * @className CustomeIdType
+ * @author jy
+ * @date 2015年11月20日
+ * @since JDK 1.7
+ * @see
+ */
+ public enum CustomeIdType {
+ /**
+ * 客服
+ */
+ kf,
+ /**
+ * 企业员工userid
+ */
+ userid,
+ /**
+ * 公众号openid
+ */
+ openid
+ }
+
+ /**
+ * 消息对象
+ *
+ * @className CustomeTarget
+ * @author jy
+ * @date 2015年11月20日
+ * @since JDK 1.7
+ * @see
+ */
+ public static class CustomeTarget implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ private CustomeIdType type;
+ private String id;
+
+ public CustomeTarget(CustomeIdType type, String id) {
+ this.type = type;
+ this.id = id;
+ }
+
+ public CustomeIdType getType() {
+ return type;
+ }
+
+ public String getId() {
+ return id;
+ }
+ }
+
+ @Override
+ public String toString() {
+ return "CustomeMessage [sender=" + sender + ", receiver=" + receiver
+ + ", tuple=" + tuple + "]";
+ }
+}
diff --git a/weixin4j-qy/src/main/java/com/foxinmy/weixin4j/qy/message/NotifyMessage.java b/weixin4j-qy/src/main/java/com/foxinmy/weixin4j/qy/message/NotifyMessage.java
index dd100dc6..bb195e9c 100644
--- a/weixin4j-qy/src/main/java/com/foxinmy/weixin4j/qy/message/NotifyMessage.java
+++ b/weixin4j-qy/src/main/java/com/foxinmy/weixin4j/qy/message/NotifyMessage.java
@@ -7,7 +7,7 @@ import com.foxinmy.weixin4j.qy.model.IdParameter;
import com.foxinmy.weixin4j.tuple.NotifyTuple;
/**
- * 客服消息对象
+ * 消息提醒对象
*
* @className NotifyMessage
* @author jy
diff --git a/weixin4j-server/src/main/java/com/foxinmy/weixin4j/qy/chat/ChatReceiver.java b/weixin4j-server/src/main/java/com/foxinmy/weixin4j/qy/chat/ChatReceiver.java
index 5fb47fb4..4e37fbf2 100644
--- a/weixin4j-server/src/main/java/com/foxinmy/weixin4j/qy/chat/ChatReceiver.java
+++ b/weixin4j-server/src/main/java/com/foxinmy/weixin4j/qy/chat/ChatReceiver.java
@@ -23,7 +23,7 @@ public class ChatReceiver implements Serializable {
@XmlElement(name = "id")
private String targetId;
/**
- * 群聊|单聊
+ * 群聊|单聊|userid|openid
*/
@XmlElement(name = "type")
private String chatType;
diff --git a/weixin4j-server/src/main/java/com/foxinmy/weixin4j/startup/WeixinServerBootstrap.java b/weixin4j-server/src/main/java/com/foxinmy/weixin4j/startup/WeixinServerBootstrap.java
index 7caded64..e54e8509 100644
--- a/weixin4j-server/src/main/java/com/foxinmy/weixin4j/startup/WeixinServerBootstrap.java
+++ b/weixin4j-server/src/main/java/com/foxinmy/weixin4j/startup/WeixinServerBootstrap.java
@@ -159,16 +159,16 @@ public final class WeixinServerBootstrap {
* 默认端口启动服务
*
*/
- public void startup() throws WeixinException {
- startup(DEFAULT_SERVERPORT);
+ public Channel startup() throws WeixinException {
+ return startup(DEFAULT_SERVERPORT);
}
/**
* 指定端口启动服务
*
*/
- public void startup(int serverPort) throws WeixinException {
- startup(DEFAULT_BOSSTHREADS, DEFAULT_WORKERTHREADS, serverPort);
+ public Channel startup(int serverPort) throws WeixinException {
+ return startup(DEFAULT_BOSSTHREADS, DEFAULT_WORKERTHREADS, serverPort);
}
/**
@@ -180,9 +180,10 @@ public final class WeixinServerBootstrap {
* worker线程数
* @param serverPort
* 服务启动端口
+ * @return
* @throws WeixinException
*/
- public void startup(int bossThreads, int workerThreads, int serverPort)
+ public Channel startup(int bossThreads, int workerThreads, int serverPort)
throws WeixinException {
messageDispatcher.setMessageHandlerList(messageHandlerList);
messageDispatcher.setMessageInterceptorList(messageInterceptorList);
@@ -200,7 +201,7 @@ public final class WeixinServerBootstrap {
messageDispatcher));
Channel ch = b.bind(serverPort).sync().channel();
logger.info("weixin4j server startup OK:{}", serverPort);
- ch.closeFuture().sync();
+ return ch.closeFuture().channel();
} catch (WeixinException e) {
throw e;
} catch (InterruptedException e) {
diff --git a/weixin4j-server/src/main/java/com/foxinmy/weixin4j/type/AgentType.java b/weixin4j-server/src/main/java/com/foxinmy/weixin4j/type/AgentType.java
index baa5fc8d..7cff67e1 100644
--- a/weixin4j-server/src/main/java/com/foxinmy/weixin4j/type/AgentType.java
+++ b/weixin4j-server/src/main/java/com/foxinmy/weixin4j/type/AgentType.java
@@ -13,5 +13,14 @@ public enum AgentType {
/**
* 聊天应用
*/
- chat
+ chat,
+ // 企业客服回调
+ /**
+ * 企业号内部客服,客户为企业号通讯录成员
+ */
+ kf_internal,
+ /**
+ * 企业号外部客服,客户为服务号openid
+ */
+ kf_external
}