首页 > 微信一次性订阅消息

微信一次性订阅消息

微信一次性订阅消息官方文档:消息管理>发送一次性订阅消息

开发者可以通过一次性订阅消息授权让微信用户授权第三方移动应用(接入说明)或公众号,获得发送一次订阅消息给到授权微信用户的机会。授权微信用户可以不需要关注公众号。微信用户每授权一次,开发者可获得一次下发消息的权限。对于已关注公众号的,消息将下发到公众号会话;未关注公众号的,将下发到服务通知

本篇文章主要讨论公众号

1、确认是否有权限

已认证的公众号即有权限,可登陆公众平台在接口权限列表处查看(如下图)。目前测试号还无法测试一次性订阅消息

一次性订阅消息-查看模板ID

2、配置相关的参数

  • 查看AppId以及AppSecret (发送一次性订阅消息需要ACCESS_TOKEN、获取ACCESS_TOKEN需要使用到)
  • 配置回调域名

image.png

设置授权域名-1

设置授权域名-2

3、授权发送一次性订阅消息

具体的参数看文档这里就不详细介绍了。

public static String getAuthorizeURL(String appId, String scene, String template_id,String redirectUri, String reserved) throws UnsupportedEncodingException {StringBuffer sbf = new StringBuffer();sbf.append(authorize_uri).append("&appid=").append(appId).append("&scene=").append(scene).append("&template_id=").append(template_id).append("&redirect_uri=").append(URLEncoder.encode(redirectUri, Charsets.UTF_8.name()).replace("+", "%20"));if (StrKit.notBlank(reserved)) {sbf.append("&reserved=").append(reserved);}sbf.append("#wechat_redirect");return sbf.toString();}

用户同意或取消授权后会返回相关信息

如果用户点击同意或取消授权,页面将跳转至:

redirect_url/?openid=OPENID&template_id=TEMPLATE_ID&action=ACTION&scene=SCENE

1240

4、通过API推送订阅模板消息给到授权微信用户

http请求方式: post

https://api.weixin.qq.com/cgi-bin/message/template/subscribe?access_token=ACCESS_TOKEN

{"touser": "OPENID","template_id": "TEMPLATE_ID","url": "URL","scene": "SCENE","title": "TITLE","data": {"content": {"value": "VALUE","color": "COLOR"}}
}

1240

具体封装代码如下:

/*** 发送一次性订阅消息* * @param jsonStr*            json字符串* @return ApiResult * */public static ApiResult subscribe(String jsonStr) {String jsonResult = HttpUtils.post(subscribe + AccessTokenApi.getAccessTokenStr(), jsonStr);return new ApiResult(jsonResult);}public static ApiResult subscribe(SubscribeInfo subscribeInfo) {return new ApiResult(JsonKit.toJson(subscribeInfo));}public static ApiResult subscribe(String openId, String templateId, String url, int scene, String title,String value, String color) {SubscribeInfo subscribeInfo = new SubscribeInfo.Builder().setTouser(openId).setTemplate_id(templateId).setUrl(url).setScene(String.valueOf(scene)).setTitle(title).setData(new Data.Builder().setContent(new Content.Builder().setColor(color).setValue(value).create()).create()).create();System.out.println(JsonUtils.toJson(subscribeInfo));                return subscribe(JsonUtils.toJson(subscribeInfo));}

Builder模式构建请求参数的json对象

class SubscribeInfo {private String touser;private String template_id;private String url;private String scene;private String title;private Data data;public static class Builder{private String touser;private String template_id;private String url;private String scene;private String title;private Data data;public Builder setTouser(String touser) {this.touser = touser;return this;}public Builder setTemplate_id(String template_id) {this.template_id = template_id;return this;}public Builder setUrl(String url) {this.url = url;return this;}public Builder setScene(String scene) {this.scene = scene;return this;}public Builder setTitle(String title) {this.title = title;return this;}public Builder setData(Data data) {this.data = data;return this;}public SubscribeInfo create(){    return new SubscribeInfo(this);    }}private SubscribeInfo(Builder builder) {if (StrKit.isBlank(builder.touser)) {throw new IllegalStateException("touser is null");}if (StrKit.isBlank(builder.template_id)) {throw new IllegalStateException("template_id is null");}if (StrKit.isBlank(builder.url)) {throw new IllegalStateException("url is null");}if (StrKit.isBlank(builder.scene)) {throw new IllegalStateException("scene is null");}if (StrKit.isBlank(builder.title)) {throw new IllegalStateException("title is null");}if (!StrKit.notNull(builder.data)) {throw new IllegalStateException("data is null");}this.touser = builder.touser;this.template_id = builder.template_id;this.url = builder.url;this.scene = builder.scene;this.title = builder.title;this.data = builder.data;}public String getTouser() {return touser;}public String getTemplate_id() {return template_id;}public String getUrl() {return url;}public String getScene() {return scene;}public String getTitle() {return title;}public Data getData() {return data;}
}class Data {private Content content;public static class Builder {private Content content;public Builder setContent(Content content) {this.content = content;return this;}public Data create(){    return new Data(this);    }    }private Data(Builder builder) {if (!StrKit.notNull(builder.content)) {throw new IllegalStateException("content is null");}this.content = builder.content;}public Content getContent() {return content;}}class Content {private String value;private String color;public static class  Builder{private String value;private String color;public Builder setValue(String value) {this.value = value;return this;}public Builder setColor(String color) {this.color = color;return this;}public Content create(){return new Content(this);}}private Content(Builder builder) {if (StrKit.isBlank(builder.value)) {throw new IllegalStateException("value is null");}if (StrKit.isBlank(builder.color)) {throw new IllegalStateException("color is null");}this.value = builder.value;this.color = builder.color;}public String getValue() {return value;}public String getColor() {return color;}
}

