Implement template management and template message sending for WXA.

This commit is contained in:
Sutra Zhou 2018-05-26 17:55:32 +08:00
parent 23d591fc0a
commit 1241072a1b
21 changed files with 874 additions and 2 deletions

View File

@ -9,6 +9,8 @@ import com.foxinmy.weixin4j.token.TokenCreator;
import com.foxinmy.weixin4j.token.TokenManager;
import com.foxinmy.weixin4j.wxa.api.LoginApi;
import com.foxinmy.weixin4j.wxa.api.QrCodeApi;
import com.foxinmy.weixin4j.wxa.api.TemplateApi;
import com.foxinmy.weixin4j.wxa.api.TemplateMessageApi;
/**
* @since 1.8
@ -17,6 +19,8 @@ public class WeixinProxy {
private final LoginApi loginApi;
private final QrCodeApi qrCodeApi;
private final TemplateApi templateApi;
private final TemplateMessageApi templateMessageApi;
public WeixinProxy(
WeixinAccount weixinAccount
@ -62,6 +66,8 @@ public class WeixinProxy {
this.loginApi = new LoginApi(weixinAccount);
this.qrCodeApi = new QrCodeApi(tokenManager);
this.templateApi = new TemplateApi(tokenManager);
this.templateMessageApi = new TemplateMessageApi(tokenManager);
}
public LoginApi getLoginApi() {
@ -72,4 +78,12 @@ public class WeixinProxy {
return qrCodeApi;
}
public TemplateApi getTemplateApi() {
return templateApi;
}
public TemplateMessageApi getTemplateMessageApi() {
return templateMessageApi;
}
}

View File

@ -0,0 +1,39 @@
package com.foxinmy.weixin4j.wxa.api;
import java.io.Serializable;
import com.alibaba.fastjson.annotation.JSONField;
class AddTemplateParameter implements Serializable {
private static final long serialVersionUID = 2018052601L;
private String id;
private int[] keywordIds;
public AddTemplateParameter() {
}
public AddTemplateParameter(String id, int[] keywordIds) {
this.id = id;
this.keywordIds = keywordIds;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
@JSONField(name = "keyword_id_list")
public int[] getKeywordIds() {
return keywordIds;
}
public void setKeywordIds(int[] keywordIds) {
this.keywordIds = keywordIds;
}
}

View File

@ -0,0 +1,30 @@
package com.foxinmy.weixin4j.wxa.api;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.foxinmy.weixin4j.exception.WeixinException;
import com.foxinmy.weixin4j.http.weixin.WeixinResponse;
import com.foxinmy.weixin4j.token.TokenManager;
abstract class NoticeApi extends WxaApi {
private final TokenManager tokenManager;
public NoticeApi(final TokenManager tokenManager) {
this.tokenManager = tokenManager;
}
<T> T post(String key, Object params, TypeReference<T> typeReference) throws WeixinException {
final String uri = this.getAccessTokenRequestUri(key);
final String body = JSON.toJSONString(params);
final WeixinResponse response = this.weixinExecutor.post(uri, body);
return response.getAsObject(typeReference);
}
String getAccessTokenRequestUri(String key) throws WeixinException {
final String accessToken = tokenManager.getAccessToken();
final String uri = this.getRequestUri(key, accessToken);
return uri;
}
}

View File

@ -0,0 +1,122 @@
package com.foxinmy.weixin4j.wxa.api;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.foxinmy.weixin4j.exception.WeixinException;
import com.foxinmy.weixin4j.model.paging.Pageable;
import com.foxinmy.weixin4j.model.paging.Pagedata;
import com.foxinmy.weixin4j.token.TokenManager;
import com.foxinmy.weixin4j.wxa.model.template.Template;
/**
* 模版消息管理
*
* @see <a href="https://developers.weixin.qq.com/miniprogram/dev/api/notice.html#%E6%A8%A1%E7%89%88%E6%B6%88%E6%81%AF%E7%AE%A1%E7%90%86">模版消息管理</a>
* @since 1.8
*/
public class TemplateApi extends NoticeApi {
public TemplateApi(TokenManager tokenManager) {
super(tokenManager);
}
/**
* 获取小程序模板库标题列表
*
* @param pageable the pagination information.
* @return templates in library.
* @throws WeixinException indicates getting access token failed or getting templates failed.
* @see <a href="https://developers.weixin.qq.com/miniprogram/dev/api/notice.html#1%E8%8E%B7%E5%8F%96%E5%B0%8F%E7%A8%8B%E5%BA%8F%E6%A8%A1%E6%9D%BF%E5%BA%93%E6%A0%87%E9%A2%98%E5%88%97%E8%A1%A8">获取小程序模板库标题列表</a>
*/
public Pagedata<Template> getTemplatesInLibrary(final Pageable pageable) throws WeixinException {
final TemplateListResult r = post(
"wxopen_template_library_list",
toPageableRequestParams(pageable),
TemplateListResult.TYPE_REFERENCE
);
return r.toPage(pageable);
}
/**
* 获取模板库某个模板标题下关键词库
*
* @param id 模板标题id可通过接口获取也可登录小程序后台查看获取
* @return the template in library with specified ID.
* @throws WeixinException indicates getting access token failed or getting template failed.
* @see <a href="https://developers.weixin.qq.com/miniprogram/dev/api/notice.html#2%E8%8E%B7%E5%8F%96%E6%A8%A1%E6%9D%BF%E5%BA%93%E6%9F%90%E4%B8%AA%E6%A8%A1%E6%9D%BF%E6%A0%87%E9%A2%98%E4%B8%8B%E5%85%B3%E9%94%AE%E8%AF%8D%E5%BA%93">获取模板库某个模板标题下关键词库</a>
*/
public Template getTemplateInLibrary(String id) throws WeixinException {
final Map<String, String> params = new HashMap<String, String>(1);
params.put("id", id);
final TemplateResult r = this.post(
"wxopen_template_library_get",
params,
TemplateResult.TYPE_REFERENCE
);
return r.toTemplate();
}
/**
* 组合模板并添加至帐号下的个人模板库
*
* @param id 模板标题id可通过接口获取也可登录小程序后台查看获取
* @param keywordIds 开发者自行组合好的模板关键词列表关键词顺序可以自由搭配例如[3,5,4][4,5,3]最多支持10个关键词组合
* @return the added template ID.
* @throws WeixinException indicates getting access token failed or adding template failed.
* @see <a href="https://developers.weixin.qq.com/miniprogram/dev/api/notice.html#3%E7%BB%84%E5%90%88%E6%A8%A1%E6%9D%BF%E5%B9%B6%E6%B7%BB%E5%8A%A0%E8%87%B3%E5%B8%90%E5%8F%B7%E4%B8%8B%E7%9A%84%E4%B8%AA%E4%BA%BA%E6%A8%A1%E6%9D%BF%E5%BA%93">组合模板并添加至帐号下的个人模板库</a>
*/
public String addTemplate(String id, int[] keywordIds) throws WeixinException {
final AddTemplateParameter params = new AddTemplateParameter(id, keywordIds);
final TemplateResult r = this.post(
"wxopen_template_add",
params,
TemplateResult.TYPE_REFERENCE
);
return r.toTemplate().getId();
}
/**
* 获取帐号下已存在的模板列表
*
* @param pageable the pagination information.
* @return the templates.
* @throws WeixinException indicates getting access token failed or getting template failed.
* @see <a href="https://developers.weixin.qq.com/miniprogram/dev/api/notice.html#4%E8%8E%B7%E5%8F%96%E5%B8%90%E5%8F%B7%E4%B8%8B%E5%B7%B2%E5%AD%98%E5%9C%A8%E7%9A%84%E6%A8%A1%E6%9D%BF%E5%88%97%E8%A1%A8">获取帐号下已存在的模板列表</a>
*/
public List<Template> getTemplates(final Pageable pageable) throws WeixinException {
final TemplateListResult r = post(
"wxopen_template_list",
toPageableRequestParams(pageable),
TemplateListResult.TYPE_REFERENCE
);
return r.toList();
}
/**
* 删除帐号下的某个模板
*
* @param id 要删除的模板id
* @throws WeixinException indicates getting access token failed or deleting template failed.
* @see <a href="https://developers.weixin.qq.com/miniprogram/dev/api/notice.html#5%E5%88%A0%E9%99%A4%E5%B8%90%E5%8F%B7%E4%B8%8B%E7%9A%84%E6%9F%90%E4%B8%AA%E6%A8%A1%E6%9D%BF">删除帐号下的某个模板</a>
*/
public void deleteTemplate(String id) throws WeixinException {
final Map<String, String> params = new HashMap<String, String>(1);
params.put("template_id", id);
final WxaApiResult r = this.post(
"wxopen_template_del",
params,
WxaApiResult.TYPE_REFERENCE
);
r.checkErrCode();
}
private Map<String, Integer> toPageableRequestParams(final Pageable pageable) {
final Map<String, Integer> params = new HashMap<String, Integer>(2);
params.put("offset", pageable.getOffset());
params.put("count", pageable.getPageSize());
return params;
}
}

