新增评论管理接口

This commit is contained in:
jinyu 2017-05-19 19:06:26 +08:00
parent 66417fdc8b
commit c53e0718ef
17 changed files with 3720 additions and 3192 deletions

View File

@ -783,3 +783,7 @@
+ 新增摇一摇周边接口
+ version upgrade to 1.7.4
* 2017-05-19
+ weixin4j-mp:新增评论管理接口

View File

@ -719,6 +719,18 @@
<code>45059</code>
<text>有粉丝身上的标签数已经超过限制</text>
</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>
<code>45157</code>
<text>标签名非法,请注意不能和其他标签重名</text>
@ -1655,6 +1667,61 @@
<code>86320</code>
<text>不合法的客服类型</text>
</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>
<code>90001</code>
<text>未认证摇一摇周边</text>

View File

@ -29,22 +29,29 @@ public class Button implements Serializable {
*/
private String name;
/**
* 菜单类型 </br> <font color="red">
* 公众平台官网上能够设置的菜单类型有viewtextimgphotovideovoice </font>
* 菜单类型 </br>
* <font color="red"> 公众平台官网上能够设置的菜单类型有viewtextimgphotovideovoice
* </font>
*
* @see com.foxinmy.weixin4j.type.ButtonType
*/
private ButtonType type;
private String type;
/**
* 菜单KEY值,根据type的类型而定</p> 通过公众平台设置的自定义菜单</br> <li>text:保存文字 <li>
* imgvoice保存媒体ID <li>video保存视频URL <li>
* news保存图文消息媒体ID <li>view保存链接URL
* 菜单KEY值,根据type的类型而定
* </p>
* 通过公众平台设置的自定义菜单</br>
* <li>text:保存文字
* <li>imgvoice保存媒体ID
* <li>video保存视频URL
* <li>news保存图文消息媒体ID
* <li>view保存链接URL
* <p>
* 使用API设置的自定义菜单
* </p> <li>
* clickscancode_pushscancode_waitmsgpic_sysphotopic_photo_or_album
* pic_weixinlocation_select保存key <li>view保存链接URL; <li>
* media_idview_limited保存媒体ID
* </p>
* <li>clickscancode_pushscancode_waitmsgpic_sysphotopic_photo_or_album
* pic_weixinlocation_select保存key
* <li>view保存链接URL;
* <li>media_idview_limited保存媒体ID
*/
private String content;
/**
@ -52,6 +59,15 @@ public class Button implements Serializable {
*/
@JSONField(serialize = false, deserialize = false)
private Object extra;
/**
* miniprogram类型必须 小程序的appid仅认证公众号可配置
*/
private String appid;
/**
* miniprogram类型必须 小程序的页面路径
*/
private String pagepath;
/**
* 二级菜单数组个数应为1~5个
*/
@ -88,7 +104,28 @@ public class Button implements Serializable {
public Button(String name, String content, ButtonType type) {
this.name = name;
this.content = content;
this.type = type;
this.type = type.name();
this.subs = new ArrayList<Button>();
}
/**
* 小程序菜单
*
* @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>();
}
@ -100,14 +137,18 @@ public class Button implements Serializable {
this.name = name;
}
public ButtonType getType() {
public String getType() {
return type;
}
public void setType(ButtonType type) {
public void setType(String type) {
this.type = type;
}
public void setType(ButtonType type) {
this.type = type.name();
}
public String getContent() {
return content;
}
@ -129,6 +170,22 @@ public class Button implements Serializable {
this.extra = extra;
}
public String getAppid() {
return appid;
}
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;
}
@ -144,7 +201,7 @@ public class Button implements Serializable {
@Override
public String toString() {
return "Button [name=" + name + ", type=" + type + ", content="
+ content + ", extra=" + extra + ", subs=" + subs + "]";
return "Button [name=" + name + ", type=" + type + ", content=" + content + ", extra=" + extra + ", appid="
+ appid + ", pagepath=" + pagepath + ", subs=" + subs + "]";
}
}

View File

@ -8,7 +8,7 @@ import com.alibaba.fastjson.annotation.JSONField;
/**
* 卡券对象
* <p>
* <font color="red">可用于群发消息</font>
* <font color="red">可用于群发消息客服消息</font>
* </p>
*
* @className Card
@ -17,7 +17,7 @@ import com.alibaba.fastjson.annotation.JSONField;
* @since JDK 1.6
* @see
*/
public class Card implements MassTuple {
public class Card implements MassTuple, NotifyTuple {
private static final long serialVersionUID = 6119453633595102147L;

View File

@ -56,6 +56,16 @@ public class MpArticle implements Serializable {
*/
@JSONField(name = "show_cover_pic")
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() {
}
@ -155,12 +165,45 @@ public class MpArticle implements Serializable {
return this.showCoverPic != null && this.showCoverPic.equals("1");
}
public void setOpenComment(boolean openComment) {
this.openComment = openComment ? "1" : "0";
}
public String getOpenComment() {
return openComment;
}
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
+ ", sourceUrl=" + sourceUrl + ", content=" + content
+ ", url=" + url + ", digest=" + digest + ", showCoverPic="
+ showCoverPic + "]";
return "MpArticle [thumbMediaId=" + thumbMediaId + ", thumbUrl=" + thumbUrl + ", author=" + author + ", title="
+ title + ", url=" + url + ", sourceUrl=" + sourceUrl + ", content=" + content + ", digest=" + digest
+ ", showCoverPic=" + showCoverPic + ", openComment=" + openComment + ", onlyFansCanComment="
+ onlyFansCanComment + "]";
}
}

View File

@ -66,9 +66,5 @@ public enum ButtonType {
/**
* 小程序
*/
miniprogram,
/**
* 以下类型请勿使用,在公众平台设置的按钮类型,如果尝试使用API方式创建菜单则会出错
*/
popups,text,img,voice,video,news;
miniprogram;
}

View File

@ -267,3 +267,7 @@
+ 新增批量发红包接口
+ version upgrade to 1.7.4
* 2017-05-19
+ 新增评论管理接口

View File

@ -39,6 +39,8 @@ weixin4j-mp
* CardApi `卡券API`
* CommentApi `评论API`
[如何使用](https://github.com/foxinmy/weixin4j/wiki)
---------

View File

@ -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();
}
}

View File

@ -19,7 +19,6 @@ import com.foxinmy.weixin4j.mp.model.SemQuery;
import com.foxinmy.weixin4j.mp.model.SemResult;
import com.foxinmy.weixin4j.token.TokenManager;
import com.foxinmy.weixin4j.tuple.MpArticle;
import com.foxinmy.weixin4j.type.ButtonType;
/**
* 辅助相关API
@ -45,8 +44,8 @@ public class HelperApi extends MpApi {
* 待转换的链接
* @return 短链接
* @throws WeixinException
* @see <a
* href="https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1443433600&token=&lang=zh_CN">长链接转短链接</a>
* @see <a href=
* "https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1443433600&token=&lang=zh_CN">长链接转短链接</a>
*/
public String getShorturl(String url) throws WeixinException {
String shorturl_uri = getRequestUri("shorturl_uri");
@ -54,8 +53,7 @@ public class HelperApi extends MpApi {
JSONObject obj = new JSONObject();
obj.put("action", "long2short");
obj.put("long_url", url);
WeixinResponse response = weixinExecutor.post(
String.format(shorturl_uri, token.getAccessToken()),
WeixinResponse response = weixinExecutor.post(String.format(shorturl_uri, token.getAccessToken()),
obj.toJSONString());
return response.getAsJson().getString("short_url");
@ -69,15 +67,14 @@ public class HelperApi extends MpApi {
* @return 语义理解结果
* @see com.foxinmy.weixin4j.mp.model.SemQuery
* @see com.foxinmy.weixin4j.mp.model.SemResult
* @see <a
* href="https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141241&token=&lang=zh_CN">语义理解</a>
* @see <a href=
* "https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141241&token=&lang=zh_CN">语义理解</a>
* @throws WeixinException
*/
public SemResult semantic(SemQuery semQuery) throws WeixinException {
String semantic_uri = getRequestUri("semantic_uri");
Token token = tokenManager.getCache();
WeixinResponse response = weixinExecutor.post(
String.format(semantic_uri, token.getAccessToken()),
WeixinResponse response = weixinExecutor.post(String.format(semantic_uri, token.getAccessToken()),
semQuery.toJson());
return response.getAsObject(new TypeReference<SemResult>() {
});
@ -87,17 +84,15 @@ public class HelperApi extends MpApi {
* 获取微信服务器IP地址
*
* @return IP地址
* @see <a
* href="https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140187&token=&lang=zh_CN">获取IP地址</a>
* @see <a href=
* "https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140187&token=&lang=zh_CN">获取IP地址</a>
* @throws WeixinException
*/
public List<String> getWechatServerIp() throws WeixinException {
String getcallbackip_uri = getRequestUri("getcallbackip_uri");
Token token = tokenManager.getCache();
WeixinResponse response = weixinExecutor.get(String.format(
getcallbackip_uri, token.getAccessToken()));
return JSON.parseArray(response.getAsJson().getString("ip_list"),
String.class);
WeixinResponse response = weixinExecutor.get(String.format(getcallbackip_uri, token.getAccessToken()));
return JSON.parseArray(response.getAsJson().getString("ip_list"), String.class);
}
/**
@ -106,8 +101,8 @@ public class HelperApi extends MpApi {
*
* @return 菜单配置信息
* @see {@link MenuApi#getMenu()}
* @see <a
* href="https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1434698695&token=&lang=zh_CN">获取自定义菜单配置</a>
* @see <a href=
* "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.mp.model.MenuSetting
* @see com.foxinmy.weixin4j.tuple.MpArticle
@ -116,27 +111,20 @@ public class HelperApi extends MpApi {
public MenuSetting getMenuSetting() throws WeixinException {
String menu_get_selfmenu_uri = getRequestUri("menu_get_selfmenu_uri");
Token token = tokenManager.getCache();
WeixinResponse response = weixinExecutor.get(String.format(
menu_get_selfmenu_uri, token.getAccessToken()));
WeixinResponse response = weixinExecutor.get(String.format(menu_get_selfmenu_uri, token.getAccessToken()));
JSONObject result = response.getAsJson();
JSONArray buttons = result.getJSONObject("selfmenu_info").getJSONArray(
"button");
JSONArray buttons = result.getJSONObject("selfmenu_info").getJSONArray("button");
List<Button> buttonList = new ArrayList<Button>(buttons.size());
JSONObject buttonObj = null;
for (int i = 0; i < buttons.size(); i++) {
buttonObj = buttons.getJSONObject(i);
if (buttonObj.containsKey("sub_button")) {
buttonObj.put(
"sub_button",
buttonObj.getJSONObject("sub_button").getJSONArray(
"list"));
buttonObj.put("type", ButtonType.popups);
buttonObj.put("sub_button", buttonObj.getJSONObject("sub_button").getJSONArray("list"));
buttonObj.put("type", "popups");
}
buttonList.add(JSON.parseObject(buttonObj.toJSONString(),
Button.class, ButtonExtraProcessor.global));
buttonList.add(JSON.parseObject(buttonObj.toJSONString(), Button.class, ButtonExtraProcessor.global));
}
return new MenuSetting(result.getBooleanValue("is_menu_open"),
buttonList);
return new MenuSetting(result.getBooleanValue("is_menu_open"), buttonList);
}
private static final class ButtonExtraProcessor implements ExtraProcessor {
@ -157,8 +145,7 @@ public class HelperApi extends MpApi {
article.put("show_cover_pic", article.remove("show_cover"));
article.put("thumb_url", article.remove("cover_url"));
article.put("url", article.remove("content_url"));
article.put("content_source_url",
article.remove("source_url"));
article.put("content_source_url", article.remove("source_url"));
newsList.add(JSON.toJavaObject(article, MpArticle.class));
}
((Button) object).setExtra(newsList);
@ -172,45 +159,38 @@ public class HelperApi extends MpApi {
* 获取公众号当前使用的自动回复规则包括关注后自动回复消息自动回复60分钟内触发一次关键词自动回复
*
* @see com.foxinmy.weixin4j.mp.model.AutoReplySetting
* @see <a
* href="https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1433751299&token=&lang=zh_CN">获取自动回复规则</a>
* @see <a href=
* "https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1433751299&token=&lang=zh_CN">获取自动回复规则</a>
* @return 自定义回复配置信息
* @throws WeixinException
*/
public AutoReplySetting getAutoReplySetting() throws WeixinException {
String autoreply_setting_get_uri = getRequestUri("autoreply_setting_get_uri");
Token token = tokenManager.getCache();
WeixinResponse response = weixinExecutor.get(String.format(
autoreply_setting_get_uri, token.getAccessToken()));
WeixinResponse response = weixinExecutor.get(String.format(autoreply_setting_get_uri, token.getAccessToken()));
JSONObject result = response.getAsJson();
AutoReplySetting replySetting = JSON.toJavaObject(result,
AutoReplySetting.class);
AutoReplySetting replySetting = JSON.toJavaObject(result, AutoReplySetting.class);
List<AutoReplySetting.Rule> ruleList = null;
if (result.containsKey("keyword_autoreply_info")) {
JSONArray keywordList = result.getJSONObject(
"keyword_autoreply_info").getJSONArray("list");
JSONArray keywordList = result.getJSONObject("keyword_autoreply_info").getJSONArray("list");
ruleList = new ArrayList<AutoReplySetting.Rule>(keywordList.size());
JSONObject keywordObj = null;
JSONArray replyList = null;
JSONObject replyObj = null;
for (int i = 0; i < keywordList.size(); i++) {
keywordObj = keywordList.getJSONObject(i);
AutoReplySetting.Rule rule = JSON.toJavaObject(keywordObj,
AutoReplySetting.Rule.class);
AutoReplySetting.Rule rule = JSON.toJavaObject(keywordObj, AutoReplySetting.Rule.class);
replyList = keywordObj.getJSONArray("reply_list_info");
List<AutoReplySetting.Entry> entryList = new ArrayList<AutoReplySetting.Entry>(
replyList.size());
List<AutoReplySetting.Entry> entryList = new ArrayList<AutoReplySetting.Entry>(replyList.size());
for (int j = 0; j < replyList.size(); j++) {
replyObj = replyList.getJSONObject(j);
if (replyObj.getString("type").equals("news")) {
entryList.add(JSON.parseObject(replyObj.toJSONString(),
AutoReplySetting.Entry.class,
entryList.add(JSON.parseObject(replyObj.toJSONString(), AutoReplySetting.Entry.class,
ButtonExtraProcessor.global));
} else {
entryList.add(JSON.toJavaObject(replyObj,
AutoReplySetting.Entry.class));
entryList.add(JSON.toJavaObject(replyObj, AutoReplySetting.Entry.class));
}
}
rule.setReplyList(entryList);
@ -223,22 +203,20 @@ public class HelperApi extends MpApi {
/**
* 接口调用次数调用清零公众号调用接口并不是无限制的为了防止公众号的程序错误而引发微信服务器负载异常默认情况下
* 每个公众号调用接口都不能超过一定限制
* 当超过一定限制时调用对应接口会收到{"errcode":45009,"errmsg":"api freq out of limit"
* }错误返回码
* 每个公众号调用接口都不能超过一定限制 当超过一定限制时调用对应接口会收到{"errcode":45009,"errmsg":"api freq
* out of limit" }错误返回码。
*
* @param appId
* 公众号ID
* @see <a
* href="https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1433744592&token=&lang=zh_CN">接口清零</a>
* @see <a href=
* "https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1433744592&token=&lang=zh_CN">接口清零</a>
* @return 操作结果
* @throws WeixinException
*/
public ApiResult clearQuota(String appId) throws WeixinException {
String clearquota_uri = getRequestUri("clearquota_uri");
String body = String.format("{\"appid\":\"%s\"}", appId);
WeixinResponse response = weixinExecutor.post(
String.format(clearquota_uri, tokenManager.getAccessToken()),
WeixinResponse response = weixinExecutor.post(String.format(clearquota_uri, tokenManager.getAccessToken()),
body);
return response.getAsResult();
}

View File

@ -34,25 +34,24 @@ public class MassApi extends MpApi {
}
/**
* 上传图文消息,一个图文消息支持1到10条图文</br> <font
* color="red">具备微信支付权限的公众号在使用高级群发接口上传群发图文消息类型时可使用&lta&gt标签加入外链</font>
* 上传图文消息,一个图文消息支持1到10条图文</br>
* <font color=
* "red">具备微信支付权限的公众号在使用高级群发接口上传群发图文消息类型时可使用&lta&gt标签加入外链</font>
*
* @param articles
* 图片消息
* @return 媒体ID
* @throws WeixinException
* @see <a
* href="https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140549&token=&lang=zh_CN">上传图文素材</a>
* @see <a href=
* "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");
Token token = tokenManager.getCache();
JSONObject obj = new JSONObject();
obj.put("articles", articles);
WeixinResponse response = weixinExecutor.post(
String.format(article_upload_uri, token.getAccessToken()),
WeixinResponse response = weixinExecutor.post(String.format(article_upload_uri, token.getAccessToken()),
obj.toJSONString());
return response.getAsJson().getString("media_id");
@ -83,19 +82,17 @@ public class MassApi extends MpApi {
* @see com.foxinmy.weixin4j.tuple.Card
* @see com.foxinmy.weixin4j.tuple.MassTuple
* @see {@link GroupApi#getGroups()}
* @see <a
* href="https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140549&token=&lang=zh_CN">根据分组群发</a>
* @see <a href=
* "https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140549&token=&lang=zh_CN">根据分组群发</a>
*/
@Deprecated
public String[] massByGroupId(MassTuple tuple, boolean isToAll, int groupId)
throws WeixinException {
public String[] massByGroupId(MassTuple tuple, boolean isToAll, int groupId) 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");
throw new WeixinException("mass fail:mediaId or articles is required");
}
tuple = new MpNews(uploadArticle(_articles));
}
@ -112,13 +109,11 @@ public class MassApi extends MpApi {
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()),
WeixinResponse response = weixinExecutor.post(String.format(mass_group_uri, token.getAccessToken()),
obj.toJSONString());
obj = response.getAsJson();
return new String[] { obj.getString("msg_id"),
obj.getString("msg_data_id") };
return new String[] { obj.getString("msg_id"), obj.getString("msg_data_id") };
}
/**
@ -129,21 +124,20 @@ public class MassApi extends MpApi {
* @param groupId
* 分组ID
* @return 第一个元素为消息发送任务的ID,第二个元素为消息的数据ID该字段只有在群发图文消息时才会出现
* @see <a
* href="https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140549&token=&lang=zh_CN">根据分组群发</a>
* @see <a href=
* "https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140549&token=&lang=zh_CN">根据分组群发</a>
* @see {@link #massByGroupId(Tuple,int)}
* @see com.foxinmy.weixin4j.tuple.MpArticle
* @throws WeixinException
*/
@Deprecated
public String[] massArticleByGroupId(List<MpArticle> articles, int groupId)
throws WeixinException {
public String[] massArticleByGroupId(List<MpArticle> articles, int groupId) throws WeixinException {
String mediaId = uploadArticle(articles);
return massByGroupId(new MpNews(mediaId), false, groupId);
}
/**
* 标签群发
* 群发消息
* <p>
* 在返回成功时,意味着群发任务提交成功,并不意味着此时群发已经结束,所以,仍有可能在后续的发送过程中出现异常情况导致用户未收到消息,
* 如消息有时会进行审核服务器不稳定等,此外,群发任务一般需要较长的时间才能全部发送完毕
@ -151,11 +145,8 @@ public class MassApi extends MpApi {
*
* @param tuple
* 消息元件
* @param isToAll
* 用于设定是否向全部用户发送值为true或false选择true该消息群发给所有用户
* 选择false可根据group_id发送给指定群组的用户
* @param tagId
* 标签ID
* @param filter
* 过滤条件
* @return 第一个元素为消息发送任务的ID,第二个元素为消息的数据ID该字段只有在群发图文消息时才会出现,可以用于在图文分析数据接口中
* @throws WeixinException
* @see Tag
@ -166,42 +157,68 @@ public class MassApi extends MpApi {
* @see com.foxinmy.weixin4j.tuple.MpNews
* @see com.foxinmy.weixin4j.tuple.Card
* @see com.foxinmy.weixin4j.tuple.MassTuple
* @see {@link TagApi#listTags()}
* @see <a
* href="https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140549&token=&lang=zh_CN">根据标签群发</a>
*/
public String[] massByTagId(MassTuple tuple, boolean isToAll, int tagId)
throws WeixinException {
private String[] mass(MassTuple tuple, JSONObject filter) 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");
throw new WeixinException("mass fail:mediaId or articles is required");
}
tuple = new MpNews(uploadArticle(_articles));
}
if (!filter.containsKey("send_ignore_reprint")) {
filter.put("send_ignore_reprint", 0);
}
}
String msgtype = tuple.getMessageType();
JSONObject obj = new JSONObject();
JSONObject item = new JSONObject();
item.put("is_to_all", isToAll);
if (!isToAll) {
item.put("tag_id", tagId);
}
obj.put("filter", item);
obj.putAll(filter);
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()),
WeixinResponse response = weixinExecutor.post(String.format(mass_group_uri, token.getAccessToken()),
obj.toJSONString());
obj = response.getAsJson();
return new String[] { obj.getString("msg_id"),
obj.getString("msg_data_id") };
return new String[] { obj.getString("msg_id"), obj.getString("msg_data_id") };
}
/**
* 群发消息给所有粉丝
*
* @param tuple
* 消息元件
* @return 第一个元素为消息发送任务的ID,第二个元素为消息的数据ID该字段只有在群发图文消息时才会出现,可以用于在图文分析数据接口中
* @throws WeixinException
* @see <a href=
* "https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140549&token=&lang=zh_CN">根据标签群发</a>
*/
public String[] massToAll(MassTuple tuple) throws WeixinException {
String filter = String.format("{\"filter\":{\"is_to_all\":true}}");
return mass(tuple, JSON.parseObject(filter));
}
/**
* 标签群发消息
*
* @param tuple
* 消息元件
* @param tagId
* 标签ID
* @return 第一个元素为消息发送任务的ID,第二个元素为消息的数据ID该字段只有在群发图文消息时才会出现,可以用于在图文分析数据接口中
* @throws WeixinException
* @see Tag
* @see {@link TagApi#listTags()}
* @see #mass(MassTuple, JSONObject, boolean)
* @see <a href=
* "https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140549&token=&lang=zh_CN">根据标签群发</a>
*/
public String[] massByTagId(MassTuple tuple, int tagId) throws WeixinException {
String filter = String.format("{\"filter\":{\"is_to_all\":false,\"tag_id\":%d}}", tagId);
return mass(tuple, JSON.parseObject(filter));
}
/**
@ -211,21 +228,26 @@ public class MassApi extends MpApi {
* 图文列表
* @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 <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)
public String[] massArticleByTagId(List<MpArticle> articles, int tagId, boolean ignoreReprint)
throws WeixinException {
String mediaId = uploadArticle(articles);
return massByTagId(new MpNews(mediaId), false, tagId);
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 tuple
* 消息元件
@ -233,65 +255,54 @@ public class MassApi extends MpApi {
* openId列表
* @return 第一个元素为消息发送任务的ID,第二个元素为消息的数据ID该字段只有在群发图文消息时才会出现,可以用于在图文分析数据接口中
* @throws WeixinException
* @see com.foxinmy.weixin4j.mp.model.User
* @see com.foxinmy.weixin4j.tuple.Text
* @see com.foxinmy.weixin4j.tuple.Image
* @see com.foxinmy.weixin4j.tuple.Voice
* @see com.foxinmy.weixin4j.tuple.MpVideo
* @see com.foxinmy.weixin4j.tuple.MpNews
* @see com.foxinmy.weixin4j.tuple.Card
* @see com.foxinmy.weixin4j.tuple.MassTuple
* @see <a
* href="https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140549&token=&lang=zh_CN">根据openid群发</a>
* @see <a href=
* "https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140549&token=&lang=zh_CN">根据openid群发</a>
* @see {@link UserApi#getUser(String)}
* @see #mass(MassTuple, JSONObject, boolean)
*/
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") };
public String[] massByOpenIds(MassTuple tuple, String... openIds) throws WeixinException {
JSONObject filter = new JSONObject();
filter.put("touser", openIds);
return mass(tuple, filter);
}
/**
* 根据openid群发图文消息
* openid群发图文消息
*
* @param articles
* 图文列表
* @param ignoreReprint
* 图文消息被判定为转载时是否继续群发
* @param openIds
* openId列表
* @return 第一个元素为消息发送任务的ID,第二个元素为消息的数据ID该字段只有在群发图文消息时才会出现,可以用于在图文分析数据接口中.
* @see <a
* href="https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140549&token=&lang=zh_CN">根据openid群发</a>
* @see <a href=
* "https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140549&token=&lang=zh_CN">根据openid群发</a>
* @see {@link #massByOpenIds(Tuple,String...)}
* @see com.foxinmy.weixin4j.tuple.MpArticle
* @throws WeixinException
*/
public String[] massArticleByOpenIds(List<MpArticle> articles,
String... openIds) throws WeixinException {
public String[] massArticleByOpenIds(List<MpArticle> articles, boolean ignoreReprint, String... openIds)
throws WeixinException {
String mediaId = uploadArticle(articles);
return massByOpenIds(new MpNews(mediaId), openIds);
JSONObject filter = new JSONObject();
filter.put("touser", openIds);
filter.put("send_ignore_reprint", ignoreReprint ? 1 : 0);
return mass(new MpNews(mediaId), filter);
}
/**
* 删除群发消息
*
* @param msgid
* 发送出去的消息ID
* @throws WeixinException
* @see <a href=
* "https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140549&token=&lang=zh_CN">删除群发</a>
* @see #deleteMassNews(String, int)
*/
public ApiResult deleteMassNews(String msgid) throws WeixinException {
return deleteMassNews(msgid, 0);
}
/**
@ -302,27 +313,31 @@ public class MassApi extends MpApi {
*
* @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 <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) throws WeixinException {
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()),
WeixinResponse response = weixinExecutor.post(String.format(mass_delete_uri, token.getAccessToken()),
obj.toJSONString());
return response.getAsResult();
}
/**
* 预览群发消息</br> 开发者可通过该接口发送消息给指定用户在手机端查看消息的样式和排版
* 预览群发消息</br>
* 开发者可通过该接口发送消息给指定用户在手机端查看消息的样式和排版
*
* @param toUser
* 接收用户的openID
@ -333,11 +348,10 @@ public class MassApi extends MpApi {
* @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>
* @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 {
public ApiResult previewMassNews(String toUser, String toWxName, MassTuple tuple) throws WeixinException {
String msgtype = tuple.getMessageType();
JSONObject obj = new JSONObject();
obj.put("touser", toUser);
@ -346,8 +360,7 @@ public class MassApi extends MpApi {
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()),
WeixinResponse response = weixinExecutor.post(String.format(mass_preview_uri, token.getAccessToken()),
obj.toJSONString());
return response.getAsResult();
@ -360,16 +373,15 @@ public class MassApi extends MpApi {
* 消息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>
* @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()),
WeixinResponse response = weixinExecutor.post(String.format(mass_get_uri, token.getAccessToken()),
obj.toJSONString());
String status = response.getAsJson().getString("msg_status");

View File

@ -54,21 +54,17 @@ public class MenuApi extends MpApi {
return createMenu0(menu_create_uri, obj).getAsResult();
}
private WeixinResponse createMenu0(String url, JSONObject data)
throws WeixinException {
return weixinExecutor.post(
String.format(url, tokenManager.getAccessToken()),
private WeixinResponse createMenu0(String url, JSONObject data) throws WeixinException {
return weixinExecutor.post(String.format(url, tokenManager.getAccessToken()),
JSON.toJSONString(data, new NameFilter() {
@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")) {
ButtonType buttonType = ((Button) object).getType();
ButtonType buttonType = ButtonType.valueOf(((Button) object).getType());
if (buttonType != null) {
if (ButtonType.view == buttonType) {
if (ButtonType.view == buttonType || ButtonType.miniprogram == buttonType) {
return "url";
} else if (ButtonType.media_id == buttonType
|| ButtonType.view_limited == buttonType) {
} else if (ButtonType.media_id == buttonType || ButtonType.view_limited == buttonType) {
return "media_id";
} else {
return "key";
@ -98,8 +94,7 @@ public class MenuApi extends MpApi {
private JSONObject getMenu0() throws WeixinException {
String menu_get_uri = getRequestUri("menu_get_uri");
Token token = tokenManager.getCache();
WeixinResponse response = weixinExecutor.get(String.format(
menu_get_uri, token.getAccessToken()));
WeixinResponse response = weixinExecutor.get(String.format(menu_get_uri, token.getAccessToken()));
return response.getAsJson();
}
@ -122,16 +117,14 @@ public class MenuApi extends MpApi {
List<Menu> menus = new ArrayList<Menu>();
// 普通菜单
JSONObject menuObj = response.getJSONObject("menu");
menus.add(new Menu(menuObj.getString("menuid"),
buttonsConvertor(menuObj), null));
menus.add(new Menu(menuObj.getString("menuid"), buttonsConvertor(menuObj), null));
// 个性化菜单
JSONArray menuObjs = response.getJSONArray("conditionalmenu");
if (menuObjs != null && !menuObjs.isEmpty()) {
for (int i = 0; i < menuObjs.size(); i++) {
menuObj = menuObjs.getJSONObject(i);
menus.add(new Menu(menuObj.getString("menuid"),
buttonsConvertor(menuObj), menuObj.getObject(
"matchrule", MenuMatchRule.class)));
menus.add(new Menu(menuObj.getString("menuid"), buttonsConvertor(menuObj),
menuObj.getObject("matchrule", MenuMatchRule.class)));
}
}
return menus;
@ -150,8 +143,7 @@ public class MenuApi extends MpApi {
public ApiResult deleteMenu() throws WeixinException {
String menu_delete_uri = getRequestUri("menu_delete_uri");
Token token = tokenManager.getCache();
WeixinResponse response = weixinExecutor.get(String.format(
menu_delete_uri, token.getAccessToken()));
WeixinResponse response = weixinExecutor.get(String.format(menu_delete_uri, token.getAccessToken()));
return response.getAsResult();
}
@ -170,14 +162,12 @@ public class MenuApi extends MpApi {
* @see com.foxinmy.weixin4j.model.Button
* @return 菜单ID
*/
public String createCustomMenu(List<Button> buttons, MenuMatchRule matchRule)
throws WeixinException {
public String createCustomMenu(List<Button> buttons, MenuMatchRule matchRule) throws WeixinException {
String menu_create_uri = getRequestUri("menu_custom_create_uri");
JSONObject obj = new JSONObject();
obj.put("button", buttons);
obj.put("matchrule", matchRule.getRule());
return createMenu0(menu_create_uri, obj).getAsJson()
.getString("menuid");
return createMenu0(menu_create_uri, obj).getAsJson().getString("menuid");
}
/**
@ -194,8 +184,7 @@ public class MenuApi extends MpApi {
Token token = tokenManager.getCache();
JSONObject obj = new JSONObject();
obj.put("menuid", menuId);
WeixinResponse response = weixinExecutor.post(
String.format(menu_delete_uri, token.getAccessToken()),
WeixinResponse response = weixinExecutor.post(String.format(menu_delete_uri, token.getAccessToken()),
obj.toJSONString());
return response.getAsResult();
@ -218,8 +207,7 @@ public class MenuApi extends MpApi {
Token token = tokenManager.getCache();
JSONObject obj = new JSONObject();
obj.put("user_id", userId);
WeixinResponse response = weixinExecutor.post(
String.format(menu_trymatch_uri, token.getAccessToken()),
WeixinResponse response = weixinExecutor.post(String.format(menu_trymatch_uri, token.getAccessToken()),
obj.toJSONString());
return buttonsConvertor(response.getAsJson().getJSONObject("menu"));
@ -236,8 +224,7 @@ public class MenuApi extends MpApi {
JSONArray buttons = menu.getJSONArray("button");
List<Button> buttonList = new ArrayList<Button>(buttons.size());
for (int i = 0; i < buttons.size(); i++) {
buttonList.add(JSON.parseObject(buttons.getString(i), Button.class,
buttonProcess));
buttonList.add(JSON.parseObject(buttons.getString(i), Button.class, buttonProcess));
}
return buttonList;
}

View File

@ -239,3 +239,22 @@ shake_around_device_update_uri={api_base_url}/shakearound/device/update?access_t
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
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

View File

@ -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 // 精选评论
}
}

View File

@ -42,8 +42,7 @@ public class MassTest extends TokenTest {
public void uploadArticle() throws IOException, WeixinException {
List<MpArticle> articles = new ArrayList<MpArticle>();
File file = new File("/tmp/test.jpg");
MediaUploadResult mediaResult = mediaApi.uploadMedia(false,
new FileInputStream(file), file.getName());
MediaUploadResult mediaResult = mediaApi.uploadMedia(false, new FileInputStream(file), file.getName());
articles.add(new MpArticle(mediaResult.getMediaId(), "title", "content"));
massApi.uploadArticle(articles);
}
@ -56,8 +55,7 @@ public class MassTest extends TokenTest {
@Test
public void massByOpenIds() throws WeixinException {
String[] msgId = massApi.massByOpenIds(new Text("HI"),
"oyFLst1bqtuTcxK-ojF8hOGtLQao");
String[] msgId = massApi.massByOpenIds(new Text("HI"), "oyFLst1bqtuTcxK-ojF8hOGtLQao");
Assert.assertTrue(msgId[0] != null);
}
@ -65,8 +63,7 @@ public class MassTest extends TokenTest {
public void massArticleByGroup() throws IOException, WeixinException {
List<MpArticle> articles = new ArrayList<MpArticle>();
File file = new File("/tmp/test.jpg");
MediaUploadResult mediaResult = mediaApi.uploadMedia(false,
new FileInputStream(file), file.getName());
MediaUploadResult mediaResult = mediaApi.uploadMedia(false, new FileInputStream(file), file.getName());
articles.add(new MpArticle(mediaResult.getMediaId(), "title", "content"));
String[] massId = massApi.massArticleByGroupId(articles, 0);
Assert.assertTrue(massId[0] != null);
@ -76,11 +73,9 @@ public class MassTest extends TokenTest {
public void massArticleByOpenIds() throws IOException, WeixinException {
List<MpArticle> articles = new ArrayList<MpArticle>();
File file = new File("/tmp/test.jpg");
MediaUploadResult mediaResult = mediaApi.uploadMedia(false,
new FileInputStream(file), file.getName());
MediaUploadResult mediaResult = mediaApi.uploadMedia(false, new FileInputStream(file), file.getName());
articles.add(new MpArticle(mediaResult.getMediaId(), "title", "content"));
String[] massId = massApi.massArticleByOpenIds(articles,
"owGBft_vbBbOaQOmpEUE4xDLeRSU");
String[] massId = massApi.massArticleByOpenIds(articles, false, "owGBft_vbBbOaQOmpEUE4xDLeRSU");
Assert.assertTrue(massId[0] != null);
}
@ -92,8 +87,7 @@ public class MassTest extends TokenTest {
@Test
public void previewMass() throws WeixinException {
ApiResult result = massApi.previewMassNews(
"oyFLst1bqtuTcxK-ojF8hOGtLQao", null, new Text("test"));
ApiResult result = massApi.previewMassNews("oyFLst1bqtuTcxK-ojF8hOGtLQao", null, new Text("test"));
Assert.assertEquals("0", result.getReturnCode());
}

View File

@ -58,7 +58,7 @@ public class MenuApi extends QyApi {
@Override
public String process(Object object, String name, Object value) {
if (object instanceof Button && name.equals("content")) {
ButtonType buttonType = ((Button) object).getType();
ButtonType buttonType = ButtonType.valueOf(((Button) object).getType());
if (buttonType != null) {
if (ButtonType.view == buttonType) {
return "url";