调整了Tuple消息元件&新增视频上传接口&新增企业好聊天服务接口
This commit is contained in:
parent
b6b1fd98ea
commit
97dc88d7c7
12
CHANGE.md
12
CHANGE.md
@ -401,4 +401,14 @@
|
||||
|
||||
+ **weixin4j-server**:`MessageHandlerAdapter` 声明时限定泛型为`WeixinMessage`的子类
|
||||
|
||||
+ **weixin4j-mp**: 新增图文消息中上传图片接口
|
||||
+ **weixin4j-mp**: 新增图文消息中上传图片接口
|
||||
|
||||
* 2015-08-01
|
||||
|
||||
+ **weixin4j-base**: 整理了Tuple消息元件
|
||||
|
||||
+ **weixin4j-mp**: 新增了群发消息中的上传视频接口
|
||||
|
||||
+ **weixin4j-mp**: 调整群发消息接口返回类型为字符串数组[{msg_id,msg_data_id}]
|
||||
|
||||
+ **weixin4j-qy**: 新增聊天服务接口[ChatApi](./weixin4j-qy/src/main/java/com/foxinmy/weixin4j/qy/api/ChatApi.java)
|
||||
@ -60,4 +60,8 @@
|
||||
|
||||
* 2015-06-26
|
||||
|
||||
+ 移入微信支付模块
|
||||
+ 移入微信支付模块
|
||||
|
||||
* 2015-08-01
|
||||
|
||||
+ 整理了Tuple消息元件并新增ChatTuple企业号聊天消息元件
|
||||
@ -0,0 +1,16 @@
|
||||
package com.foxinmy.weixin4j.tuple;
|
||||
|
||||
/**
|
||||
* 聊天消息元件
|
||||
*
|
||||
* @className ChatTuple
|
||||
* @author jy
|
||||
* @date 2015年8月1日
|
||||
* @since JDK 1.7
|
||||
* @see com.foxinmy.weixin4j.tuple.Text
|
||||
* @see com.foxinmy.weixin4j.tuple.Image
|
||||
* @see com.foxinmy.weixin4j.tuple.File
|
||||
*/
|
||||
public interface ChatTuple extends Tuple {
|
||||
|
||||
}
|
||||
@ -8,7 +8,7 @@ import com.alibaba.fastjson.annotation.JSONField;
|
||||
/**
|
||||
* 文件对象
|
||||
* <p>
|
||||
* <font color="red">可用于「企业号的客服消息」</font>
|
||||
* <font color="red">可用于企业号的「客服消息」及「聊天消息」</font>
|
||||
* </p>
|
||||
*
|
||||
* @className File
|
||||
@ -17,7 +17,7 @@ import com.alibaba.fastjson.annotation.JSONField;
|
||||
* @since JDK 1.7
|
||||
* @see
|
||||
*/
|
||||
public class File implements NotifyTuple {
|
||||
public class File implements NotifyTuple, ChatTuple {
|
||||
|
||||
private static final long serialVersionUID = -8149837316289636110L;
|
||||
|
||||
|
||||
@ -8,7 +8,7 @@ import com.alibaba.fastjson.annotation.JSONField;
|
||||
/**
|
||||
* 图片对象
|
||||
* <p>
|
||||
* <font color="red">可用于「客服消息」「群发消息」</font>
|
||||
* <font color="red">可用于「客服消息」「群发消息」及企业号的「聊天消息」</font>
|
||||
* </p>
|
||||
*
|
||||
* @className Image
|
||||
@ -17,7 +17,7 @@ import com.alibaba.fastjson.annotation.JSONField;
|
||||
* @since JDK 1.7
|
||||
* @see
|
||||
*/
|
||||
public class Image implements MassTuple, NotifyTuple {
|
||||
public class Image implements MassTuple, NotifyTuple, ChatTuple {
|
||||
|
||||
private static final long serialVersionUID = 6928681900960656161L;
|
||||
|
||||
@ -34,7 +34,7 @@ public class Image implements MassTuple, NotifyTuple {
|
||||
private String mediaId;
|
||||
|
||||
@JSONCreator
|
||||
public Image(@JSONField(name = "media_id")String mediaId) {
|
||||
public Image(@JSONField(name = "media_id") String mediaId) {
|
||||
this.mediaId = mediaId;
|
||||
}
|
||||
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
package com.foxinmy.weixin4j.tuple;
|
||||
|
||||
|
||||
/**
|
||||
* 群发消息元件
|
||||
*
|
||||
|
||||
@ -6,6 +6,7 @@ import java.util.List;
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlTransient;
|
||||
|
||||
import com.alibaba.fastjson.annotation.JSONCreator;
|
||||
import com.alibaba.fastjson.annotation.JSONField;
|
||||
|
||||
/**
|
||||
@ -50,7 +51,8 @@ public class MpNews implements MassTuple, NotifyTuple {
|
||||
this(null);
|
||||
}
|
||||
|
||||
public MpNews(String mediaId) {
|
||||
@JSONCreator
|
||||
public MpNews(@JSONField(name = "media_id") String mediaId) {
|
||||
this.mediaId = mediaId;
|
||||
this.articles = new LinkedList<MpArticle>();
|
||||
}
|
||||
|
||||
@ -2,7 +2,6 @@ package com.foxinmy.weixin4j.tuple;
|
||||
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
|
||||
import com.alibaba.fastjson.annotation.JSONCreator;
|
||||
import com.alibaba.fastjson.annotation.JSONField;
|
||||
|
||||
/**
|
||||
@ -56,9 +55,8 @@ public class Music implements NotifyTuple {
|
||||
@XmlElement(name = "ThumbMediaId")
|
||||
private String thumbMediaId;
|
||||
|
||||
@JSONCreator
|
||||
public Music(@JSONField(name = "thumb_media_id") String thumbMediaId) {
|
||||
this.thumbMediaId = thumbMediaId;
|
||||
public Music(String musicUrl, String hqMusicUrl, String thumbMediaId) {
|
||||
this(null, null, musicUrl, hqMusicUrl, thumbMediaId);
|
||||
}
|
||||
|
||||
public Music(@JSONField(name = "title") String title,
|
||||
@ -93,18 +91,10 @@ public class Music implements NotifyTuple {
|
||||
return musicUrl;
|
||||
}
|
||||
|
||||
public void setMusicUrl(String musicUrl) {
|
||||
this.musicUrl = musicUrl;
|
||||
}
|
||||
|
||||
public String getHqMusicUrl() {
|
||||
return hqMusicUrl;
|
||||
}
|
||||
|
||||
public void setHqMusicUrl(String hqMusicUrl) {
|
||||
this.hqMusicUrl = hqMusicUrl;
|
||||
}
|
||||
|
||||
public String getThumbMediaId() {
|
||||
return thumbMediaId;
|
||||
}
|
||||
|
||||
@ -12,7 +12,9 @@ package com.foxinmy.weixin4j.tuple;
|
||||
* @see com.foxinmy.weixin4j.tuple.Voice
|
||||
* @see com.foxinmy.weixin4j.tuple.Video
|
||||
* @see com.foxinmy.weixin4j.tuple.Music
|
||||
* @see com.foxinmy.weixin4j.tuple.File
|
||||
* @see com.foxinmy.weixin4j.tuple.News
|
||||
* @see com.foxinmy.weixin4j.tuple.MpNews
|
||||
*/
|
||||
public interface NotifyTuple extends Tuple {
|
||||
|
||||
|
||||
@ -6,7 +6,7 @@ import com.alibaba.fastjson.annotation.JSONField;
|
||||
/**
|
||||
* 文本对象
|
||||
* <p>
|
||||
* <font color="red">可用于「客服消息」「群发消息」</font>
|
||||
* <font color="red">可用于「客服消息」「群发消息」及企业号的「聊天消息」</font>
|
||||
* </p>
|
||||
*
|
||||
* @className Text
|
||||
@ -15,7 +15,7 @@ import com.alibaba.fastjson.annotation.JSONField;
|
||||
* @since JDK 1.7
|
||||
* @see
|
||||
*/
|
||||
public class Text implements MassTuple, NotifyTuple {
|
||||
public class Text implements MassTuple, NotifyTuple, ChatTuple {
|
||||
|
||||
private static final long serialVersionUID = 520050144519064503L;
|
||||
|
||||
|
||||
@ -51,27 +51,15 @@ public class Video implements NotifyTuple {
|
||||
@XmlElement(name = "Description")
|
||||
private String desc;
|
||||
|
||||
@JSONCreator
|
||||
public Video(@JSONField(name = "media_id") String mediaId) {
|
||||
this.mediaId = mediaId;
|
||||
}
|
||||
|
||||
/**
|
||||
* 公众平台
|
||||
*
|
||||
* @param mediaId
|
||||
* @param thumbMediaId
|
||||
*/
|
||||
public Video(String mediaId, String thumbMediaId) {
|
||||
this(mediaId, thumbMediaId, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 企业号 & 公众号群发
|
||||
* 企业号的视频消息不需要缩略图
|
||||
*
|
||||
* @param mediaId
|
||||
* 视频媒体文件id,可以调用上传临时素材或者永久素材接口获取
|
||||
* @param title
|
||||
* 视频标题
|
||||
* @param desc
|
||||
* 视频描述
|
||||
*/
|
||||
public Video(String mediaId, String title, String desc) {
|
||||
this(mediaId, null, title, desc);
|
||||
@ -96,26 +84,14 @@ public class Video implements NotifyTuple {
|
||||
return thumbMediaId;
|
||||
}
|
||||
|
||||
public void setThumbMediaId(String thumbMediaId) {
|
||||
this.thumbMediaId = thumbMediaId;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public void setTitle(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public String getDesc() {
|
||||
return desc;
|
||||
}
|
||||
|
||||
public void setDesc(String desc) {
|
||||
this.desc = desc;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Video [thumbMediaId=" + thumbMediaId + ", title=" + title
|
||||
|
||||
@ -130,4 +130,10 @@
|
||||
|
||||
* 2015-07-31
|
||||
|
||||
+ 新增图文消息中上传图片接口
|
||||
+ 新增图文消息中上传图片接口
|
||||
|
||||
* 2015-08-01
|
||||
|
||||
+ 新增了群发消息中的上传视频接口
|
||||
|
||||
+ 调整群发消息接口返回类型为字符串数组[{msg_id,msg_data_id}]
|
||||
@ -48,8 +48,8 @@ import com.foxinmy.weixin4j.token.TokenHolder;
|
||||
import com.foxinmy.weixin4j.token.TokenStorager;
|
||||
import com.foxinmy.weixin4j.tuple.MassTuple;
|
||||
import com.foxinmy.weixin4j.tuple.MpArticle;
|
||||
import com.foxinmy.weixin4j.tuple.MpVideo;
|
||||
import com.foxinmy.weixin4j.tuple.Tuple;
|
||||
import com.foxinmy.weixin4j.tuple.Video;
|
||||
import com.foxinmy.weixin4j.type.MediaType;
|
||||
|
||||
/**
|
||||
@ -145,6 +145,29 @@ public class WeixinProxy {
|
||||
return mediaApi.uploadImage(is, fileName);
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传群发中的视频素材
|
||||
*
|
||||
* @param is
|
||||
* 图片数据流
|
||||
* @param fileName
|
||||
* 文件名 为空时将自动生成
|
||||
* @param title
|
||||
* 视频标题 非空
|
||||
* @param description
|
||||
* 视频描述 可为空
|
||||
* @return 群发视频消息对象
|
||||
* @throws WeixinException
|
||||
* @see com.foxinmy.weixin4j.mp.api.MediaApi
|
||||
* @see <a
|
||||
* href="http://mp.weixin.qq.com/wiki/15/5380a4e6f02f2ffdc7981a8ed7a40753.html">高级群发</a>
|
||||
* @see com.foxinmy.weixin4j.tuple.MpVideo
|
||||
*/
|
||||
public MpVideo uploadVideo(InputStream is, String fileName, String title,
|
||||
String description) throws WeixinException {
|
||||
return mediaApi.uploadVideo(is, fileName, title, description);
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传媒体文件 </br> <font color="red">此接口只包含图片、语音、缩略图、视频(临时)四种媒体类型的上传</font>
|
||||
* <p>
|
||||
@ -640,25 +663,6 @@ public class WeixinProxy {
|
||||
return massApi.uploadArticle(articles);
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传分组群发的视频素材
|
||||
*
|
||||
* @param video
|
||||
* 视频对象 其中mediaId媒体文件中上传得到的Id 不能为空
|
||||
* @return 上传后的ID
|
||||
* @throws WeixinException
|
||||
*
|
||||
* @see <a
|
||||
* href="http://mp.weixin.qq.com/wiki/15/5380a4e6f02f2ffdc7981a8ed7a40753.html">高级群发</a>
|
||||
* @see com.foxinmy.weixin4j.mp.api.MassApi
|
||||
* @see com.foxinmy.weixin4j.tuple.Video
|
||||
* @see com.foxinmy.weixin4j.tuple.MpVideo
|
||||
* @see {@link com.foxinmy.weixin4j.mp.api.MediaApi#uploadMedia(File)}
|
||||
*/
|
||||
public String uploadMassVideo(Video video) throws WeixinException {
|
||||
return massApi.uploadVideo(video);
|
||||
}
|
||||
|
||||
/**
|
||||
* 群发消息
|
||||
* <p>
|
||||
@ -673,7 +677,7 @@ public class WeixinProxy {
|
||||
* 选择false可根据group_id发送给指定群组的用户
|
||||
* @param groupId
|
||||
* 分组ID
|
||||
* @return 群发后的消息ID
|
||||
* @return 第一个元素为消息发送任务的ID,第二个元素为消息的数据ID,该字段只有在群发图文消息时,才会出现,可以用于在图文分析数据接口中
|
||||
* @throws WeixinException
|
||||
* @see com.foxinmy.weixin4j.mp.model.Group
|
||||
* @see com.foxinmy.weixin4j.tuple.Text
|
||||
@ -687,7 +691,7 @@ public class WeixinProxy {
|
||||
* @see <a
|
||||
* href="http://mp.weixin.qq.com/wiki/15/5380a4e6f02f2ffdc7981a8ed7a40753.html#.E6.A0.B9.E6.8D.AE.E5.88.86.E7.BB.84.E8.BF.9B.E8.A1.8C.E7.BE.A4.E5.8F.91.E3.80.90.E8.AE.A2.E9.98.85.E5.8F.B7.E4.B8.8E.E6.9C.8D.E5.8A.A1.E5.8F.B7.E8.AE.A4.E8.AF.81.E5.90.8E.E5.9D.87.E5.8F.AF.E7.94.A8.E3.80.91">根据分组群发</a>
|
||||
*/
|
||||
public String massByGroupId(MassTuple tuple, boolean isToAll, int groupId)
|
||||
public String[] massByGroupId(MassTuple tuple, boolean isToAll, int groupId)
|
||||
throws WeixinException {
|
||||
return massApi.massByGroupId(tuple, isToAll, groupId);
|
||||
}
|
||||
@ -699,14 +703,14 @@ public class WeixinProxy {
|
||||
* 图文列表
|
||||
* @param groupId
|
||||
* 分组ID
|
||||
* @return 群发后的消息ID
|
||||
* @return 第一个元素为消息发送任务的ID,第二个元素为消息的数据ID,该字段只有在群发图文消息时,才会出现,可以用于在图文分析数据接口中
|
||||
* @see {@link #massByGroupId(Tuple,int)}
|
||||
* @see <a
|
||||
* href="http://mp.weixin.qq.com/wiki/15/5380a4e6f02f2ffdc7981a8ed7a40753.html#.E6.A0.B9.E6.8D.AE.E5.88.86.E7.BB.84.E8.BF.9B.E8.A1.8C.E7.BE.A4.E5.8F.91.E3.80.90.E8.AE.A2.E9.98.85.E5.8F.B7.E4.B8.8E.E6.9C.8D.E5.8A.A1.E5.8F.B7.E8.AE.A4.E8.AF.81.E5.90.8E.E5.9D.87.E5.8F.AF.E7.94.A8.E3.80.91">根据分组群发</a>
|
||||
* @see com.foxinmy.weixin4j.tuple.MpArticle
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public String massArticleByGroupId(List<MpArticle> articles, int groupId)
|
||||
public String[] massArticleByGroupId(List<MpArticle> articles, int groupId)
|
||||
throws WeixinException {
|
||||
return massApi.massArticleByGroupId(articles, groupId);
|
||||
}
|
||||
@ -723,7 +727,7 @@ public class WeixinProxy {
|
||||
* 消息元件
|
||||
* @param openIds
|
||||
* openId列表
|
||||
* @return 群发后的消息ID
|
||||
* @return 第一个元素为消息发送任务的ID,第二个元素为消息的数据ID,该字段只有在群发图文消息时,才会出现,可以用于在图文分析数据接口中
|
||||
* @throws WeixinException
|
||||
* @see com.foxinmy.weixin4j.mp.model.User
|
||||
* @see com.foxinmy.weixin4j.tuple.Text
|
||||
@ -738,7 +742,7 @@ public class WeixinProxy {
|
||||
* @see {@link com.foxinmy.weixin4j.mp.api.MediaApi#uploadMedia(File)}
|
||||
* @see {@link com.foxinmy.weixin4j.mp.api.UserApi#getUser(String)}
|
||||
*/
|
||||
public String massByOpenIds(MassTuple tuple, String... openIds)
|
||||
public String[] massByOpenIds(MassTuple tuple, String... openIds)
|
||||
throws WeixinException {
|
||||
return massApi.massByOpenIds(tuple, openIds);
|
||||
}
|
||||
@ -750,14 +754,14 @@ public class WeixinProxy {
|
||||
* 图文列表
|
||||
* @param openIds
|
||||
* openId列表
|
||||
* @return 群发后的消息ID
|
||||
* @return 第一个元素为消息发送任务的ID,第二个元素为消息的数据ID,该字段只有在群发图文消息时,才会出现,可以用于在图文分析数据接口中
|
||||
* @see <a
|
||||
* href="http://mp.weixin.qq.com/wiki/15/5380a4e6f02f2ffdc7981a8ed7a40753.html#.E6.A0.B9.E6.8D.AEOpenID.E5.88.97.E8.A1.A8.E7.BE.A4.E5.8F.91.E3.80.90.E8.AE.A2.E9.98.85.E5.8F.B7.E4.B8.8D.E5.8F.AF.E7.94.A8.EF.BC.8C.E6.9C.8D.E5.8A.A1.E5.8F.B7.E8.AE.A4.E8.AF.81.E5.90.8E.E5.8F.AF.E7.94.A8.E3.80.91">根据openid群发</a>
|
||||
* @see {@link #massByOpenIds(Tuple,String...)}
|
||||
* @see com.foxinmy.weixin4j.tuple.MpArticle
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public String massArticleByOpenIds(List<MpArticle> articles,
|
||||
public String[] massArticleByOpenIds(List<MpArticle> articles,
|
||||
String... openIds) throws WeixinException {
|
||||
return massApi.massArticleByOpenIds(articles, openIds);
|
||||
}
|
||||
|
||||
@ -15,7 +15,6 @@ import com.foxinmy.weixin4j.tuple.MassTuple;
|
||||
import com.foxinmy.weixin4j.tuple.MpArticle;
|
||||
import com.foxinmy.weixin4j.tuple.MpNews;
|
||||
import com.foxinmy.weixin4j.tuple.Tuple;
|
||||
import com.foxinmy.weixin4j.tuple.Video;
|
||||
import com.foxinmy.weixin4j.util.StringUtil;
|
||||
|
||||
/**
|
||||
@ -61,28 +60,6 @@ public class MassApi extends MpApi {
|
||||
return response.getAsJson().getString("media_id");
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传分组群发的视频素材
|
||||
*
|
||||
* @param video
|
||||
* 视频对象 其中mediaId媒体文件中上传得到的Id 不能为空
|
||||
* @return 上传后的ID 可用于群发视频消息
|
||||
* @throws WeixinException
|
||||
* @see <a
|
||||
* href="http://mp.weixin.qq.com/wiki/15/5380a4e6f02f2ffdc7981a8ed7a40753.html">高级群发</a>
|
||||
* @see com.foxinmy.weixin4j.tuple.Video
|
||||
* @see com.foxinmy.weixin4j.tuple.MpVideo
|
||||
*/
|
||||
public String uploadVideo(Video video) throws WeixinException {
|
||||
String video_upload_uri = getRequestUri("video_upload_uri");
|
||||
Token token = tokenHolder.getToken();
|
||||
WeixinResponse response = weixinClient.post(
|
||||
String.format(video_upload_uri, token.getAccessToken()),
|
||||
JSON.toJSONString(video));
|
||||
|
||||
return response.getAsJson().getString("media_id");
|
||||
}
|
||||
|
||||
/**
|
||||
* 分组群发
|
||||
* <p>
|
||||
@ -97,7 +74,7 @@ public class MassApi extends MpApi {
|
||||
* 选择false可根据group_id发送给指定群组的用户
|
||||
* @param groupId
|
||||
* 分组ID
|
||||
* @return 群发后的消息ID
|
||||
* @return 第一个元素为消息发送任务的ID,第二个元素为消息的数据ID,该字段只有在群发图文消息时,才会出现,可以用于在图文分析数据接口中
|
||||
* @throws WeixinException
|
||||
* @see com.foxinmy.weixin4j.mp.model.Group
|
||||
* @see com.foxinmy.weixin4j.tuple.Text
|
||||
@ -105,12 +82,13 @@ public class MassApi extends MpApi {
|
||||
* @see com.foxinmy.weixin4j.tuple.Voice
|
||||
* @see com.foxinmy.weixin4j.tuple.MpVideo
|
||||
* @see com.foxinmy.weixin4j.tuple.MpNews
|
||||
* @see com.foxinmy.weixin4j.tuple.Card
|
||||
* @see com.foxinmy.weixin4j.tuple.MassTuple
|
||||
* @see {@link GroupApi#getGroups()}
|
||||
* @see <a
|
||||
* href="http://mp.weixin.qq.com/wiki/15/5380a4e6f02f2ffdc7981a8ed7a40753.html#.E6.A0.B9.E6.8D.AE.E5.88.86.E7.BB.84.E8.BF.9B.E8.A1.8C.E7.BE.A4.E5.8F.91.E3.80.90.E8.AE.A2.E9.98.85.E5.8F.B7.E4.B8.8E.E6.9C.8D.E5.8A.A1.E5.8F.B7.E8.AE.A4.E8.AF.81.E5.90.8E.E5.9D.87.E5.8F.AF.E7.94.A8.E3.80.91">根据分组群发</a>
|
||||
*/
|
||||
public String massByGroupId(MassTuple tuple, boolean isToAll, int groupId)
|
||||
public String[] massByGroupId(MassTuple tuple, boolean isToAll, int groupId)
|
||||
throws WeixinException {
|
||||
if (tuple instanceof MpNews) {
|
||||
MpNews _news = (MpNews) tuple;
|
||||
@ -139,7 +117,9 @@ public class MassApi extends MpApi {
|
||||
String.format(mass_group_uri, token.getAccessToken()),
|
||||
obj.toJSONString());
|
||||
|
||||
return response.getAsJson().getString("msg_id");
|
||||
obj = response.getAsJson();
|
||||
return new String[] { obj.getString("msg_id"),
|
||||
obj.getString("msg_data_id") };
|
||||
}
|
||||
|
||||
/**
|
||||
@ -149,14 +129,14 @@ public class MassApi extends MpApi {
|
||||
* 图文列表
|
||||
* @param groupId
|
||||
* 分组ID
|
||||
* @return 群发后的消息ID
|
||||
* @return 第一个元素为消息发送任务的ID,第二个元素为消息的数据ID,该字段只有在群发图文消息时,才会出现。
|
||||
* @see <a
|
||||
* href="http://mp.weixin.qq.com/wiki/15/5380a4e6f02f2ffdc7981a8ed7a40753.html#.E6.A0.B9.E6.8D.AE.E5.88.86.E7.BB.84.E8.BF.9B.E8.A1.8C.E7.BE.A4.E5.8F.91.E3.80.90.E8.AE.A2.E9.98.85.E5.8F.B7.E4.B8.8E.E6.9C.8D.E5.8A.A1.E5.8F.B7.E8.AE.A4.E8.AF.81.E5.90.8E.E5.9D.87.E5.8F.AF.E7.94.A8.E3.80.91">根据分组群发</a>
|
||||
* @see {@link #massByGroupId(Tuple,int)}
|
||||
* @see com.foxinmy.weixin4j.tuple.MpArticle
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public String massArticleByGroupId(List<MpArticle> articles, int groupId)
|
||||
public String[] massArticleByGroupId(List<MpArticle> articles, int groupId)
|
||||
throws WeixinException {
|
||||
String mediaId = uploadArticle(articles);
|
||||
return massByGroupId(new MpNews(mediaId), false, groupId);
|
||||
@ -169,7 +149,7 @@ public class MassApi extends MpApi {
|
||||
* 消息元件
|
||||
* @param openIds
|
||||
* openId列表
|
||||
* @return 群发后的消息ID
|
||||
* @return 第一个元素为消息发送任务的ID,第二个元素为消息的数据ID,该字段只有在群发图文消息时,才会出现,可以用于在图文分析数据接口中
|
||||
* @throws WeixinException
|
||||
* @see com.foxinmy.weixin4j.mp.model.User
|
||||
* @see com.foxinmy.weixin4j.tuple.Text
|
||||
@ -177,12 +157,13 @@ public class MassApi extends MpApi {
|
||||
* @see com.foxinmy.weixin4j.tuple.Voice
|
||||
* @see com.foxinmy.weixin4j.tuple.MpVideo
|
||||
* @see com.foxinmy.weixin4j.tuple.MpNews
|
||||
* @see com.foxinmy.weixin4j.tuple.Card
|
||||
* @see com.foxinmy.weixin4j.tuple.MassTuple
|
||||
* @see <a
|
||||
* href="http://mp.weixin.qq.com/wiki/15/5380a4e6f02f2ffdc7981a8ed7a40753.html#.E6.A0.B9.E6.8D.AEOpenID.E5.88.97.E8.A1.A8.E7.BE.A4.E5.8F.91.E3.80.90.E8.AE.A2.E9.98.85.E5.8F.B7.E4.B8.8D.E5.8F.AF.E7.94.A8.EF.BC.8C.E6.9C.8D.E5.8A.A1.E5.8F.B7.E8.AE.A4.E8.AF.81.E5.90.8E.E5.8F.AF.E7.94.A8.E3.80.91">根据openid群发</a>
|
||||
* @see {@link UserApi#getUser(String)}
|
||||
*/
|
||||
public String massByOpenIds(MassTuple tuple, String... openIds)
|
||||
public String[] massByOpenIds(MassTuple tuple, String... openIds)
|
||||
throws WeixinException {
|
||||
if (tuple instanceof MpNews) {
|
||||
MpNews _news = (MpNews) tuple;
|
||||
@ -205,7 +186,9 @@ public class MassApi extends MpApi {
|
||||
String.format(mass_openid_uri, token.getAccessToken()),
|
||||
obj.toJSONString());
|
||||
|
||||
return response.getAsJson().getString("msg_id");
|
||||
obj = response.getAsJson();
|
||||
return new String[] { obj.getString("msg_id"),
|
||||
obj.getString("msg_data_id") };
|
||||
}
|
||||
|
||||
/**
|
||||
@ -215,14 +198,14 @@ public class MassApi extends MpApi {
|
||||
* 图文列表
|
||||
* @param openIds
|
||||
* openId列表
|
||||
* @return 群发后的消息ID
|
||||
* @return 第一个元素为消息发送任务的ID,第二个元素为消息的数据ID,该字段只有在群发图文消息时,才会出现,可以用于在图文分析数据接口中.
|
||||
* @see <a
|
||||
* href="http://mp.weixin.qq.com/wiki/15/5380a4e6f02f2ffdc7981a8ed7a40753.html#.E6.A0.B9.E6.8D.AEOpenID.E5.88.97.E8.A1.A8.E7.BE.A4.E5.8F.91.E3.80.90.E8.AE.A2.E9.98.85.E5.8F.B7.E4.B8.8D.E5.8F.AF.E7.94.A8.EF.BC.8C.E6.9C.8D.E5.8A.A1.E5.8F.B7.E8.AE.A4.E8.AF.81.E5.90.8E.E5.8F.AF.E7.94.A8.E3.80.91">根据openid群发</a>
|
||||
* @see {@link #massByOpenIds(Tuple,String...)}
|
||||
* @see com.foxinmy.weixin4j.tuple.MpArticle
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public String massArticleByOpenIds(List<MpArticle> articles,
|
||||
public String[] massArticleByOpenIds(List<MpArticle> articles,
|
||||
String... openIds) throws WeixinException {
|
||||
String mediaId = uploadArticle(articles);
|
||||
return massByOpenIds(new MpNews(mediaId), openIds);
|
||||
|
||||
@ -38,6 +38,7 @@ import com.foxinmy.weixin4j.model.MediaUploadResult;
|
||||
import com.foxinmy.weixin4j.model.Token;
|
||||
import com.foxinmy.weixin4j.token.TokenHolder;
|
||||
import com.foxinmy.weixin4j.tuple.MpArticle;
|
||||
import com.foxinmy.weixin4j.tuple.MpVideo;
|
||||
import com.foxinmy.weixin4j.type.MediaType;
|
||||
import com.foxinmy.weixin4j.util.ConfigUtil;
|
||||
import com.foxinmy.weixin4j.util.ErrorUtil;
|
||||
@ -92,6 +93,40 @@ public class MediaApi extends MpApi {
|
||||
return response.getAsJson().getString("url");
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传群发中的视频素材
|
||||
*
|
||||
* @param is
|
||||
* 图片数据流
|
||||
* @param fileName
|
||||
* 文件名 为空时将自动生成
|
||||
* @param title
|
||||
* 视频标题 非空
|
||||
* @param description
|
||||
* 视频描述 可为空
|
||||
* @return 群发视频消息对象
|
||||
* @throws WeixinException
|
||||
* @see <a
|
||||
* href="http://mp.weixin.qq.com/wiki/15/5380a4e6f02f2ffdc7981a8ed7a40753.html">高级群发</a>
|
||||
* @see com.foxinmy.weixin4j.tuple.MpVideo
|
||||
*/
|
||||
public MpVideo uploadVideo(InputStream is, String fileName, String title,
|
||||
String description) throws WeixinException {
|
||||
MediaUploadResult uploadResult = uploadMedia(false, is, fileName);
|
||||
JSONObject obj = new JSONObject();
|
||||
obj.put("media_id", uploadResult.getMediaId());
|
||||
obj.put("title", title);
|
||||
obj.put("description", description);
|
||||
String video_upload_uri = getRequestUri("video_upload_uri");
|
||||
Token token = tokenHolder.getToken();
|
||||
WeixinResponse response = weixinClient.post(
|
||||
String.format(video_upload_uri, token.getAccessToken()),
|
||||
obj.toJSONString());
|
||||
|
||||
String mediaId = response.getAsJson().getString("media_id");
|
||||
return new MpVideo(mediaId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传媒体文件:图片(image)、语音(voice)、视频(video)和缩略图(thumb) </br> <font
|
||||
* color="red">此接口只包含图片、语音、缩略图、视频(临时)四种媒体类型的上传</font>
|
||||
|
||||
@ -83,6 +83,9 @@ public class TmplApi extends MpApi {
|
||||
* @throws WeixinException
|
||||
* @see <a
|
||||
* href="http://mp.weixin.qq.com/wiki/17/304c1885ea66dbedf7dc170d84999a9d.html#.E5.8F.91.E9.80.81.E6.A8.A1.E6.9D.BF.E6.B6.88.E6.81.AF">模板消息</a>
|
||||
* <a href=
|
||||
* "http://mp.weixin.qq.com/wiki/2/def71e3ecb5706c132229ae505815966.html"
|
||||
* >运营规范</a>
|
||||
* @see com.foxinmy.weixin4j.mp.message.TemplateMessage
|
||||
* @seee com.foxinmy.weixin4j.msg.event.TemplatesendjobfinishMessage
|
||||
*/
|
||||
|
||||
@ -41,18 +41,10 @@ public class NotifyMessage implements Serializable {
|
||||
return touser;
|
||||
}
|
||||
|
||||
public void setTouser(String touser) {
|
||||
this.touser = touser;
|
||||
}
|
||||
|
||||
public NotifyTuple getTuple() {
|
||||
return tuple;
|
||||
}
|
||||
|
||||
public void setTuple(NotifyTuple tuple) {
|
||||
this.tuple = tuple;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "NotifyMessage [touser=" + touser + ", tuple=" + tuple + "]";
|
||||
|
||||
@ -18,7 +18,6 @@ import com.foxinmy.weixin4j.mp.api.MediaApi;
|
||||
import com.foxinmy.weixin4j.tuple.Image;
|
||||
import com.foxinmy.weixin4j.tuple.MpArticle;
|
||||
import com.foxinmy.weixin4j.tuple.Text;
|
||||
import com.foxinmy.weixin4j.tuple.Video;
|
||||
|
||||
/**
|
||||
* 群发消息
|
||||
@ -49,24 +48,17 @@ public class MassTest extends TokenTest {
|
||||
massApi.uploadArticle(articles);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void uploadVideo() throws WeixinException {
|
||||
Video video = new Video("mediaId", "title", "desc");
|
||||
String massId = massApi.uploadVideo(video);
|
||||
Assert.assertTrue(massId != null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void massByGroupId() throws WeixinException {
|
||||
String msgId = massApi.massByGroupId(new Image("mediaId"), true, 0);
|
||||
Assert.assertTrue(msgId != null);
|
||||
String[] msgId = massApi.massByGroupId(new Image("mediaId"), true, 0);
|
||||
Assert.assertTrue(msgId[0] != null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void massByOpenIds() throws WeixinException {
|
||||
String msgId = massApi.massByOpenIds(new Text("HI"),
|
||||
String[] msgId = massApi.massByOpenIds(new Text("HI"),
|
||||
"oyFLst1bqtuTcxK-ojF8hOGtLQao");
|
||||
Assert.assertTrue(msgId != null);
|
||||
Assert.assertTrue(msgId[0] != null);
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -76,8 +68,8 @@ public class MassTest extends TokenTest {
|
||||
MediaUploadResult mediaResult = mediaApi.uploadMedia(false,
|
||||
new FileInputStream(file), file.getName());
|
||||
articles.add(new MpArticle(mediaResult.getMediaId(), "title", "content"));
|
||||
String massId = massApi.massArticleByGroupId(articles, 0);
|
||||
Assert.assertTrue(massId != null);
|
||||
String[] massId = massApi.massArticleByGroupId(articles, 0);
|
||||
Assert.assertTrue(massId[0] != null);
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -87,9 +79,9 @@ public class MassTest extends TokenTest {
|
||||
MediaUploadResult mediaResult = mediaApi.uploadMedia(false,
|
||||
new FileInputStream(file), file.getName());
|
||||
articles.add(new MpArticle(mediaResult.getMediaId(), "title", "content"));
|
||||
String massId = massApi.massArticleByOpenIds(articles,
|
||||
String[] massId = massApi.massArticleByOpenIds(articles,
|
||||
"owGBft_vbBbOaQOmpEUE4xDLeRSU");
|
||||
Assert.assertTrue(massId != null);
|
||||
Assert.assertTrue(massId[0] != null);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@ -3,6 +3,7 @@ package com.foxinmy.weixin4j.mp.test;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@ -19,6 +20,7 @@ import com.foxinmy.weixin4j.model.MediaRecord;
|
||||
import com.foxinmy.weixin4j.model.MediaUploadResult;
|
||||
import com.foxinmy.weixin4j.mp.api.MediaApi;
|
||||
import com.foxinmy.weixin4j.tuple.MpArticle;
|
||||
import com.foxinmy.weixin4j.tuple.MpVideo;
|
||||
import com.foxinmy.weixin4j.type.MediaType;
|
||||
|
||||
/**
|
||||
@ -42,8 +44,8 @@ public class MediaTest extends TokenTest {
|
||||
@Test
|
||||
public void upload1() throws IOException, WeixinException {
|
||||
File file = new File("/Users/jy/Downloads/weixin4j.png");
|
||||
MediaUploadResult mediaId = mediaApi.uploadMedia(false, new FileInputStream(
|
||||
file), file.getName());
|
||||
MediaUploadResult mediaId = mediaApi.uploadMedia(false,
|
||||
new FileInputStream(file), file.getName());
|
||||
// 1Vgd1R5DdznSc3rPxd-sNZ3pLt54cejhJ5ItuNcCgrqoQArNANWy5oxso_r9KNlE
|
||||
Assert.assertNotNull(mediaId);
|
||||
System.err.println(mediaId);
|
||||
@ -59,8 +61,8 @@ public class MediaTest extends TokenTest {
|
||||
@Test
|
||||
public void upload2() throws IOException, WeixinException {
|
||||
File file = new File("/Users/jy/Downloads/test.jpg");
|
||||
MediaUploadResult mediaId = mediaApi.uploadMedia(true, new FileInputStream(
|
||||
file), file.getName());
|
||||
MediaUploadResult mediaId = mediaApi.uploadMedia(true,
|
||||
new FileInputStream(file), file.getName());
|
||||
// 8790403529
|
||||
Assert.assertNotNull(mediaId);
|
||||
System.err.println(mediaId);
|
||||
@ -139,4 +141,15 @@ public class MediaTest extends TokenTest {
|
||||
.listAllMaterialMedia(MediaType.image);
|
||||
System.err.println(mediaList);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void uploadVideo() throws WeixinException {
|
||||
InputStream is = null;
|
||||
String fileName = "视频文件名";
|
||||
String title = "视频标题";
|
||||
String description = "视频描述";
|
||||
MpVideo mpVideo = mediaApi
|
||||
.uploadVideo(is, fileName, title, description);
|
||||
Assert.assertTrue(mpVideo.getMediaId() != null);
|
||||
}
|
||||
}
|
||||
|
||||
@ -61,13 +61,15 @@ public class NotifyTest extends TokenTest {
|
||||
|
||||
@Test
|
||||
public void video() throws WeixinException {
|
||||
NotifyMessage notify = new NotifyMessage("to", new Video("video"));
|
||||
NotifyMessage notify = new NotifyMessage("to", new Video("mediaId",
|
||||
"title", "desc"));
|
||||
System.out.println(notifyApi.sendNotify(notify));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void music() throws WeixinException {
|
||||
NotifyMessage notify = new NotifyMessage("to", new Music("music"));
|
||||
NotifyMessage notify = new NotifyMessage("to", new Music("musicUrl",
|
||||
"hqMusicUrl", "thumbMediaId"));
|
||||
System.out.println(notifyApi.sendNotify(notify));
|
||||
}
|
||||
|
||||
|
||||
@ -82,4 +82,8 @@
|
||||
|
||||
* 2015-07-30
|
||||
|
||||
+ **weixin4j-qy**: 调整[WeixinSuiteProxy](.src/main/java/com/foxinmy/weixin4j/qy/WeixinSuiteProxy.java)对多个套件的支持
|
||||
+ **weixin4j-qy**: 调整[WeixinSuiteProxy](.src/main/java/com/foxinmy/weixin4j/qy/WeixinSuiteProxy.java)对多个套件的支持
|
||||
|
||||
* 2015-08-01
|
||||
|
||||
+ 新增聊天服务接口[ChatApi](./src/main/java/com/foxinmy/weixin4j/qy/api/ChatApi.java)
|
||||
@ -32,6 +32,8 @@ weixin4j-qy
|
||||
* CouponApi `代金券API`
|
||||
|
||||
* CashApi `现金API`
|
||||
|
||||
* ChatApi `聊天API`
|
||||
|
||||
如何使用
|
||||
--------
|
||||
|
||||
@ -0,0 +1,222 @@
|
||||
package com.foxinmy.weixin4j.qy.api;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.foxinmy.weixin4j.exception.WeixinException;
|
||||
import com.foxinmy.weixin4j.http.weixin.JsonResult;
|
||||
import com.foxinmy.weixin4j.http.weixin.WeixinResponse;
|
||||
import com.foxinmy.weixin4j.model.Token;
|
||||
import com.foxinmy.weixin4j.qy.message.ChatMessage;
|
||||
import com.foxinmy.weixin4j.qy.model.ChatInfo;
|
||||
import com.foxinmy.weixin4j.qy.model.ChatMute;
|
||||
import com.foxinmy.weixin4j.qy.type.ChatType;
|
||||
import com.foxinmy.weixin4j.token.TokenHolder;
|
||||
import com.foxinmy.weixin4j.tuple.ChatTuple;
|
||||
import com.foxinmy.weixin4j.util.ObjectId;
|
||||
import com.foxinmy.weixin4j.util.StringUtil;
|
||||
|
||||
/**
|
||||
* 聊天服务接口
|
||||
*
|
||||
* @className ChatApi
|
||||
* @author jy
|
||||
* @date 2015年7月31日
|
||||
* @since JDK 1.7
|
||||
* @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%9C%8D%E5%8A%A1">企业号消息服务</a>
|
||||
*/
|
||||
public class ChatApi extends QyApi {
|
||||
private final TokenHolder tokenHolder;
|
||||
|
||||
public ChatApi(TokenHolder tokenHolder) {
|
||||
this.tokenHolder = tokenHolder;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建会话 <font color="red">如果会话id为空,程序会自动生成一个唯一ID</font>
|
||||
*
|
||||
* @param chatInfo
|
||||
* 会话信息
|
||||
* @return 会话ID
|
||||
* @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 {
|
||||
String chatId = chatInfo.getChatId();
|
||||
JSONObject obj = (JSONObject) JSON.toJSON(chatInfo);
|
||||
if (StringUtil.isBlank(chatId)) {
|
||||
chatId = ObjectId.get().toHexString();
|
||||
obj.put("chatid", chatId);
|
||||
}
|
||||
String message_chat_create_uri = getRequestUri("message_chat_create_uri");
|
||||
Token token = tokenHolder.getToken();
|
||||
weixinClient.post(
|
||||
String.format(message_chat_create_uri, token.getAccessToken()),
|
||||
obj.toJSONString());
|
||||
return chatId;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取会话
|
||||
*
|
||||
* @param chatId
|
||||
* 会话ID
|
||||
* @return 会话信息
|
||||
* @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 {
|
||||
String message_chat_get_uri = getRequestUri("message_chat_get_uri");
|
||||
Token token = tokenHolder.getToken();
|
||||
WeixinResponse response = weixinClient.get(String.format(
|
||||
message_chat_get_uri, token.getAccessToken(), chatId));
|
||||
return response.getAsJson().getObject("chat_info", ChatInfo.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新会话
|
||||
*
|
||||
* @param chatInfo
|
||||
* 会话信息 至少保持会话ID不能为空
|
||||
* @param operator
|
||||
* 操作人userid
|
||||
* @param addUsers
|
||||
* 会话新增成员列表
|
||||
* @param deleteUsers
|
||||
* 会话退出成员列表
|
||||
* @return 处理结果
|
||||
* @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 {
|
||||
JSONObject obj = (JSONObject) JSON.toJSON(chatInfo);
|
||||
obj.remove("userlist");
|
||||
obj.put("op_user", operator);
|
||||
obj.put("add_user_list", addUsers);
|
||||
obj.put("del_user_list", deleteUsers);
|
||||
String message_chat_update_uri = getRequestUri("message_chat_update_uri");
|
||||
Token token = tokenHolder.getToken();
|
||||
WeixinResponse response = weixinClient.post(
|
||||
String.format(message_chat_update_uri, token.getAccessToken()),
|
||||
obj.toJSONString());
|
||||
return response.getAsJsonResult();
|
||||
}
|
||||
|
||||
/**
|
||||
* 退出会话
|
||||
*
|
||||
* @param chatId
|
||||
* 会话ID
|
||||
* @param operator
|
||||
* 操作人userid
|
||||
* @return 处理结果
|
||||
* @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 {
|
||||
JSONObject obj = new JSONObject();
|
||||
obj.put("chatid", chatId);
|
||||
obj.put("op_user", operator);
|
||||
String message_chat_quit_uri = getRequestUri("message_chat_quit_uri");
|
||||
Token token = tokenHolder.getToken();
|
||||
WeixinResponse response = weixinClient.post(
|
||||
String.format(message_chat_quit_uri, token.getAccessToken()),
|
||||
obj.toJSONString());
|
||||
return response.getAsJsonResult();
|
||||
}
|
||||
|
||||
/**
|
||||
* 清除会话未读状态
|
||||
*
|
||||
* @param v
|
||||
* 会话值,为userid|chatid,分别表示:成员id|会话id
|
||||
* @param owner
|
||||
* 会话所有者的userid
|
||||
* @param chatType
|
||||
* 会话类型:single|group,分别表示:群聊|单聊
|
||||
* @return 处理结果
|
||||
* @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 clearNotify(String targetId, String owner,
|
||||
ChatType chatType) throws WeixinException {
|
||||
JSONObject chat = new JSONObject();
|
||||
chat.put("type", chatType.name());
|
||||
chat.put("id", targetId);
|
||||
String message_chat_clearnotify_uri = getRequestUri("message_chat_clearnotify_uri");
|
||||
Token token = tokenHolder.getToken();
|
||||
WeixinResponse response = weixinClient.post(
|
||||
String.format(message_chat_clearnotify_uri,
|
||||
token.getAccessToken()),
|
||||
String.format("{\"op_user\": \"%s\",\"chat\":%s", owner,
|
||||
chat.toJSONString()));
|
||||
return response.getAsJsonResult();
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置成员接收到的消息是否提醒。主要场景是用于对接企业im的在线状态,如成员处于在线状态时,可以设置该成员的消息免打扰。当成员离线时,关闭免打扰状态
|
||||
* ,对微信端进行提醒。
|
||||
*
|
||||
* @param chatMutes
|
||||
* @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)
|
||||
throws WeixinException {
|
||||
JSONObject mute = new JSONObject();
|
||||
mute.put("user_mute_list", chatMutes);
|
||||
String message_chat_setmute_uri = getRequestUri("message_chat_setmute_uri");
|
||||
Token token = tokenHolder.getToken();
|
||||
WeixinResponse response = weixinClient
|
||||
.post(String.format(message_chat_setmute_uri,
|
||||
token.getAccessToken()), mute.toJSONString());
|
||||
return JSON.parseArray(response.getAsJson().getString("invaliduser"),
|
||||
String.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送消息
|
||||
*
|
||||
* @param message
|
||||
* 消息对象
|
||||
* @return 处理结果
|
||||
* @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 sendMessage(ChatMessage message) throws WeixinException {
|
||||
ChatTuple tuple = message.getChatTuple();
|
||||
String msgtype = tuple.getMessageType();
|
||||
JSONObject msg = new JSONObject();
|
||||
JSONObject receiver = new JSONObject();
|
||||
receiver.put("id", message.getTargetId());
|
||||
receiver.put("type", message.getChatType().name());
|
||||
msg.put("receiver", receiver);
|
||||
msg.put("sender", message.getSenderId());
|
||||
msg.put("msgtype", msgtype);
|
||||
msg.put(msgtype, tuple);
|
||||
String message_chat_send_uri = getRequestUri("message_chat_send_uri");
|
||||
Token token = tokenHolder.getToken();
|
||||
WeixinResponse response = weixinClient.post(
|
||||
String.format(message_chat_send_uri, token.getAccessToken()),
|
||||
msg.toJSONString());
|
||||
return response.getAsJsonResult();
|
||||
}
|
||||
}
|
||||
@ -120,4 +120,19 @@ material_media_del_uri={api_base_url}/material/del?access_token=%s&media_id=%s&a
|
||||
# \u83b7\u53d6\u5a92\u4f53\u7d20\u6750\u603b\u6570
|
||||
material_media_count_uri={api_base_url}/material/get_count?access_token=%s&agentid=%d
|
||||
# \u83b7\u53d6\u5a92\u4f53\u7d20\u6750\u5217\u8868
|
||||
material_media_list_uri={api_base_url}/material/batchget?access_token=%s
|
||||
material_media_list_uri={api_base_url}/material/batchget?access_token=%s
|
||||
|
||||
# \u6d88\u606f\u670d\u52a1-\u521b\u5efa\u4f1a\u8bdd
|
||||
message_chat_create_uri={api_base_url}/chat/create?access_token=%s
|
||||
# \u6d88\u606f\u670d\u52a1-\u83b7\u53d6\u4f1a\u8bdd
|
||||
message_chat_get_uri={api_base_url}/chat/get?access_token=%s&chatid=%s
|
||||
# \u6d88\u606f\u670d\u52a1-\u66f4\u65b0\u4f1a\u8bdd
|
||||
message_chat_update_uri={api_base_url}/chat/update?access_token=%s
|
||||
# \u6d88\u606f\u670d\u52a1-\u9000\u51fa\u4f1a\u8bdd
|
||||
message_chat_quit_uri={api_base_url}/chat/quit?access_token=%s
|
||||
# \u6d88\u606f\u670d\u52a1-\u6e05\u9664\u4f1a\u8bdd\u672a\u8bfb\u72b6\u6001
|
||||
message_chat_clearnotify_uri={api_base_url}/chat/clearnotify?access_token=%s
|
||||
# \u6d88\u606f\u670d\u52a1-\u8bbe\u7f6e\u6210\u5458\u65b0\u6d88\u606f\u514d\u6253\u6270
|
||||
message_chat_setmute_uri={api_base_url}/chat/setmute?access_token=%s
|
||||
# \u6d88\u606f\u670d\u52a1-\u53d1\u6d88\u606f
|
||||
message_chat_send_uri={api_base_url}/chat/send?access_token=%s
|
||||
@ -0,0 +1,69 @@
|
||||
package com.foxinmy.weixin4j.qy.message;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import com.foxinmy.weixin4j.qy.type.ChatType;
|
||||
import com.foxinmy.weixin4j.tuple.ChatTuple;
|
||||
|
||||
/**
|
||||
* 聊天消息对象
|
||||
*
|
||||
* @className ChatMessage
|
||||
* @author jy
|
||||
* @date 2015年8月1日
|
||||
* @since JDK 1.7
|
||||
* @see com.foxinmy.weixin4j.tuple.Text
|
||||
* @see com.foxinmy.weixin4j.tuple.Image
|
||||
* @see com.foxinmy.weixin4j.tuple.File
|
||||
*/
|
||||
public class ChatMessage implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = -4973029130270955777L;
|
||||
|
||||
/**
|
||||
* 成员id|会话id
|
||||
*/
|
||||
private String targetId;
|
||||
/**
|
||||
* 群聊|单聊
|
||||
*/
|
||||
private ChatType chatType;
|
||||
/**
|
||||
* 发送人id
|
||||
*/
|
||||
private String senderId;
|
||||
/**
|
||||
* 消息对象
|
||||
*/
|
||||
private ChatTuple chatTuple;
|
||||
|
||||
public ChatMessage(String targetId, ChatType chatType, String senderId,
|
||||
ChatTuple chatTuple) {
|
||||
this.targetId = targetId;
|
||||
this.chatType = chatType;
|
||||
this.senderId = senderId;
|
||||
this.chatTuple = chatTuple;
|
||||
}
|
||||
|
||||
public String getTargetId() {
|
||||
return targetId;
|
||||
}
|
||||
|
||||
public ChatType getChatType() {
|
||||
return chatType;
|
||||
}
|
||||
|
||||
public String getSenderId() {
|
||||
return senderId;
|
||||
}
|
||||
|
||||
public ChatTuple getChatTuple() {
|
||||
return chatTuple;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ChatMessage [targetId=" + targetId + ", chatType=" + chatType
|
||||
+ ", senderId=" + senderId + ", chatTuple=" + chatTuple + "]";
|
||||
}
|
||||
}
|
||||
@ -7,7 +7,7 @@ import com.foxinmy.weixin4j.qy.model.IdParameter;
|
||||
import com.foxinmy.weixin4j.tuple.NotifyTuple;
|
||||
|
||||
/**
|
||||
* 发送消息对象
|
||||
* 客服消息对象
|
||||
*
|
||||
* @className NotifyMessage
|
||||
* @author jy
|
||||
@ -38,6 +38,7 @@ public class NotifyMessage implements Serializable {
|
||||
/**
|
||||
* 消息对象
|
||||
*/
|
||||
@JSONField(serialize = false)
|
||||
private NotifyTuple tuple;
|
||||
/**
|
||||
* 发送对象
|
||||
|
||||
@ -0,0 +1,80 @@
|
||||
package com.foxinmy.weixin4j.qy.model;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
import com.alibaba.fastjson.annotation.JSONCreator;
|
||||
import com.alibaba.fastjson.annotation.JSONField;
|
||||
|
||||
/**
|
||||
* 聊天会话信息
|
||||
*
|
||||
* @className ChatInfo
|
||||
* @author jy
|
||||
* @date 2015年7月31日
|
||||
* @since JDK 1.7
|
||||
* @see
|
||||
*/
|
||||
public class ChatInfo implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1899784347096501375L;
|
||||
/**
|
||||
* 会话id
|
||||
*/
|
||||
@JSONField(name = "chatid")
|
||||
private String chatId;
|
||||
/**
|
||||
* 会话标题
|
||||
*/
|
||||
private String name;
|
||||
/**
|
||||
* 管理员userid
|
||||
*/
|
||||
private String owner;
|
||||
/**
|
||||
* 会话成员列表
|
||||
*/
|
||||
@JSONField(name = "userlist")
|
||||
private List<String> members;
|
||||
|
||||
public ChatInfo(String chatId, String name, String owner) {
|
||||
this(chatId, name, owner, null);
|
||||
}
|
||||
|
||||
@JSONCreator
|
||||
public ChatInfo(@JSONField(name = "chatId") String chatId,
|
||||
@JSONField(name = "name") String name,
|
||||
@JSONField(name = "owner") String owner,
|
||||
@JSONField(name = "userlist") List<String> members) {
|
||||
this.chatId = chatId;
|
||||
this.name = name;
|
||||
this.owner = owner;
|
||||
this.members = members;
|
||||
}
|
||||
|
||||
public String getChatId() {
|
||||
return chatId;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getOwner() {
|
||||
return owner;
|
||||
}
|
||||
|
||||
public List<String> getMembers() {
|
||||
return members;
|
||||
}
|
||||
|
||||
public void setMembers(List<String> members) {
|
||||
this.members = members;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ChatInfo [chatId=" + chatId + ", name=" + name + ", owner="
|
||||
+ owner + ", members=" + members + "]";
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,63 @@
|
||||
package com.foxinmy.weixin4j.qy.model;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import com.alibaba.fastjson.annotation.JSONField;
|
||||
|
||||
/**
|
||||
* 成员新消息免打扰
|
||||
*
|
||||
* @className ChatMute
|
||||
* @author jy
|
||||
* @date 2015年8月1日
|
||||
* @since JDK 1.7
|
||||
* @see
|
||||
*/
|
||||
public class ChatMute implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 6734443056426236273L;
|
||||
|
||||
private String userid;
|
||||
private int status;
|
||||
|
||||
/**
|
||||
* 默认关闭免打扰
|
||||
*
|
||||
* @param userid
|
||||
*/
|
||||
public ChatMute(String userid) {
|
||||
this.userid = userid;
|
||||
}
|
||||
|
||||
/**
|
||||
* 传入true时开启免打扰
|
||||
*
|
||||
* @param userid
|
||||
* 成员userid
|
||||
* @param status
|
||||
* 是否开启免打扰
|
||||
*/
|
||||
public ChatMute(String userid, boolean status) {
|
||||
this.userid = userid;
|
||||
this.status = status ? 1 : 0;
|
||||
}
|
||||
|
||||
public String getUserid() {
|
||||
return userid;
|
||||
}
|
||||
|
||||
public int getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
@JSONField(deserialize = false)
|
||||
public boolean getFormatStatus() {
|
||||
return status == 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ChatMute [userid=" + userid + ", status=" + getFormatStatus()
|
||||
+ "]";
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,21 @@
|
||||
package com.foxinmy.weixin4j.qy.type;
|
||||
|
||||
/**
|
||||
* 会话类型
|
||||
*
|
||||
* @className ChatType
|
||||
* @author jy
|
||||
* @date 2015年7月31日
|
||||
* @since JDK 1.7
|
||||
* @see
|
||||
*/
|
||||
public enum ChatType {
|
||||
/**
|
||||
* 单聊
|
||||
*/
|
||||
single,
|
||||
/**
|
||||
* 群聊
|
||||
*/
|
||||
group
|
||||
}
|
||||
@ -55,7 +55,8 @@ public class NotifyMsgTest extends TokenTest {
|
||||
|
||||
@Test
|
||||
public void video() throws WeixinException {
|
||||
NotifyMessage notify = new NotifyMessage(0, new Video("123"));
|
||||
NotifyMessage notify = new NotifyMessage(0, new Video("mediaId",
|
||||
"title", "desc"));
|
||||
System.out.println(notifyApi.sendNotify(notify));
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user