View File

@ -0,0 +1,55 @@
package com.foxinmy.weixin4j.wxa.api;
import java.util.List;
import com.alibaba.fastjson.TypeReference;
import com.foxinmy.weixin4j.exception.WeixinException;
import com.foxinmy.weixin4j.model.paging.Pageable;
import com.foxinmy.weixin4j.model.paging.Pagedata;
import com.foxinmy.weixin4j.wxa.model.template.Template;
class TemplateListResult extends WxaApiResult {
private static final long serialVersionUID = 2018052602L;
public static final TypeReference<TemplateListResult> TYPE_REFERENCE
= new TypeReference<TemplateListResult>() {
};
private List<Template> list;
private Long totalCount;
public List<Template> getList() {
return list;
}
public void setList(List<Template> list) {
this.list = list;
}
public Long getTotalCount() {
return totalCount;
}
public void setTotalCount(Long totalCount) {
this.totalCount = totalCount;
}
public Pagedata<Template> toPage(Pageable pageable) throws WeixinException {
this.checkErrCode();
final Pagedata<Template> page = new Pagedata<Template>(
pageable,
this.getTotalCount().intValue(),
this.getList()
);
return page;
}
public List<Template> toList() throws WeixinException {
this.checkErrCode();
return this.getList();
}
}

