@@ -25,7 +25,7 @@ public class Utf8ResponseHandler implements ResponseHandler<String> { | |||||
final HttpEntity entity = response.getEntity(); | final HttpEntity entity = response.getEntity(); | ||||
if (statusLine.getStatusCode() >= 300) { | if (statusLine.getStatusCode() >= 300) { | ||||
EntityUtils.consume(entity); | EntityUtils.consume(entity); | ||||
throw new HttpResponseException(statusLine.getStatusCode(), statusLine.getReasonPhrase()); | |||||
throw new HttpResponseException(statusLine.getStatusCode(), statusLine.toString()); | |||||
} | } | ||||
return entity == null ? null : EntityUtils.toString(entity, Consts.UTF_8); | return entity == null ? null : EntityUtils.toString(entity, Consts.UTF_8); | ||||
} | } | ||||
@@ -33,16 +33,23 @@ public interface WxMaMsgService { | |||||
* 发送模板消息 | * 发送模板消息 | ||||
* 详情请见: <a href="https://developers.weixin.qq.com/miniprogram/dev/api-backend/templateMessage.send.html">发送模板消息</a> | * 详情请见: <a href="https://developers.weixin.qq.com/miniprogram/dev/api-backend/templateMessage.send.html">发送模板消息</a> | ||||
* 接口url格式:https://api.weixin.qq.com/cgi-bin/message/wxopen/template/send?access_token=ACCESS_TOKEN | * 接口url格式:https://api.weixin.qq.com/cgi-bin/message/wxopen/template/send?access_token=ACCESS_TOKEN | ||||
* 小程序模板消息接口将于2020年1月10日下线,开发者可使用订阅消息功能 | |||||
* </pre> | * </pre> | ||||
* | |||||
* @param templateMessage 模版消息 | |||||
* @throws WxErrorException . | |||||
*/ | */ | ||||
@Deprecated | |||||
void sendTemplateMsg(WxMaTemplateMessage templateMessage) throws WxErrorException; | void sendTemplateMsg(WxMaTemplateMessage templateMessage) throws WxErrorException; | ||||
/** | /** | ||||
* <pre> | * <pre> | ||||
* 发送订阅消息 | |||||
* https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/subscribe-message/subscribeMessage.send.html | * https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/subscribe-message/subscribeMessage.send.html | ||||
* </pre> | * </pre> | ||||
* 发送订阅消息 | |||||
* | |||||
* @param subscribeMessage 订阅消息 | |||||
* @throws WxErrorException . | |||||
*/ | */ | ||||
void sendSubscribeMsg(WxMaSubscribeMessage subscribeMessage) throws WxErrorException; | void sendSubscribeMsg(WxMaSubscribeMessage subscribeMessage) throws WxErrorException; | ||||
@@ -158,6 +158,13 @@ public interface WxMaService { | |||||
*/ | */ | ||||
WxMaTemplateService getTemplateService(); | WxMaTemplateService getTemplateService(); | ||||
/** | |||||
* 返回订阅消息配置相关接口方法的实现类对象, 以方便调用其各个接口. | |||||
* | |||||
* @return WxMaSubscribeService | |||||
*/ | |||||
WxMaSubscribeService getSubscribeService(); | |||||
/** | /** | ||||
* 数据分析相关查询服务. | * 数据分析相关查询服务. | ||||
* | * | ||||
@@ -226,6 +233,7 @@ public interface WxMaService { | |||||
/** | /** | ||||
* 获取物流助手接口服务对象 | * 获取物流助手接口服务对象 | ||||
* | |||||
* @return | * @return | ||||
*/ | */ | ||||
WxMaExpressService getExpressService(); | WxMaExpressService getExpressService(); | ||||
@@ -0,0 +1,153 @@ | |||||
package cn.binarywang.wx.miniapp.api; | |||||
import cn.binarywang.wx.miniapp.bean.template.WxMaTemplateLibraryListResult; | |||||
import lombok.Data; | |||||
import me.chanjar.weixin.common.error.WxErrorException; | |||||
import java.util.List; | |||||
/** | |||||
* 订阅消息类 | |||||
* | |||||
* @author <a href="https://github.com/binarywang">Binary Wang</a> | |||||
* @date 2019-12-15 | |||||
*/ | |||||
public interface WxMaSubscribeService { | |||||
/** | |||||
* 获取模板标题下的关键词列表. | |||||
*/ | |||||
String GET_PUB_TEMPLATE_TITLE_LIST_URL = "https://api.weixin.qq.com/wxaapi/newtmpl/getpubtemplatetitles"; | |||||
/** | |||||
* 获取模板标题下的关键词列表. | |||||
*/ | |||||
String GET_PUB_TEMPLATE_KEY_WORDS_BY_ID_URL = "https://api.weixin.qq.com/wxaapi/newtmpl/getpubtemplatekeywords"; | |||||
/** | |||||
* 组合模板并添加至帐号下的个人模板库. | |||||
*/ | |||||
String TEMPLATE_ADD_URL = "https://api.weixin.qq.com/wxaapi/newtmpl/addtemplate"; | |||||
/** | |||||
* 获取当前帐号下的个人模板列表. | |||||
*/ | |||||
String TEMPLATE_LIST_URL = "https://api.weixin.qq.com/wxaapi/newtmpl/gettemplate"; | |||||
/** | |||||
* 删除帐号下的某个模板. | |||||
*/ | |||||
String TEMPLATE_DEL_URL = "https://api.weixin.qq.com/wxaapi/newtmpl/deltemplate"; | |||||
/** | |||||
* 获取小程序账号的类目 | |||||
*/ | |||||
String GET_CATEGORY_URL = "https://api.weixin.qq.com/wxaapi/newtmpl/getcategory"; | |||||
/** | |||||
* <pre> | |||||
* 获取帐号所属类目下的公共模板标题 | |||||
* | |||||
* 详情请见: <a href="https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/subscribe-message/subscribeMessage.getPubTemplateTitleList.html">获取帐号所属类目下的公共模板标题</a> | |||||
* 接口url格式: https://api.weixin.qq.com/wxaapi/newtmpl/getpubtemplatetitles?access_token=ACCESS_TOKEN | |||||
* </pre> | |||||
* | |||||
* @param ids 类目 id,多个用逗号隔开 | |||||
* @param limit 用于分页,表示拉取 limit 条记录。最大为 30。 | |||||
* @param start 用于分页,表示从 start 开始。从 0 开始计数。 | |||||
* @return . | |||||
* @throws WxErrorException . | |||||
*/ | |||||
WxMaTemplateLibraryListResult getPubTemplateTitleList(Integer[] ids, int start, int limit) throws WxErrorException; | |||||
/** | |||||
* <pre> | |||||
* 获取模板库某个模板标题下关键词库 | |||||
* | |||||
* 详情请见: <a href="https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/subscribe-message/subscribeMessage.getPubTemplateKeyWordsById.html">获取模板标题下的关键词列表</a> | |||||
* 接口url格式: GET https://api.weixin.qq.com/wxaapi/newtmpl/getpubtemplatekeywords?access_token=ACCESS_TOKEN | |||||
* </pre> | |||||
* | |||||
* @param id 模板标题 id,可通过接口获取 | |||||
* @return . | |||||
* @throws WxErrorException . | |||||
*/ | |||||
List<PubTemplateKeyword> getPubTemplateKeyWordsById(String id) throws WxErrorException; | |||||
/** | |||||
* <pre> | |||||
* 组合模板并添加至帐号下的个人模板库 | |||||
* | |||||
* 详情请见: <a href="https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/subscribe-message/subscribeMessage.addTemplate.html">获取小程序模板库标题列表</a> | |||||
* 接口url格式: POST https://api.weixin.qq.com/wxaapi/newtmpl/addtemplate?access_token=ACCESS_TOKEN | |||||
* </pre> | |||||
* | |||||
* @param id 模板标题 id,可通过接口获取,也可登录小程序后台查看获取 | |||||
* @param keywordIdList 模板关键词列表 | |||||
* @param sceneDesc 服务场景描述,15个字以内 | |||||
* @return 添加至帐号下的模板id,发送小程序订阅消息时所需 | |||||
* @throws WxErrorException . | |||||
*/ | |||||
String addTemplate(String id, List<Integer> keywordIdList, String sceneDesc) throws WxErrorException; | |||||
/** | |||||
* <pre> | |||||
* 获取当前帐号下的个人模板列表 | |||||
* | |||||
* 详情请见: <a href="https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/subscribe-message/subscribeMessage.getTemplateList.html">获取当前帐号下的个人模板列表</a> | |||||
* 接口url格式: GET https://api.weixin.qq.com/wxaapi/newtmpl/gettemplate?access_token=ACCESS_TOKEN | |||||
* </pre> | |||||
* | |||||
* @return . | |||||
* @throws WxErrorException . | |||||
*/ | |||||
List<TemplateInfo> getTemplateList() throws WxErrorException; | |||||
/** | |||||
* <pre> | |||||
* 删除帐号下的某个模板 | |||||
* | |||||
* 详情请见: <a href="https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/subscribe-message/subscribeMessage.deleteTemplate.html">删除帐号下的个人模板</a> | |||||
* 接口url格式: POST https://api.weixin.qq.com/wxaapi/newtmpl/deltemplate?access_token=ACCESS_TOKEN | |||||
* </pre> | |||||
* | |||||
* @param templateId 要删除的模板id | |||||
* @return 删除是否成功 | |||||
* @throws WxErrorException . | |||||
*/ | |||||
boolean delTemplate(String templateId) throws WxErrorException; | |||||
/** | |||||
* <pre> | |||||
* 获取小程序账号的类目 | |||||
* https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/subscribe-message/subscribeMessage.getCategory.html | |||||
* GET https://api.weixin.qq.com/wxaapi/newtmpl/getcategory?access_token=ACCESS_TOKEN | |||||
* </pre> | |||||
* | |||||
* @return . | |||||
* @throws WxErrorException . | |||||
*/ | |||||
List<CategoryData> getCategory() throws WxErrorException; | |||||
@Data | |||||
class CategoryData { | |||||
int id; | |||||
String name; | |||||
} | |||||
@Data | |||||
class TemplateInfo { | |||||
private String priTmplId; | |||||
private String title; | |||||
private String content; | |||||
private String example; | |||||
private int type; | |||||
} | |||||
@Data | |||||
class PubTemplateKeyword{ | |||||
private int kid; | |||||
private String name; | |||||
private String example; | |||||
private String rule; | |||||
} | |||||
} |
@@ -8,6 +8,10 @@ import me.chanjar.weixin.common.error.WxErrorException; | |||||
import java.util.List; | import java.util.List; | ||||
/** | |||||
* @author IOMan(lewis.lynn1006@gmail.com) | |||||
*/ | |||||
@Deprecated | |||||
public interface WxMaTemplateService { | public interface WxMaTemplateService { | ||||
/** | /** | ||||
* 获取小程序模板库标题列表. | * 获取小程序模板库标题列表. | ||||
@@ -28,11 +28,6 @@ public class WxMaMsgServiceImpl implements WxMaMsgService { | |||||
return responseContent != null; | return responseContent != null; | ||||
} | } | ||||
/** | |||||
* <pre> | |||||
* 小程序模板消息接口将于2020年1月10日下线,开发者可使用订阅消息功能 | |||||
* </pre> | |||||
*/ | |||||
@Override | @Override | ||||
public void sendTemplateMsg(WxMaTemplateMessage templateMessage) throws WxErrorException { | public void sendTemplateMsg(WxMaTemplateMessage templateMessage) throws WxErrorException { | ||||
String responseContent = this.wxMaService.post(TEMPLATE_MSG_SEND_URL, templateMessage.toJson()); | String responseContent = this.wxMaService.post(TEMPLATE_MSG_SEND_URL, templateMessage.toJson()); | ||||
@@ -55,6 +55,7 @@ public class WxMaServiceImpl implements WxMaService, RequestHttp<CloseableHttpCl | |||||
private WxMaSecCheckService secCheckService = new WxMaSecCheckServiceImpl(this); | private WxMaSecCheckService secCheckService = new WxMaSecCheckServiceImpl(this); | ||||
private WxMaPluginService pluginService = new WxMaPluginServiceImpl(this); | private WxMaPluginService pluginService = new WxMaPluginServiceImpl(this); | ||||
private WxMaExpressService expressService = new WxMaExpressServiceImpl(this); | private WxMaExpressService expressService = new WxMaExpressServiceImpl(this); | ||||
private WxMaSubscribeService subscribeService = new WxMaSubscribeServiceImpl(this); | |||||
private int retrySleepMillis = 1000; | private int retrySleepMillis = 1000; | ||||
private int maxRetryTimes = 5; | private int maxRetryTimes = 5; | ||||
@@ -327,6 +328,11 @@ public class WxMaServiceImpl implements WxMaService, RequestHttp<CloseableHttpCl | |||||
return this.templateService; | return this.templateService; | ||||
} | } | ||||
@Override | |||||
public WxMaSubscribeService getSubscribeService() { | |||||
return this.subscribeService; | |||||
} | |||||
@Override | @Override | ||||
public WxMaAnalysisService getAnalysisService() { | public WxMaAnalysisService getAnalysisService() { | ||||
return this.analysisService; | return this.analysisService; | ||||
@@ -368,5 +374,7 @@ public class WxMaServiceImpl implements WxMaService, RequestHttp<CloseableHttpCl | |||||
} | } | ||||
@Override | @Override | ||||
public WxMaExpressService getExpressService() { return this.expressService; } | |||||
public WxMaExpressService getExpressService() { | |||||
return this.expressService; | |||||
} | |||||
} | } |
@@ -0,0 +1,74 @@ | |||||
package cn.binarywang.wx.miniapp.api.impl; | |||||
import cn.binarywang.wx.miniapp.api.WxMaService; | |||||
import cn.binarywang.wx.miniapp.api.WxMaSubscribeService; | |||||
import cn.binarywang.wx.miniapp.bean.template.WxMaTemplateLibraryListResult; | |||||
import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder; | |||||
import com.google.common.collect.ImmutableMap; | |||||
import com.google.gson.JsonParser; | |||||
import com.google.gson.reflect.TypeToken; | |||||
import lombok.AllArgsConstructor; | |||||
import me.chanjar.weixin.common.error.WxErrorException; | |||||
import me.chanjar.weixin.common.util.json.WxGsonBuilder; | |||||
import org.apache.commons.lang3.StringUtils; | |||||
import java.io.Serializable; | |||||
import java.util.List; | |||||
import java.util.Map; | |||||
/** | |||||
* @author <a href="https://github.com/binarywang">Binary Wang</a> | |||||
* @date 2019-12-15 | |||||
*/ | |||||
@AllArgsConstructor | |||||
public class WxMaSubscribeServiceImpl implements WxMaSubscribeService { | |||||
private WxMaService wxMaService; | |||||
@Override | |||||
public WxMaTemplateLibraryListResult getPubTemplateTitleList(Integer[] ids, int start, int limit) throws WxErrorException { | |||||
ImmutableMap<String, ? extends Serializable> params = ImmutableMap.of("ids", StringUtils.join(ids, ","), | |||||
"start", start, "limit", limit); | |||||
String responseText = this.wxMaService.post(GET_PUB_TEMPLATE_TITLE_LIST_URL, WxGsonBuilder.create().toJson(params)); | |||||
return WxMaTemplateLibraryListResult.fromJson(responseText); | |||||
} | |||||
@Override | |||||
public List<PubTemplateKeyword> getPubTemplateKeyWordsById(String id) throws WxErrorException { | |||||
String responseText = this.wxMaService.post(GET_PUB_TEMPLATE_KEY_WORDS_BY_ID_URL, | |||||
WxGsonBuilder.create().toJson(ImmutableMap.of("tid", id))); | |||||
return WxMaGsonBuilder.create().fromJson(new JsonParser().parse(responseText).getAsJsonObject() | |||||
.getAsJsonArray("data"), new TypeToken<List<PubTemplateKeyword>>() { | |||||
}.getType()); | |||||
} | |||||
@Override | |||||
public String addTemplate(String id, List<Integer> keywordIdList, String sceneDesc) throws WxErrorException { | |||||
String responseText = this.wxMaService.post(TEMPLATE_ADD_URL, WxGsonBuilder.create().toJson(ImmutableMap.of("tid", id, | |||||
"kidList", keywordIdList.toArray(), | |||||
"sceneDesc", sceneDesc))); | |||||
return new JsonParser().parse(responseText).getAsJsonObject().get("priTmplId").getAsString(); | |||||
} | |||||
@Override | |||||
public List<TemplateInfo> getTemplateList() throws WxErrorException { | |||||
String responseText = this.wxMaService.get(TEMPLATE_LIST_URL, null); | |||||
return WxMaGsonBuilder.create().fromJson(new JsonParser().parse(responseText).getAsJsonObject() | |||||
.getAsJsonArray("data"), new TypeToken<List<TemplateInfo>>() { | |||||
}.getType()); | |||||
} | |||||
@Override | |||||
public boolean delTemplate(String templateId) throws WxErrorException { | |||||
Map<String, String> params = ImmutableMap.of("priTmplId", templateId); | |||||
this.wxMaService.post(TEMPLATE_DEL_URL, WxGsonBuilder.create().toJson(params)); | |||||
return true; | |||||
} | |||||
@Override | |||||
public List<CategoryData> getCategory() throws WxErrorException { | |||||
String responseText = this.wxMaService.get(GET_CATEGORY_URL, null); | |||||
return WxMaGsonBuilder.create().fromJson(new JsonParser().parse(responseText).getAsJsonObject() | |||||
.getAsJsonArray("data"), new TypeToken<List<CategoryData>>() { | |||||
}.getType()); | |||||
} | |||||
} |
@@ -0,0 +1,62 @@ | |||||
package cn.binarywang.wx.miniapp.api.impl; | |||||
import cn.binarywang.wx.miniapp.api.WxMaService; | |||||
import cn.binarywang.wx.miniapp.api.WxMaSubscribeService; | |||||
import cn.binarywang.wx.miniapp.test.ApiTestModule; | |||||
import com.google.common.collect.Lists; | |||||
import com.google.inject.Inject; | |||||
import me.chanjar.weixin.common.error.WxErrorException; | |||||
import org.testng.annotations.Guice; | |||||
import org.testng.annotations.Test; | |||||
import java.util.List; | |||||
import static org.assertj.core.api.Assertions.assertThat; | |||||
/** | |||||
* 测试类. | |||||
* | |||||
* @author <a href="https://github.com/binarywang">Binary Wang</a> | |||||
* @date 2019-12-15 | |||||
*/ | |||||
@Test | |||||
@Guice(modules = ApiTestModule.class) | |||||
public class WxMaSubscribeServiceImplTest { | |||||
@Inject | |||||
protected WxMaService wxService; | |||||
@Test | |||||
public void testGetPubTemplateTitleList() throws WxErrorException { | |||||
this.wxService.getSubscribeService().getPubTemplateTitleList(new Integer[]{578}, 1, 1); | |||||
} | |||||
@Test | |||||
public void testGetPubTemplateKeyWordsById() throws WxErrorException { | |||||
final List<WxMaSubscribeService.PubTemplateKeyword> result = this.wxService.getSubscribeService().getPubTemplateKeyWordsById("578"); | |||||
System.out.println(result); | |||||
} | |||||
@Test | |||||
public void testAddTemplate() throws WxErrorException { | |||||
final String templateId = this.wxService.getSubscribeService().addTemplate("1", Lists.newArrayList(1), ""); | |||||
System.out.println(templateId); | |||||
} | |||||
@Test | |||||
public void testGetTemplateList() throws WxErrorException { | |||||
final List<WxMaSubscribeService.TemplateInfo> templateList = this.wxService.getSubscribeService().getTemplateList(); | |||||
System.out.println(templateList); | |||||
} | |||||
@Test | |||||
public void testDelTemplate() throws WxErrorException { | |||||
this.wxService.getSubscribeService().delTemplate("priTmplId"); | |||||
} | |||||
@Test | |||||
public void testGetCategory() throws WxErrorException { | |||||
final List<WxMaSubscribeService.CategoryData> categoryData = this.wxService.getSubscribeService().getCategory(); | |||||
assertThat(categoryData).isNotNull(); | |||||
System.out.println(categoryData); | |||||
} | |||||
} |
@@ -17,7 +17,6 @@ import java.util.List; | |||||
@Test | @Test | ||||
@Guice(modules = ApiTestModule.class) | @Guice(modules = ApiTestModule.class) | ||||
public class WxMaTemplateServiceImplTest { | public class WxMaTemplateServiceImplTest { | ||||
@Inject | @Inject | ||||
protected WxMaService wxService; | protected WxMaService wxService; | ||||
@@ -36,7 +35,7 @@ public class WxMaTemplateServiceImplTest { | |||||
} | } | ||||
@Test | @Test | ||||
public void testAddTemplate() throws Exception{ | |||||
public void testAddTemplate() throws Exception { | |||||
List<Integer> list = Lists.newArrayList(); | List<Integer> list = Lists.newArrayList(); | ||||
list.add(1); | list.add(1); | ||||
list.add(20); | list.add(20); | ||||
@@ -48,7 +47,7 @@ public class WxMaTemplateServiceImplTest { | |||||
} | } | ||||
@Test | @Test | ||||
public void testFindTemplateList() throws Exception{ | |||||
public void testFindTemplateList() throws Exception { | |||||
WxMaTemplateListResult result = this.wxService.getTemplateService().findTemplateList(0, 20); | WxMaTemplateListResult result = this.wxService.getTemplateService().findTemplateList(0, 20); | ||||
System.out.println(result); | System.out.println(result); | ||||
} | } | ||||