diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/error/WxMaErrorMsgEnum.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/error/WxMaErrorMsgEnum.java index 9650ce41d..f1ced3fd0 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/error/WxMaErrorMsgEnum.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/error/WxMaErrorMsgEnum.java @@ -444,6 +444,14 @@ public enum WxMaErrorMsgEnum { CODE_85064(85064, "找不到模版/草稿"), CODE_85065(85065, "模版库已满"), + + /** + * 小程序订阅消息错误码 + * https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/subscribe-message/subscribeMessage.send.html + */ + CODE_43101(43101, "用户拒绝接受消息,如果用户之前曾经订阅过,则表示用户取消了订阅关系"), + + CODE_47003(47003, "模板参数不准确,可能为空或者不满足规则,errmsg会提示具体是哪个字段出错"), ; private int code; diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaMsgService.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaMsgService.java index f0dbccd81..3dec5140f 100644 --- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaMsgService.java +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaMsgService.java @@ -1,6 +1,7 @@ package cn.binarywang.wx.miniapp.api; import cn.binarywang.wx.miniapp.bean.WxMaKefuMessage; +import cn.binarywang.wx.miniapp.bean.WxMaSubscribeMessage; import cn.binarywang.wx.miniapp.bean.WxMaTemplateMessage; import cn.binarywang.wx.miniapp.bean.WxMaUniformMessage; import me.chanjar.weixin.common.error.WxErrorException; @@ -15,6 +16,7 @@ import me.chanjar.weixin.common.error.WxErrorException; public interface WxMaMsgService { String KEFU_MESSAGE_SEND_URL = "https://api.weixin.qq.com/cgi-bin/message/custom/send"; String TEMPLATE_MSG_SEND_URL = "https://api.weixin.qq.com/cgi-bin/message/wxopen/template/send"; + String SUBSCRIBE_MSG_SEND_URL = "https://api.weixin.qq.com/cgi-bin/message/subscribe/send"; String UNIFORM_MSG_SEND_URL = "https://api.weixin.qq.com/cgi-bin/message/wxopen/template/uniform_send"; /** @@ -36,6 +38,15 @@ public interface WxMaMsgService { void sendTemplateMsg(WxMaTemplateMessage templateMessage) throws WxErrorException; + /** + *
+ * https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/subscribe-message/subscribeMessage.send.html + *+ * 发送订阅消息 + */ + void sendSubscribeMsg(WxMaSubscribeMessage subscribeMessage) throws WxErrorException; + + /** *
* 下发小程序和公众号统一的服务消息
diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaMsgServiceImpl.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaMsgServiceImpl.java
index c4cb456e2..26ebd74bc 100644
--- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaMsgServiceImpl.java
+++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaMsgServiceImpl.java
@@ -3,6 +3,7 @@ package cn.binarywang.wx.miniapp.api.impl;
import cn.binarywang.wx.miniapp.api.WxMaMsgService;
import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaKefuMessage;
+import cn.binarywang.wx.miniapp.bean.WxMaSubscribeMessage;
import cn.binarywang.wx.miniapp.bean.WxMaTemplateMessage;
import cn.binarywang.wx.miniapp.bean.WxMaUniformMessage;
import cn.binarywang.wx.miniapp.constant.WxMaConstants;
@@ -27,6 +28,11 @@ public class WxMaMsgServiceImpl implements WxMaMsgService {
return responseContent != null;
}
+ /**
+ *
+ * 小程序模板消息接口将于2020年1月10日下线,开发者可使用订阅消息功能
+ *
+ */
@Override
public void sendTemplateMsg(WxMaTemplateMessage templateMessage) throws WxErrorException {
String responseContent = this.wxMaService.post(TEMPLATE_MSG_SEND_URL, templateMessage.toJson());
@@ -36,6 +42,15 @@ public class WxMaMsgServiceImpl implements WxMaMsgService {
}
}
+ @Override
+ public void sendSubscribeMsg(WxMaSubscribeMessage subscribeMessage) throws WxErrorException {
+ String responseContent = this.wxMaService.post(SUBSCRIBE_MSG_SEND_URL, subscribeMessage.toJson());
+ JsonObject jsonObject = JSON_PARSER.parse(responseContent).getAsJsonObject();
+ if (jsonObject.get(WxMaConstants.ERRCODE).getAsInt() != 0) {
+ throw new WxErrorException(WxError.fromJson(responseContent, WxType.MiniApp));
+ }
+ }
+
@Override
public void sendUniformMsg(WxMaUniformMessage uniformMessage) throws WxErrorException {
String responseContent = this.wxMaService.post(UNIFORM_MSG_SEND_URL, uniformMessage.toJson());
diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaSubscribeData.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaSubscribeData.java
new file mode 100644
index 000000000..048e6dae8
--- /dev/null
+++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaSubscribeData.java
@@ -0,0 +1,30 @@
+package cn.binarywang.wx.miniapp.bean;
+
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ *
+ * 参考文档 https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/subscribe-message/subscribeMessage.send.html
+ *
+ */
+@Data
+@NoArgsConstructor
+public class WxMaSubscribeData {
+ private String name;
+ private String value;
+ private String color;
+
+ public WxMaSubscribeData(String name, String value) {
+ this.name = name;
+ this.value = value;
+ }
+
+ public WxMaSubscribeData(String name, String value, String color) {
+ this.name = name;
+ this.value = value;
+ this.color = color;
+ }
+
+
+}
diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaSubscribeMessage.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaSubscribeMessage.java
new file mode 100644
index 000000000..a43fd5b47
--- /dev/null
+++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaSubscribeMessage.java
@@ -0,0 +1,77 @@
+package cn.binarywang.wx.miniapp.bean;
+
+import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder;
+import lombok.*;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 订阅消息.
+ * https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/subscribe-message/subscribeMessage.send.html
+ */
+@Getter
+@Setter
+@NoArgsConstructor
+@AllArgsConstructor
+@Builder
+public class WxMaSubscribeMessage implements Serializable {
+
+ private static final long serialVersionUID = 6846729898251286686L;
+
+ /**
+ * 接收者(用户)的 openid.
+ *
+ * 参数:touser
+ * 是否必填: 是
+ * 描述: 接收者(用户)的 openid
+ *
+ */
+ private String toUser;
+
+ /**
+ * 所需下发的模板消息的id.
+ *
+ * 参数:template_id
+ * 是否必填: 是
+ * 描述: 所需下发的模板消息的id
+ *
+ */
+ private String templateId;
+
+ /**
+ * 点击模板卡片后的跳转页面,仅限本小程序内的页面.
+ *
+ * 参数:page
+ * 是否必填: 否
+ * 描述: 点击模板卡片后的跳转页面,仅限本小程序内的页面。支持带参数,(示例index?foo=bar)。该字段不填则模板无跳转。
+ *
+ */
+ private String page;
+
+ /**
+ * 模板内容,不填则下发空模板.
+ *
+ * 参数:data
+ * 是否必填: 是
+ * 描述: 模板内容,不填则下发空模板
+ *
+ */
+ private List data;
+
+
+ public WxMaSubscribeMessage addData(WxMaSubscribeData datum) {
+ if (this.data == null) {
+ this.data = new ArrayList<>();
+ }
+ this.data.add(datum);
+
+ return this;
+ }
+
+ public String toJson() {
+ return WxMaGsonBuilder.create().toJson(this);
+ }
+
+}
diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/util/json/WxMaGsonBuilder.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/util/json/WxMaGsonBuilder.java
index f01eb33d6..5fab9de74 100644
--- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/util/json/WxMaGsonBuilder.java
+++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/util/json/WxMaGsonBuilder.java
@@ -1,5 +1,6 @@
package cn.binarywang.wx.miniapp.util.json;
+import cn.binarywang.wx.miniapp.bean.WxMaSubscribeMessage;
import cn.binarywang.wx.miniapp.bean.WxMaTemplateMessage;
import cn.binarywang.wx.miniapp.bean.WxMaUniformMessage;
import cn.binarywang.wx.miniapp.bean.analysis.WxMaRetainInfo;
@@ -19,6 +20,7 @@ public class WxMaGsonBuilder {
static {
INSTANCE.disableHtmlEscaping();
INSTANCE.registerTypeAdapter(WxMaTemplateMessage.class, new WxMaTemplateMessageGsonAdapter());
+ INSTANCE.registerTypeAdapter(WxMaSubscribeMessage.class, new WxMaSubscribeMessageGsonAdapter());
INSTANCE.registerTypeAdapter(WxMaUniformMessage.class, new WxMaUniformMessageGsonAdapter());
INSTANCE.registerTypeAdapter(WxMaCodeCommitRequest.class, new WxMaCodeCommitRequestGsonAdapter());
INSTANCE.registerTypeAdapter(WxMaCodeVersionDistribution.class, new WxMaCodeVersionDistributionGsonAdapter());
diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/util/json/WxMaSubscribeMessageGsonAdapter.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/util/json/WxMaSubscribeMessageGsonAdapter.java
new file mode 100644
index 000000000..d15226a9e
--- /dev/null
+++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/util/json/WxMaSubscribeMessageGsonAdapter.java
@@ -0,0 +1,40 @@
+package cn.binarywang.wx.miniapp.util.json;
+
+import cn.binarywang.wx.miniapp.bean.WxMaSubscribeData;
+import cn.binarywang.wx.miniapp.bean.WxMaSubscribeMessage;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonSerializationContext;
+import com.google.gson.JsonSerializer;
+
+import java.lang.reflect.Type;
+
+public class WxMaSubscribeMessageGsonAdapter implements JsonSerializer {
+
+ @Override
+ public JsonElement serialize(WxMaSubscribeMessage message, Type typeOfSrc, JsonSerializationContext context) {
+ JsonObject messageJson = new JsonObject();
+ messageJson.addProperty("touser", message.getToUser());
+ messageJson.addProperty("template_id", message.getTemplateId());
+ if (message.getPage() != null) {
+ messageJson.addProperty("page", message.getPage());
+ }
+
+
+ JsonObject data = new JsonObject();
+ messageJson.add("data", data);
+
+ if (message.getData() == null) {
+ return messageJson;
+ }
+
+ for (WxMaSubscribeData datum : message.getData()) {
+ JsonObject dataJson = new JsonObject();
+ dataJson.addProperty("value", datum.getValue());
+ data.add(datum.getName(), dataJson);
+ }
+
+ return messageJson;
+ }
+
+}
diff --git a/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/api/impl/WxMaMsgServiceImplTest.java b/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/api/impl/WxMaMsgServiceImplTest.java
index 298a9c934..f5f62cc57 100644
--- a/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/api/impl/WxMaMsgServiceImplTest.java
+++ b/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/api/impl/WxMaMsgServiceImplTest.java
@@ -3,13 +3,10 @@ package cn.binarywang.wx.miniapp.api.impl;
import java.text.SimpleDateFormat;
import java.util.Date;
+import cn.binarywang.wx.miniapp.bean.*;
import org.testng.annotations.*;
import cn.binarywang.wx.miniapp.api.WxMaService;
-import cn.binarywang.wx.miniapp.bean.WxMaKefuMessage;
-import cn.binarywang.wx.miniapp.bean.WxMaTemplateData;
-import cn.binarywang.wx.miniapp.bean.WxMaTemplateMessage;
-import cn.binarywang.wx.miniapp.bean.WxMaUniformMessage;
import cn.binarywang.wx.miniapp.test.ApiTestModule;
import cn.binarywang.wx.miniapp.test.TestConfig;
import com.google.common.collect.Lists;
@@ -59,6 +56,21 @@ public class WxMaMsgServiceImplTest {
this.wxService.getMsgService().sendTemplateMsg(templateMessage);
}
+
+ @Test
+ public void testSendSubscribeMsg() throws WxErrorException {
+ TestConfig config = (TestConfig) this.wxService.getWxMaConfig();
+
+ WxMaSubscribeMessage message = new WxMaSubscribeMessage();
+ message.setTemplateId(config.getTemplateId());
+ message.setToUser(config.getOpenid());
+ message.addData(new WxMaSubscribeData("thing1", "苹果到货啦"));
+ message.addData(new WxMaSubscribeData("amount3", "¥5"));
+ message.addData(new WxMaSubscribeData("thing5", "记得领取哦"));
+ this.wxService.getMsgService().sendSubscribeMsg(message);
+ }
+
+
@Test
public void testSendUniformMsg() throws WxErrorException {
TestConfig config = (TestConfig) this.wxService.getWxMaConfig();