View File

@ -0,0 +1,51 @@
package com.foxinmy.weixin4j.wxa.api;
import java.util.Map;
import com.foxinmy.weixin4j.exception.WeixinException;
import com.foxinmy.weixin4j.token.TokenManager;
/**
* 发送模版消息
*
* @see <a href="https://developers.weixin.qq.com/miniprogram/dev/api/notice.html#%E5%8F%91%E9%80%81%E6%A8%A1%E7%89%88%E6%B6%88%E6%81%AF">发送模版消息</a>
* @since 1.8
*/
public class TemplateMessageApi extends NoticeApi {
public TemplateMessageApi(TokenManager tokenManager) {
super(tokenManager);
}
/**
* 发送模板消息
*
* @param toUser 接收者用户 openid
* @param templateId 所需下发的模板消息的 id
* @param page 点击模板卡片后的跳转页面仅限本小程序内的页面支持带参数,示例index?foo=bar该字段不填则模板无跳转
* @param formId 表单提交场景下 submit 事件带上的 formId支付场景下为本次支付的 prepay_id
* @param data 模板内容不填则下发空模板
* @param emphasisKeyword 模板需要放大的关键词不填则默认无放大
* @throws WeixinException indicates getting access token failed, or sending template message failed.
* @see <a href="https://developers.weixin.qq.com/miniprogram/dev/api/notice.html#%E5%8F%91%E9%80%81%E6%A8%A1%E7%89%88%E6%B6%88%E6%81%AF">发送模版消息</a>
*/
public void sendTemplateMessage(
final String toUser,
final String templateId,
final String page,
final String formId,
final Map<String, String> data,
final String emphasisKeyword
) throws WeixinException {
final TemplateMessageParameter message = new TemplateMessageParameter(
toUser, templateId, page, formId, data, emphasisKeyword
);
final WxaApiResult r = this.post(
"wxopen_template_message_send",
message,
WxaApiResult.TYPE_REFERENCE
);
r.checkErrCode();
}
}

