新增评论管理接口
This commit is contained in:
parent
66417fdc8b
commit
c53e0718ef
52
CHANGE.md
52
CHANGE.md
@ -714,72 +714,76 @@
|
|||||||
+ 优化PayOldApi
|
+ 优化PayOldApi
|
||||||
|
|
||||||
+ weixin4j-mp:新增接口调用次数清零接口
|
+ weixin4j-mp:新增接口调用次数清零接口
|
||||||
|
|
||||||
* 2016-06-20
|
* 2016-06-20
|
||||||
|
|
||||||
+ version upgrade to 1.7.0
|
+ version upgrade to 1.7.0
|
||||||
|
|
||||||
* 2016-07-05
|
* 2016-07-05
|
||||||
|
|
||||||
+ weixin4j-mp:初始化开放平台第三方组件TokenCreator
|
+ weixin4j-mp:初始化开放平台第三方组件TokenCreator
|
||||||
|
|
||||||
+ weixin4j-mp:新增第三方组件ComponentApi
|
+ weixin4j-mp:新增第三方组件ComponentApi
|
||||||
|
|
||||||
* 2016-07-06
|
* 2016-07-06
|
||||||
|
|
||||||
+ weixin4j-mp:新增第三方组件WeixinComponentProxy
|
+ weixin4j-mp:新增第三方组件WeixinComponentProxy
|
||||||
|
|
||||||
* 2016-07-21
|
* 2016-07-21
|
||||||
|
|
||||||
+ weixin4j-base:新增MessageConverter
|
+ weixin4j-base:新增MessageConverter
|
||||||
|
|
||||||
* 2016-07-22
|
* 2016-07-22
|
||||||
|
|
||||||
+ weixin4j-base:主要调整退款相关类与官网一致
|
+ weixin4j-base:主要调整退款相关类与官网一致
|
||||||
|
|
||||||
+ weixin4j-base:获取cache时加锁处理(via 风车车)
|
+ weixin4j-base:获取cache时加锁处理(via 风车车)
|
||||||
|
|
||||||
* 2016-08-05
|
* 2016-08-05
|
||||||
|
|
||||||
+ weixin4j-base:model包拆分media/paging
|
+ weixin4j-base:model包拆分media/paging
|
||||||
|
|
||||||
+ weixin4j-base:type包拆分card/mch
|
+ weixin4j-base:type包拆分card/mch
|
||||||
|
|
||||||
+ weixin4j-base:新增card卡券相关类
|
+ weixin4j-base:新增card卡券相关类
|
||||||
|
|
||||||
+ weixin4j-mp:新增CardApi:创建卡券接口
|
+ weixin4j-mp:新增CardApi:创建卡券接口
|
||||||
|
|
||||||
* 2016-08-09
|
* 2016-08-09
|
||||||
|
|
||||||
+ weixin4j-base:修复媒体消息转换错误bug
|
+ weixin4j-base:修复媒体消息转换错误bug
|
||||||
|
|
||||||
+ weixin4j-mp:新增创建卡券二维码接口
|
+ weixin4j-mp:新增创建卡券二维码接口
|
||||||
|
|
||||||
+ version upgrade to 1.7.1
|
+ version upgrade to 1.7.1
|
||||||
|
|
||||||
+ LOGGER级别优化
|
+ LOGGER级别优化
|
||||||
|
|
||||||
|
|
||||||
* 2016-08-22
|
* 2016-08-22
|
||||||
|
|
||||||
+ weixin4j-base:删除`Weixin4jSettings`配置类
|
+ weixin4j-base:删除`Weixin4jSettings`配置类
|
||||||
|
|
||||||
* 2016-10-10
|
* 2016-10-10
|
||||||
|
|
||||||
+ version upgrade to 1.7.2
|
+ version upgrade to 1.7.2
|
||||||
|
|
||||||
* 2016-11-22
|
* 2016-11-22
|
||||||
|
|
||||||
+ weixin4j-mp:新增黑名单接口
|
+ weixin4j-mp:新增黑名单接口
|
||||||
|
|
||||||
* 2016-12-13
|
* 2016-12-13
|
||||||
|
|
||||||
+ version upgrade to 1.7.3
|
+ version upgrade to 1.7.3
|
||||||
|
|
||||||
* 2017-01-09
|
* 2017-01-09
|
||||||
|
|
||||||
+ 新增批量发红包接口
|
+ 新增批量发红包接口
|
||||||
|
|
||||||
+ 新增摇一摇周边接口
|
+ 新增摇一摇周边接口
|
||||||
|
|
||||||
+ version upgrade to 1.7.4
|
+ version upgrade to 1.7.4
|
||||||
|
|
||||||
|
* 2017-05-19
|
||||||
|
|
||||||
|
+ weixin4j-mp:新增评论管理接口
|
||||||
@ -719,6 +719,18 @@
|
|||||||
<code>45059</code>
|
<code>45059</code>
|
||||||
<text>有粉丝身上的标签数已经超过限制</text>
|
<text>有粉丝身上的标签数已经超过限制</text>
|
||||||
</error>
|
</error>
|
||||||
|
<error>
|
||||||
|
<code>45065</code>
|
||||||
|
<text>相同 clientmsgid 已存在群发记录,返回数据中带有已存在的群发任务的 msgid</text>
|
||||||
|
</error>
|
||||||
|
<error>
|
||||||
|
<code>45066</code>
|
||||||
|
<text>相同 clientmsgid 重试速度过快,请间隔1分钟重试</text>
|
||||||
|
</error>
|
||||||
|
<error>
|
||||||
|
<code>45067</code>
|
||||||
|
<text>clientmsgid 长度超过限制</text>
|
||||||
|
</error>
|
||||||
<error>
|
<error>
|
||||||
<code>45157</code>
|
<code>45157</code>
|
||||||
<text>标签名非法,请注意不能和其他标签重名</text>
|
<text>标签名非法,请注意不能和其他标签重名</text>
|
||||||
@ -1655,6 +1667,61 @@
|
|||||||
<code>86320</code>
|
<code>86320</code>
|
||||||
<text>不合法的客服类型</text>
|
<text>不合法的客服类型</text>
|
||||||
</error>
|
</error>
|
||||||
|
<error>
|
||||||
|
<code>45009</code>
|
||||||
|
<msg>reach max api daily quota limit</msg>
|
||||||
|
<text>没有剩余的调用次数</text>
|
||||||
|
</error>
|
||||||
|
<error>
|
||||||
|
<code>88000</code>
|
||||||
|
<msg>without comment privilege</msg>
|
||||||
|
<text>没有留言权限</text>
|
||||||
|
</error>
|
||||||
|
<error>
|
||||||
|
<code>88001</code>
|
||||||
|
<msg>msg_data is not exists</msg>
|
||||||
|
<text>该图文不存在</text>
|
||||||
|
</error>
|
||||||
|
<error>
|
||||||
|
<code>88002</code>
|
||||||
|
<msg>the article is limit for safety</msg>
|
||||||
|
<text>文章存在敏感信息</text>
|
||||||
|
</error>
|
||||||
|
<error>
|
||||||
|
<code>88003</code>
|
||||||
|
<msg>elected comment upper limit</msg>
|
||||||
|
<text>精选评论数已达上限</text>
|
||||||
|
</error>
|
||||||
|
<error>
|
||||||
|
<code>88004</code>
|
||||||
|
<msg>comment was deleted by user</msg>
|
||||||
|
<text>已被用户删除,无法精选</text>
|
||||||
|
</error>
|
||||||
|
<error>
|
||||||
|
<code>88005</code>
|
||||||
|
<msg>already reply</msg>
|
||||||
|
<text>该评论已回复</text>
|
||||||
|
</error>
|
||||||
|
<error>
|
||||||
|
<code>88007</code>
|
||||||
|
<msg>reply content beyond max len or content len is zero</msg>
|
||||||
|
<text>回复超过长度限制或为0</text>
|
||||||
|
</error>
|
||||||
|
<error>
|
||||||
|
<code>88008</code>
|
||||||
|
<msg>comment is not exists</msg>
|
||||||
|
<text>该评论不存在</text>
|
||||||
|
</error>
|
||||||
|
<error>
|
||||||
|
<code>88009</code>
|
||||||
|
<msg>reply is not exists</msg>
|
||||||
|
<text>该回复不存在</text>
|
||||||
|
</error>
|
||||||
|
<error>
|
||||||
|
<code>88010</code>
|
||||||
|
<msg>count range error. cout <= 0 or count > 50</msg>
|
||||||
|
<text>获取评论数目不合法</text>
|
||||||
|
</error>
|
||||||
<error>
|
<error>
|
||||||
<code>90001</code>
|
<code>90001</code>
|
||||||
<text>未认证摇一摇周边</text>
|
<text>未认证摇一摇周边</text>
|
||||||
|
|||||||
@ -22,129 +22,186 @@ import com.foxinmy.weixin4j.type.ButtonType;
|
|||||||
*/
|
*/
|
||||||
public class Button implements Serializable {
|
public class Button implements Serializable {
|
||||||
|
|
||||||
private static final long serialVersionUID = -6422234732203854866L;
|
private static final long serialVersionUID = -6422234732203854866L;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 菜单标题,不超过16个字节,子菜单不超过40个字节
|
* 菜单标题,不超过16个字节,子菜单不超过40个字节
|
||||||
*/
|
*/
|
||||||
private String name;
|
private String name;
|
||||||
/**
|
/**
|
||||||
* 菜单类型 </br> <font color="red">
|
* 菜单类型 </br>
|
||||||
* 公众平台官网上能够设置的菜单类型有view、text、img、photo、video、voice </font>
|
* <font color="red"> 公众平台官网上能够设置的菜单类型有view、text、img、photo、video、voice
|
||||||
*
|
* </font>
|
||||||
* @see com.foxinmy.weixin4j.type.ButtonType
|
*
|
||||||
*/
|
* @see com.foxinmy.weixin4j.type.ButtonType
|
||||||
private ButtonType type;
|
*/
|
||||||
/**
|
private String type;
|
||||||
* 菜单KEY值,根据type的类型而定</p> 通过公众平台设置的自定义菜单:</br> <li>text:保存文字; <li>
|
/**
|
||||||
* img、voice:保存媒体ID; <li>video:保存视频URL; <li>
|
* 菜单KEY值,根据type的类型而定
|
||||||
* news:保存图文消息媒体ID <li>view:保存链接URL;
|
* </p>
|
||||||
* <p>
|
* 通过公众平台设置的自定义菜单:</br>
|
||||||
* 使用API设置的自定义菜单:
|
* <li>text:保存文字;
|
||||||
* </p> <li>
|
* <li>img、voice:保存媒体ID;
|
||||||
* click、scancode_push、scancode_waitmsg、pic_sysphoto、pic_photo_or_album、
|
* <li>video:保存视频URL;
|
||||||
* pic_weixin、location_select:保存key; <li>view:保存链接URL; <li>
|
* <li>news:保存图文消息媒体ID
|
||||||
* media_id、view_limited:保存媒体ID
|
* <li>view:保存链接URL;
|
||||||
*/
|
* <p>
|
||||||
private String content;
|
* 使用API设置的自定义菜单:
|
||||||
/**
|
* </p>
|
||||||
* 扩展属性,比如在公众平台设置菜单时的图文列表
|
* <li>click、scancode_push、scancode_waitmsg、pic_sysphoto、pic_photo_or_album、
|
||||||
*/
|
* pic_weixin、location_select:保存key;
|
||||||
@JSONField(serialize = false, deserialize = false)
|
* <li>view:保存链接URL;
|
||||||
private Object extra;
|
* <li>media_id、view_limited:保存媒体ID
|
||||||
/**
|
*/
|
||||||
* 二级菜单数组,个数应为1~5个
|
private String content;
|
||||||
*/
|
/**
|
||||||
@JSONField(name = "sub_button")
|
* 扩展属性,比如在公众平台设置菜单时的图文列表
|
||||||
private List<Button> subs;
|
*/
|
||||||
|
@JSONField(serialize = false, deserialize = false)
|
||||||
|
private Object extra;
|
||||||
|
/**
|
||||||
|
* miniprogram类型必须 小程序的appid(仅认证公众号可配置)
|
||||||
|
*/
|
||||||
|
private String appid;
|
||||||
|
/**
|
||||||
|
* miniprogram类型必须 小程序的页面路径
|
||||||
|
*/
|
||||||
|
private String pagepath;
|
||||||
|
|
||||||
protected Button() {
|
/**
|
||||||
this.subs = new ArrayList<Button>();
|
* 二级菜单数组,个数应为1~5个
|
||||||
}
|
*/
|
||||||
|
@JSONField(name = "sub_button")
|
||||||
|
private List<Button> subs;
|
||||||
|
|
||||||
/**
|
protected Button() {
|
||||||
* 创建一个具有子菜单的菜单
|
this.subs = new ArrayList<Button>();
|
||||||
*
|
}
|
||||||
* @param name
|
|
||||||
* 菜单名
|
|
||||||
* @param subButtons
|
|
||||||
* 二级菜单列表
|
|
||||||
*/
|
|
||||||
public Button(String name, Button... subButtons) {
|
|
||||||
this.name = name;
|
|
||||||
this.subs = new ArrayList<Button>(Arrays.asList(subButtons));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 创建一个普通菜单
|
* 创建一个具有子菜单的菜单
|
||||||
*
|
*
|
||||||
* @param name
|
* @param name
|
||||||
* 菜单名
|
* 菜单名
|
||||||
* @param content
|
* @param subButtons
|
||||||
* 菜单内容
|
* 二级菜单列表
|
||||||
* @param type
|
*/
|
||||||
* 菜单类型
|
public Button(String name, Button... subButtons) {
|
||||||
*/
|
this.name = name;
|
||||||
public Button(String name, String content, ButtonType type) {
|
this.subs = new ArrayList<Button>(Arrays.asList(subButtons));
|
||||||
this.name = name;
|
}
|
||||||
this.content = content;
|
|
||||||
this.type = type;
|
|
||||||
this.subs = new ArrayList<Button>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getName() {
|
/**
|
||||||
return name;
|
* 创建一个普通菜单
|
||||||
}
|
*
|
||||||
|
* @param name
|
||||||
|
* 菜单名
|
||||||
|
* @param content
|
||||||
|
* 菜单内容
|
||||||
|
* @param type
|
||||||
|
* 菜单类型
|
||||||
|
*/
|
||||||
|
public Button(String name, String content, ButtonType type) {
|
||||||
|
this.name = name;
|
||||||
|
this.content = content;
|
||||||
|
this.type = type.name();
|
||||||
|
this.subs = new ArrayList<Button>();
|
||||||
|
}
|
||||||
|
|
||||||
public void setName(String name) {
|
/**
|
||||||
this.name = name;
|
* 小程序菜单
|
||||||
}
|
*
|
||||||
|
* @param name
|
||||||
|
* 菜单名
|
||||||
|
* @param url
|
||||||
|
* 小程序的url页面
|
||||||
|
* @param appid
|
||||||
|
* 小程序的appid
|
||||||
|
* @param pagepath
|
||||||
|
* 小程序员的页面路径
|
||||||
|
*/
|
||||||
|
public Button(String name, String url, String appid, String pagepath) {
|
||||||
|
this.name = name;
|
||||||
|
this.content = url;
|
||||||
|
this.appid = appid;
|
||||||
|
this.pagepath = pagepath;
|
||||||
|
this.type = ButtonType.miniprogram.name();
|
||||||
|
this.subs = new ArrayList<Button>();
|
||||||
|
}
|
||||||
|
|
||||||
public ButtonType getType() {
|
public String getName() {
|
||||||
return type;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setType(ButtonType type) {
|
public void setName(String name) {
|
||||||
this.type = type;
|
this.name = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getContent() {
|
public String getType() {
|
||||||
return content;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setContent(String content) {
|
public void setType(String type) {
|
||||||
this.content = content;
|
this.type = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object getExtra() {
|
public void setType(ButtonType type) {
|
||||||
return extra;
|
this.type = type.name();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public String getContent() {
|
||||||
* 扩展只读属性,设置无效
|
return content;
|
||||||
*
|
}
|
||||||
* @param extra
|
|
||||||
*/
|
|
||||||
public void setExtra(Object extra) {
|
|
||||||
this.extra = extra;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<Button> getSubs() {
|
public void setContent(String content) {
|
||||||
return subs;
|
this.content = content;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSubs(List<Button> subs) {
|
public Object getExtra() {
|
||||||
this.subs = subs;
|
return extra;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Button pushSub(Button btn) {
|
/**
|
||||||
this.subs.add(btn);
|
* 扩展只读属性,设置无效
|
||||||
return this;
|
*
|
||||||
}
|
* @param extra
|
||||||
|
*/
|
||||||
|
public void setExtra(Object extra) {
|
||||||
|
this.extra = extra;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
public String getAppid() {
|
||||||
public String toString() {
|
return appid;
|
||||||
return "Button [name=" + name + ", type=" + type + ", content="
|
}
|
||||||
+ content + ", extra=" + extra + ", subs=" + subs + "]";
|
|
||||||
}
|
public void setAppid(String appid) {
|
||||||
|
this.appid = appid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPagepath() {
|
||||||
|
return pagepath;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPagepath(String pagepath) {
|
||||||
|
this.pagepath = pagepath;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Button> getSubs() {
|
||||||
|
return subs;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSubs(List<Button> subs) {
|
||||||
|
this.subs = subs;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Button pushSub(Button btn) {
|
||||||
|
this.subs.add(btn);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Button [name=" + name + ", type=" + type + ", content=" + content + ", extra=" + extra + ", appid="
|
||||||
|
+ appid + ", pagepath=" + pagepath + ", subs=" + subs + "]";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,42 +8,42 @@ import com.alibaba.fastjson.annotation.JSONField;
|
|||||||
/**
|
/**
|
||||||
* 卡券对象
|
* 卡券对象
|
||||||
* <p>
|
* <p>
|
||||||
* <font color="red">可用于「群发消息」</font>
|
* <font color="red">可用于「群发消息」和「客服消息」</font>
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* @className Card
|
* @className Card
|
||||||
* @author jinyu(foxinmy@gmail.com)
|
* @author jinyu(foxinmy@gmail.com)
|
||||||
* @date 2015年6月8日
|
* @date 2015年6月8日
|
||||||
* @since JDK 1.6
|
* @since JDK 1.6
|
||||||
* @see
|
* @see
|
||||||
*/
|
*/
|
||||||
public class Card implements MassTuple {
|
public class Card implements MassTuple, NotifyTuple {
|
||||||
|
|
||||||
private static final long serialVersionUID = 6119453633595102147L;
|
private static final long serialVersionUID = 6119453633595102147L;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getMessageType() {
|
public String getMessageType() {
|
||||||
return "wxcard";
|
return "wxcard";
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 上传后的微信返回的媒体ID
|
* 上传后的微信返回的媒体ID
|
||||||
*/
|
*/
|
||||||
@JSONField(name = "card_id")
|
@JSONField(name = "card_id")
|
||||||
@XmlElement(name = "CardId")
|
@XmlElement(name = "CardId")
|
||||||
private String cardId;
|
private String cardId;
|
||||||
|
|
||||||
@JSONCreator
|
@JSONCreator
|
||||||
public Card(@JSONField(name = "cardId") String cardId) {
|
public Card(@JSONField(name = "cardId") String cardId) {
|
||||||
this.cardId = cardId;
|
this.cardId = cardId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getCardId() {
|
public String getCardId() {
|
||||||
return cardId;
|
return cardId;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "Card [cardId=" + cardId + "]";
|
return "Card [cardId=" + cardId + "]";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,153 +14,196 @@ import com.alibaba.fastjson.annotation.JSONField;
|
|||||||
*/
|
*/
|
||||||
public class MpArticle implements Serializable {
|
public class MpArticle implements Serializable {
|
||||||
|
|
||||||
private static final long serialVersionUID = 5583479943661639234L;
|
private static final long serialVersionUID = 5583479943661639234L;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 图文消息缩略图的media_id,可以在基础支持-上传多媒体文件接口中获得 非空
|
* 图文消息缩略图的media_id,可以在基础支持-上传多媒体文件接口中获得 非空
|
||||||
*/
|
*/
|
||||||
@JSONField(name = "thumb_media_id")
|
@JSONField(name = "thumb_media_id")
|
||||||
private String thumbMediaId;
|
private String thumbMediaId;
|
||||||
/**
|
/**
|
||||||
* 图文消息的封面图片的地址(不一定有,请关注thumbMediaId)
|
* 图文消息的封面图片的地址(不一定有,请关注thumbMediaId)
|
||||||
*/
|
*/
|
||||||
@JSONField(name = "thumb_url")
|
@JSONField(name = "thumb_url")
|
||||||
private String thumbUrl;
|
private String thumbUrl;
|
||||||
/**
|
/**
|
||||||
* 图文消息的作者 可为空
|
* 图文消息的作者 可为空
|
||||||
*/
|
*/
|
||||||
private String author;
|
private String author;
|
||||||
/**
|
/**
|
||||||
* 图文消息的标题 非空
|
* 图文消息的标题 非空
|
||||||
*/
|
*/
|
||||||
private String title;
|
private String title;
|
||||||
/**
|
/**
|
||||||
* 图文页的URL 获取图文消息时,群发消息时填写无效。
|
* 图文页的URL 获取图文消息时,群发消息时填写无效。
|
||||||
*/
|
*/
|
||||||
private String url;
|
private String url;
|
||||||
/**
|
/**
|
||||||
* 在图文消息页面点击“阅读原文”后的页面 可为空
|
* 在图文消息页面点击“阅读原文”后的页面 可为空
|
||||||
*/
|
*/
|
||||||
@JSONField(name = "content_source_url")
|
@JSONField(name = "content_source_url")
|
||||||
private String sourceUrl;
|
private String sourceUrl;
|
||||||
/**
|
/**
|
||||||
* 图文消息页面的内容,支持HTML标签 非空
|
* 图文消息页面的内容,支持HTML标签 非空
|
||||||
*/
|
*/
|
||||||
private String content;
|
private String content;
|
||||||
/**
|
/**
|
||||||
* 图文消息的描述 可为空
|
* 图文消息的描述 可为空
|
||||||
*/
|
*/
|
||||||
private String digest;
|
private String digest;
|
||||||
/**
|
/**
|
||||||
* 是否显示封面,1为显示,0为不显示 可为空
|
* 是否显示封面,1为显示,0为不显示 可为空
|
||||||
*/
|
*/
|
||||||
@JSONField(name = "show_cover_pic")
|
@JSONField(name = "show_cover_pic")
|
||||||
private String showCoverPic;
|
private String showCoverPic;
|
||||||
|
/**
|
||||||
|
* 是否打开评论,0不打开,1打开
|
||||||
|
*/
|
||||||
|
@JSONField(name = "need_open_comment")
|
||||||
|
private String openComment;
|
||||||
|
/**
|
||||||
|
* 是否粉丝才可评论,0所有人可评论,1粉丝才可评论
|
||||||
|
*/
|
||||||
|
@JSONField(name = "only_fans_can_comment")
|
||||||
|
private String onlyFansCanComment;
|
||||||
|
|
||||||
protected MpArticle() {
|
protected MpArticle() {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param thumbMediaId
|
* @param thumbMediaId
|
||||||
* 缩略图
|
* 缩略图
|
||||||
* @param title
|
* @param title
|
||||||
* 标题
|
* 标题
|
||||||
* @param content
|
* @param content
|
||||||
* 内容
|
* 内容
|
||||||
*/
|
*/
|
||||||
public MpArticle(String thumbMediaId, String title, String content) {
|
public MpArticle(String thumbMediaId, String title, String content) {
|
||||||
this.thumbMediaId = thumbMediaId;
|
this.thumbMediaId = thumbMediaId;
|
||||||
this.title = title;
|
this.title = title;
|
||||||
this.content = content;
|
this.content = content;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getThumbMediaId() {
|
public String getThumbMediaId() {
|
||||||
return thumbMediaId;
|
return thumbMediaId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setThumbMediaId(String thumbMediaId) {
|
public void setThumbMediaId(String thumbMediaId) {
|
||||||
this.thumbMediaId = thumbMediaId;
|
this.thumbMediaId = thumbMediaId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getThumbUrl() {
|
public String getThumbUrl() {
|
||||||
return thumbUrl;
|
return thumbUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setThumbUrl(String thumbUrl) {
|
public void setThumbUrl(String thumbUrl) {
|
||||||
this.thumbUrl = thumbUrl;
|
this.thumbUrl = thumbUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getAuthor() {
|
public String getAuthor() {
|
||||||
return author;
|
return author;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setAuthor(String author) {
|
public void setAuthor(String author) {
|
||||||
this.author = author;
|
this.author = author;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getTitle() {
|
public String getTitle() {
|
||||||
return title;
|
return title;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTitle(String title) {
|
public void setTitle(String title) {
|
||||||
this.title = title;
|
this.title = title;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getUrl() {
|
public String getUrl() {
|
||||||
return url;
|
return url;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setUrl(String url) {
|
public void setUrl(String url) {
|
||||||
this.url = url;
|
this.url = url;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getSourceUrl() {
|
public String getSourceUrl() {
|
||||||
return sourceUrl;
|
return sourceUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSourceUrl(String sourceUrl) {
|
public void setSourceUrl(String sourceUrl) {
|
||||||
this.sourceUrl = sourceUrl;
|
this.sourceUrl = sourceUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getContent() {
|
public String getContent() {
|
||||||
return content;
|
return content;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setContent(String content) {
|
public void setContent(String content) {
|
||||||
this.content = content;
|
this.content = content;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getDigest() {
|
public String getDigest() {
|
||||||
return digest;
|
return digest;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDigest(String digest) {
|
public void setDigest(String digest) {
|
||||||
this.digest = digest;
|
this.digest = digest;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getShowCoverPic() {
|
public String getShowCoverPic() {
|
||||||
return showCoverPic;
|
return showCoverPic;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setShowCoverPic(String showCoverPic) {
|
public void setShowCoverPic(String showCoverPic) {
|
||||||
this.showCoverPic = showCoverPic;
|
this.showCoverPic = showCoverPic;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setShowCoverPic(boolean showCoverPic) {
|
public void setShowCoverPic(boolean showCoverPic) {
|
||||||
this.showCoverPic = showCoverPic ? "1" : "0";
|
this.showCoverPic = showCoverPic ? "1" : "0";
|
||||||
}
|
}
|
||||||
|
|
||||||
@JSONField(serialize = false)
|
@JSONField(serialize = false)
|
||||||
public boolean getFormatShowCoverPic() {
|
public boolean getFormatShowCoverPic() {
|
||||||
return this.showCoverPic != null && this.showCoverPic.equals("1");
|
return this.showCoverPic != null && this.showCoverPic.equals("1");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public void setOpenComment(boolean openComment) {
|
||||||
public String toString() {
|
this.openComment = openComment ? "1" : "0";
|
||||||
return "MpArticle [thumbMediaId=" + thumbMediaId + ", thumbUrl="
|
}
|
||||||
+ thumbUrl + ", author=" + author + ", title=" + title
|
|
||||||
+ ", sourceUrl=" + sourceUrl + ", content=" + content
|
public String getOpenComment() {
|
||||||
+ ", url=" + url + ", digest=" + digest + ", showCoverPic="
|
return openComment;
|
||||||
+ showCoverPic + "]";
|
}
|
||||||
}
|
|
||||||
|
public void setOpenComment(String openComment) {
|
||||||
|
this.openComment = openComment;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getOnlyFansCanComment() {
|
||||||
|
return onlyFansCanComment;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOnlyFansCanComment(String onlyFansCanComment) {
|
||||||
|
this.onlyFansCanComment = onlyFansCanComment;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JSONField(serialize = false)
|
||||||
|
public boolean getFormatOpenComment() {
|
||||||
|
return this.openComment != null && this.openComment.equals("1");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOnlyFansCanComment(boolean onlyFansCanComment) {
|
||||||
|
this.onlyFansCanComment = onlyFansCanComment ? "1" : "0";
|
||||||
|
}
|
||||||
|
|
||||||
|
@JSONField(serialize = false)
|
||||||
|
public boolean getFormatOnlyFansCanComment() {
|
||||||
|
return this.onlyFansCanComment != null && this.onlyFansCanComment.equals("1");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "MpArticle [thumbMediaId=" + thumbMediaId + ", thumbUrl=" + thumbUrl + ", author=" + author + ", title="
|
||||||
|
+ title + ", url=" + url + ", sourceUrl=" + sourceUrl + ", content=" + content + ", digest=" + digest
|
||||||
|
+ ", showCoverPic=" + showCoverPic + ", openComment=" + openComment + ", onlyFansCanComment="
|
||||||
|
+ onlyFansCanComment + "]";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -66,9 +66,5 @@ public enum ButtonType {
|
|||||||
/**
|
/**
|
||||||
* 小程序
|
* 小程序
|
||||||
*/
|
*/
|
||||||
miniprogram,
|
miniprogram;
|
||||||
/**
|
|
||||||
* 以下类型请勿使用,在公众平台设置的按钮类型,如果尝试使用API方式创建菜单则会出错。
|
|
||||||
*/
|
|
||||||
popups,text,img,voice,video,news;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,129 +3,129 @@
|
|||||||
+ 用netty构建http服务器&消息分发
|
+ 用netty构建http服务器&消息分发
|
||||||
|
|
||||||
* 2014-10-28
|
* 2014-10-28
|
||||||
|
|
||||||
+ 调整`ActionMapping`抽象化
|
+ 调整`ActionMapping`抽象化
|
||||||
|
|
||||||
* 2014-10-31
|
* 2014-10-31
|
||||||
|
|
||||||
+ `weixin.properties`切分为API调用地址和公众号appid等信息两部分
|
+ `weixin.properties`切分为API调用地址和公众号appid等信息两部分
|
||||||
|
|
||||||
* 2014-11-03
|
* 2014-11-03
|
||||||
|
|
||||||
+ 分离为`weixin-mp-api`和`weixin-mp-server`两个工程
|
+ 分离为`weixin-mp-api`和`weixin-mp-server`两个工程
|
||||||
|
|
||||||
+ 新增`支付模块`
|
+ 新增`支付模块`
|
||||||
|
|
||||||
* 2014-11-06
|
* 2014-11-06
|
||||||
|
|
||||||
+ 新增V3版本`退款申请`接口
|
+ 新增V3版本`退款申请`接口
|
||||||
|
|
||||||
* 2014-11-08
|
* 2014-11-08
|
||||||
|
|
||||||
+ 新增V2版本`退款申请`、`退款查询`、`对账单下载`三个接口
|
+ 新增V2版本`退款申请`、`退款查询`、`对账单下载`三个接口
|
||||||
|
|
||||||
+ 新增一个简单的`语义理解`接口
|
+ 新增一个简单的`语义理解`接口
|
||||||
|
|
||||||
* 2014-11-11
|
* 2014-11-11
|
||||||
|
|
||||||
+ 自定义`assembly`将`weixin4j-base`工程也一起打包(`weixin4j-mp-api-full.jar`)
|
+ 自定义`assembly`将`weixin4j-base`工程也一起打包(`weixin4j-mp-api-full.jar`)
|
||||||
|
|
||||||
* 2014-11-15
|
* 2014-11-15
|
||||||
|
|
||||||
+ 新增获取`微信服务器IP地址接口`
|
+ 新增获取`微信服务器IP地址接口`
|
||||||
|
|
||||||
* 2014-11-16
|
* 2014-11-16
|
||||||
|
|
||||||
+ 新增`多客服`接口
|
+ 新增`多客服`接口
|
||||||
|
|
||||||
* 2014-11-17
|
* 2014-11-17
|
||||||
|
|
||||||
+ 新增`冲正`和`被扫支付`接口
|
+ 新增`冲正`和`被扫支付`接口
|
||||||
|
|
||||||
* 2014-12-12
|
* 2014-12-12
|
||||||
|
|
||||||
+ 新增设置`模板消息所处行业`、`获取模板消息ID`接口
|
+ 新增设置`模板消息所处行业`、`获取模板消息ID`接口
|
||||||
|
|
||||||
* 2014-12-16
|
* 2014-12-16
|
||||||
|
|
||||||
+ 调整方法上@see注解的文档说明接口url
|
+ 调整方法上@see注解的文档说明接口url
|
||||||
|
|
||||||
+ 新增群发消息预览、状态查询接口
|
+ 新增群发消息预览、状态查询接口
|
||||||
|
|
||||||
+ 新增多客服添加账号、更新账号、上传头像、删除账号接口
|
+ 新增多客服添加账号、更新账号、上传头像、删除账号接口
|
||||||
|
|
||||||
* 2015-01-04
|
* 2015-01-04
|
||||||
|
|
||||||
+ 支付模块拆分为V2跟V3,新增WeixinPayProxy类
|
+ 支付模块拆分为V2跟V3,新增WeixinPayProxy类
|
||||||
|
|
||||||
+ 退款相关类拆分为V2跟V3
|
+ 退款相关类拆分为V2跟V3
|
||||||
|
|
||||||
+ 新增接口上报接口
|
+ 新增接口上报接口
|
||||||
|
|
||||||
* 2015-01-31
|
* 2015-01-31
|
||||||
|
|
||||||
+ 新增数据分析接口
|
+ 新增数据分析接口
|
||||||
|
|
||||||
* 2015-03-06
|
* 2015-03-06
|
||||||
|
|
||||||
+ 新增oauth授权接口
|
+ 新增oauth授权接口
|
||||||
|
|
||||||
* 2015-03-21
|
* 2015-03-21
|
||||||
|
|
||||||
+ 新增群发消息给所有人接口
|
+ 新增群发消息给所有人接口
|
||||||
|
|
||||||
+ 新增素材管理多个接口
|
+ 新增素材管理多个接口
|
||||||
|
|
||||||
+ 新增多客服会话管理多个接口
|
+ 新增多客服会话管理多个接口
|
||||||
|
|
||||||
* 2015-03-25
|
* 2015-03-25
|
||||||
|
|
||||||
+ 根据《微信商户平台文档》修缮[Pay3Api](./src/main/java/com/foxinmy/weixin4j/mp/api/Pay3Api.java)类
|
+ 根据《微信商户平台文档》修缮[Pay3Api](./src/main/java/com/foxinmy/weixin4j/mp/api/Pay3Api.java)类
|
||||||
|
|
||||||
* 2015-03-29
|
* 2015-03-29
|
||||||
|
|
||||||
+ 单行注释调整为多行文档注释
|
+ 单行注释调整为多行文档注释
|
||||||
|
|
||||||
+ 新增[CouponApi](./src/main/java/com/foxinmy/weixin4j/mp/api/CouponApi.java)代金券接口
|
+ 新增[CouponApi](./src/main/java/com/foxinmy/weixin4j/mp/api/CouponApi.java)代金券接口
|
||||||
|
|
||||||
* 2015-04-01
|
* 2015-04-01
|
||||||
|
|
||||||
+ 新增[CashApi](./src/main/java/com/foxinmy/weixin4j/mp/api/CashApi.java)发红包、企业付款接口
|
+ 新增[CashApi](./src/main/java/com/foxinmy/weixin4j/mp/api/CashApi.java)发红包、企业付款接口
|
||||||
|
|
||||||
* 2015-04-13
|
* 2015-04-13
|
||||||
|
|
||||||
+ 新增WeixinTokenCreator与WeixinJSTicketCreator类
|
+ 新增WeixinTokenCreator与WeixinJSTicketCreator类
|
||||||
|
|
||||||
+ 新增用户分组批量移动、删除组别接口
|
+ 新增用户分组批量移动、删除组别接口
|
||||||
|
|
||||||
* 2015-04-16
|
* 2015-04-16
|
||||||
|
|
||||||
+ **weixin4j-mp-api**: <font color="red">调整[二维码参数](./src/main/java/com/foxinmy/weixin4j/mp/model/QRParameter.java)类</font>
|
+ **weixin4j-mp-api**: <font color="red">调整[二维码参数](./src/main/java/com/foxinmy/weixin4j/mp/model/QRParameter.java)类</font>
|
||||||
|
|
||||||
+ **weixin4j-mp-api**: 新增获取[自定义菜单配置、自动回复配置](./src/main/java/com/foxinmy/weixin4j/mp/api/HelperApi.java)接口
|
+ **weixin4j-mp-api**: 新增获取[自定义菜单配置、自动回复配置](./src/main/java/com/foxinmy/weixin4j/mp/api/HelperApi.java)接口
|
||||||
|
|
||||||
* 2015-04-18
|
* 2015-04-18
|
||||||
|
|
||||||
+ <font color="red">调整[客服接口](./src/main/java/com/foxinmy/weixin4j/mp/api/CustomApi.java)类的方法名</font>
|
+ <font color="red">调整[客服接口](./src/main/java/com/foxinmy/weixin4j/mp/api/CustomApi.java)类的方法名</font>
|
||||||
|
|
||||||
+ <font color="red">在[二维码接口](./src/main/java/com/foxinmy/weixin4j/mp/api/QRApi.java)类新增获取二维码url方法</font>
|
+ <font color="red">在[二维码接口](./src/main/java/com/foxinmy/weixin4j/mp/api/QRApi.java)类新增获取二维码url方法</font>
|
||||||
|
|
||||||
* 2015-06-04
|
* 2015-06-04
|
||||||
|
|
||||||
+ 新增查询红包接口
|
+ 新增查询红包接口
|
||||||
|
|
||||||
* 2015-06-23
|
* 2015-06-23
|
||||||
|
|
||||||
+ 新增企业付款查询接口
|
+ 新增企业付款查询接口
|
||||||
|
|
||||||
* 2015-07-04
|
* 2015-07-04
|
||||||
|
|
||||||
+ released 1.5.1
|
+ released 1.5.1
|
||||||
|
|
||||||
* 2015-07-29
|
* 2015-07-29
|
||||||
|
|
||||||
+ 新增二维码结果类[QRResult.java](./src/main/java/com/foxinmy/weixin4j/mp/model/QRResult.java)并将二维码接口[QRApi.java](./weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/api/QrApi.java)名称变更为createQR和createQRFile
|
+ 新增二维码结果类[QRResult.java](./src/main/java/com/foxinmy/weixin4j/mp/model/QRResult.java)并将二维码接口[QRApi.java](./weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/api/QrApi.java)名称变更为createQR和createQRFile
|
||||||
|
|
||||||
+ [Oauth授权](./src/main/java/com/foxinmy/weixin4j/mp/api/OauthApi.java)跳转的uri在配置文件的属性名改为`oauth_redirect_uri`
|
+ [Oauth授权](./src/main/java/com/foxinmy/weixin4j/mp/api/OauthApi.java)跳转的uri在配置文件的属性名改为`oauth_redirect_uri`
|
||||||
|
|
||||||
* 2015-07-31
|
* 2015-07-31
|
||||||
@ -135,25 +135,25 @@
|
|||||||
* 2015-08-01
|
* 2015-08-01
|
||||||
|
|
||||||
+ 新增了群发消息中的上传视频接口
|
+ 新增了群发消息中的上传视频接口
|
||||||
|
|
||||||
+ 调整群发消息接口返回类型为字符串数组[{msg_id,msg_data_id}]
|
+ 调整群发消息接口返回类型为字符串数组[{msg_id,msg_data_id}]
|
||||||
|
|
||||||
* 2015-08-09
|
* 2015-08-09
|
||||||
|
|
||||||
+ version upgrade to 1.5.2
|
+ version upgrade to 1.5.2
|
||||||
|
|
||||||
+ oauth_redirect_uri配置属性名更改为user_oauth_redirect_uri
|
+ oauth_redirect_uri配置属性名更改为user_oauth_redirect_uri
|
||||||
|
|
||||||
* 2015-08-13
|
* 2015-08-13
|
||||||
|
|
||||||
+ version upgrade to 1.5.3
|
+ version upgrade to 1.5.3
|
||||||
|
|
||||||
+ 媒体接口类(MediaApi)查询素材接口调整:去掉offset,count替换为Pageable类
|
+ 媒体接口类(MediaApi)查询素材接口调整:去掉offset,count替换为Pageable类
|
||||||
|
|
||||||
* 2015-09-08
|
* 2015-09-08
|
||||||
|
|
||||||
+ 新增批量获取用户信息接口
|
+ 新增批量获取用户信息接口
|
||||||
|
|
||||||
* 2015-09-11
|
* 2015-09-11
|
||||||
|
|
||||||
+ version upgrade to 1.6.0
|
+ version upgrade to 1.6.0
|
||||||
@ -165,105 +165,109 @@
|
|||||||
* 2015-09-21
|
* 2015-09-21
|
||||||
|
|
||||||
+ version upgrade to 1.6.2
|
+ version upgrade to 1.6.2
|
||||||
|
|
||||||
* 2015-11-09
|
* 2015-11-09
|
||||||
|
|
||||||
+ version upgrade to 1.6.3
|
+ version upgrade to 1.6.3
|
||||||
|
|
||||||
* 2015-12-10
|
* 2015-12-10
|
||||||
|
|
||||||
+ version upgrade to 1.6.4
|
+ version upgrade to 1.6.4
|
||||||
|
|
||||||
+ 【特大注意】weixin4j.properties全部的属性名添加`weixin4j`前缀,并用`.`代替原来的`_`
|
+ 【特大注意】weixin4j.properties全部的属性名添加`weixin4j`前缀,并用`.`代替原来的`_`
|
||||||
|
|
||||||
* 2015-12-15
|
* 2015-12-15
|
||||||
|
|
||||||
+ version upgrade to 1.6.5
|
+ version upgrade to 1.6.5
|
||||||
|
|
||||||
* 2015-12-18
|
* 2015-12-18
|
||||||
|
|
||||||
+ 新增个性化菜单接口
|
+ 新增个性化菜单接口
|
||||||
|
|
||||||
+ WeixinProxy.getCustomRecord 参数变更为 Date startTime, Date endTime, Pageable pageable
|
+ WeixinProxy.getCustomRecord 参数变更为 Date startTime, Date endTime, Pageable pageable
|
||||||
|
|
||||||
* 2015-12-25
|
* 2015-12-25
|
||||||
|
|
||||||
+ WeixinProxy新增获取appid(getAppId)方法
|
+ WeixinProxy新增获取appid(getAppId)方法
|
||||||
|
|
||||||
+ WeixinProxy新增获取jsticket(getJSTicketHolder)方法
|
+ WeixinProxy新增获取jsticket(getJSTicketHolder)方法
|
||||||
|
|
||||||
+ 私有化WeixinProxy(TokenHolder)构造器
|
+ 私有化WeixinProxy(TokenHolder)构造器
|
||||||
|
|
||||||
+ 调整WeixinTicketCreator类
|
+ 调整WeixinTicketCreator类
|
||||||
|
|
||||||
* 2015-12-31
|
* 2015-12-31
|
||||||
|
|
||||||
+ version upgrade to 1.6.6
|
+ version upgrade to 1.6.6
|
||||||
|
|
||||||
* 2016-01-20
|
* 2016-01-20
|
||||||
|
|
||||||
+ 新增获取模板和删除模板接口
|
+ 新增获取模板和删除模板接口
|
||||||
|
|
||||||
+ 新增自定义个性化菜单语言信息匹配项
|
+ 新增自定义个性化菜单语言信息匹配项
|
||||||
|
|
||||||
* 2015-02-04
|
* 2015-02-04
|
||||||
|
|
||||||
+ version upgrade to 1.6.7
|
+ version upgrade to 1.6.7
|
||||||
|
|
||||||
* 2016-04-02
|
* 2016-04-02
|
||||||
|
|
||||||
+ version upgrade to 1.6.8
|
+ version upgrade to 1.6.8
|
||||||
|
|
||||||
* 2016-04-29
|
* 2016-04-29
|
||||||
|
|
||||||
+ weixin4j-mp:新增标签管理API
|
+ weixin4j-mp:新增标签管理API
|
||||||
|
|
||||||
* 2016-05-07
|
* 2016-05-07
|
||||||
|
|
||||||
+ version upgrade to 1.6.9
|
+ version upgrade to 1.6.9
|
||||||
|
|
||||||
* 2016-05-30
|
* 2016-05-30
|
||||||
|
|
||||||
+ 新增接口调用次数清零接口
|
+ 新增接口调用次数清零接口
|
||||||
|
|
||||||
* 2016-06-20
|
* 2016-06-20
|
||||||
|
|
||||||
+ version upgrade to 1.7.0
|
+ version upgrade to 1.7.0
|
||||||
|
|
||||||
* 2016-07-05
|
* 2016-07-05
|
||||||
|
|
||||||
+ 初始化开放平台第三方组件TokenCreator
|
+ 初始化开放平台第三方组件TokenCreator
|
||||||
|
|
||||||
+ 新增第三方组件ComponentApi
|
+ 新增第三方组件ComponentApi
|
||||||
|
|
||||||
* 2016-07-06
|
* 2016-07-06
|
||||||
|
|
||||||
+ 新增第三方组件WeixinComponentProxy
|
+ 新增第三方组件WeixinComponentProxy
|
||||||
|
|
||||||
* 2016-08-05
|
* 2016-08-05
|
||||||
|
|
||||||
+ 新增CardApi:创建卡券接口
|
+ 新增CardApi:创建卡券接口
|
||||||
|
|
||||||
* 2016-08-09
|
* 2016-08-09
|
||||||
|
|
||||||
+ 新增创建卡券二维码接口
|
+ 新增创建卡券二维码接口
|
||||||
|
|
||||||
+ version upgrade to 1.7.1
|
+ version upgrade to 1.7.1
|
||||||
|
|
||||||
* 2016-10-10
|
* 2016-10-10
|
||||||
|
|
||||||
+ version upgrade to 1.7.2
|
+ version upgrade to 1.7.2
|
||||||
|
|
||||||
* 2016-11-22
|
* 2016-11-22
|
||||||
|
|
||||||
+ 新增黑名单接口
|
+ 新增黑名单接口
|
||||||
|
|
||||||
* 2016-12-13
|
* 2016-12-13
|
||||||
|
|
||||||
+ version upgrade to 1.7.3
|
+ version upgrade to 1.7.3
|
||||||
|
|
||||||
* 2017-01-09
|
* 2017-01-09
|
||||||
|
|
||||||
+ 新增批量发红包接口
|
+ 新增批量发红包接口
|
||||||
|
|
||||||
+ version upgrade to 1.7.4
|
+ version upgrade to 1.7.4
|
||||||
|
|
||||||
|
* 2017-05-19
|
||||||
|
|
||||||
|
+ 新增评论管理接口
|
||||||
@ -32,13 +32,15 @@ weixin4j-mp
|
|||||||
* TmplApi `模板消息API`
|
* TmplApi `模板消息API`
|
||||||
|
|
||||||
* UserApi `用户管理API`
|
* UserApi `用户管理API`
|
||||||
|
|
||||||
* TagApi `用户标签管理API`
|
* TagApi `用户标签管理API`
|
||||||
|
|
||||||
* ComponentApi `第三方组件API`
|
* ComponentApi `第三方组件API`
|
||||||
|
|
||||||
* CardApi `卡券API`
|
* CardApi `卡券API`
|
||||||
|
|
||||||
|
* CommentApi `评论API`
|
||||||
|
|
||||||
[如何使用](https://github.com/foxinmy/weixin4j/wiki)
|
[如何使用](https://github.com/foxinmy/weixin4j/wiki)
|
||||||
---------
|
---------
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,240 @@
|
|||||||
|
package com.foxinmy.weixin4j.mp.api;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
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.ApiResult;
|
||||||
|
import com.foxinmy.weixin4j.http.weixin.WeixinResponse;
|
||||||
|
import com.foxinmy.weixin4j.model.Token;
|
||||||
|
import com.foxinmy.weixin4j.model.paging.Pageable;
|
||||||
|
import com.foxinmy.weixin4j.model.paging.Pagedata;
|
||||||
|
import com.foxinmy.weixin4j.mp.model.ArticleComment;
|
||||||
|
import com.foxinmy.weixin4j.mp.model.ArticleComment.ArticleCommentType;
|
||||||
|
import com.foxinmy.weixin4j.token.TokenManager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文章评论API
|
||||||
|
*
|
||||||
|
* @className CommentApi
|
||||||
|
* @author jinyu
|
||||||
|
* @date May 19, 2017
|
||||||
|
* @since JDK 1.6
|
||||||
|
* @see <a href=
|
||||||
|
* "https://mp.weixin.qq.com/wiki?action=doc&id=mp1494572718_WzHIY&t=0.6758084213658122">图文消息留言管理接口</a>
|
||||||
|
*/
|
||||||
|
public class CommentApi extends MpApi {
|
||||||
|
private final TokenManager tokenManager;
|
||||||
|
|
||||||
|
public CommentApi(TokenManager tokenManager) {
|
||||||
|
this.tokenManager = tokenManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 打开/关闭已群发文章评论
|
||||||
|
*
|
||||||
|
* @param open
|
||||||
|
* true为打开,false为关闭
|
||||||
|
* @param msgid
|
||||||
|
* 群发返回的msg_data_id
|
||||||
|
* @param index
|
||||||
|
* 多图文时,用来指定第几篇图文,从0开始,不带默认操作该msg_data_id的第一篇图文
|
||||||
|
* @return 操作结果
|
||||||
|
* @see {@link MassApi#massByTagId(com.foxinmy.weixin4j.tuple.MassTuple, int)}
|
||||||
|
* @see {@link MassApi#massByOpenIds(com.foxinmy.weixin4j.tuple.MassTuple, String...)}
|
||||||
|
* @throws WeixinException
|
||||||
|
*/
|
||||||
|
public ApiResult openComment(boolean open, String msgid, int index) throws WeixinException {
|
||||||
|
String news_comment = open ? getRequestUri("news_comment_open") : getRequestUri("news_comment_close");
|
||||||
|
Token token = tokenManager.getCache();
|
||||||
|
JSONObject obj = new JSONObject();
|
||||||
|
obj.put("msg_data_id", msgid);
|
||||||
|
obj.put("index", index);
|
||||||
|
WeixinResponse response = weixinExecutor.post(String.format(news_comment, token.getAccessToken()),
|
||||||
|
obj.toJSONString());
|
||||||
|
|
||||||
|
return response.getAsResult();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取评论列表
|
||||||
|
*
|
||||||
|
* @param page
|
||||||
|
* 分页信息
|
||||||
|
* @param commentType
|
||||||
|
* 评论类型 为空获取全部类型
|
||||||
|
* @param msgid
|
||||||
|
* 群发返回的msg_data_id
|
||||||
|
* @param index
|
||||||
|
* 多图文时,用来指定第几篇图文,从0开始,不带默认操作该msg_data_id的第一篇图文
|
||||||
|
* @return 分页数据
|
||||||
|
* @see ArticleComment
|
||||||
|
* @see ArticleCommentType
|
||||||
|
* @see {@link MassApi#massByTagId(com.foxinmy.weixin4j.tuple.MassTuple, int)}
|
||||||
|
* @see {@link MassApi#massByOpenIds(com.foxinmy.weixin4j.tuple.MassTuple, String...)}
|
||||||
|
* @throws WeixinException
|
||||||
|
*/
|
||||||
|
public Pagedata<ArticleComment> listArticleComments(Pageable page, ArticleCommentType commentType, String msgid,
|
||||||
|
int index) throws WeixinException {
|
||||||
|
String news_comment_list = getRequestUri("news_comment_list");
|
||||||
|
Token token = tokenManager.getCache();
|
||||||
|
JSONObject obj = new JSONObject();
|
||||||
|
obj.put("msg_data_id", "msgid");
|
||||||
|
obj.put("index", index);
|
||||||
|
obj.put("begin", page.getOffset());
|
||||||
|
obj.put("count", Math.max(50, page.getPageSize())); // 获取数目(>=50会被拒绝)
|
||||||
|
if (commentType != null) {
|
||||||
|
obj.put("type", commentType.ordinal() + 1);
|
||||||
|
} else {
|
||||||
|
obj.put("type", 0);
|
||||||
|
}
|
||||||
|
WeixinResponse response = weixinExecutor.post(String.format(news_comment_list, token.getAccessToken()),
|
||||||
|
obj.toJSONString());
|
||||||
|
|
||||||
|
JSONObject result = response.getAsJson();
|
||||||
|
int total = result.getIntValue("total");
|
||||||
|
List<ArticleComment> content = JSON.parseArray(result.getString("comment"), ArticleComment.class);
|
||||||
|
return new Pagedata<ArticleComment>(page, total, content);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取评论列表
|
||||||
|
*
|
||||||
|
* @param commentType
|
||||||
|
* 评论类型 为空获取全部类型
|
||||||
|
* @param msgid
|
||||||
|
* 群发返回的msg_data_id
|
||||||
|
* @param index
|
||||||
|
* 多图文时,用来指定第几篇图文,从0开始,不带默认操作该msg_data_id的第一篇图文
|
||||||
|
* @return 分页数据
|
||||||
|
* @see #listArticleComments(Pageable, ArticleCommentType, String, int)
|
||||||
|
* @throws WeixinException
|
||||||
|
*/
|
||||||
|
public List<ArticleComment> listAllArticleComments(ArticleCommentType commentType, String msgid, int index)
|
||||||
|
throws WeixinException {
|
||||||
|
List<ArticleComment> comments = new ArrayList<ArticleComment>();
|
||||||
|
Pagedata<ArticleComment> page = null;
|
||||||
|
Pageable pageable = null;
|
||||||
|
for (pageable = new Pageable(1, 50);; pageable = pageable.next()) {
|
||||||
|
page = listArticleComments(pageable, commentType, msgid, index);
|
||||||
|
if (!page.hasContent()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
comments.addAll(page.getContent());
|
||||||
|
}
|
||||||
|
return comments;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 评论标记/取消精选
|
||||||
|
*
|
||||||
|
* @param markelect
|
||||||
|
* true为标记,false为取消
|
||||||
|
* @param msgid
|
||||||
|
* 群发返回的msg_data_id
|
||||||
|
* @param index
|
||||||
|
* 多图文时,用来指定第几篇图文,从0开始,不带默认操作该msg_data_id的第一篇图文
|
||||||
|
* @param commentId
|
||||||
|
* 用户评论ID
|
||||||
|
* @return 操作结果
|
||||||
|
* @see #listArticleComments(Pageable, ArticleCommentType, String, int)
|
||||||
|
* @throws WeixinException
|
||||||
|
*/
|
||||||
|
public ApiResult markelectComment(boolean markelect, String msgid, int index, String commentId)
|
||||||
|
throws WeixinException {
|
||||||
|
String news_comment = markelect ? getRequestUri("news_comment_markelect")
|
||||||
|
: getRequestUri("news_comment_unmarkelect");
|
||||||
|
Token token = tokenManager.getCache();
|
||||||
|
JSONObject obj = new JSONObject();
|
||||||
|
obj.put("msg_data_id", "msgid");
|
||||||
|
obj.put("index", index);
|
||||||
|
obj.put("user_comment_id", commentId);
|
||||||
|
WeixinResponse response = weixinExecutor.post(String.format(news_comment, token.getAccessToken()),
|
||||||
|
obj.toJSONString());
|
||||||
|
|
||||||
|
return response.getAsResult();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除评论
|
||||||
|
*
|
||||||
|
* @param msgid
|
||||||
|
* 群发返回的msg_data_id
|
||||||
|
* @param index
|
||||||
|
* 多图文时,用来指定第几篇图文,从0开始,不带默认操作该msg_data_id的第一篇图文
|
||||||
|
* @param commentId
|
||||||
|
* 用户评论ID
|
||||||
|
* @return 操作结果
|
||||||
|
* @see #listArticleComments(Pageable, ArticleCommentType, String, int)
|
||||||
|
* @throws WeixinException
|
||||||
|
*/
|
||||||
|
public ApiResult deleteComment(String msgid, int index, String commentId) throws WeixinException {
|
||||||
|
String news_comment_delete = getRequestUri("news_comment_delete");
|
||||||
|
Token token = tokenManager.getCache();
|
||||||
|
JSONObject obj = new JSONObject();
|
||||||
|
obj.put("msg_data_id", "msgid");
|
||||||
|
obj.put("index", index);
|
||||||
|
obj.put("user_comment_id", commentId);
|
||||||
|
WeixinResponse response = weixinExecutor.post(String.format(news_comment_delete, token.getAccessToken()),
|
||||||
|
obj.toJSONString());
|
||||||
|
|
||||||
|
return response.getAsResult();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 回复评论
|
||||||
|
*
|
||||||
|
* @param msgid
|
||||||
|
* 群发返回的msg_data_id
|
||||||
|
* @param index
|
||||||
|
* 多图文时,用来指定第几篇图文,从0开始,不带默认操作该msg_data_id的第一篇图文
|
||||||
|
* @param commentId
|
||||||
|
* 用户评论ID
|
||||||
|
* @param content
|
||||||
|
* 回复内容
|
||||||
|
* @return 操作结果
|
||||||
|
* @see #listArticleComments(Pageable, ArticleCommentType, String, int)
|
||||||
|
* @throws WeixinException
|
||||||
|
*/
|
||||||
|
public ApiResult replyComment(String msgid, int index, String commentId, String content) throws WeixinException {
|
||||||
|
String news_comment_reply = getRequestUri("news_comment_reply_add");
|
||||||
|
Token token = tokenManager.getCache();
|
||||||
|
JSONObject obj = new JSONObject();
|
||||||
|
obj.put("msg_data_id", "msgid");
|
||||||
|
obj.put("index", index);
|
||||||
|
obj.put("user_comment_id", commentId);
|
||||||
|
obj.put("content", content);
|
||||||
|
WeixinResponse response = weixinExecutor.post(String.format(news_comment_reply, token.getAccessToken()),
|
||||||
|
obj.toJSONString());
|
||||||
|
|
||||||
|
return response.getAsResult();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除回复
|
||||||
|
*
|
||||||
|
* @param msgid
|
||||||
|
* 群发返回的msg_data_id
|
||||||
|
* @param index
|
||||||
|
* 多图文时,用来指定第几篇图文,从0开始,不带默认操作该msg_data_id的第一篇图文
|
||||||
|
* @param commentId
|
||||||
|
* 用户评论ID
|
||||||
|
* @return 操作结果
|
||||||
|
* @see #listArticleComments(Pageable, ArticleCommentType, String, int)
|
||||||
|
* @throws WeixinException
|
||||||
|
*/
|
||||||
|
public ApiResult deleteCommentReply(String msgid, int index, String commentId) throws WeixinException {
|
||||||
|
String news_comment_reply = getRequestUri("news_comment_reply_delete");
|
||||||
|
Token token = tokenManager.getCache();
|
||||||
|
JSONObject obj = new JSONObject();
|
||||||
|
obj.put("msg_data_id", "msgid");
|
||||||
|
obj.put("index", index);
|
||||||
|
obj.put("user_comment_id", commentId);
|
||||||
|
WeixinResponse response = weixinExecutor.post(String.format(news_comment_reply, token.getAccessToken()),
|
||||||
|
obj.toJSONString());
|
||||||
|
|
||||||
|
return response.getAsResult();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -19,7 +19,6 @@ import com.foxinmy.weixin4j.mp.model.SemQuery;
|
|||||||
import com.foxinmy.weixin4j.mp.model.SemResult;
|
import com.foxinmy.weixin4j.mp.model.SemResult;
|
||||||
import com.foxinmy.weixin4j.token.TokenManager;
|
import com.foxinmy.weixin4j.token.TokenManager;
|
||||||
import com.foxinmy.weixin4j.tuple.MpArticle;
|
import com.foxinmy.weixin4j.tuple.MpArticle;
|
||||||
import com.foxinmy.weixin4j.type.ButtonType;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 辅助相关API
|
* 辅助相关API
|
||||||
@ -32,214 +31,193 @@ import com.foxinmy.weixin4j.type.ButtonType;
|
|||||||
*/
|
*/
|
||||||
public class HelperApi extends MpApi {
|
public class HelperApi extends MpApi {
|
||||||
|
|
||||||
private final TokenManager tokenManager;
|
private final TokenManager tokenManager;
|
||||||
|
|
||||||
public HelperApi(TokenManager tokenManager) {
|
public HelperApi(TokenManager tokenManager) {
|
||||||
this.tokenManager = tokenManager;
|
this.tokenManager = tokenManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 长链接转短链接
|
* 长链接转短链接
|
||||||
*
|
*
|
||||||
* @param url
|
* @param url
|
||||||
* 待转换的链接
|
* 待转换的链接
|
||||||
* @return 短链接
|
* @return 短链接
|
||||||
* @throws WeixinException
|
* @throws WeixinException
|
||||||
* @see <a
|
* @see <a href=
|
||||||
* href="https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1443433600&token=&lang=zh_CN">长链接转短链接</a>
|
* "https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1443433600&token=&lang=zh_CN">长链接转短链接</a>
|
||||||
*/
|
*/
|
||||||
public String getShorturl(String url) throws WeixinException {
|
public String getShorturl(String url) throws WeixinException {
|
||||||
String shorturl_uri = getRequestUri("shorturl_uri");
|
String shorturl_uri = getRequestUri("shorturl_uri");
|
||||||
Token token = tokenManager.getCache();
|
Token token = tokenManager.getCache();
|
||||||
JSONObject obj = new JSONObject();
|
JSONObject obj = new JSONObject();
|
||||||
obj.put("action", "long2short");
|
obj.put("action", "long2short");
|
||||||
obj.put("long_url", url);
|
obj.put("long_url", url);
|
||||||
WeixinResponse response = weixinExecutor.post(
|
WeixinResponse response = weixinExecutor.post(String.format(shorturl_uri, token.getAccessToken()),
|
||||||
String.format(shorturl_uri, token.getAccessToken()),
|
obj.toJSONString());
|
||||||
obj.toJSONString());
|
|
||||||
|
|
||||||
return response.getAsJson().getString("short_url");
|
return response.getAsJson().getString("short_url");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 语义理解
|
* 语义理解
|
||||||
*
|
*
|
||||||
* @param semQuery
|
* @param semQuery
|
||||||
* 语义理解协议
|
* 语义理解协议
|
||||||
* @return 语义理解结果
|
* @return 语义理解结果
|
||||||
* @see com.foxinmy.weixin4j.mp.model.SemQuery
|
* @see com.foxinmy.weixin4j.mp.model.SemQuery
|
||||||
* @see com.foxinmy.weixin4j.mp.model.SemResult
|
* @see com.foxinmy.weixin4j.mp.model.SemResult
|
||||||
* @see <a
|
* @see <a href=
|
||||||
* href="https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141241&token=&lang=zh_CN">语义理解</a>
|
* "https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141241&token=&lang=zh_CN">语义理解</a>
|
||||||
* @throws WeixinException
|
* @throws WeixinException
|
||||||
*/
|
*/
|
||||||
public SemResult semantic(SemQuery semQuery) throws WeixinException {
|
public SemResult semantic(SemQuery semQuery) throws WeixinException {
|
||||||
String semantic_uri = getRequestUri("semantic_uri");
|
String semantic_uri = getRequestUri("semantic_uri");
|
||||||
Token token = tokenManager.getCache();
|
Token token = tokenManager.getCache();
|
||||||
WeixinResponse response = weixinExecutor.post(
|
WeixinResponse response = weixinExecutor.post(String.format(semantic_uri, token.getAccessToken()),
|
||||||
String.format(semantic_uri, token.getAccessToken()),
|
semQuery.toJson());
|
||||||
semQuery.toJson());
|
return response.getAsObject(new TypeReference<SemResult>() {
|
||||||
return response.getAsObject(new TypeReference<SemResult>() {
|
});
|
||||||
});
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取微信服务器IP地址
|
* 获取微信服务器IP地址
|
||||||
*
|
*
|
||||||
* @return IP地址
|
* @return IP地址
|
||||||
* @see <a
|
* @see <a href=
|
||||||
* href="https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140187&token=&lang=zh_CN">获取IP地址</a>
|
* "https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140187&token=&lang=zh_CN">获取IP地址</a>
|
||||||
* @throws WeixinException
|
* @throws WeixinException
|
||||||
*/
|
*/
|
||||||
public List<String> getWechatServerIp() throws WeixinException {
|
public List<String> getWechatServerIp() throws WeixinException {
|
||||||
String getcallbackip_uri = getRequestUri("getcallbackip_uri");
|
String getcallbackip_uri = getRequestUri("getcallbackip_uri");
|
||||||
Token token = tokenManager.getCache();
|
Token token = tokenManager.getCache();
|
||||||
WeixinResponse response = weixinExecutor.get(String.format(
|
WeixinResponse response = weixinExecutor.get(String.format(getcallbackip_uri, token.getAccessToken()));
|
||||||
getcallbackip_uri, token.getAccessToken()));
|
return JSON.parseArray(response.getAsJson().getString("ip_list"), String.class);
|
||||||
return JSON.parseArray(response.getAsJson().getString("ip_list"),
|
}
|
||||||
String.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取公众号当前使用的自定义菜单的配置,如果公众号是通过API调用设置的菜单,则返回菜单的开发配置,
|
* 获取公众号当前使用的自定义菜单的配置,如果公众号是通过API调用设置的菜单,则返回菜单的开发配置,
|
||||||
* 而如果公众号是在公众平台官网通过网站功能发布菜单,则本接口返回运营者设置的菜单配置。
|
* 而如果公众号是在公众平台官网通过网站功能发布菜单,则本接口返回运营者设置的菜单配置。
|
||||||
*
|
*
|
||||||
* @return 菜单配置信息
|
* @return 菜单配置信息
|
||||||
* @see {@link MenuApi#getMenu()}
|
* @see {@link MenuApi#getMenu()}
|
||||||
* @see <a
|
* @see <a href=
|
||||||
* href="https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1434698695&token=&lang=zh_CN">获取自定义菜单配置</a>
|
* "https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1434698695&token=&lang=zh_CN">获取自定义菜单配置</a>
|
||||||
* @see com.foxinmy.weixin4j.model.Button
|
* @see com.foxinmy.weixin4j.model.Button
|
||||||
* @see com.foxinmy.weixin4j.mp.model.MenuSetting
|
* @see com.foxinmy.weixin4j.mp.model.MenuSetting
|
||||||
* @see com.foxinmy.weixin4j.tuple.MpArticle
|
* @see com.foxinmy.weixin4j.tuple.MpArticle
|
||||||
* @throws WeixinException
|
* @throws WeixinException
|
||||||
*/
|
*/
|
||||||
public MenuSetting getMenuSetting() throws WeixinException {
|
public MenuSetting getMenuSetting() throws WeixinException {
|
||||||
String menu_get_selfmenu_uri = getRequestUri("menu_get_selfmenu_uri");
|
String menu_get_selfmenu_uri = getRequestUri("menu_get_selfmenu_uri");
|
||||||
Token token = tokenManager.getCache();
|
Token token = tokenManager.getCache();
|
||||||
WeixinResponse response = weixinExecutor.get(String.format(
|
WeixinResponse response = weixinExecutor.get(String.format(menu_get_selfmenu_uri, token.getAccessToken()));
|
||||||
menu_get_selfmenu_uri, token.getAccessToken()));
|
JSONObject result = response.getAsJson();
|
||||||
JSONObject result = response.getAsJson();
|
JSONArray buttons = result.getJSONObject("selfmenu_info").getJSONArray("button");
|
||||||
JSONArray buttons = result.getJSONObject("selfmenu_info").getJSONArray(
|
List<Button> buttonList = new ArrayList<Button>(buttons.size());
|
||||||
"button");
|
JSONObject buttonObj = null;
|
||||||
List<Button> buttonList = new ArrayList<Button>(buttons.size());
|
for (int i = 0; i < buttons.size(); i++) {
|
||||||
JSONObject buttonObj = null;
|
buttonObj = buttons.getJSONObject(i);
|
||||||
for (int i = 0; i < buttons.size(); i++) {
|
if (buttonObj.containsKey("sub_button")) {
|
||||||
buttonObj = buttons.getJSONObject(i);
|
buttonObj.put("sub_button", buttonObj.getJSONObject("sub_button").getJSONArray("list"));
|
||||||
if (buttonObj.containsKey("sub_button")) {
|
buttonObj.put("type", "popups");
|
||||||
buttonObj.put(
|
}
|
||||||
"sub_button",
|
buttonList.add(JSON.parseObject(buttonObj.toJSONString(), Button.class, ButtonExtraProcessor.global));
|
||||||
buttonObj.getJSONObject("sub_button").getJSONArray(
|
}
|
||||||
"list"));
|
return new MenuSetting(result.getBooleanValue("is_menu_open"), buttonList);
|
||||||
buttonObj.put("type", ButtonType.popups);
|
}
|
||||||
}
|
|
||||||
buttonList.add(JSON.parseObject(buttonObj.toJSONString(),
|
|
||||||
Button.class, ButtonExtraProcessor.global));
|
|
||||||
}
|
|
||||||
return new MenuSetting(result.getBooleanValue("is_menu_open"),
|
|
||||||
buttonList);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final class ButtonExtraProcessor implements ExtraProcessor {
|
private static final class ButtonExtraProcessor implements ExtraProcessor {
|
||||||
private static ButtonExtraProcessor global = new ButtonExtraProcessor();
|
private static ButtonExtraProcessor global = new ButtonExtraProcessor();
|
||||||
private static final String KEY = "news_info";
|
private static final String KEY = "news_info";
|
||||||
|
|
||||||
private ButtonExtraProcessor() {
|
private ButtonExtraProcessor() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void processExtra(Object object, String key, Object value) {
|
public void processExtra(Object object, String key, Object value) {
|
||||||
if (KEY.equalsIgnoreCase(key)) {
|
if (KEY.equalsIgnoreCase(key)) {
|
||||||
JSONArray news = ((JSONObject) value).getJSONArray("list");
|
JSONArray news = ((JSONObject) value).getJSONArray("list");
|
||||||
List<MpArticle> newsList = new ArrayList<MpArticle>(news.size());
|
List<MpArticle> newsList = new ArrayList<MpArticle>(news.size());
|
||||||
JSONObject article = null;
|
JSONObject article = null;
|
||||||
for (int i = 0; i < news.size(); i++) {
|
for (int i = 0; i < news.size(); i++) {
|
||||||
article = news.getJSONObject(i);
|
article = news.getJSONObject(i);
|
||||||
article.put("show_cover_pic", article.remove("show_cover"));
|
article.put("show_cover_pic", article.remove("show_cover"));
|
||||||
article.put("thumb_url", article.remove("cover_url"));
|
article.put("thumb_url", article.remove("cover_url"));
|
||||||
article.put("url", article.remove("content_url"));
|
article.put("url", article.remove("content_url"));
|
||||||
article.put("content_source_url",
|
article.put("content_source_url", article.remove("source_url"));
|
||||||
article.remove("source_url"));
|
newsList.add(JSON.toJavaObject(article, MpArticle.class));
|
||||||
newsList.add(JSON.toJavaObject(article, MpArticle.class));
|
}
|
||||||
}
|
((Button) object).setExtra(newsList);
|
||||||
((Button) object).setExtra(newsList);
|
} else {
|
||||||
} else {
|
((Button) object).setContent(String.valueOf(value));
|
||||||
((Button) object).setContent(String.valueOf(value));
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取公众号当前使用的自动回复规则,包括关注后自动回复、消息自动回复(60分钟内触发一次)、关键词自动回复。
|
* 获取公众号当前使用的自动回复规则,包括关注后自动回复、消息自动回复(60分钟内触发一次)、关键词自动回复。
|
||||||
*
|
*
|
||||||
* @see com.foxinmy.weixin4j.mp.model.AutoReplySetting
|
* @see com.foxinmy.weixin4j.mp.model.AutoReplySetting
|
||||||
* @see <a
|
* @see <a href=
|
||||||
* href="https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1433751299&token=&lang=zh_CN">获取自动回复规则</a>
|
* "https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1433751299&token=&lang=zh_CN">获取自动回复规则</a>
|
||||||
* @return 自定义回复配置信息
|
* @return 自定义回复配置信息
|
||||||
* @throws WeixinException
|
* @throws WeixinException
|
||||||
*/
|
*/
|
||||||
public AutoReplySetting getAutoReplySetting() throws WeixinException {
|
public AutoReplySetting getAutoReplySetting() throws WeixinException {
|
||||||
String autoreply_setting_get_uri = getRequestUri("autoreply_setting_get_uri");
|
String autoreply_setting_get_uri = getRequestUri("autoreply_setting_get_uri");
|
||||||
Token token = tokenManager.getCache();
|
Token token = tokenManager.getCache();
|
||||||
WeixinResponse response = weixinExecutor.get(String.format(
|
WeixinResponse response = weixinExecutor.get(String.format(autoreply_setting_get_uri, token.getAccessToken()));
|
||||||
autoreply_setting_get_uri, token.getAccessToken()));
|
|
||||||
|
|
||||||
JSONObject result = response.getAsJson();
|
JSONObject result = response.getAsJson();
|
||||||
|
|
||||||
AutoReplySetting replySetting = JSON.toJavaObject(result,
|
AutoReplySetting replySetting = JSON.toJavaObject(result, AutoReplySetting.class);
|
||||||
AutoReplySetting.class);
|
List<AutoReplySetting.Rule> ruleList = null;
|
||||||
List<AutoReplySetting.Rule> ruleList = null;
|
if (result.containsKey("keyword_autoreply_info")) {
|
||||||
if (result.containsKey("keyword_autoreply_info")) {
|
JSONArray keywordList = result.getJSONObject("keyword_autoreply_info").getJSONArray("list");
|
||||||
JSONArray keywordList = result.getJSONObject(
|
ruleList = new ArrayList<AutoReplySetting.Rule>(keywordList.size());
|
||||||
"keyword_autoreply_info").getJSONArray("list");
|
JSONObject keywordObj = null;
|
||||||
ruleList = new ArrayList<AutoReplySetting.Rule>(keywordList.size());
|
JSONArray replyList = null;
|
||||||
JSONObject keywordObj = null;
|
JSONObject replyObj = null;
|
||||||
JSONArray replyList = null;
|
for (int i = 0; i < keywordList.size(); i++) {
|
||||||
JSONObject replyObj = null;
|
keywordObj = keywordList.getJSONObject(i);
|
||||||
for (int i = 0; i < keywordList.size(); i++) {
|
AutoReplySetting.Rule rule = JSON.toJavaObject(keywordObj, AutoReplySetting.Rule.class);
|
||||||
keywordObj = keywordList.getJSONObject(i);
|
replyList = keywordObj.getJSONArray("reply_list_info");
|
||||||
AutoReplySetting.Rule rule = JSON.toJavaObject(keywordObj,
|
List<AutoReplySetting.Entry> entryList = new ArrayList<AutoReplySetting.Entry>(replyList.size());
|
||||||
AutoReplySetting.Rule.class);
|
for (int j = 0; j < replyList.size(); j++) {
|
||||||
replyList = keywordObj.getJSONArray("reply_list_info");
|
replyObj = replyList.getJSONObject(j);
|
||||||
List<AutoReplySetting.Entry> entryList = new ArrayList<AutoReplySetting.Entry>(
|
if (replyObj.getString("type").equals("news")) {
|
||||||
replyList.size());
|
entryList.add(JSON.parseObject(replyObj.toJSONString(), AutoReplySetting.Entry.class,
|
||||||
for (int j = 0; j < replyList.size(); j++) {
|
ButtonExtraProcessor.global));
|
||||||
replyObj = replyList.getJSONObject(j);
|
} else {
|
||||||
if (replyObj.getString("type").equals("news")) {
|
entryList.add(JSON.toJavaObject(replyObj, AutoReplySetting.Entry.class));
|
||||||
entryList.add(JSON.parseObject(replyObj.toJSONString(),
|
}
|
||||||
AutoReplySetting.Entry.class,
|
}
|
||||||
ButtonExtraProcessor.global));
|
rule.setReplyList(entryList);
|
||||||
} else {
|
ruleList.add(rule);
|
||||||
entryList.add(JSON.toJavaObject(replyObj,
|
}
|
||||||
AutoReplySetting.Entry.class));
|
}
|
||||||
}
|
replySetting.setKeywordReplyList(ruleList);
|
||||||
}
|
return replySetting;
|
||||||
rule.setReplyList(entryList);
|
}
|
||||||
ruleList.add(rule);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
replySetting.setKeywordReplyList(ruleList);
|
|
||||||
return replySetting;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 接口调用次数调用清零:公众号调用接口并不是无限制的。为了防止公众号的程序错误而引发微信服务器负载异常,默认情况下,
|
* 接口调用次数调用清零:公众号调用接口并不是无限制的。为了防止公众号的程序错误而引发微信服务器负载异常,默认情况下,
|
||||||
* 每个公众号调用接口都不能超过一定限制
|
* 每个公众号调用接口都不能超过一定限制 ,当超过一定限制时,调用对应接口会收到{"errcode":45009,"errmsg":"api freq
|
||||||
* ,当超过一定限制时,调用对应接口会收到{"errcode":45009,"errmsg":"api freq out of limit"
|
* out of limit" }错误返回码。
|
||||||
* }错误返回码。
|
*
|
||||||
*
|
* @param appId
|
||||||
* @param appId
|
* 公众号ID
|
||||||
* 公众号ID
|
* @see <a href=
|
||||||
* @see <a
|
* "https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1433744592&token=&lang=zh_CN">接口清零</a>
|
||||||
* href="https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1433744592&token=&lang=zh_CN">接口清零</a>
|
* @return 操作结果
|
||||||
* @return 操作结果
|
* @throws WeixinException
|
||||||
* @throws WeixinException
|
*/
|
||||||
*/
|
public ApiResult clearQuota(String appId) throws WeixinException {
|
||||||
public ApiResult clearQuota(String appId) throws WeixinException {
|
String clearquota_uri = getRequestUri("clearquota_uri");
|
||||||
String clearquota_uri = getRequestUri("clearquota_uri");
|
String body = String.format("{\"appid\":\"%s\"}", appId);
|
||||||
String body = String.format("{\"appid\":\"%s\"}", appId);
|
WeixinResponse response = weixinExecutor.post(String.format(clearquota_uri, tokenManager.getAccessToken()),
|
||||||
WeixinResponse response = weixinExecutor.post(
|
body);
|
||||||
String.format(clearquota_uri, tokenManager.getAccessToken()),
|
return response.getAsResult();
|
||||||
body);
|
}
|
||||||
return response.getAsResult();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@ -19,7 +19,7 @@ import com.foxinmy.weixin4j.util.StringUtil;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 群发相关API
|
* 群发相关API
|
||||||
*
|
*
|
||||||
* @className MassApi
|
* @className MassApi
|
||||||
* @author jinyu(foxinmy@gmail.com)
|
* @author jinyu(foxinmy@gmail.com)
|
||||||
* @date 2014年9月25日
|
* @date 2014年9月25日
|
||||||
@ -27,374 +27,386 @@ import com.foxinmy.weixin4j.util.StringUtil;
|
|||||||
*/
|
*/
|
||||||
public class MassApi extends MpApi {
|
public class MassApi extends MpApi {
|
||||||
|
|
||||||
private final TokenManager tokenManager;
|
private final TokenManager tokenManager;
|
||||||
|
|
||||||
public MassApi(TokenManager tokenManager) {
|
public MassApi(TokenManager tokenManager) {
|
||||||
this.tokenManager = tokenManager;
|
this.tokenManager = tokenManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 上传图文消息,一个图文消息支持1到10条图文</br> <font
|
* 上传图文消息,一个图文消息支持1到10条图文</br>
|
||||||
* color="red">具备微信支付权限的公众号,在使用高级群发接口上传、群发图文消息类型时,可使用<a>标签加入外链</font>
|
* <font color=
|
||||||
*
|
* "red">具备微信支付权限的公众号,在使用高级群发接口上传、群发图文消息类型时,可使用<a>标签加入外链</font>
|
||||||
* @param articles
|
*
|
||||||
* 图片消息
|
* @param articles
|
||||||
* @return 媒体ID
|
* 图片消息
|
||||||
* @throws WeixinException
|
* @return 媒体ID
|
||||||
* @see <a
|
* @throws WeixinException
|
||||||
* href="https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140549&token=&lang=zh_CN">上传图文素材</a>
|
* @see <a href=
|
||||||
* @see com.foxinmy.weixin4j.tuple.MpArticle
|
* "https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140549&token=&lang=zh_CN">上传图文素材</a>
|
||||||
*/
|
* @see com.foxinmy.weixin4j.tuple.MpArticle
|
||||||
public String uploadArticle(List<MpArticle> articles)
|
*/
|
||||||
throws WeixinException {
|
public String uploadArticle(List<MpArticle> articles) throws WeixinException {
|
||||||
String article_upload_uri = getRequestUri("article_upload_uri");
|
String article_upload_uri = getRequestUri("article_upload_uri");
|
||||||
Token token = tokenManager.getCache();
|
Token token = tokenManager.getCache();
|
||||||
JSONObject obj = new JSONObject();
|
JSONObject obj = new JSONObject();
|
||||||
obj.put("articles", articles);
|
obj.put("articles", articles);
|
||||||
WeixinResponse response = weixinExecutor.post(
|
WeixinResponse response = weixinExecutor.post(String.format(article_upload_uri, token.getAccessToken()),
|
||||||
String.format(article_upload_uri, token.getAccessToken()),
|
obj.toJSONString());
|
||||||
obj.toJSONString());
|
|
||||||
|
|
||||||
return response.getAsJson().getString("media_id");
|
return response.getAsJson().getString("media_id");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 分组群发
|
* 分组群发
|
||||||
* <p>
|
* <p>
|
||||||
* 在返回成功时,意味着群发任务提交成功,并不意味着此时群发已经结束,所以,仍有可能在后续的发送过程中出现异常情况导致用户未收到消息,
|
* 在返回成功时,意味着群发任务提交成功,并不意味着此时群发已经结束,所以,仍有可能在后续的发送过程中出现异常情况导致用户未收到消息,
|
||||||
* 如消息有时会进行审核、服务器不稳定等,此外,群发任务一般需要较长的时间才能全部发送完毕
|
* 如消息有时会进行审核、服务器不稳定等,此外,群发任务一般需要较长的时间才能全部发送完毕
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* @param tuple
|
* @param tuple
|
||||||
* 消息元件
|
* 消息元件
|
||||||
* @param isToAll
|
* @param isToAll
|
||||||
* 用于设定是否向全部用户发送,值为true或false,选择true该消息群发给所有用户,
|
* 用于设定是否向全部用户发送,值为true或false,选择true该消息群发给所有用户,
|
||||||
* 选择false可根据group_id发送给指定群组的用户
|
* 选择false可根据group_id发送给指定群组的用户
|
||||||
* @param groupId
|
* @param groupId
|
||||||
* 分组ID
|
* 分组ID
|
||||||
* @return 第一个元素为消息发送任务的ID,第二个元素为消息的数据ID,该字段只有在群发图文消息时,才会出现,可以用于在图文分析数据接口中
|
* @return 第一个元素为消息发送任务的ID,第二个元素为消息的数据ID,该字段只有在群发图文消息时,才会出现,可以用于在图文分析数据接口中
|
||||||
* @throws WeixinException
|
* @throws WeixinException
|
||||||
* @see com.foxinmy.weixin4j.mp.model.Group
|
* @see com.foxinmy.weixin4j.mp.model.Group
|
||||||
* @see com.foxinmy.weixin4j.tuple.Text
|
* @see com.foxinmy.weixin4j.tuple.Text
|
||||||
* @see com.foxinmy.weixin4j.tuple.Image
|
* @see com.foxinmy.weixin4j.tuple.Image
|
||||||
* @see com.foxinmy.weixin4j.tuple.Voice
|
* @see com.foxinmy.weixin4j.tuple.Voice
|
||||||
* @see com.foxinmy.weixin4j.tuple.MpVideo
|
* @see com.foxinmy.weixin4j.tuple.MpVideo
|
||||||
* @see com.foxinmy.weixin4j.tuple.MpNews
|
* @see com.foxinmy.weixin4j.tuple.MpNews
|
||||||
* @see com.foxinmy.weixin4j.tuple.Card
|
* @see com.foxinmy.weixin4j.tuple.Card
|
||||||
* @see com.foxinmy.weixin4j.tuple.MassTuple
|
* @see com.foxinmy.weixin4j.tuple.MassTuple
|
||||||
* @see {@link GroupApi#getGroups()}
|
* @see {@link GroupApi#getGroups()}
|
||||||
* @see <a
|
* @see <a href=
|
||||||
* href="https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140549&token=&lang=zh_CN">根据分组群发</a>
|
* "https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140549&token=&lang=zh_CN">根据分组群发</a>
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public String[] massByGroupId(MassTuple tuple, boolean isToAll, int groupId)
|
public String[] massByGroupId(MassTuple tuple, boolean isToAll, int groupId) throws WeixinException {
|
||||||
throws WeixinException {
|
if (tuple instanceof MpNews) {
|
||||||
if (tuple instanceof MpNews) {
|
MpNews _news = (MpNews) tuple;
|
||||||
MpNews _news = (MpNews) tuple;
|
List<MpArticle> _articles = _news.getArticles();
|
||||||
List<MpArticle> _articles = _news.getArticles();
|
if (StringUtil.isBlank(_news.getMediaId())) {
|
||||||
if (StringUtil.isBlank(_news.getMediaId())) {
|
if (_articles.isEmpty()) {
|
||||||
if (_articles.isEmpty()) {
|
throw new WeixinException("mass fail:mediaId or articles is required");
|
||||||
throw new WeixinException(
|
}
|
||||||
"mass fail:mediaId or articles is required");
|
tuple = new MpNews(uploadArticle(_articles));
|
||||||
}
|
}
|
||||||
tuple = new MpNews(uploadArticle(_articles));
|
}
|
||||||
}
|
String msgtype = tuple.getMessageType();
|
||||||
}
|
JSONObject obj = new JSONObject();
|
||||||
String msgtype = tuple.getMessageType();
|
JSONObject item = new JSONObject();
|
||||||
JSONObject obj = new JSONObject();
|
item.put("is_to_all", isToAll);
|
||||||
JSONObject item = new JSONObject();
|
if (!isToAll) {
|
||||||
item.put("is_to_all", isToAll);
|
item.put("group_id", groupId);
|
||||||
if (!isToAll) {
|
}
|
||||||
item.put("group_id", groupId);
|
obj.put("filter", item);
|
||||||
}
|
obj.put(msgtype, JSON.toJSON(tuple));
|
||||||
obj.put("filter", item);
|
obj.put("msgtype", msgtype);
|
||||||
obj.put(msgtype, JSON.toJSON(tuple));
|
String mass_group_uri = getRequestUri("mass_group_uri");
|
||||||
obj.put("msgtype", msgtype);
|
Token token = tokenManager.getCache();
|
||||||
String mass_group_uri = getRequestUri("mass_group_uri");
|
WeixinResponse response = weixinExecutor.post(String.format(mass_group_uri, token.getAccessToken()),
|
||||||
Token token = tokenManager.getCache();
|
obj.toJSONString());
|
||||||
WeixinResponse response = weixinExecutor.post(
|
|
||||||
String.format(mass_group_uri, token.getAccessToken()),
|
|
||||||
obj.toJSONString());
|
|
||||||
|
|
||||||
obj = response.getAsJson();
|
obj = response.getAsJson();
|
||||||
return new String[] { obj.getString("msg_id"),
|
return new String[] { obj.getString("msg_id"), obj.getString("msg_data_id") };
|
||||||
obj.getString("msg_data_id") };
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 分组ID群发图文消息
|
* 分组ID群发图文消息
|
||||||
*
|
*
|
||||||
* @param articles
|
* @param articles
|
||||||
* 图文列表
|
* 图文列表
|
||||||
* @param groupId
|
* @param groupId
|
||||||
* 分组ID
|
* 分组ID
|
||||||
* @return 第一个元素为消息发送任务的ID,第二个元素为消息的数据ID,该字段只有在群发图文消息时,才会出现。
|
* @return 第一个元素为消息发送任务的ID,第二个元素为消息的数据ID,该字段只有在群发图文消息时,才会出现。
|
||||||
* @see <a
|
* @see <a href=
|
||||||
* href="https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140549&token=&lang=zh_CN">根据分组群发</a>
|
* "https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140549&token=&lang=zh_CN">根据分组群发</a>
|
||||||
* @see {@link #massByGroupId(Tuple,int)}
|
* @see {@link #massByGroupId(Tuple,int)}
|
||||||
* @see com.foxinmy.weixin4j.tuple.MpArticle
|
* @see com.foxinmy.weixin4j.tuple.MpArticle
|
||||||
* @throws WeixinException
|
* @throws WeixinException
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public String[] massArticleByGroupId(List<MpArticle> articles, int groupId)
|
public String[] massArticleByGroupId(List<MpArticle> articles, int groupId) throws WeixinException {
|
||||||
throws WeixinException {
|
String mediaId = uploadArticle(articles);
|
||||||
String mediaId = uploadArticle(articles);
|
return massByGroupId(new MpNews(mediaId), false, groupId);
|
||||||
return massByGroupId(new MpNews(mediaId), false, groupId);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 标签群发
|
* 群发消息
|
||||||
* <p>
|
* <p>
|
||||||
* 在返回成功时,意味着群发任务提交成功,并不意味着此时群发已经结束,所以,仍有可能在后续的发送过程中出现异常情况导致用户未收到消息,
|
* 在返回成功时,意味着群发任务提交成功,并不意味着此时群发已经结束,所以,仍有可能在后续的发送过程中出现异常情况导致用户未收到消息,
|
||||||
* 如消息有时会进行审核、服务器不稳定等,此外,群发任务一般需要较长的时间才能全部发送完毕
|
* 如消息有时会进行审核、服务器不稳定等,此外,群发任务一般需要较长的时间才能全部发送完毕
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* @param tuple
|
* @param tuple
|
||||||
* 消息元件
|
* 消息元件
|
||||||
* @param isToAll
|
* @param filter
|
||||||
* 用于设定是否向全部用户发送,值为true或false,选择true该消息群发给所有用户,
|
* 过滤条件
|
||||||
* 选择false可根据group_id发送给指定群组的用户
|
* @return 第一个元素为消息发送任务的ID,第二个元素为消息的数据ID,该字段只有在群发图文消息时,才会出现,可以用于在图文分析数据接口中
|
||||||
* @param tagId
|
* @throws WeixinException
|
||||||
* 标签ID
|
* @see Tag
|
||||||
* @return 第一个元素为消息发送任务的ID,第二个元素为消息的数据ID,该字段只有在群发图文消息时,才会出现,可以用于在图文分析数据接口中
|
* @see com.foxinmy.weixin4j.tuple.Text
|
||||||
* @throws WeixinException
|
* @see com.foxinmy.weixin4j.tuple.Image
|
||||||
* @see Tag
|
* @see com.foxinmy.weixin4j.tuple.Voice
|
||||||
* @see com.foxinmy.weixin4j.tuple.Text
|
* @see com.foxinmy.weixin4j.tuple.MpVideo
|
||||||
* @see com.foxinmy.weixin4j.tuple.Image
|
* @see com.foxinmy.weixin4j.tuple.MpNews
|
||||||
* @see com.foxinmy.weixin4j.tuple.Voice
|
* @see com.foxinmy.weixin4j.tuple.Card
|
||||||
* @see com.foxinmy.weixin4j.tuple.MpVideo
|
* @see com.foxinmy.weixin4j.tuple.MassTuple
|
||||||
* @see com.foxinmy.weixin4j.tuple.MpNews
|
*/
|
||||||
* @see com.foxinmy.weixin4j.tuple.Card
|
private String[] mass(MassTuple tuple, JSONObject filter) throws WeixinException {
|
||||||
* @see com.foxinmy.weixin4j.tuple.MassTuple
|
if (tuple instanceof MpNews) {
|
||||||
* @see {@link TagApi#listTags()}
|
MpNews _news = (MpNews) tuple;
|
||||||
* @see <a
|
List<MpArticle> _articles = _news.getArticles();
|
||||||
* href="https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140549&token=&lang=zh_CN">根据标签群发</a>
|
if (StringUtil.isBlank(_news.getMediaId())) {
|
||||||
*/
|
if (_articles.isEmpty()) {
|
||||||
public String[] massByTagId(MassTuple tuple, boolean isToAll, int tagId)
|
throw new WeixinException("mass fail:mediaId or articles is required");
|
||||||
throws WeixinException {
|
}
|
||||||
if (tuple instanceof MpNews) {
|
tuple = new MpNews(uploadArticle(_articles));
|
||||||
MpNews _news = (MpNews) tuple;
|
}
|
||||||
List<MpArticle> _articles = _news.getArticles();
|
if (!filter.containsKey("send_ignore_reprint")) {
|
||||||
if (StringUtil.isBlank(_news.getMediaId())) {
|
filter.put("send_ignore_reprint", 0);
|
||||||
if (_articles.isEmpty()) {
|
}
|
||||||
throw new WeixinException(
|
}
|
||||||
"mass fail:mediaId or articles is required");
|
String msgtype = tuple.getMessageType();
|
||||||
}
|
JSONObject obj = new JSONObject();
|
||||||
tuple = new MpNews(uploadArticle(_articles));
|
obj.putAll(filter);
|
||||||
}
|
obj.put(msgtype, JSON.toJSON(tuple));
|
||||||
}
|
obj.put("msgtype", msgtype);
|
||||||
String msgtype = tuple.getMessageType();
|
String mass_group_uri = getRequestUri("mass_group_uri");
|
||||||
JSONObject obj = new JSONObject();
|
Token token = tokenManager.getCache();
|
||||||
JSONObject item = new JSONObject();
|
WeixinResponse response = weixinExecutor.post(String.format(mass_group_uri, token.getAccessToken()),
|
||||||
item.put("is_to_all", isToAll);
|
obj.toJSONString());
|
||||||
if (!isToAll) {
|
|
||||||
item.put("tag_id", tagId);
|
|
||||||
}
|
|
||||||
obj.put("filter", item);
|
|
||||||
obj.put(msgtype, JSON.toJSON(tuple));
|
|
||||||
obj.put("msgtype", msgtype);
|
|
||||||
String mass_group_uri = getRequestUri("mass_group_uri");
|
|
||||||
Token token = tokenManager.getCache();
|
|
||||||
WeixinResponse response = weixinExecutor.post(
|
|
||||||
String.format(mass_group_uri, token.getAccessToken()),
|
|
||||||
obj.toJSONString());
|
|
||||||
|
|
||||||
obj = response.getAsJson();
|
obj = response.getAsJson();
|
||||||
return new String[] { obj.getString("msg_id"),
|
return new String[] { obj.getString("msg_id"), obj.getString("msg_data_id") };
|
||||||
obj.getString("msg_data_id") };
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 标签群发图文消息
|
* 群发消息给所有粉丝
|
||||||
*
|
*
|
||||||
* @param articles
|
* @param tuple
|
||||||
* 图文列表
|
* 消息元件
|
||||||
* @param tagId
|
* @return 第一个元素为消息发送任务的ID,第二个元素为消息的数据ID,该字段只有在群发图文消息时,才会出现,可以用于在图文分析数据接口中
|
||||||
* 标签ID
|
* @throws WeixinException
|
||||||
* @return 第一个元素为消息发送任务的ID,第二个元素为消息的数据ID,该字段只有在群发图文消息时,才会出现。
|
* @see <a href=
|
||||||
* @see <a
|
* "https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140549&token=&lang=zh_CN">根据标签群发</a>
|
||||||
* href="https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140549&token=&lang=zh_CN">根据标签群发</a>
|
*/
|
||||||
* @see {@link #massByTagId(Tuple,int)}
|
public String[] massToAll(MassTuple tuple) throws WeixinException {
|
||||||
* @see com.foxinmy.weixin4j.tuple.MpArticle
|
String filter = String.format("{\"filter\":{\"is_to_all\":true}}");
|
||||||
* @throws WeixinException
|
return mass(tuple, JSON.parseObject(filter));
|
||||||
*/
|
}
|
||||||
public String[] massArticleByTagId(List<MpArticle> articles, int tagId)
|
|
||||||
throws WeixinException {
|
|
||||||
String mediaId = uploadArticle(articles);
|
|
||||||
return massByTagId(new MpNews(mediaId), false, tagId);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* openId群发
|
* 标签群发消息
|
||||||
*
|
*
|
||||||
* @param tuple
|
* @param tuple
|
||||||
* 消息元件
|
* 消息元件
|
||||||
* @param openIds
|
* @param tagId
|
||||||
* openId列表
|
* 标签ID
|
||||||
* @return 第一个元素为消息发送任务的ID,第二个元素为消息的数据ID,该字段只有在群发图文消息时,才会出现,可以用于在图文分析数据接口中
|
* @return 第一个元素为消息发送任务的ID,第二个元素为消息的数据ID,该字段只有在群发图文消息时,才会出现,可以用于在图文分析数据接口中
|
||||||
* @throws WeixinException
|
* @throws WeixinException
|
||||||
* @see com.foxinmy.weixin4j.mp.model.User
|
* @see Tag
|
||||||
* @see com.foxinmy.weixin4j.tuple.Text
|
* @see {@link TagApi#listTags()}
|
||||||
* @see com.foxinmy.weixin4j.tuple.Image
|
* @see #mass(MassTuple, JSONObject, boolean)
|
||||||
* @see com.foxinmy.weixin4j.tuple.Voice
|
* @see <a href=
|
||||||
* @see com.foxinmy.weixin4j.tuple.MpVideo
|
* "https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140549&token=&lang=zh_CN">根据标签群发</a>
|
||||||
* @see com.foxinmy.weixin4j.tuple.MpNews
|
*/
|
||||||
* @see com.foxinmy.weixin4j.tuple.Card
|
public String[] massByTagId(MassTuple tuple, int tagId) throws WeixinException {
|
||||||
* @see com.foxinmy.weixin4j.tuple.MassTuple
|
String filter = String.format("{\"filter\":{\"is_to_all\":false,\"tag_id\":%d}}", tagId);
|
||||||
* @see <a
|
return mass(tuple, JSON.parseObject(filter));
|
||||||
* href="https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140549&token=&lang=zh_CN">根据openid群发</a>
|
}
|
||||||
* @see {@link UserApi#getUser(String)}
|
|
||||||
*/
|
|
||||||
public String[] massByOpenIds(MassTuple tuple, String... openIds)
|
|
||||||
throws WeixinException {
|
|
||||||
if (tuple instanceof MpNews) {
|
|
||||||
MpNews _news = (MpNews) tuple;
|
|
||||||
List<MpArticle> _articles = _news.getArticles();
|
|
||||||
if (StringUtil.isBlank(_news.getMediaId())) {
|
|
||||||
if (_articles.isEmpty()) {
|
|
||||||
throw new WeixinException(
|
|
||||||
"mass fail:mediaId or articles is required");
|
|
||||||
}
|
|
||||||
tuple = new MpNews(uploadArticle(_articles));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
String msgtype = tuple.getMessageType();
|
|
||||||
JSONObject obj = new JSONObject();
|
|
||||||
obj.put("touser", openIds);
|
|
||||||
obj.put(msgtype, JSON.toJSON(tuple));
|
|
||||||
obj.put("msgtype", msgtype);
|
|
||||||
String mass_openid_uri = getRequestUri("mass_openid_uri");
|
|
||||||
Token token = tokenManager.getCache();
|
|
||||||
WeixinResponse response = weixinExecutor.post(
|
|
||||||
String.format(mass_openid_uri, token.getAccessToken()),
|
|
||||||
obj.toJSONString());
|
|
||||||
|
|
||||||
obj = response.getAsJson();
|
/**
|
||||||
return new String[] { obj.getString("msg_id"),
|
* 标签群发图文消息
|
||||||
obj.getString("msg_data_id") };
|
*
|
||||||
}
|
* @param articles
|
||||||
|
* 图文列表
|
||||||
|
* @param tagId
|
||||||
|
* 标签ID
|
||||||
|
* @param ignoreReprint
|
||||||
|
* 图文消息被判定为转载时,是否继续群发
|
||||||
|
* @return 第一个元素为消息发送任务的ID,第二个元素为消息的数据ID,该字段只有在群发图文消息时,才会出现。
|
||||||
|
* @see <a href=
|
||||||
|
* "https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140549&token=&lang=zh_CN">根据标签群发</a>
|
||||||
|
* @see {@link #massByTagId(Tuple,int)}
|
||||||
|
* @see com.foxinmy.weixin4j.tuple.MpArticle
|
||||||
|
* @throws WeixinException
|
||||||
|
*/
|
||||||
|
public String[] massArticleByTagId(List<MpArticle> articles, int tagId, boolean ignoreReprint)
|
||||||
|
throws WeixinException {
|
||||||
|
String mediaId = uploadArticle(articles);
|
||||||
|
String text = String.format("{\"filter\":{\"is_to_all\":false,\"tag_id\":%d}}", tagId);
|
||||||
|
JSONObject filter = JSON.parseObject(text);
|
||||||
|
filter.put("send_ignore_reprint", ignoreReprint ? 1 : 0);
|
||||||
|
return mass(new MpNews(mediaId), filter);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据openid群发图文消息
|
* openId群发消息
|
||||||
*
|
*
|
||||||
* @param articles
|
* @param tuple
|
||||||
* 图文列表
|
* 消息元件
|
||||||
* @param openIds
|
* @param openIds
|
||||||
* openId列表
|
* openId列表
|
||||||
* @return 第一个元素为消息发送任务的ID,第二个元素为消息的数据ID,该字段只有在群发图文消息时,才会出现,可以用于在图文分析数据接口中.
|
* @return 第一个元素为消息发送任务的ID,第二个元素为消息的数据ID,该字段只有在群发图文消息时,才会出现,可以用于在图文分析数据接口中
|
||||||
* @see <a
|
* @throws WeixinException
|
||||||
* href="https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140549&token=&lang=zh_CN">根据openid群发</a>
|
* @see <a href=
|
||||||
* @see {@link #massByOpenIds(Tuple,String...)}
|
* "https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140549&token=&lang=zh_CN">根据openid群发</a>
|
||||||
* @see com.foxinmy.weixin4j.tuple.MpArticle
|
* @see {@link UserApi#getUser(String)}
|
||||||
* @throws WeixinException
|
* @see #mass(MassTuple, JSONObject, boolean)
|
||||||
*/
|
*/
|
||||||
public String[] massArticleByOpenIds(List<MpArticle> articles,
|
public String[] massByOpenIds(MassTuple tuple, String... openIds) throws WeixinException {
|
||||||
String... openIds) throws WeixinException {
|
JSONObject filter = new JSONObject();
|
||||||
String mediaId = uploadArticle(articles);
|
filter.put("touser", openIds);
|
||||||
return massByOpenIds(new MpNews(mediaId), openIds);
|
return mass(tuple, filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 删除群发消息
|
* openid群发图文消息
|
||||||
* <p>
|
*
|
||||||
* 请注意,只有已经发送成功的消息才能删除删除消息只是将消息的图文详情页失效,已经收到的用户,还是能在其本地看到消息卡片
|
* @param articles
|
||||||
* </p>
|
* 图文列表
|
||||||
*
|
* @param ignoreReprint
|
||||||
* @param msgid
|
* 图文消息被判定为转载时,是否继续群发
|
||||||
* 发送出去的消息ID
|
* @param openIds
|
||||||
* @throws WeixinException
|
* openId列表
|
||||||
* @see <a
|
* @return 第一个元素为消息发送任务的ID,第二个元素为消息的数据ID,该字段只有在群发图文消息时,才会出现,可以用于在图文分析数据接口中.
|
||||||
* href="https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140549&token=&lang=zh_CN">删除群发</a>
|
* @see <a href=
|
||||||
* @see {@link #massByTagId(Tuple, int)}
|
* "https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140549&token=&lang=zh_CN">根据openid群发</a>
|
||||||
* @see {@link #massByOpenIds(Tuple, String...)
|
* @see {@link #massByOpenIds(Tuple,String...)}
|
||||||
|
* @see com.foxinmy.weixin4j.tuple.MpArticle
|
||||||
|
* @throws WeixinException
|
||||||
|
*/
|
||||||
|
public String[] massArticleByOpenIds(List<MpArticle> articles, boolean ignoreReprint, String... openIds)
|
||||||
|
throws WeixinException {
|
||||||
|
String mediaId = uploadArticle(articles);
|
||||||
|
JSONObject filter = new JSONObject();
|
||||||
|
filter.put("touser", openIds);
|
||||||
|
filter.put("send_ignore_reprint", ignoreReprint ? 1 : 0);
|
||||||
|
return mass(new MpNews(mediaId), filter);
|
||||||
|
}
|
||||||
|
|
||||||
*/
|
/**
|
||||||
public ApiResult deleteMassNews(String msgid) throws WeixinException {
|
* 删除群发消息
|
||||||
JSONObject obj = new JSONObject();
|
*
|
||||||
obj.put("msgid", msgid);
|
* @param msgid
|
||||||
String mass_delete_uri = getRequestUri("mass_delete_uri");
|
* 发送出去的消息ID
|
||||||
Token token = tokenManager.getCache();
|
* @throws WeixinException
|
||||||
WeixinResponse response = weixinExecutor.post(
|
* @see <a href=
|
||||||
String.format(mass_delete_uri, token.getAccessToken()),
|
* "https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140549&token=&lang=zh_CN">删除群发</a>
|
||||||
obj.toJSONString());
|
* @see #deleteMassNews(String, int)
|
||||||
|
*/
|
||||||
|
public ApiResult deleteMassNews(String msgid) throws WeixinException {
|
||||||
|
return deleteMassNews(msgid, 0);
|
||||||
|
}
|
||||||
|
|
||||||
return response.getAsResult();
|
/**
|
||||||
}
|
* 删除群发消息
|
||||||
|
* <p>
|
||||||
|
* 请注意,只有已经发送成功的消息才能删除删除消息只是将消息的图文详情页失效,已经收到的用户,还是能在其本地看到消息卡片
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @param msgid
|
||||||
|
* 发送出去的消息ID
|
||||||
|
* @param articleIndex
|
||||||
|
* 要删除的文章在图文消息中的位置,第一篇编号为1,该字段不填或填0会删除全部文章
|
||||||
|
* @throws WeixinException
|
||||||
|
* @see <a href=
|
||||||
|
* "https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140549&token=&lang=zh_CN">删除群发</a>
|
||||||
|
* @see {@link #massByTagId(Tuple, int)}
|
||||||
|
* @see {@link #massByOpenIds(Tuple, String...)
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public ApiResult deleteMassNews(String msgid, int articleIndex) throws WeixinException {
|
||||||
|
JSONObject obj = new JSONObject();
|
||||||
|
obj.put("msgid", msgid);
|
||||||
|
if (articleIndex > 0)
|
||||||
|
obj.put("article_idx", articleIndex);
|
||||||
|
String mass_delete_uri = getRequestUri("mass_delete_uri");
|
||||||
|
Token token = tokenManager.getCache();
|
||||||
|
WeixinResponse response = weixinExecutor.post(String.format(mass_delete_uri, token.getAccessToken()),
|
||||||
|
obj.toJSONString());
|
||||||
|
|
||||||
/**
|
return response.getAsResult();
|
||||||
* 预览群发消息</br> 开发者可通过该接口发送消息给指定用户,在手机端查看消息的样式和排版
|
}
|
||||||
*
|
|
||||||
* @param toUser
|
|
||||||
* 接收用户的openID
|
|
||||||
* @param toWxName
|
|
||||||
* 接收用户的微信号 towxname和touser同时赋值时,以towxname优先
|
|
||||||
* @param tuple
|
|
||||||
* 消息元件
|
|
||||||
* @return 处理结果
|
|
||||||
* @throws WeixinException
|
|
||||||
* @see com.foxinmy.weixin4j.tuple.MassTuple
|
|
||||||
* @see <a
|
|
||||||
* href="https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140549&token=&lang=zh_CN">预览群发消息</a>
|
|
||||||
*/
|
|
||||||
public ApiResult previewMassNews(String toUser, String toWxName,
|
|
||||||
MassTuple tuple) throws WeixinException {
|
|
||||||
String msgtype = tuple.getMessageType();
|
|
||||||
JSONObject obj = new JSONObject();
|
|
||||||
obj.put("touser", toUser);
|
|
||||||
obj.put("towxname", toWxName);
|
|
||||||
obj.put(msgtype, JSON.toJSON(tuple));
|
|
||||||
obj.put("msgtype", msgtype);
|
|
||||||
String mass_preview_uri = getRequestUri("mass_preview_uri");
|
|
||||||
Token token = tokenManager.getCache();
|
|
||||||
WeixinResponse response = weixinExecutor.post(
|
|
||||||
String.format(mass_preview_uri, token.getAccessToken()),
|
|
||||||
obj.toJSONString());
|
|
||||||
|
|
||||||
return response.getAsResult();
|
/**
|
||||||
}
|
* 预览群发消息</br>
|
||||||
|
* 开发者可通过该接口发送消息给指定用户,在手机端查看消息的样式和排版
|
||||||
|
*
|
||||||
|
* @param toUser
|
||||||
|
* 接收用户的openID
|
||||||
|
* @param toWxName
|
||||||
|
* 接收用户的微信号 towxname和touser同时赋值时,以towxname优先
|
||||||
|
* @param tuple
|
||||||
|
* 消息元件
|
||||||
|
* @return 处理结果
|
||||||
|
* @throws WeixinException
|
||||||
|
* @see com.foxinmy.weixin4j.tuple.MassTuple
|
||||||
|
* @see <a href=
|
||||||
|
* "https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140549&token=&lang=zh_CN">预览群发消息</a>
|
||||||
|
*/
|
||||||
|
public ApiResult previewMassNews(String toUser, String toWxName, MassTuple tuple) throws WeixinException {
|
||||||
|
String msgtype = tuple.getMessageType();
|
||||||
|
JSONObject obj = new JSONObject();
|
||||||
|
obj.put("touser", toUser);
|
||||||
|
obj.put("towxname", toWxName);
|
||||||
|
obj.put(msgtype, JSON.toJSON(tuple));
|
||||||
|
obj.put("msgtype", msgtype);
|
||||||
|
String mass_preview_uri = getRequestUri("mass_preview_uri");
|
||||||
|
Token token = tokenManager.getCache();
|
||||||
|
WeixinResponse response = weixinExecutor.post(String.format(mass_preview_uri, token.getAccessToken()),
|
||||||
|
obj.toJSONString());
|
||||||
|
|
||||||
/**
|
return response.getAsResult();
|
||||||
* 查询群发发送状态
|
}
|
||||||
*
|
|
||||||
* @param msgId
|
|
||||||
* 消息ID
|
|
||||||
* @return 消息发送状态,如sendsuccess:发送成功、sendfail:发送失败
|
|
||||||
* @throws WeixinException
|
|
||||||
* @see <a
|
|
||||||
* href="https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140549&token=&lang=zh_CN">查询群发状态</a>
|
|
||||||
*/
|
|
||||||
public String getMassNewStatus(String msgId) throws WeixinException {
|
|
||||||
JSONObject obj = new JSONObject();
|
|
||||||
obj.put("msg_id", msgId);
|
|
||||||
String mass_get_uri = getRequestUri("mass_get_uri");
|
|
||||||
Token token = tokenManager.getCache();
|
|
||||||
WeixinResponse response = weixinExecutor.post(
|
|
||||||
String.format(mass_get_uri, token.getAccessToken()),
|
|
||||||
obj.toJSONString());
|
|
||||||
|
|
||||||
String status = response.getAsJson().getString("msg_status");
|
/**
|
||||||
String desc = massStatusMap.get(status);
|
* 查询群发发送状态
|
||||||
return String.format("%s:%s", status, desc);
|
*
|
||||||
}
|
* @param msgId
|
||||||
|
* 消息ID
|
||||||
|
* @return 消息发送状态,如sendsuccess:发送成功、sendfail:发送失败
|
||||||
|
* @throws WeixinException
|
||||||
|
* @see <a href=
|
||||||
|
* "https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140549&token=&lang=zh_CN">查询群发状态</a>
|
||||||
|
*/
|
||||||
|
public String getMassNewStatus(String msgId) throws WeixinException {
|
||||||
|
JSONObject obj = new JSONObject();
|
||||||
|
obj.put("msg_id", msgId);
|
||||||
|
String mass_get_uri = getRequestUri("mass_get_uri");
|
||||||
|
Token token = tokenManager.getCache();
|
||||||
|
WeixinResponse response = weixinExecutor.post(String.format(mass_get_uri, token.getAccessToken()),
|
||||||
|
obj.toJSONString());
|
||||||
|
|
||||||
private final static Map<String, String> massStatusMap;
|
String status = response.getAsJson().getString("msg_status");
|
||||||
static {
|
String desc = massStatusMap.get(status);
|
||||||
massStatusMap = new HashMap<String, String>();
|
return String.format("%s:%s", status, desc);
|
||||||
massStatusMap.put("sendsuccess", "发送成功");
|
}
|
||||||
massStatusMap.put("send_success", "发送成功");
|
|
||||||
massStatusMap.put("success", "发送成功");
|
private final static Map<String, String> massStatusMap;
|
||||||
massStatusMap.put("send success", "发送成功");
|
static {
|
||||||
massStatusMap.put("sendfail", "发送失败");
|
massStatusMap = new HashMap<String, String>();
|
||||||
massStatusMap.put("send_fail", "发送失败");
|
massStatusMap.put("sendsuccess", "发送成功");
|
||||||
massStatusMap.put("fail", "发送失败");
|
massStatusMap.put("send_success", "发送成功");
|
||||||
massStatusMap.put("send fail", "发送失败");
|
massStatusMap.put("success", "发送成功");
|
||||||
massStatusMap.put("err(10001)", "涉嫌广告");
|
massStatusMap.put("send success", "发送成功");
|
||||||
massStatusMap.put("err(20001)", "涉嫌政治");
|
massStatusMap.put("sendfail", "发送失败");
|
||||||
massStatusMap.put("err(20004)", "涉嫌社会");
|
massStatusMap.put("send_fail", "发送失败");
|
||||||
massStatusMap.put("err(20006)", "涉嫌违法犯罪");
|
massStatusMap.put("fail", "发送失败");
|
||||||
massStatusMap.put("err(20008)", "涉嫌欺诈");
|
massStatusMap.put("send fail", "发送失败");
|
||||||
massStatusMap.put("err(20013)", "涉嫌版权");
|
massStatusMap.put("err(10001)", "涉嫌广告");
|
||||||
massStatusMap.put("err(22000)", "涉嫌互推(互相宣传)");
|
massStatusMap.put("err(20001)", "涉嫌政治");
|
||||||
massStatusMap.put("err(21000)", "涉嫌其他");
|
massStatusMap.put("err(20004)", "涉嫌社会");
|
||||||
}
|
massStatusMap.put("err(20006)", "涉嫌违法犯罪");
|
||||||
|
massStatusMap.put("err(20008)", "涉嫌欺诈");
|
||||||
|
massStatusMap.put("err(20013)", "涉嫌版权");
|
||||||
|
massStatusMap.put("err(22000)", "涉嫌互推(互相宣传)");
|
||||||
|
massStatusMap.put("err(21000)", "涉嫌其他");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -21,7 +21,7 @@ import com.foxinmy.weixin4j.type.ButtonType;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 菜单相关API
|
* 菜单相关API
|
||||||
*
|
*
|
||||||
* @className MenuApi
|
* @className MenuApi
|
||||||
* @author jinyu(foxinmy@gmail.com)
|
* @author jinyu(foxinmy@gmail.com)
|
||||||
* @date 2014年9月25日
|
* @date 2014年9月25日
|
||||||
@ -29,216 +29,203 @@ import com.foxinmy.weixin4j.type.ButtonType;
|
|||||||
*/
|
*/
|
||||||
public class MenuApi extends MpApi {
|
public class MenuApi extends MpApi {
|
||||||
|
|
||||||
private final TokenManager tokenManager;
|
private final TokenManager tokenManager;
|
||||||
|
|
||||||
public MenuApi(TokenManager tokenManager) {
|
public MenuApi(TokenManager tokenManager) {
|
||||||
this.tokenManager = tokenManager;
|
this.tokenManager = tokenManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 自定义菜单
|
* 自定义菜单
|
||||||
*
|
*
|
||||||
* @param buttons
|
* @param buttons
|
||||||
* 菜单列表
|
* 菜单列表
|
||||||
* @throws WeixinException
|
* @throws WeixinException
|
||||||
* @see <a href=
|
* @see <a href=
|
||||||
* "https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141013&token=&lang=zh_CN">
|
* "https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141013&token=&lang=zh_CN">
|
||||||
* 创建自定义菜单</a>
|
* 创建自定义菜单</a>
|
||||||
* @see com.foxinmy.weixin4j.model.Button
|
* @see com.foxinmy.weixin4j.model.Button
|
||||||
* @return 处理结果
|
* @return 处理结果
|
||||||
*/
|
*/
|
||||||
public ApiResult createMenu(List<Button> buttons) throws WeixinException {
|
public ApiResult createMenu(List<Button> buttons) throws WeixinException {
|
||||||
String menu_create_uri = getRequestUri("menu_create_uri");
|
String menu_create_uri = getRequestUri("menu_create_uri");
|
||||||
JSONObject obj = new JSONObject();
|
JSONObject obj = new JSONObject();
|
||||||
obj.put("button", buttons);
|
obj.put("button", buttons);
|
||||||
return createMenu0(menu_create_uri, obj).getAsResult();
|
return createMenu0(menu_create_uri, obj).getAsResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
private WeixinResponse createMenu0(String url, JSONObject data)
|
private WeixinResponse createMenu0(String url, JSONObject data) throws WeixinException {
|
||||||
throws WeixinException {
|
return weixinExecutor.post(String.format(url, tokenManager.getAccessToken()),
|
||||||
return weixinExecutor.post(
|
JSON.toJSONString(data, new NameFilter() {
|
||||||
String.format(url, tokenManager.getAccessToken()),
|
@Override
|
||||||
JSON.toJSONString(data, new NameFilter() {
|
public String process(Object object, String name, Object value) {
|
||||||
@Override
|
if (object instanceof Button && name.equals("content")) {
|
||||||
public String process(Object object, String name,
|
ButtonType buttonType = ButtonType.valueOf(((Button) object).getType());
|
||||||
Object value) {
|
if (buttonType != null) {
|
||||||
if (object instanceof Button && name.equals("content")) {
|
if (ButtonType.view == buttonType || ButtonType.miniprogram == buttonType) {
|
||||||
ButtonType buttonType = ((Button) object).getType();
|
return "url";
|
||||||
if (buttonType != null) {
|
} else if (ButtonType.media_id == buttonType || ButtonType.view_limited == buttonType) {
|
||||||
if (ButtonType.view == buttonType) {
|
return "media_id";
|
||||||
return "url";
|
} else {
|
||||||
} else if (ButtonType.media_id == buttonType
|
return "key";
|
||||||
|| ButtonType.view_limited == buttonType) {
|
}
|
||||||
return "media_id";
|
}
|
||||||
} else {
|
}
|
||||||
return "key";
|
return name;
|
||||||
}
|
}
|
||||||
}
|
}));
|
||||||
}
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询菜单
|
* 查询菜单
|
||||||
*
|
*
|
||||||
* @throws WeixinException
|
* @throws WeixinException
|
||||||
* @see <a href=
|
* @see <a href=
|
||||||
* "https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141014&token=&lang=zh_CN">
|
* "https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141014&token=&lang=zh_CN">
|
||||||
* 查询菜单</a>
|
* 查询菜单</a>
|
||||||
* @see com.foxinmy.weixin4j.model.Button
|
* @see com.foxinmy.weixin4j.model.Button
|
||||||
* @return 菜单集合
|
* @return 菜单集合
|
||||||
*/
|
*/
|
||||||
public List<Button> getMenu() throws WeixinException {
|
public List<Button> getMenu() throws WeixinException {
|
||||||
return buttonsConvertor(getMenu0().getJSONObject("menu"));
|
return buttonsConvertor(getMenu0().getJSONObject("menu"));
|
||||||
}
|
}
|
||||||
|
|
||||||
private JSONObject getMenu0() throws WeixinException {
|
private JSONObject getMenu0() throws WeixinException {
|
||||||
String menu_get_uri = getRequestUri("menu_get_uri");
|
String menu_get_uri = getRequestUri("menu_get_uri");
|
||||||
Token token = tokenManager.getCache();
|
Token token = tokenManager.getCache();
|
||||||
WeixinResponse response = weixinExecutor.get(String.format(
|
WeixinResponse response = weixinExecutor.get(String.format(menu_get_uri, token.getAccessToken()));
|
||||||
menu_get_uri, token.getAccessToken()));
|
return response.getAsJson();
|
||||||
return response.getAsJson();
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询全部菜单(包含个性化菜单)
|
* 查询全部菜单(包含个性化菜单)
|
||||||
*
|
*
|
||||||
* @throws WeixinException
|
* @throws WeixinException
|
||||||
* @see <a href=
|
* @see <a href=
|
||||||
* "https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141014&token=&lang=zh_CN">
|
* "https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141014&token=&lang=zh_CN">
|
||||||
* 普通菜单</a>
|
* 普通菜单</a>
|
||||||
* @see <a href=
|
* @see <a href=
|
||||||
* "https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1455782296&token=&lang=zh_CN">
|
* "https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1455782296&token=&lang=zh_CN">
|
||||||
* 个性化菜单</a>
|
* 个性化菜单</a>
|
||||||
* @see com.foxinmy.weixin4j.model.Button
|
* @see com.foxinmy.weixin4j.model.Button
|
||||||
* @see com.foxinmy.weixin4j.mp.model.Menu
|
* @see com.foxinmy.weixin4j.mp.model.Menu
|
||||||
* @return 菜单集合
|
* @return 菜单集合
|
||||||
*/
|
*/
|
||||||
public List<Menu> getAllMenu() throws WeixinException {
|
public List<Menu> getAllMenu() throws WeixinException {
|
||||||
JSONObject response = getMenu0();
|
JSONObject response = getMenu0();
|
||||||
List<Menu> menus = new ArrayList<Menu>();
|
List<Menu> menus = new ArrayList<Menu>();
|
||||||
// 普通菜单
|
// 普通菜单
|
||||||
JSONObject menuObj = response.getJSONObject("menu");
|
JSONObject menuObj = response.getJSONObject("menu");
|
||||||
menus.add(new Menu(menuObj.getString("menuid"),
|
menus.add(new Menu(menuObj.getString("menuid"), buttonsConvertor(menuObj), null));
|
||||||
buttonsConvertor(menuObj), null));
|
// 个性化菜单
|
||||||
// 个性化菜单
|
JSONArray menuObjs = response.getJSONArray("conditionalmenu");
|
||||||
JSONArray menuObjs = response.getJSONArray("conditionalmenu");
|
if (menuObjs != null && !menuObjs.isEmpty()) {
|
||||||
if (menuObjs != null && !menuObjs.isEmpty()) {
|
for (int i = 0; i < menuObjs.size(); i++) {
|
||||||
for (int i = 0; i < menuObjs.size(); i++) {
|
menuObj = menuObjs.getJSONObject(i);
|
||||||
menuObj = menuObjs.getJSONObject(i);
|
menus.add(new Menu(menuObj.getString("menuid"), buttonsConvertor(menuObj),
|
||||||
menus.add(new Menu(menuObj.getString("menuid"),
|
menuObj.getObject("matchrule", MenuMatchRule.class)));
|
||||||
buttonsConvertor(menuObj), menuObj.getObject(
|
}
|
||||||
"matchrule", MenuMatchRule.class)));
|
}
|
||||||
}
|
return menus;
|
||||||
}
|
}
|
||||||
return menus;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 删除菜单
|
* 删除菜单
|
||||||
*
|
*
|
||||||
* @return 处理结果
|
* @return 处理结果
|
||||||
* @throws WeixinException
|
* @throws WeixinException
|
||||||
* @see <a href=
|
* @see <a href=
|
||||||
* "https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141015&token=&lang=zh_CN">
|
* "https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141015&token=&lang=zh_CN">
|
||||||
* 删除菜单</a>
|
* 删除菜单</a>
|
||||||
* @return 处理结果
|
* @return 处理结果
|
||||||
*/
|
*/
|
||||||
public ApiResult deleteMenu() throws WeixinException {
|
public ApiResult deleteMenu() throws WeixinException {
|
||||||
String menu_delete_uri = getRequestUri("menu_delete_uri");
|
String menu_delete_uri = getRequestUri("menu_delete_uri");
|
||||||
Token token = tokenManager.getCache();
|
Token token = tokenManager.getCache();
|
||||||
WeixinResponse response = weixinExecutor.get(String.format(
|
WeixinResponse response = weixinExecutor.get(String.format(menu_delete_uri, token.getAccessToken()));
|
||||||
menu_delete_uri, token.getAccessToken()));
|
|
||||||
|
|
||||||
return response.getAsResult();
|
return response.getAsResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 创建个性化菜单
|
* 创建个性化菜单
|
||||||
*
|
*
|
||||||
* @param buttons
|
* @param buttons
|
||||||
* 菜单列表
|
* 菜单列表
|
||||||
* @param matchRule
|
* @param matchRule
|
||||||
* 匹配规则 至少要有一个匹配信息是不为空
|
* 匹配规则 至少要有一个匹配信息是不为空
|
||||||
* @throws WeixinException
|
* @throws WeixinException
|
||||||
* @see <a href=
|
* @see <a href=
|
||||||
* "https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1455782296&token=&lang=zh_CN">
|
* "https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1455782296&token=&lang=zh_CN">
|
||||||
* 创建个性化菜单</a>
|
* 创建个性化菜单</a>
|
||||||
* @see com.foxinmy.weixin4j.model.Button
|
* @see com.foxinmy.weixin4j.model.Button
|
||||||
* @return 菜单ID
|
* @return 菜单ID
|
||||||
*/
|
*/
|
||||||
public String createCustomMenu(List<Button> buttons, MenuMatchRule matchRule)
|
public String createCustomMenu(List<Button> buttons, MenuMatchRule matchRule) throws WeixinException {
|
||||||
throws WeixinException {
|
String menu_create_uri = getRequestUri("menu_custom_create_uri");
|
||||||
String menu_create_uri = getRequestUri("menu_custom_create_uri");
|
JSONObject obj = new JSONObject();
|
||||||
JSONObject obj = new JSONObject();
|
obj.put("button", buttons);
|
||||||
obj.put("button", buttons);
|
obj.put("matchrule", matchRule.getRule());
|
||||||
obj.put("matchrule", matchRule.getRule());
|
return createMenu0(menu_create_uri, obj).getAsJson().getString("menuid");
|
||||||
return createMenu0(menu_create_uri, obj).getAsJson()
|
}
|
||||||
.getString("menuid");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 删除个性化菜单
|
* 删除个性化菜单
|
||||||
*
|
*
|
||||||
* @throws WeixinException
|
* @throws WeixinException
|
||||||
* @see <a href=
|
* @see <a href=
|
||||||
* "https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1455782296&token=&lang=zh_CN">
|
* "https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1455782296&token=&lang=zh_CN">
|
||||||
* 删除个性化菜单</a>
|
* 删除个性化菜单</a>
|
||||||
* @return 处理结果
|
* @return 处理结果
|
||||||
*/
|
*/
|
||||||
public ApiResult deleteCustomMenu(String menuId) throws WeixinException {
|
public ApiResult deleteCustomMenu(String menuId) throws WeixinException {
|
||||||
String menu_delete_uri = getRequestUri("menu_delete_custom_uri");
|
String menu_delete_uri = getRequestUri("menu_delete_custom_uri");
|
||||||
Token token = tokenManager.getCache();
|
Token token = tokenManager.getCache();
|
||||||
JSONObject obj = new JSONObject();
|
JSONObject obj = new JSONObject();
|
||||||
obj.put("menuid", menuId);
|
obj.put("menuid", menuId);
|
||||||
WeixinResponse response = weixinExecutor.post(
|
WeixinResponse response = weixinExecutor.post(String.format(menu_delete_uri, token.getAccessToken()),
|
||||||
String.format(menu_delete_uri, token.getAccessToken()),
|
obj.toJSONString());
|
||||||
obj.toJSONString());
|
|
||||||
|
|
||||||
return response.getAsResult();
|
return response.getAsResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 测试个性化菜单匹配结果
|
* 测试个性化菜单匹配结果
|
||||||
*
|
*
|
||||||
* @param userId
|
* @param userId
|
||||||
* 可以是粉丝的OpenID,也可以是粉丝的微信号。
|
* 可以是粉丝的OpenID,也可以是粉丝的微信号。
|
||||||
* @return 匹配到的菜单配置
|
* @return 匹配到的菜单配置
|
||||||
* @see <a href=
|
* @see <a href=
|
||||||
* "https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1455782296&token=&lang=zh_CN">
|
* "https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1455782296&token=&lang=zh_CN">
|
||||||
* 测试个性化菜单</a>
|
* 测试个性化菜单</a>
|
||||||
* @see com.foxinmy.weixin4j.model.Button
|
* @see com.foxinmy.weixin4j.model.Button
|
||||||
* @throws WeixinException
|
* @throws WeixinException
|
||||||
*/
|
*/
|
||||||
public List<Button> matchCustomMenu(String userId) throws WeixinException {
|
public List<Button> matchCustomMenu(String userId) throws WeixinException {
|
||||||
String menu_trymatch_uri = getRequestUri("menu_trymatch_uri");
|
String menu_trymatch_uri = getRequestUri("menu_trymatch_uri");
|
||||||
Token token = tokenManager.getCache();
|
Token token = tokenManager.getCache();
|
||||||
JSONObject obj = new JSONObject();
|
JSONObject obj = new JSONObject();
|
||||||
obj.put("user_id", userId);
|
obj.put("user_id", userId);
|
||||||
WeixinResponse response = weixinExecutor.post(
|
WeixinResponse response = weixinExecutor.post(String.format(menu_trymatch_uri, token.getAccessToken()),
|
||||||
String.format(menu_trymatch_uri, token.getAccessToken()),
|
obj.toJSONString());
|
||||||
obj.toJSONString());
|
|
||||||
|
|
||||||
return buttonsConvertor(response.getAsJson().getJSONObject("menu"));
|
return buttonsConvertor(response.getAsJson().getJSONObject("menu"));
|
||||||
}
|
}
|
||||||
|
|
||||||
private final ParseProcess buttonProcess = new ExtraProcessor() {
|
private final ParseProcess buttonProcess = new ExtraProcessor() {
|
||||||
@Override
|
@Override
|
||||||
public void processExtra(Object object, String key, Object value) {
|
public void processExtra(Object object, String key, Object value) {
|
||||||
((Button) object).setContent(String.valueOf(value));
|
((Button) object).setContent(String.valueOf(value));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private List<Button> buttonsConvertor(JSONObject menu) {
|
private List<Button> buttonsConvertor(JSONObject menu) {
|
||||||
JSONArray buttons = menu.getJSONArray("button");
|
JSONArray buttons = menu.getJSONArray("button");
|
||||||
List<Button> buttonList = new ArrayList<Button>(buttons.size());
|
List<Button> buttonList = new ArrayList<Button>(buttons.size());
|
||||||
for (int i = 0; i < buttons.size(); i++) {
|
for (int i = 0; i < buttons.size(); i++) {
|
||||||
buttonList.add(JSON.parseObject(buttons.getString(i), Button.class,
|
buttonList.add(JSON.parseObject(buttons.getString(i), Button.class, buttonProcess));
|
||||||
buttonProcess));
|
}
|
||||||
}
|
return buttonList;
|
||||||
return buttonList;
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -238,4 +238,23 @@ shake_around_device_update_uri={api_base_url}/shakearound/device/update?access_t
|
|||||||
#\u6447\u4e00\u6447\u5468\u8fb9-\u67e5\u8be2\u8bbe\u5907\u5217\u8868
|
#\u6447\u4e00\u6447\u5468\u8fb9-\u67e5\u8be2\u8bbe\u5907\u5217\u8868
|
||||||
shake_around_device_search_uri={api_base_url}/shakearound/device/search?access_token=%s
|
shake_around_device_search_uri={api_base_url}/shakearound/device/search?access_token=%s
|
||||||
#\u6447\u4e00\u6447\u5468\u8fb9-\u83b7\u53d6\u8bbe\u5907\u548c\u7528\u6237\u4fe1\u606f
|
#\u6447\u4e00\u6447\u5468\u8fb9-\u83b7\u53d6\u8bbe\u5907\u548c\u7528\u6237\u4fe1\u606f
|
||||||
shake_around_user_get_shake_info={api_base_url}/shakearound/user/getshakeinfo?access_token=%s
|
shake_around_user_get_shake_info={api_base_url}/shakearound/user/getshakeinfo?access_token=%s
|
||||||
|
|
||||||
|
# \u6253\u5f00\u5df2\u7fa4\u53d1\u6587\u7ae0\u8bc4\u8bba
|
||||||
|
news_comment_open={api_cgi_url}/comment/open?access_token=%s
|
||||||
|
# \u5173\u95ed\u5df2\u7fa4\u53d1\u6587\u7ae0\u8bc4\u8bba
|
||||||
|
news_comment_open={api_cgi_url}/comment/close?access_token=%s
|
||||||
|
# \u5c06\u8bc4\u8bba\u6807\u8bb0\u7cbe\u9009
|
||||||
|
news_comment_markelect={api_cgi_url}/comment/markelect?access_token=%s
|
||||||
|
# \u5c06\u8bc4\u8bba\u53d6\u6d88\u7cbe\u9009
|
||||||
|
news_comment_unmarkelect={api_cgi_url}/comment/unmarkelect?access_token=%s
|
||||||
|
# \u5220\u9664\u8bc4\u8bba
|
||||||
|
news_comment_delete={api_cgi_url}/comment/delete?access_token=%s
|
||||||
|
# \u56de\u590d\u8bc4\u8bba
|
||||||
|
news_comment_reply_add={api_cgi_url}/comment/reply/add?access_token=%s
|
||||||
|
# \u5220\u9664\u56de\u590d
|
||||||
|
news_comment_reply_delete={api_cgi_url}/comment/reply/delete?access_token=%s
|
||||||
|
# \u83b7\u53d6\u8bc4\u8bba
|
||||||
|
news_comment_list={api_cgi_url}/comment/list?access_token=%s
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,22 @@
|
|||||||
|
package com.foxinmy.weixin4j.mp.model;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文章评论
|
||||||
|
*
|
||||||
|
* @className ArticleComment
|
||||||
|
* @author jinyu
|
||||||
|
* @date May 19, 2017
|
||||||
|
* @since JDK 1.6
|
||||||
|
* @see
|
||||||
|
*/
|
||||||
|
public class ArticleComment implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = -8506024679132313314L;
|
||||||
|
|
||||||
|
public enum ArticleCommentType {
|
||||||
|
GENERAL, // 普通评论
|
||||||
|
MARKELECT // 精选评论
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -21,7 +21,7 @@ import com.foxinmy.weixin4j.tuple.Text;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 群发消息
|
* 群发消息
|
||||||
*
|
*
|
||||||
* @className MpNewsTest
|
* @className MpNewsTest
|
||||||
* @author jinyu(foxinmy@gmail.com)
|
* @author jinyu(foxinmy@gmail.com)
|
||||||
* @date 2014年4月27日
|
* @date 2014年4月27日
|
||||||
@ -29,78 +29,72 @@ import com.foxinmy.weixin4j.tuple.Text;
|
|||||||
* @see
|
* @see
|
||||||
*/
|
*/
|
||||||
public class MassTest extends TokenTest {
|
public class MassTest extends TokenTest {
|
||||||
private MassApi massApi;
|
private MassApi massApi;
|
||||||
private MediaApi mediaApi;
|
private MediaApi mediaApi;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void init() {
|
public void init() {
|
||||||
this.massApi = new MassApi(tokenManager);
|
this.massApi = new MassApi(tokenManager);
|
||||||
this.mediaApi = new MediaApi(tokenManager);
|
this.mediaApi = new MediaApi(tokenManager);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void uploadArticle() throws IOException, WeixinException {
|
public void uploadArticle() throws IOException, WeixinException {
|
||||||
List<MpArticle> articles = new ArrayList<MpArticle>();
|
List<MpArticle> articles = new ArrayList<MpArticle>();
|
||||||
File file = new File("/tmp/test.jpg");
|
File file = new File("/tmp/test.jpg");
|
||||||
MediaUploadResult mediaResult = mediaApi.uploadMedia(false,
|
MediaUploadResult mediaResult = mediaApi.uploadMedia(false, new FileInputStream(file), file.getName());
|
||||||
new FileInputStream(file), file.getName());
|
articles.add(new MpArticle(mediaResult.getMediaId(), "title", "content"));
|
||||||
articles.add(new MpArticle(mediaResult.getMediaId(), "title", "content"));
|
massApi.uploadArticle(articles);
|
||||||
massApi.uploadArticle(articles);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void massByGroupId() throws WeixinException {
|
public void massByGroupId() throws WeixinException {
|
||||||
String[] msgId = massApi.massByGroupId(new Image("mediaId"), true, 0);
|
String[] msgId = massApi.massByGroupId(new Image("mediaId"), true, 0);
|
||||||
Assert.assertTrue(msgId[0] != null);
|
Assert.assertTrue(msgId[0] != null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void massByOpenIds() throws WeixinException {
|
public void massByOpenIds() throws WeixinException {
|
||||||
String[] msgId = massApi.massByOpenIds(new Text("HI"),
|
String[] msgId = massApi.massByOpenIds(new Text("HI"), "oyFLst1bqtuTcxK-ojF8hOGtLQao");
|
||||||
"oyFLst1bqtuTcxK-ojF8hOGtLQao");
|
Assert.assertTrue(msgId[0] != null);
|
||||||
Assert.assertTrue(msgId[0] != null);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void massArticleByGroup() throws IOException, WeixinException {
|
public void massArticleByGroup() throws IOException, WeixinException {
|
||||||
List<MpArticle> articles = new ArrayList<MpArticle>();
|
List<MpArticle> articles = new ArrayList<MpArticle>();
|
||||||
File file = new File("/tmp/test.jpg");
|
File file = new File("/tmp/test.jpg");
|
||||||
MediaUploadResult mediaResult = mediaApi.uploadMedia(false,
|
MediaUploadResult mediaResult = mediaApi.uploadMedia(false, new FileInputStream(file), file.getName());
|
||||||
new FileInputStream(file), file.getName());
|
articles.add(new MpArticle(mediaResult.getMediaId(), "title", "content"));
|
||||||
articles.add(new MpArticle(mediaResult.getMediaId(), "title", "content"));
|
String[] massId = massApi.massArticleByGroupId(articles, 0);
|
||||||
String[] massId = massApi.massArticleByGroupId(articles, 0);
|
Assert.assertTrue(massId[0] != null);
|
||||||
Assert.assertTrue(massId[0] != null);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void massArticleByOpenIds() throws IOException, WeixinException {
|
public void massArticleByOpenIds() throws IOException, WeixinException {
|
||||||
List<MpArticle> articles = new ArrayList<MpArticle>();
|
List<MpArticle> articles = new ArrayList<MpArticle>();
|
||||||
File file = new File("/tmp/test.jpg");
|
File file = new File("/tmp/test.jpg");
|
||||||
MediaUploadResult mediaResult = mediaApi.uploadMedia(false,
|
MediaUploadResult mediaResult = mediaApi.uploadMedia(false, new FileInputStream(file), file.getName());
|
||||||
new FileInputStream(file), file.getName());
|
articles.add(new MpArticle(mediaResult.getMediaId(), "title", "content"));
|
||||||
articles.add(new MpArticle(mediaResult.getMediaId(), "title", "content"));
|
String[] massId = massApi.massArticleByOpenIds(articles, false, "owGBft_vbBbOaQOmpEUE4xDLeRSU");
|
||||||
String[] massId = massApi.massArticleByOpenIds(articles,
|
Assert.assertTrue(massId[0] != null);
|
||||||
"owGBft_vbBbOaQOmpEUE4xDLeRSU");
|
}
|
||||||
Assert.assertTrue(massId[0] != null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void deleteMass() throws WeixinException {
|
public void deleteMass() throws WeixinException {
|
||||||
ApiResult result = massApi.deleteMassNews("34182");
|
ApiResult result = massApi.deleteMassNews("34182");
|
||||||
Assert.assertEquals("0", result.getReturnCode());
|
Assert.assertEquals("0", result.getReturnCode());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void previewMass() throws WeixinException {
|
public void previewMass() throws WeixinException {
|
||||||
ApiResult result = massApi.previewMassNews(
|
ApiResult result = massApi.previewMassNews("oyFLst1bqtuTcxK-ojF8hOGtLQao", null, new Text("test"));
|
||||||
"oyFLst1bqtuTcxK-ojF8hOGtLQao", null, new Text("test"));
|
Assert.assertEquals("0", result.getReturnCode());
|
||||||
Assert.assertEquals("0", result.getReturnCode());
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void getMassNews() throws WeixinException {
|
public void getMassNews() throws WeixinException {
|
||||||
String status = massApi.getMassNewStatus("82358");
|
String status = massApi.getMassNewStatus("82358");
|
||||||
System.out.println(status);
|
System.out.println(status);
|
||||||
Assert.assertNotNull(status);
|
Assert.assertNotNull(status);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -19,7 +19,7 @@ import com.foxinmy.weixin4j.type.ButtonType;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 菜单相关API
|
* 菜单相关API
|
||||||
*
|
*
|
||||||
* @className MenuApi
|
* @className MenuApi
|
||||||
* @author jinyu(foxinmy@gmail.com)
|
* @author jinyu(foxinmy@gmail.com)
|
||||||
* @date 2014年9月25日
|
* @date 2014年9月25日
|
||||||
@ -36,10 +36,10 @@ public class MenuApi extends QyApi {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 自定义菜单(管理员须拥有应用的管理权限 并且应用必须设置在回调模式)
|
* 自定义菜单(管理员须拥有应用的管理权限 并且应用必须设置在回调模式)
|
||||||
*
|
*
|
||||||
* @param agentid
|
* @param agentid
|
||||||
* 应用ID
|
* 应用ID
|
||||||
*
|
*
|
||||||
* @param buttons
|
* @param buttons
|
||||||
* 菜单列表
|
* 菜单列表
|
||||||
* @throws WeixinException
|
* @throws WeixinException
|
||||||
@ -58,7 +58,7 @@ public class MenuApi extends QyApi {
|
|||||||
@Override
|
@Override
|
||||||
public String process(Object object, String name, Object value) {
|
public String process(Object object, String name, Object value) {
|
||||||
if (object instanceof Button && name.equals("content")) {
|
if (object instanceof Button && name.equals("content")) {
|
||||||
ButtonType buttonType = ((Button) object).getType();
|
ButtonType buttonType = ButtonType.valueOf(((Button) object).getType());
|
||||||
if (buttonType != null) {
|
if (buttonType != null) {
|
||||||
if (ButtonType.view == buttonType) {
|
if (ButtonType.view == buttonType) {
|
||||||
return "url";
|
return "url";
|
||||||
@ -78,7 +78,7 @@ public class MenuApi extends QyApi {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询菜单(管理员须拥有应用的管理权限 并且应用必须设置在回调模式。)
|
* 查询菜单(管理员须拥有应用的管理权限 并且应用必须设置在回调模式。)
|
||||||
*
|
*
|
||||||
* @param agentid
|
* @param agentid
|
||||||
* 应用ID
|
* 应用ID
|
||||||
* @return 菜单集合
|
* @return 菜单集合
|
||||||
@ -108,7 +108,7 @@ public class MenuApi extends QyApi {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 删除菜单(管理员须拥有应用的管理权限 并且应用必须设置在回调模式)
|
* 删除菜单(管理员须拥有应用的管理权限 并且应用必须设置在回调模式)
|
||||||
*
|
*
|
||||||
* @param agentid
|
* @param agentid
|
||||||
* 应用ID
|
* 应用ID
|
||||||
* @throws WeixinException
|
* @throws WeixinException
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user