weixin4j-qy:会话API暴露到WeixinProxy类&重命名NotifyApi#sendNotify为sendNotifyMessage

This commit is contained in:
jinyu 2015-08-09 09:25:22 +08:00
parent 000cfacd6b
commit 23c7960a83
10 changed files with 191 additions and 34 deletions

View File

@ -428,3 +428,9 @@
* 2015-08-07
+ 主要去掉了实体类中的字段上@JSONFiled上的deserialize=false属性和不合理的format方法
* 2015-08-09
+ **weixin4j-qy**: 会话API暴露到WeixinProxy类
+ **weixin4j-qy**: 重命名NotifyApi#sendNotify为sendNotifyMessage

View File

@ -1,6 +1,6 @@
# \u6d4b\u8bd5\u4e4b\u7528 \u6b63\u5f0f\u73af\u5883\u4e0bcopy\u4e00\u4efd\u5230classpath
# \u516c\u4f17\u53f7\u4fe1\u606f
account={"id":"wxd5d03da81b799b9a","secret":"c787a9fcec16fd712b77679c1fc8084f",\
account={"id":"wx4ab8f8de58159a57","secret":"1d4eb0f4bf556aaed539f30ed05ca795",\
"mchId":"V3.x\u7248\u672c\u4e0b\u7684\u5fae\u4fe1\u5546\u6237\u53f7 \u670d\u52a1\u53f7\u652f\u4ed8\u65f6\u9700\u8981\u586b\u5165",\
"partnerId":"V2\u7248\u672c\u4e0b\u7684\u8d22\u4ed8\u901a\u7684\u5546\u6237\u53f7 \u670d\u52a1\u53f7\u652f\u4ed8\u65f6\u9700\u8981\u586b\u5165",\
"partnerKey":"V2\u7248\u672c\u4e0b\u7684\u8d22\u4ed8\u901a\u5546\u6237\u6743\u9650\u5bc6\u94a5Key \u670d\u52a1\u53f7\u652f\u4ed8\u65f6\u9700\u8981\u586b\u5165",\

View File

@ -86,4 +86,10 @@
* 2015-08-01
+ 新增聊天服务接口[ChatApi](./src/main/java/com/foxinmy/weixin4j/qy/api/ChatApi.java)
+ 新增会话服务接口[ChatApi](./src/main/java/com/foxinmy/weixin4j/qy/api/ChatApi.java)
* 2015-08-09
+ 会话API暴露到WeixinProxy类
+ 重命名NotifyApi#sendNotify为sendNotifyMessage

View File

@ -15,6 +15,7 @@ import com.foxinmy.weixin4j.model.MediaRecord;
import com.foxinmy.weixin4j.model.MediaUploadResult;
import com.foxinmy.weixin4j.qy.api.AgentApi;
import com.foxinmy.weixin4j.qy.api.BatchApi;
import com.foxinmy.weixin4j.qy.api.ChatApi;
import com.foxinmy.weixin4j.qy.api.HelperApi;
import com.foxinmy.weixin4j.qy.api.MediaApi;
import com.foxinmy.weixin4j.qy.api.MenuApi;
@ -23,17 +24,21 @@ import com.foxinmy.weixin4j.qy.api.PartyApi;
import com.foxinmy.weixin4j.qy.api.QyApi;
import com.foxinmy.weixin4j.qy.api.TagApi;
import com.foxinmy.weixin4j.qy.api.UserApi;
import com.foxinmy.weixin4j.qy.message.ChatMessage;
import com.foxinmy.weixin4j.qy.message.NotifyMessage;
import com.foxinmy.weixin4j.qy.model.AgentInfo;
import com.foxinmy.weixin4j.qy.model.AgentOverview;
import com.foxinmy.weixin4j.qy.model.AgentSetter;
import com.foxinmy.weixin4j.qy.model.BatchResult;
import com.foxinmy.weixin4j.qy.model.Callback;
import com.foxinmy.weixin4j.qy.model.ChatInfo;
import com.foxinmy.weixin4j.qy.model.ChatMute;
import com.foxinmy.weixin4j.qy.model.IdParameter;
import com.foxinmy.weixin4j.qy.model.Party;
import com.foxinmy.weixin4j.qy.model.Tag;
import com.foxinmy.weixin4j.qy.model.User;
import com.foxinmy.weixin4j.qy.token.WeixinTokenCreator;
import com.foxinmy.weixin4j.qy.type.ChatType;
import com.foxinmy.weixin4j.qy.type.InviteType;
import com.foxinmy.weixin4j.qy.type.UserStatus;
import com.foxinmy.weixin4j.token.TokenHolder;
@ -61,6 +66,7 @@ public class WeixinProxy {
private final HelperApi helperApi;
private final AgentApi agentApi;
private final BatchApi batchApi;
private final ChatApi chatApi;
private final TokenHolder tokenHolder;
@ -118,6 +124,7 @@ public class WeixinProxy {
this.notifyApi = new NotifyApi(tokenHolder);
this.menuApi = new MenuApi(tokenHolder);
this.mediaApi = new MediaApi(tokenHolder);
this.chatApi = new ChatApi(tokenHolder);
}
public TokenHolder getTokenHolder() {
@ -125,14 +132,14 @@ public class WeixinProxy {
}
/**
* 发送消息(需要管理员对应用有使用权限对收件人tousertopartytotag有查看权限否则本次调用失败)
* 发送客服消息(需要管理员对应用有使用权限对收件人tousertopartytotag有查看权限否则本次调用失败)
* <p>
* 1 发送人员列表存在错误的userid执行发送开发者需注意返回结果说明</br>
* 2发送人员不在通讯录权限范围内不执行发送任务返回首个出错的userid</br>
* 3发送人员不在应用可见范围内不执行发送任务返回首个出错的userid</br>
* </p>
*
* @param notify
* @param message
* 客服消息对象
* @return
* 如果对应用或收件人部门标签任何一个无权限则本次发送失败如果收件人部门或标签不存在发送仍然执行但返回无效的部分</br>
@ -153,8 +160,9 @@ public class WeixinProxy {
* @see com.foxinmy.weixin4j.tuple.MpNews
* @see com.foxinmy.weixin4j.qy.message.NotifyMessage
*/
public JSONObject sendNotify(NotifyMessage notify) throws WeixinException {
return notifyApi.sendNotify(notify);
public JSONObject sendNotifyMessage(NotifyMessage message)
throws WeixinException {
return notifyApi.sendNotifyMessage(message);
}
/**
@ -1040,6 +1048,136 @@ public class WeixinProxy {
public String openid2userid(String openid) throws WeixinException {
return userApi.openid2userid(openid);
}
/**
* 创建会话 <font color="red">如果会话id为空,程序会自动生成一个唯一ID</font>
*
* @param chatInfo
* 会话信息
* @return 会话ID
* @see com.foxinmy.weixin4j.qy.api.ChatApi
* @see com.foxinmy.weixin4j.qy.model.ChatInfo
* @see <a
* href="http://qydev.weixin.qq.com/wiki/index.php?title=%E4%BC%81%E4%B8%9A%E5%8F%B7%E6%B6%88%E6%81%AF%E6%8E%A5%E5%8F%A3%E8%AF%B4%E6%98%8E#.E5.88.9B.E5.BB.BA.E4.BC.9A.E8.AF.9D">创建会话</a>
* @throws WeixinException
*/
public String createChat(ChatInfo chatInfo) throws WeixinException {
return chatApi.createChat(chatInfo);
}
/**
* 获取会话
*
* @param chatId
* 会话ID
* @return 会话信息
* @see com.foxinmy.weixin4j.qy.api.ChatApi
* @see com.foxinmy.weixin4j.qy.model.ChatInfo
* @see <a
* href="http://qydev.weixin.qq.com/wiki/index.php?title=%E4%BC%81%E4%B8%9A%E5%8F%B7%E6%B6%88%E6%81%AF%E6%8E%A5%E5%8F%A3%E8%AF%B4%E6%98%8E#.E8.8E.B7.E5.8F.96.E4.BC.9A.E8.AF.9D">获取会话</a>
* @throws WeixinException
*/
public ChatInfo getChat(String chatId) throws WeixinException {
return chatApi.getChat(chatId);
}
/**
* 更新会话
*
* @param chatInfo
* 会话信息 至少保持会话ID不能为空
* @param operator
* 操作人userid
* @param addUsers
* 会话新增成员列表
* @param deleteUsers
* 会话退出成员列表
* @return 处理结果
* @see com.foxinmy.weixin4j.qy.api.ChatApi
* @see com.foxinmy.weixin4j.qy.model.ChatInfo
* @see <a
* href="http://qydev.weixin.qq.com/wiki/index.php?title=%E4%BC%81%E4%B8%9A%E5%8F%B7%E6%B6%88%E6%81%AF%E6%8E%A5%E5%8F%A3%E8%AF%B4%E6%98%8E#.E4.BF.AE.E6.94.B9.E4.BC.9A.E8.AF.9D.E4.BF.A1.E6.81.AF">修改会话信息</a>
* @throws WeixinException
*/
public JsonResult updateChat(ChatInfo chatInfo, String operator,
List<String> addUsers, List<String> deleteUsers)
throws WeixinException {
return chatApi.updateChat(chatInfo, operator, addUsers, deleteUsers);
}
/**
* 退出会话
*
* @param chatId
* 会话ID
* @param operator
* 操作人userid
* @return 处理结果
* @see com.foxinmy.weixin4j.qy.api.ChatApi
* @see <a
* href="http://qydev.weixin.qq.com/wiki/index.php?title=%E4%BC%81%E4%B8%9A%E5%8F%B7%E6%B6%88%E6%81%AF%E6%8E%A5%E5%8F%A3%E8%AF%B4%E6%98%8E#.E9.80.80.E5.87.BA.E4.BC.9A.E8.AF.9D">退出会话</a>
* @throws WeixinException
*/
public JsonResult quitChat(String chatId, String operator)
throws WeixinException {
return chatApi.quitChat(chatId, operator);
}
/**
* 清除会话未读状态
*
* @param targetId
* 会话值为userid|chatid分别表示成员id|会话id
* @param owner
* 会话所有者的userid
* @param chatType
* 会话类型single|group分别表示群聊|单聊
* @return 处理结果
* @see com.foxinmy.weixin4j.qy.api.ChatApi
* @see <a
* href="http://qydev.weixin.qq.com/wiki/index.php?title=%E4%BC%81%E4%B8%9A%E5%8F%B7%E6%B6%88%E6%81%AF%E6%8E%A5%E5%8F%A3%E8%AF%B4%E6%98%8E#.E6.B8.85.E9.99.A4.E4.BC.9A.E8.AF.9D.E6.9C.AA.E8.AF.BB.E7.8A.B6.E6.80.81">清除会话未读状态</a>
* @throws WeixinException
*/
public JsonResult clearChatNotify(String targetId, String owner,
ChatType chatType) throws WeixinException {
return chatApi.clearChatNotify(targetId, owner, chatType);
}
/**
* 设置成员接收到的消息是否提醒主要场景是用于对接企业im的在线状态如成员处于在线状态时可以设置该成员的消息免打扰当成员离线时关闭免打扰状态
* 对微信端进行提醒
*
* @param chatMutes
* 提醒参数
* @see com.foxinmy.weixin4j.qy.api.ChatApi
* @see com.foxinmy.weixin4j.qy.model.ChatMute
* @see <a href=
* "http://qydev.weixin.qq.com/wiki/index.php?title=%E4%BC%81%E4%B8%9A%E5%8F%B7%E6%B6%88%E6%81%AF%E6%8E%A5%E5%8F%A3%E8%AF%B4%E6%98%8E#.E8.AE.BE.E7.BD.AE.E6.88.90.E5.91.98.E6.96.B0.E6.B6.88.E6.81.AF.E5.85.8D.E6.89.93.E6.89.B0"
* >设置成员新消息免打扰</a>
* @return 列表中不存在的成员剩余合法成员会继续执行
* @throws WeixinException
*/
public List<String> setChatMute(List<ChatMute> chatMutes)
throws WeixinException {
return chatApi.setChatMute(chatMutes);
}
/**
* 发送会话消息
*
* @param message
* 消息对象
* @return 处理结果
* @see com.foxinmy.weixin4j.qy.api.ChatApi
* @see com.foxinmy.weixin4j.qy.message.ChatMessage
* @see <a
* href="http://qydev.weixin.qq.com/wiki/index.php?title=%E4%BC%81%E4%B8%9A%E5%8F%B7%E6%B6%88%E6%81%AF%E6%8E%A5%E5%8F%A3%E8%AF%B4%E6%98%8E#.E5.8F.91.E6.B6.88.E6.81.AF">发送消息</a>
* @throws WeixinException
*/
public JsonResult sendChatMessage(ChatMessage message)
throws WeixinException {
return chatApi.sendChatMessage(message);
}
public final static String VERSION = "1.5.2";
}

View File

@ -140,7 +140,7 @@ public class ChatApi extends QyApi {
/**
* 清除会话未读状态
*
* @param v
* @param targetId
* 会话值为userid|chatid分别表示成员id|会话id
* @param owner
* 会话所有者的userid
@ -151,7 +151,7 @@ public class ChatApi extends QyApi {
* href="http://qydev.weixin.qq.com/wiki/index.php?title=%E4%BC%81%E4%B8%9A%E5%8F%B7%E6%B6%88%E6%81%AF%E6%8E%A5%E5%8F%A3%E8%AF%B4%E6%98%8E#.E6.B8.85.E9.99.A4.E4.BC.9A.E8.AF.9D.E6.9C.AA.E8.AF.BB.E7.8A.B6.E6.80.81">清除会话未读状态</a>
* @throws WeixinException
*/
public JsonResult clearNotify(String targetId, String owner,
public JsonResult clearChatNotify(String targetId, String owner,
ChatType chatType) throws WeixinException {
JSONObject chat = new JSONObject();
chat.put("type", chatType.name());
@ -171,13 +171,15 @@ public class ChatApi extends QyApi {
* 对微信端进行提醒
*
* @param chatMutes
* 提醒参数
* @see com.foxinmy.weixin4j.qy.model.ChatMute
* @see <a href=
* "http://qydev.weixin.qq.com/wiki/index.php?title=%E4%BC%81%E4%B8%9A%E5%8F%B7%E6%B6%88%E6%81%AF%E6%8E%A5%E5%8F%A3%E8%AF%B4%E6%98%8E#.E8.AE.BE.E7.BD.AE.E6.88.90.E5.91.98.E6.96.B0.E6.B6.88.E6.81.AF.E5.85.8D.E6.89.93.E6.89.B0"
* >设置成员新消息免打扰</a>
* @return 列表中不存在的成员剩余合法成员会继续执行
* @throws WeixinException
*/
public List<String> setMute(List<ChatMute> chatMutes)
public List<String> setChatMute(List<ChatMute> chatMutes)
throws WeixinException {
JSONObject mute = new JSONObject();
mute.put("user_mute_list", chatMutes);
@ -201,7 +203,8 @@ public class ChatApi extends QyApi {
* href="http://qydev.weixin.qq.com/wiki/index.php?title=%E4%BC%81%E4%B8%9A%E5%8F%B7%E6%B6%88%E6%81%AF%E6%8E%A5%E5%8F%A3%E8%AF%B4%E6%98%8E#.E5.8F.91.E6.B6.88.E6.81.AF">发送消息</a>
* @throws WeixinException
*/
public JsonResult sendMessage(ChatMessage message) throws WeixinException {
public JsonResult sendChatMessage(ChatMessage message)
throws WeixinException {
ChatTuple tuple = message.getChatTuple();
String msgtype = tuple.getMessageType();
JSONObject msg = new JSONObject();

View File

@ -9,6 +9,7 @@ import java.io.InputStream;
import java.io.OutputStream;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
@ -523,9 +524,10 @@ public class MediaApi extends QyApi {
public boolean apply(Object object, String name,
Object value) {
if (column.containsKey(name)) {
if (name.equalsIgnoreCase("department")) {
column.put(name, StringUtil.join(
(JSONArray) JSON.toJSON(value), ';'));
if (value instanceof Collection) {
column.put(name,
StringUtil.join(((Collection<?>) value)
.iterator(), ';'));
} else {
column.put(name, value);
}

View File

@ -12,7 +12,7 @@ import com.foxinmy.weixin4j.token.TokenHolder;
import com.foxinmy.weixin4j.tuple.NotifyTuple;
/**
* 发送消息API
* 客服消息API
*
* @className NotifyApi
* @author jy.hu
@ -46,7 +46,7 @@ public class NotifyApi extends QyApi {
* 3发送人员不在应用可见范围内不执行发送任务返回首个出错的userid</br>
* </p>
*
* @param notify
* @param message
* 客服消息对象
* @return 如果无权限则本次发送失败如果收件人不存在或未关注发送仍然执行两种情况下均返回无效的部分</br> { "errcode":
* 0, "errmsg": "ok", "invaliduser": "UserID1",
@ -65,11 +65,12 @@ public class NotifyApi extends QyApi {
* @see com.foxinmy.weixin4j.tuple.MpNews
* @see com.foxinmy.weixin4j.qy.message.NotifyMessage
*/
public JSONObject sendNotify(NotifyMessage notify) throws WeixinException {
NotifyTuple tuple = notify.getTuple();
Map<String, String> target = notify.getTarget().getParameter();
public JSONObject sendNotifyMessage(NotifyMessage message)
throws WeixinException {
NotifyTuple tuple = message.getTuple();
Map<String, String> target = message.getTarget().getParameter();
String msgtype = tuple.getMessageType();
JSONObject obj = (JSONObject) JSON.toJSON(notify);
JSONObject obj = (JSONObject) JSON.toJSON(message);
obj.put("msgtype", msgtype);
obj.put(msgtype, tuple);
if (target == null || target.isEmpty()) {

View File

@ -8,7 +8,7 @@ import com.foxinmy.weixin4j.qy.type.ChatType;
import com.foxinmy.weixin4j.tuple.ChatTuple;
/**
* 聊天消息对象
* 会话消息对象
*
* @className ChatMessage
* @author jy

View File

@ -38,33 +38,33 @@ public class NotifyMsgTest extends TokenTest {
@Test
public void text() throws WeixinException {
NotifyMessage notify = new NotifyMessage(0, new Text("content"));
System.out.println(notifyApi.sendNotify(notify));
System.out.println(notifyApi.sendNotifyMessage(notify));
}
@Test
public void image() throws WeixinException {
NotifyMessage notify = new NotifyMessage(0, new Image("123"));
System.out.println(notifyApi.sendNotify(notify));
System.out.println(notifyApi.sendNotifyMessage(notify));
}
@Test
public void voice() throws WeixinException {
NotifyMessage notify = new NotifyMessage(0, new Voice("123"));
System.out.println(notifyApi.sendNotify(notify));
System.out.println(notifyApi.sendNotifyMessage(notify));
}
@Test
public void video() throws WeixinException {
NotifyMessage notify = new NotifyMessage(0, new Video("mediaId",
"title", "desc"));
System.out.println(notifyApi.sendNotify(notify));
System.out.println(notifyApi.sendNotifyMessage(notify));
}
@Test
public void file() throws WeixinException {
File file = new File("file");
NotifyMessage notify = new NotifyMessage(0, file);
System.out.println(notifyApi.sendNotify(notify));
System.out.println(notifyApi.sendNotifyMessage(notify));
}
@Test
@ -73,7 +73,7 @@ public class NotifyMsgTest extends TokenTest {
NotifyMessage notify = new NotifyMessage(0, news);
news.addArticle("title1", "desc1", "picUrl1", "url1");
news.addArticle("title2", "desc2", "picUrl2", "url2");
System.out.println(notifyApi.sendNotify(notify));
System.out.println(notifyApi.sendNotifyMessage(notify));
}
@Test
@ -82,13 +82,14 @@ public class NotifyMsgTest extends TokenTest {
NotifyMessage notify = new NotifyMessage(0, news);
news.addArticle("thumbMediaId1", "title1", "content1");
news.addArticle("thumbMediaId2", "title1", "content2");
System.out.println(notifyApi.sendNotify(notify));
System.out.println(notifyApi.sendNotifyMessage(notify));
}
@Test
public void send1() throws WeixinException {
Text text = new Text("this is a text");
JSONObject result = notifyApi.sendNotify(new NotifyMessage(1, text));
JSONObject result = notifyApi.sendNotifyMessage(new NotifyMessage(1,
text));
Assert.assertEquals(0, result.getIntValue("errcode"));
}
}

View File

@ -30,7 +30,7 @@ public class CruxMessageHandler extends DefaultHandler {
private String toUserName;
private String msgType;
private String eventType;
private boolean agentId;
private boolean hasAgent;
private Set<String> nodeNames;
private String content;
@ -41,7 +41,7 @@ public class CruxMessageHandler extends DefaultHandler {
toUserName = null;
msgType = null;
eventType = null;
agentId = false;
hasAgent = false;
nodeNames = new HashSet<String>();
}
@ -57,8 +57,8 @@ public class CruxMessageHandler extends DefaultHandler {
msgType = content.toLowerCase();
} else if (localName.equalsIgnoreCase("event")) {
eventType = content.toLowerCase();
} else if (localName.equalsIgnoreCase("agentId")) {
agentId = true;
} else if (localName.startsWith("agent")) {
hasAgent = true;
}
}
@ -69,7 +69,7 @@ public class CruxMessageHandler extends DefaultHandler {
}
public AccountType getAccountType() {
if (agentId) {
if (hasAgent) {
return AccountType.QY;
}
if (StringUtil.isBlank(msgType) && StringUtil.isBlank(eventType)) {