View File

@ -0,0 +1,116 @@
package com.foxinmy.weixin4j.wxa.api;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import com.alibaba.fastjson.annotation.JSONField;
class TemplateMessageParameter implements Serializable {
private static final long serialVersionUID = 2018052601L;
private String toUser;
private String templateId;
private String page;
private String formId;
private Map<String, TemplateMessageData> data;
private String emphasisKeyword;
public TemplateMessageParameter() {
}
public TemplateMessageParameter(
String toUser,
String templateId,
String page,
String formId,
Map<String, String> data,
String emphasisKeyword
) {
this.toUser = toUser;
this.templateId = templateId;
this.page = page;
this.formId = formId;
if (data != null) {
this.data = new HashMap<String, TemplateMessageData>(data.size());
for (Map.Entry<String, String> entry : data.entrySet()) {
this.data.put(entry.getKey(), new TemplateMessageData(entry.getValue()));
}
}
this.emphasisKeyword = emphasisKeyword;
}
@JSONField(name = "touser")
public String getToUser() {
return toUser;
}
public void setToUser(String toUser) {
this.toUser = toUser;
}
@JSONField(name = "template_id")
public String getTemplateId() {
return templateId;
}
public void setTemplateId(String templateId) {
this.templateId = templateId;
}
public String getPage() {
return page;
}
public void setPage(String page) {
this.page = page;
}
@JSONField(name = "form_id")
public String getFormId() {
return formId;
}
public void setFormId(String formId) {
this.formId = formId;
}
public Map<String, TemplateMessageData> getData() {
return data;
}
public void setData(Map<String, TemplateMessageData> data) {
this.data = data;
}
@JSONField(name = "emphasis_keyword")
public String getEmphasisKeyword() {
return emphasisKeyword;
}
public void setEmphasisKeyword(String emphasisKeyword) {
this.emphasisKeyword = emphasisKeyword;
}
public static class TemplateMessageData implements Serializable {
private static final long serialVersionUID = 2018052601L;
private String value;
public TemplateMessageData(String value) {
this.value = value;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
}

View File

@ -0,0 +1,54 @@
package com.foxinmy.weixin4j.wxa.api;
import java.util.List;
import com.alibaba.fastjson.TypeReference;
import com.alibaba.fastjson.annotation.JSONField;
import com.foxinmy.weixin4j.exception.WeixinException;
import com.foxinmy.weixin4j.wxa.model.template.Keyword;
import com.foxinmy.weixin4j.wxa.model.template.Template;
class TemplateResult extends WxaApiResult {
private static final long serialVersionUID = 2018052601L;
public static final TypeReference<TemplateResult> TYPE_REFERENCE
= new TypeReference<TemplateResult>() {
};
private String id;
private String title;
private List<Keyword> keywords;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public List<Keyword> getKeywords() {
return keywords;
}
@JSONField(name = "keyword_list")
public void setKeywords(List<Keyword> keywords) {
this.keywords = keywords;
}
public Template toTemplate() throws WeixinException {
this.checkErrCode();
return new Template(id, title, keywords);
}
}

View File

@ -7,7 +7,7 @@ import com.foxinmy.weixin4j.api.BaseApi;
/**
* @since 1.8
*/
public abstract class WxaApi extends BaseApi {
abstract class WxaApi extends BaseApi {
private static final ResourceBundle WEIXIN_BUNDLE;
@ -15,12 +15,13 @@ public abstract class WxaApi extends BaseApi {
WEIXIN_BUNDLE = ResourceBundle
.getBundle("com/foxinmy/weixin4j/wxa/api/weixin");
}
@Override
protected ResourceBundle weixinBundle() {
return WEIXIN_BUNDLE;
}
protected String getRequestUri(String key, Object... args) {
String getRequestUri(String key, Object... args) {
return String.format(getRequestUri(key), args);
}

View File

@ -0,0 +1,48 @@
package com.foxinmy.weixin4j.wxa.api;
import java.io.Serializable;
import com.alibaba.fastjson.TypeReference;
import com.foxinmy.weixin4j.exception.WeixinException;
class WxaApiResult implements Serializable {
private static final long serialVersionUID = 2018052601L;
public static final TypeReference<WxaApiResult> TYPE_REFERENCE
= new TypeReference<WxaApiResult>() {
};
private int errCode;
private String errMsg;
public WxaApiResult() {
}
public int getErrCode() {
return errCode;
}
public void setErrCode(int errCode) {
this.errCode = errCode;
}
public String getErrMsg() {
return errMsg;
}
public void setErrMsg(String errMsg) {
this.errMsg = errMsg;
}
public WeixinException toWeixinException() {
return new WeixinException(Integer.toString(errCode), errMsg);
}
public void checkErrCode() throws WeixinException {
if (getErrCode() != 0) {
throw this.toWeixinException();
}
}
}

View File

@ -0,0 +1,40 @@
package com.foxinmy.weixin4j.wxa.model.template;
import java.io.Serializable;
import com.alibaba.fastjson.annotation.JSONField;
public class Keyword implements Serializable {
private static final long serialVersionUID = 2018052601L;
private int id;
private String name;
private String example;
public int getId() {
return id;
}
@JSONField(name = "keyword_id")
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getExample() {
return example;
}
public void setExample(String example) {
this.example = example;
}
}

View File

@ -0,0 +1,68 @@
package com.foxinmy.weixin4j.wxa.model.template;
import java.io.Serializable;
import java.util.List;
import com.alibaba.fastjson.annotation.JSONField;
public class Template implements Serializable {
private static final long serialVersionUID = 2018052601L;
private String id;
private String title;
private List<Keyword> keywords;
private String content;
private String example;
public Template() {
}
public Template(String id, String title, List<Keyword> keywords) {
this.id = id;
this.title = title;
this.keywords = keywords;
}
public String getId() {
return id;
}
@JSONField(name = "id", alternateNames = { "template_id" })
public void setId(String id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public List<Keyword> getKeywords() {
return keywords;
}
public void setKeywords(List<Keyword> keywords) {
this.keywords = keywords;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getExample() {
return example;
}
public void setExample(String example) {
this.example = example;
}
}

View File

@ -0,0 +1,4 @@
/**
* Models for {@link com.foxinmy.weixin4j.wxa.api.TemplateApi}.
*/
package com.foxinmy.weixin4j.wxa.model.template;

View File

@ -3,10 +3,12 @@
# ----------------------------------------------------------------------------
api_base_url=https://api.weixin.qq.com
api_cgi_url={api_base_url}/cgi-bin
# \u767b\u5f55\u51ed\u8bc1\u6821\u9a8c
sns_jscode2session={api_base_url}/sns/jscode2session?appid=%s&secret=%s&js_code=%s&grant_type=%s
# \u83b7\u53d6\u5c0f\u7a0b\u5e8f\u7801 \u63a5\u53e3A: \u9002\u7528\u4e8e\u9700\u8981\u7684\u7801\u6570\u91cf\u8f83\u5c11\u7684\u4e1a\u52a1\u573a\u666f
wxa_getwxacode={api_base_url}/wxa/getwxacode?access_token=%s
@ -15,3 +17,22 @@ wxa_getwxacodeunlimit={api_base_url}/wxa/getwxacodeunlimit?access_token=%s
# \u83b7\u53d6\u5c0f\u7a0b\u5e8f\u4e8c\u7ef4\u7801 \u63a5\u53e3C\uff1a\u9002\u7528\u4e8e\u9700\u8981\u7684\u7801\u6570\u91cf\u8f83\u5c11\u7684\u4e1a\u52a1\u573a\u666f
wxaapp_createwxaqrcode={api_base_url}/cgi-bin/wxaapp/createwxaqrcode?access_token=%s
# \u83b7\u53d6\u5c0f\u7a0b\u5e8f\u6a21\u677f\u5e93\u6807\u9898\u5217\u8868
wxopen_template_library_list={api_cgi_url}/wxopen/template/library/list?access_token=%s
# \u83b7\u53d6\u6a21\u677f\u5e93\u67d0\u4e2a\u6a21\u677f\u6807\u9898\u4e0b\u5173\u952e\u8bcd\u5e93
wxopen_template_library_get={api_cgi_url}/wxopen/template/library/get?access_token=%s
# \u7ec4\u5408\u6a21\u677f\u5e76\u6dfb\u52a0\u81f3\u5e10\u53f7\u4e0b\u7684\u4e2a\u4eba\u6a21\u677f\u5e93
wxopen_template_add={api_cgi_url}/wxopen/template/add?access_token=%s
# \u83b7\u53d6\u5e10\u53f7\u4e0b\u5df2\u5b58\u5728\u7684\u6a21\u677f\u5217\u8868
wxopen_template_list={api_cgi_url}/wxopen/template/list?access_token=%s
# \u5220\u9664\u5e10\u53f7\u4e0b\u7684\u67d0\u4e2a\u6a21\u677f
wxopen_template_del={api_cgi_url}/wxopen/template/del?access_token=%s
# \u53d1\u9001\u6a21\u7248\u6d88\u606f
wxopen_template_message_send={api_cgi_url}/message/wxopen/template/send?access_token=%s

View File

@ -0,0 +1,18 @@
package com.foxinmy.weixin4j.wxa.api;
import static org.junit.Assert.assertEquals;
import org.junit.Test;
import com.alibaba.fastjson.JSON;
public class AddTemplateParameterTest {
@Test
public void test() {
AddTemplateParameter param = new AddTemplateParameter("AT0002", new int[] { 3, 4, 5 });
String json = JSON.toJSONString(param);
assertEquals("{\"id\":\"AT0002\",\"keyword_id_list\":[3,4,5]}", json);
}
}

View File

@ -0,0 +1,52 @@
package com.foxinmy.weixin4j.wxa.api;
import static org.junit.Assert.assertEquals;
import java.io.IOException;
import java.io.InputStream;
import org.junit.Test;
import com.alibaba.fastjson.JSON;
import com.foxinmy.weixin4j.util.IOUtil;
public class TemplateListResultTest {
@Test
public void testTemplatesInLibrary() throws IOException {
TemplateListResult r = readTemplateList("TemplateListInLibrary.json");
assertEquals(0, r.getErrCode());
assertEquals("ok", r.getErrMsg());
assertEquals(599, r.getTotalCount().longValue());
assertEquals(5, r.getList().size());
assertEquals("AT0002", r.getList().get(0).getId());
assertEquals("购买成功通知", r.getList().get(0).getTitle());
assertEquals("AT0003", r.getList().get(1).getId());
assertEquals("购买失败通知", r.getList().get(1).getTitle());
}
@Test
public void testMyTemplates() throws IOException {
TemplateListResult r = readTemplateList("TemplateList.json");
assertEquals(0, r.getErrCode());
assertEquals("ok", r.getErrMsg());
assertEquals("wDYzYZVxobJivW9oMpSCpuvACOfJXQIoKUm0PY397Tc", r.getList().get(0).getId());
assertEquals("购买成功通知", r.getList().get(0).getTitle());
assertEquals("购买地点{{keyword1.DATA}}\n购买时间{{keyword2.DATA}}\n物品名称{{keyword3.DATA}}\n", r.getList().get(0).getContent());
assertEquals("购买地点TIT造舰厂\n购买时间2016年6月6日\n物品名称咖啡\n", r.getList().get(0).getExample());
}
private TemplateListResult readTemplateList(String resourceName) throws IOException {
InputStream inputStream = getClass().getResourceAsStream(resourceName);
try {
TemplateListResult tl = JSON.parseObject(inputStream, TemplateListResult.class);
return tl;
} finally {
IOUtil.close(inputStream);
}
}
}

View File

@ -0,0 +1,39 @@
package com.foxinmy.weixin4j.wxa.api;
import static org.junit.Assert.assertTrue;
import java.util.LinkedHashMap;
import java.util.Map;
import org.junit.Test;
import com.alibaba.fastjson.JSON;
import com.foxinmy.weixin4j.wxa.api.TemplateMessageParameter.TemplateMessageData;
public class TemplateMessageParameterTest {
@Test
public void test() {
TemplateMessageParameter param = new TemplateMessageParameter();
param.setToUser("OPENID");
param.setTemplateId("TEMPLATE_ID");
param.setPage("index");
param.setFormId("FORMID");
Map<String, TemplateMessageData> data = new LinkedHashMap<String, TemplateMessageData>();
data.put("keyword1", new TemplateMessageData("339208499"));
data.put("keyword2", new TemplateMessageData("2015年01月05日 12:30"));
data.put("keyword3", new TemplateMessageData("粤海喜来登酒店"));
data.put("keyword4", new TemplateMessageData("广州市天河区天河路208号"));
param.setData(data);
param.setEmphasisKeyword("keyword1.DATA");
String json = JSON.toJSONString(param);
System.out.println(json);
assertTrue(json.contains("\"touser\":"));
assertTrue(json.contains("\"template_id\":"));
assertTrue(json.contains("\"page\":"));
assertTrue(json.contains("\"form_id\":"));
assertTrue(json.contains("\"data\":{\"keyword1\":{\"value\":\"339208499\"},\"keyword2\":{\"value\":\"2015年01月05日 12:30\"},\"keyword3\":{\"value\":\"粤海喜来登酒店\"},\"keyword4\":{\"value\":\"广州市天河区天河路208号\"}}"));
assertTrue(json.contains("\"emphasis_keyword\":"));
}
}

View File

@ -0,0 +1,38 @@
package com.foxinmy.weixin4j.wxa.api;
import static org.junit.Assert.assertEquals;
import java.io.IOException;
import java.io.InputStream;
import org.junit.Test;
import com.alibaba.fastjson.JSON;
import com.foxinmy.weixin4j.util.IOUtil;
public class TemplateResultTest {
@Test
public void test() throws IOException {
TemplateResult t = readTemplate();
assertEquals(0, t.getErrCode());
assertEquals("ok", t.getErrMsg());
assertEquals("AT0002", t.getId());
assertEquals("购买成功通知", t.getTitle());
assertEquals(3, t.getKeywords().size());
assertEquals(3, t.getKeywords().get(0).getId());
assertEquals("购买地点", t.getKeywords().get(0).getName());
assertEquals("TIT造舰厂", t.getKeywords().get(0).getExample());
}
private TemplateResult readTemplate() throws IOException {
InputStream inputStream = getClass().getResourceAsStream("Template.json");
try {
TemplateResult t = JSON.parseObject(inputStream, TemplateResult.class);
return t;
} finally {
IOUtil.close(inputStream);
}
}
}

View File

@ -0,0 +1,23 @@
{
"errcode": 0,
"errmsg": "ok",
"id": "AT0002",
"title": "购买成功通知",
"keyword_list": [
{
"keyword_id": 3,
"name": "购买地点",
"example": "TIT造舰厂"
},
{
"keyword_id": 4,
"name": "购买时间",
"example": "2016年6月6日"
},
{
"keyword_id": 5,
"name": "物品名称",
"example": "咖啡"
}
]
}

View File

@ -0,0 +1,12 @@
{
"errcode": 0,
"errmsg": "ok",
"list": [
{
"template_id": "wDYzYZVxobJivW9oMpSCpuvACOfJXQIoKUm0PY397Tc",
"title": "购买成功通知",
"content": "购买地点{{keyword1.DATA}}\n购买时间{{keyword2.DATA}}\n物品名称{{keyword3.DATA}}\n",
"example": "购买地点TIT造舰厂\n购买时间2016年6月6日\n物品名称咖啡\n"
}
]
}

View File

@ -0,0 +1,27 @@
{
"errcode": 0,
"errmsg": "ok",
"list": [
{
"id": "AT0002",
"title": "购买成功通知"
},
{
"id": "AT0003",
"title": "购买失败通知"
},
{
"id": "AT0004",
"title": "交易提醒"
},
{
"id": "AT0005",
"title": "付款成功通知"
},
{
"id": "AT0006",
"title": "付款失败通知"
}
],
"total_count": 599
}