5、遗留问题

1、授权后页面跳转无效redirect_url

2、发送一次性订阅消息提示没有权限(认证的服务号)

{"errcode":48001,"errmsg":"api unauthorized hint: [uAi6Za0855sz10!]"}

猜测:应该是官方接口存在问题

推荐阅读

10分钟搭建属于自己的ngork服务器,实现内网穿透

极速开发微信公众号

IJPay让支付触手可及

微信、支付宝App支付

转载于:https://www.cnblogs.com/zyw-205520/p/7349654.html

更多相关:

  • importjava.security.SecureRandom;importjavax.crypto.Cipher;importjavax.crypto.SecretKey;importjavax.crypto.SecretKeyFactory;importjavax.crypto.spec.DESKeySpec;//结果与DES算...

  • 题目:替换空格 请实现一个函数,把字符串 s 中的每个空格替换成"%20"。 输入:s = "We are happy." 输出:"We%20are%20happy." 限制: 0 <= s 的长度 <= 10000 解题: 时间复杂度:O(n) 空间复杂度:O(n) class Solution { public:s...

  • 在C++11标准库中,string.h已经添加了to_string方法,方便从其他类型(如整形)快速转换成字面值。 例如: for (size_t i = 0; i < texArrSize; i++)RTX_Shader.SetInt(string("TexArr[") + to_string(i) + "]", 7 + i);...

  • Ubuntu 14.04安装并升级之后,变成楷体字体非常难看,我昨天搞了一晚上,终于理了个头绪,这里整理一下。 经过网上调研,大家的一致看法是,使用开源字体库文泉驿的微黑字体效果比较理想,甚至效果不输windows平台的雅黑字体。下面我打算微黑来美化Ubuntu 14.04. 1.安装文泉驿微黑字体库 sudo aptitude...

  • 使用string时发现了一些坑。 我们知道stl 容器并不是线程安全的,所以在使用它们的过程中往往需要一些同步机制来保证并发场景下的同步更新。 应该踩的坑还是一个不拉的踩了进去,所以还是记录一下吧。 string作为一个容器,随着我们的append 或者 针对string的+ 操作都会让string内部的数据域动态增加,而动态增加的...

  • 在.Net Framework中,配置文件一般采用的是XML格式的,.NET Framework提供了专门的ConfigurationManager来读取配置文件的内容,.net core中推荐使用json格式的配置文件,那么在.net core中该如何读取json文件呢?1、在Startup类中读取json配置文件1、使用Confi...

  •   1 public class FrameSubject extends JFrame {   2    3   …………..   4    5   //因为无法使用多重继承,这儿就只能使用对象组合的方式来引入一个   6    7   //java.util.Observerable对象了。   8    9   DateSub...

  • 本案例主要说明如何使用NSwag 工具使用桌面工具快速生成c# 客户端代码、快速的访问Web Api。 NSwagStudio 下载地址 比较强大、可以生成TypeScript、WebApi Controller、CSharp Client  1、运行WebApi项目  URL http://yourserver/swagger 然后...

  •   在绑定完Action的所有参数后,WebAPI并不会马上执行该方法,而要对参数进行验证,以保证输入的合法性.   ModelState 在ApiController中一个ModelState属性用来获取参数验证结果.   public abstract class ApiController : IHttpController,...

  • 1# 引用  C:AVEVAMarineOH12.1.SP4Aveva.ApplicationFramework.dll C:AVEVAMarineOH12.1.SP4Aveva.ApplicationFramework.Presentation.dll 2# 引用命名空间, using Aveva.Applicati...

  • /*判断屏幕宽高比是否为16:9*/ function isScreen16to9() {return window.screen.height / window.screen.width === 9 / 16; }...

  • /*关闭、刷新、跳转、离开当前网页前提示*/ onbeforeunload = function () {return false; };  ...

  • let json = {/**判断JSON格式*/ isJSON: function (str) {if (typeof str == "string") {try {var obj = JSON.parse(str);if (typeof obj == "object" && obj) {return true;} else {...

  •   项目结构   index.js //必须要安装否则就别想运行了❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤ //npm i body-parser -D & cnpm i express & cnpm i node-xlsx & cnp...

  • 一、递归 函数    为什么要有函数,提高代码的可读性,避免重复的代码,提高代码的复用性      在函数中能用return的不要print 1、递归的最大深度997 def foo(n):print(n)n+=1foo(n) foo(1) 递归的最大深度 2、修改递归的最大深度     由此我们可以看出,未报错之前能看到的最大数...