微信小程序_微信小程序云开发,在群消息中点击微信小程序获取微信群信息 - CSDN
微信小程序 订阅
微信小程序,小程序的一种,英文名Wechat Mini Program,是一种不需要下载安装即可使用的应用,它实现了应用“触手可及”的梦想,用户扫一扫或搜一下即可打开应用。全面开放申请后,主体类型为企业、政府、媒体、其他组织或个人的开发者,均可申请注册小程序。微信小程序、微信订阅号、微信服务号、微信企业号是并行的体系。微信小程序是一种不用下载就能使用的应用,也是一项创新,经过将近两年的发展,已经构造了新的微信小程序开发环境和开发者生态。微信小程序也是这么多年来中国IT行业里一个真正能够影响到普通程序员的创新成果,已经有超过150万的开发者加入到了微信小程序的开发,与我们一起共同发力推动微信小程序的发展,微信小程序应用数量超过了一百万,覆盖200多个细分的行业,日活用户达到两个亿,微信小程序还在许多城市实现了支持地铁、公交服务。微信小程序发展带来更多的就业机会,2017年小程序带动就业104万人,社会效应不断提升。 [1]  2017年1月9日,张小龙在2017微信公开课Pro上发布的微信小程序正式上线。2018年2月,微信官方发布公告称:已对涉及假货高仿、色情低俗和违规“现金贷”等超过2000个微信小程序,进行永久封禁处理。2019年8月9日,微信向开发者发布新能力公测与更新公告,微信PC版新版本中,支持打开聊天中分享的微信小程序。 [2] 展开全文
微信小程序,小程序的一种,英文名Wechat Mini Program,是一种不需要下载安装即可使用的应用,它实现了应用“触手可及”的梦想,用户扫一扫或搜一下即可打开应用。全面开放申请后,主体类型为企业、政府、媒体、其他组织或个人的开发者,均可申请注册小程序。微信小程序、微信订阅号、微信服务号、微信企业号是并行的体系。微信小程序是一种不用下载就能使用的应用,也是一项创新,经过将近两年的发展,已经构造了新的微信小程序开发环境和开发者生态。微信小程序也是这么多年来中国IT行业里一个真正能够影响到普通程序员的创新成果,已经有超过150万的开发者加入到了微信小程序的开发,与我们一起共同发力推动微信小程序的发展,微信小程序应用数量超过了一百万,覆盖200多个细分的行业,日活用户达到两个亿,微信小程序还在许多城市实现了支持地铁、公交服务。微信小程序发展带来更多的就业机会,2017年小程序带动就业104万人,社会效应不断提升。 [1]  2017年1月9日,张小龙在2017微信公开课Pro上发布的微信小程序正式上线。2018年2月,微信官方发布公告称:已对涉及假货高仿、色情低俗和违规“现金贷”等超过2000个微信小程序,进行永久封禁处理。2019年8月9日,微信向开发者发布新能力公测与更新公告,微信PC版新版本中,支持打开聊天中分享的微信小程序。 [2]
信息
外文名
Mini Program
发布时间
2017年1月9日
汉语拼音
wei xin xiao cheng xu
开发商
微信公众平台
中文名
微信小程序
内测时间
2016年9月21日
属    性
应用平台
微信小程序发展历程
2016年1月11日,微信之父张小龙时隔多年的公开亮相,解读了微信的四大价值观。张小龙指出,越来越多产品通过公众号来做,因为这里开发、获取用户和传播成本更低。拆分出来的服务号并没有提供更好的服务,所以微信内部正在研究新的形态,叫「微信小程序」。2016年9月21日,微信小程序正式开启内测。在微信生态下,触手可及、用完即走的微信小程序引起广泛关注。腾讯云正式上线微信小程序解决方案,提供微信小程序在云端服务器的技术方案。2017年1月9日0点,万众瞩目的微信第一批微信小程序正式低调上线,用户可以体验到各种各样微信小程序提供的服务。 [3]  2017年12月28日,微信更新的 6.6.1 版本开放了小游戏,微信启动页面还重点推荐了小游戏「跳一跳」,你可以通过「微信小程序」找到已经玩过的小游戏。 [4]  2018年1月18日,微信提供了电子化的侵权投诉渠道,用户或者企业可以在微信公众平台以及微信客户端入口进行投诉。 [5]  2018年1月25日,微信团队在“微信公众平台”发布公告称,“从移动应用分享至微信的小程序页面,用户访问时支持打开来源应用。同时,为提升用户使用体验,开发者可以设置小程序菜单的颜色风格,并根据业务需求,对小程序菜单外的标题栏区域进行自定义。 [6]  2018年3月,微信正式宣布微信小程序广告组件启动内测,内容还包括第三方可以快速创建并认证小程序、新增小程序插件管理接口和更新基础能力,开发者可以通过微信小程序来赚取广告收入。 [7]  除了公众号文中、朋友圈广告以及公众号底部的广告位都支持微信小程序落地页投放广告,微信小程序广告位也可以直达小程序。 [7]  2018年7月13日,微信小程序任务栏功能升级,新增“我的微信小程序”板块;而微信小程序原有的“星标”功能升级,可以将喜欢的小程序直接添加到“我的微信小程序”。 [8]  2018年8月10日,微信宣布,微信小程序后台数据分析及插件功能升级,开发者可查看已添加「我的微信小程序」的用户数。此外,2018年8月1日至12月31日期间,微信小程序(含小游戏)流量主的广告收入分成比例优化上调,单日广告流水10-100万区间的部分,开发者可获得的分成由原来流水的30%上调到50%,优质微信小程序流量主可获得更高收益。 [9]  2018年9月28日,微信“功能直达”正式开放,商家与用户的距离可以更“近”一步:用户微信搜一搜功能词,搜索页面将呈现相关服务的微信小程序,点击搜索结果,可直达微信小程序相关服务页面。 [10]  2019年8月9日,微信向开发者发布新能力公测与更新公告,微信 PC 版新版本中,支持打开聊天中分享的微信小程序。安装最新PC端测试版微信后,点击聊天中的微信小程序,便会弹出微信小程序浮窗。而在微信小程序右上角的操作选项中,可以进行“最小化”操作,让微信小程序像其他PC软件一样最小化,排列于Windows系统的任务栏中。 [2] 
收起全文
  • 微信小程序开发全案精讲是一套以案例为主线的课程,课程总共九章,第一章回顾基础知识,后面八章全部是以典型的案例作为讲解,选取了美食类:仿菜谱精灵微信小程序、资讯类:仿今日头条微信小程序、生鲜类:仿爱鲜蜂...
  • 微信小程序开发实战

    2019-04-01 14:05:00
    本套课程使用了元认知教学法,直接实战式教学,摆脱学院派的理论式讲解,对于0基础的学员可以入门编写微信小程序,过程中指导如何学习使用文档查阅接口等,通过两个完整的实战小项目的实例,入手小程序开发。
  • 微信小程序开发教程”以腾讯官方资料为主。实现角度出发,以“点餐系统”作为课程案例,讲解微信小程序开发的相关知识点,分享小程序开发经验。 全套课程共2个阶段:微信小程序开发教程(第1阶段)——微信小程序...
  • 现在微信小程序越来越火了,相信不少人都通过各种途径学习过微信小程序或者尝试开发,作者就是曾经由于兴趣了解开发过微信小程序,最终自己的毕业设计也是开发一个微信小程序。所以现在用这篇博客记录我之前开发的...
    1. 前言
      现在微信小程序越来越火了,相信不少人都通过各种途径学习过微信小程序或者尝试开发,作者就是曾经由于兴趣了解开发过微信小程序,最终自己的毕业设计也是开发一个微信小程序。所以现在用这篇博客记录我之前开发的一些经验和一些心得吧。

    2. 主要内容
      springboot后端架构构建
      小程序项目构建
      小程序api调用
      后台resetful接口编写
      小程序调用后台接口
      免费的https申请
      linux下部署上线

    3. 微信小程序项目构建
      这些基础的东西我就不过多介绍,大家在刚开始开发的时候一般都没有自己的服务器及域名,所以大家在本地编写的时候,在“详细”下的“项目设置”里面将“不校验域名安全性”勾选。这里写图片描述
      至于微信小程序的组件,即前端页面的开发希望大家耐住寂寞认真在微信开发平台上,组件https://developers.weixin.qq.com/miniprogram/dev/component/及api:https://developers.weixin.qq.com/miniprogram/dev/api/

    4. 后端详解
      我在后端编写主要是用java,当然对其他开发语言熟悉的也可以使用其他语言开发后端。现在我就java编写后端api的讲解。主要框架springboot,开发工具myeclipse,服务器阿里云服务器。
      创建一个maven项目,导入相关依赖:
      pom.xml依赖

        <!-- 统一版本控制 -->
    	<parent>
    		<groupId>org.springframework.boot</groupId>
    		<artifactId>spring-boot-starter-parent</artifactId>
    		<version>1.5.9.RELEASE</version>
    	</parent>
    	<dependencies>
    		<!-- freemarker渲染页面 -->
    		<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-freemarker -->
    		<dependency>
    			<groupId>org.springframework.boot</groupId>
    			<artifactId>spring-boot-starter-freemarker</artifactId>
    		</dependency>
    
    		<!-- spring boot 核心 -->
    		<dependency>
    			<groupId>org.springframework.boot</groupId>
    			<artifactId>spring-boot-starter-web</artifactId>
    		</dependency>
    
    		<!-- springboot整合jsp -->
    		<!-- tomcat 的支持. -->
    		<dependency>
    			<groupId>org.springframework.boot</groupId>
    			<artifactId>spring-boot-starter-web</artifactId>
    			<exclusions>
    				<exclusion>
    					<groupId>org.springframework.boot</groupId>
    					<artifactId>spring-boot-starter-tomcat</artifactId>
    				</exclusion>
    			</exclusions>
    		</dependency>
    
    		<dependency>
    			<groupId>org.apache.tomcat.embed</groupId>
    			<artifactId>tomcat-embed-jasper</artifactId>
    		</dependency>
    	</dependencies>
    

    在配置文件src/main/resources/下创建application.properties文件可以修改一些配置参数等。

    #jsp支持
    spring.mvc.view.suffix=.jsp
    spring.mvc.view.prefix=/WEB-INF/jsp/
    #this is set port
    #server.port=80
    server.port=443
    #添加ssl证书
    #ssl证书文件名
    server.ssl.key-store=classpath:xxxxxxx.pfx
    server.ssl.key-store-password=xxxxxxxx
    server.ssl.keyStoreType=xxxxxxxx
    

    在实际项目中可能涉及数据库,还要整合mybatis,在文章中,我仅仅做测试就不做使用数据库的测试。
    首先创建springboot的入口程序:app.class下面贴上代码:

    @ComponentScan(basePackages= "com.bin")//添加扫包@ComponentScan(basePackages= "")
    @EnableAutoConfiguration
    public class App{
    
    	//启动springboot
    	public static void main(String[] args) {
    		SpringApplication.run(App.class, args);
    	}
    }
    

    启动项目时直接右击run即可。
    在写一个测试的controller进行微信小程序与java后端实现通信,controller代码如下:

    @RestController
    @SpringBootApplication
    public class ControllerText {
    	
    	@RequestMapping("getUser")
    	public Map<String, Object> getUser(){
    		System.out.println("微信小程序正在调用。。。");
    		Map<String, Object> map = new HashMap<String, Object>();
    		List<String> list = new ArrayList<String>();
     		list.add("zhangsan");
     		list.add("lisi");
     		list.add("wanger");
     		list.add("mazi");
     		map.put("list",list);
    		System.out.println("微信小程序调用完成。。。");
    		return map;
    	}
    	
    	@RequestMapping("getWord")
    	public Map<String, Object> getText(String word){
    		Map<String, Object> map = new HashMap<String, Object>();
    		String message = "我能力有限,不要为难我";
    		if ("后来".equals(word)) {
    			message="正在热映的后来的我们是刘若英的处女作。";
    		}else if("微信小程序".equals(word)){
    			message= "想获取更多微信小程序相关知识,请更多的阅读微信官方文档,还有其他更多微信开发相关的内容,学无止境。";
    		}else if("西安工业大学".equals(word)){
    			message="西安工业大学(Xi'an Technological University)简称”西安工大“,位于世界历史名城古都西安,是中国西北地区唯一一所以兵工为特色,以工为主,理、文、经、管、法协调发展的教学研究型大学。原中华人民共和国兵器工业部直属的七所本科院校之一(“兵工七子”),陕西省重点建设的高水平教学研究型大学、陕西省人民政府与中国兵器工业集团、国防科技工业局共建高校、教育部“卓越工程师教育培养计划”试点高校、陕西省大学生创新能力培养综合改革试点学校。国家二级保密资格单位,是一所以\"军民结合,寓军于民\"的国防科研高校。";
    		}
    		map.put("message", message);
    		return map;
    	}
    	
    	@RequestMapping("")
    	public String getText(){
    		return "hello world";
    	}
    
    
    }
    

    至此简易的后端框架及测试基本完成。
    说明:@RestController与@Controller注解的区别@RestController相当于两个注解,它能实现将后端得到的数据在前端页面(网页)中以json串的形式传递。而微信小程序与后台之间的数据传递就是以json报文的形式传递。所以这就是选择springboot框架开发小程序后端的主要原因之一。可以方面我们进行小程序的后端开发。

    1. 小程序发起网络请求
      在完成了小程序的后端开发,下面进行小程序端发起网络请求。
      下面以一个简单的按钮请求数据为例:
      wxml文件
    <button bindtap='houduanButton1'>点击发起请求</button>
    <view wx:for="{{list}}">
        姓名:{{item}}
      </view>
    
    js文件
    
     /**
       * 页面的初始数据
       */
      data: {
        list: '',
        word: '',
        message:''
    
      },
      houduanButton1: function () {
        var that = this;
        wx.request({
          url: 'http://localhost:443/getUser',
          method: 'GET',
          header: {
            'content-type': 'application/json' // 默认值
          },
          success: function (res) {
            console.log(res.data)//打印到控制台
            var list = res.data.list;
            if (list == null) {
              var toastText = '数据获取失败';
              wx.showToast({
                title: toastText,
                icon: '',
                duration: 2000
              });
            } else {
              that.setData({
                list: list
              })
            }
          }
        })
      }
    

    主要调用的api就是wx.request,想知道将详细的介绍大家可以去微信公众平台
    接下来以搜索类型的请求为例:
    wxml文件:

     <input type="text" class="houduanTab_input" placeholder="请输入你要查询的内容" bindinput='houduanTab_input'></input>
      <button bindtap='houduanButton2'>查询</button>
      <view wx:if="{{message!=''}}">
        {{message}}
      </view>
    

    js文件:变量的定义见上一个js文件

    //获取输入框的内容
      houduanTab_input: function (e) {
        this.setData({
          word: e.detail.value
        })
      },
      // houduanButton2的网络请求
      houduanButton2: function () {
        var that = this;
        wx.request({
          url: 'http://localhost:443/getWord',
          data:{
            word: that.data.word
          },
          method: 'GET',
          header: {
            'content-type': 'application/json' // 默认值
          },
          success: function (res) {
            console.log(res.data)//打印到控制台
            var message = res.data.message;
            if (message == null) {
              var toastText = '数据获取失败';
              wx.showToast({
                title: toastText,
                icon: '',
                duration: 2000
              });
            } else {
              that.setData({
                message: message
              })
            }
          }
        })
      }
    

    至此已经完成了简易的微信小程序端与java后端进行通信。
    现在可以在启动后端项目在微信开发工具上进行测试。
    演示效果:
    这里写图片描述
    这里写图片描述
    所以至此已经完成了小程序的前后端通信。

    1. https申请
      其实也不算什么申请,在购买域名之后可以申请免费的ssl证书,在前面的配置文件application.properties中有证书的配置,将证书的pfx文件直接添加到后端项目下即可。
    2. 购买服务器部署后端api代码
      对于springboot项目,本人建议打jar,直接在服务器上部署即可,在服务器上只需要安装对应版本的jdk即可。项目部署命令:
      我购买的是阿里云的轻量级应用服务器部署的。比较划算吧。
    运行命令: nohup java -jar helloworld.jar &
    

    nohup的意思不挂服务,常驻的意思,除非云服务器重启,那就没法了;最后一个&表示执行命令后要生成日志文件nohup.out。
    当然还可以使用java -jar helloworld.jar

    源码:链接: https://pan.baidu.com/s/1PfByFfEgqkVALcc3PRhn9w 提取码: c7yf

    结束语:由于时间篇幅问题,本人介绍的内容很有限,希望对这方面有兴趣的你能有帮助。共同进步。
    觉得有帮助,给个赞赏吧。给赞赏的优先同意qq或者微信,问问题秒回复等[滑稽],谢谢老铁。
    在这里插入图片描述

    展开全文
  • 微信小程序 实例汇总 完整项目源代码
  • 'use strict'; exports.main = async (event, context) => { const token = event.token; const openid = event.openid; const name = event.custname; const phone = event.custphone;... const dizhi = event....
    'use strict';
    exports.main = async (event, context) => {
    	const token = event.token;
    	const openid = event.openid;
    	const name = event.custname;
    	const phone = event.custphone;
    	const dizhi = event.custdizhi;
    	const ydate = event.custdate;
    	const beizhu = event.custbeizhu;
    	const url = `https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=${token}`;
    	const res = await uniCloud.httpclient.request(url,{
    		method:"POST",
    		contentType: 'json',
    		dataType:"json",
    		data:{
    			touser: openid,
    			page: 'index',
    			lang: 'zh_CN',
    			data: {
    				  name1: {
    					value: name
    				  },
    				  thing2: {
    					value: dizhi
    				  },
    				  phone_number4:{
    					  value:phone
    				  },
    				  thing7:{
    					  value:ydate
    				  }
    				},
    			template_id:'krG6MsATQYYfr2xzXpmoGc4FfQh9MZXCDNoY1aGNxUU',
    			miniprogramState:'developer'
    		}
    	})
    
    	return res;
    
    };
    
    
    展开全文
  • 微信官方为提升小程序模板消息能力的使用体验,对模板消息的下发条件进行了调整。原有的小程序模板消息接口于 2020 年 1 月 10 日下线,届时将无法使用旧的小程序模板消息接口发送模板消息,取而代之的是新的一次性...
        

    微信官方为提升小程序模板消息能力的使用体验,对模板消息的下发条件进行了调整。原有的小程序模板消息接口于 2020 年 1 月 10 日下线,届时将无法使用旧的小程序模板消息接口发送模板消息,取而代之的是新的一次性订阅消息和长期订阅消息。

    订阅消息给小程序开发者带来了更好的触达用户的能力,在具体实施过程中,开发者如何把模板消息换成新的订阅消息,是否需要购买服务器来实现服务器鉴权,怎样才能在用户订阅之后一段时间后,给用户发送长期或一次性订阅消息呢?

    小程序·云开发最近支持了通过云调用免 access_token 发送订阅消息,还新增支持了在定时触发器中实现云调用,这些能力可以帮助开发者轻松玩转小程序订阅消息。

    我们今天会利用小程序·云开发进行一个小程序中实现订阅开课提醒的实战,帮助大家了解如何基于小程序·云开发快速接入小程序订阅消息。

    64173-84d95c3e5ff1cfdb.jpeg
    开课提醒小程序界面

    整体时序图

    64173-aa2d79b873960a4b.jpeg
    开课提醒订阅消息时序图

    环境准备

    获取订阅消息模板 ID

    在微信小程序管理后台中,新增一个订阅消息的模板,这里我们新增了一个开课提醒的模板。

    64173-045773b8dd9babf8.jpeg
    新增模板

    引导用户订阅

    微信小程序提供了wx.requestSubscribeMessage 接口来发起申请订阅权限界面。

    64173-7b336c2abe276e0b.jpeg
    微信申请订阅权限界面

    在 "订阅开课提醒" 的按钮上绑定 tap 事件,事件处理器我们这里用的 onSubscribe

    index.wxml

    <button
      class="btn"
      data-item="{{ item }}"
      bindtap="onSubscribe"
      hover-class="btn-hover"
    >
      订阅开课提醒
    </button>
    

    onSubscribe 函数内,我们会调用微信 API wx.requestSubscribeMessage 申请发送订阅消息权限,当用户在弹窗同意订阅之后,我们会收到 success 回调,将订阅的课程信息调用云函数 subscribe 存入云开发数据库,云函数 subscribe 的实现在下文会讲。

    index.js

    onSubscribe: function(e) {
        // 获取课程信息
        const item = e.currentTarget.dataset.item;
    
        // 调用微信 API 申请发送订阅消息
        wx.requestSubscribeMessage({
          // 传入订阅消息的模板id,模板 id 可在小程序管理后台申请
          tmplIds: [lessonTmplId],
          success(res) {
            // 申请订阅成功
            if (res.errMsg === 'requestSubscribeMessage:ok') {
              // 这里将订阅的课程信息调用云函数存入云开发数据
              wx.cloud
                .callFunction({
                  name: 'subscribe',
                  data: {
                    data: item,
                    templateId: lessonTmplId,
                  },
                })
                .then(() => {
                  wx.showToast({
                    title: '订阅成功',
                    icon: 'success',
                    duration: 2000,
                  });
                })
                .catch(() => {
                  wx.showToast({
                    title: '订阅失败',
                    icon: 'success',
                    duration: 2000,
                  });
                });
            }
          },
        });
      },
    

    将订阅消息存入云开发数据库

    接下来我们创建一个云函数 subscribe ,这个云函数的作用是将用户的订阅信息存入云开发数据库的集合 messages 中,等待将来需要通知用户时进行调用。

    在微信开发者工具的云开发面板中创建数据库集合 messages

    64173-58ac86ebbac23086.jpeg
    微信开发者工具新增数据库集合

    创建一个 subscribe 云函数,在云函数中我们将小程序端发送过来的课程订阅信息,存储在云开发数据库集合中,开发完成后,在微信开发者工具中右键上传并部署云函数。

    cloudfunctions/subscribe/index.js

    const cloud = require('wx-server-sdk');
    cloud.init();
    const db = cloud.database();
    
    exports.main = async (event, context) => {
      try {
        const {OPENID} = cloud.getWXContext();
        // 在云开发数据库中存储用户订阅的课程
        const result = await db.collection('messages').add({
          data: {
            touser: OPENID, // 订阅者的openid
            page: 'index', // 订阅消息卡片点击后会打开小程序的哪个页面
            data: event.data, // 订阅消息的数据
            templateId: event.templateId, // 订阅消息模板ID
            done: false, // 消息发送状态设置为 false
          },
        });
        return result;
      } catch (err) {
        console.log(err);
        return err;
      }
    };
    

    利用定时触发器来定期发送订阅消息

    接下来我们需要实现一个定时执行的云函数send,来检查数据库中是否有需要发送给用户的订阅消息。如果有需要发送的订阅消息,会通过云调用 cloud.openapi.subscribeMessage.send 将订阅消息发送给用户。

    创建一个名叫 send 的云函数,首先要配置云函数,在 config.jsonpermissions 中新增 subscribeMessage.send的云调用权限,然后新增一个 sendMessagerTimer 的定时触发器,定时触发器的语法和 linuxcrontab 类似,比如,我们配置的 "0 * * * * * *" 代表每分钟执行一次云函数。

    cloudfunctions/send/config.json

    {
      "permissions": {
        "openapi": ["subscribeMessage.send"]
      },
      "triggers": [
        {
          "name": "sendMessagerTimer",
          "type": "timer",
          "config": "0 * * * * * *"
        }
      ]
    }
    

    接下来是实现发送订阅消息的云函数,这个云函数会从云开发数据库集合messages中查询等待发送的消息列表,检查数据库中是否有需要发送给用户的订阅消息,发送条件可以根据自己的业务实现,比如开课提醒可以根据课程开课日期来检查是否需要发送订阅消息,在我们下面的代码示例里做了简化,筛选条件只检查了状态为未发送。

    查询到待发送的消息列表之后,我们会循环消息列表,依次发送每条订阅消息,发送成功后将数据库中消息的状态改为已发送。

    cloudfunctions/send/index.js

    const cloud = require('wx-server-sdk');
    
    exports.main = async (event, context) => {
      cloud.init();
      const db = cloud.database();
    
      try {
        // 从云开发数据库中查询等待发送的消息列表
        const messages = await db
          .collection('messages')
          // 查询条件这里做了简化,只查找了状态为未发送的消息
          // 在真正的生产环境,可以根据开课日期等条件筛选应该发送哪些消息
          .where({
            done: false,
          })
          .get();
    
        // 循环消息列表
        const sendPromises = messages.data.map(async message => {
          try {
            // 发送订阅消息
            await cloud.openapi.subscribeMessage.send({
              touser: message.touser,
              page: message.page,
              data: message.data,
              templateId: message.templateId,
            });
            // 发送成功后将消息的状态改为已发送
            return db
              .collection('messages')
              .doc(message._id)
              .update({
                data: {
                  done: true,
                },
              });
          } catch (e) {
            return e;
          }
        });
    
        return Promise.all(sendPromises);
      } catch (err) {
        console.log(err);
        return err;
      }
    };
    

    最终效果

    64173-513620ec286e7d94.jpeg
    开课提醒订阅消息截图

    源代码

    https://github.com/binggg/tcb-subscribe-demo


    关于我

    binggg(Booker Zhao) @腾讯
    
    - 先后就职于迅雷、腾讯等,个人开源项目有 mrn.js 等
    - 创办了迅雷内部组件仓库 XNPM ,参与几个迅雷前端开源项目的开发
    - 热衷于优化和提效,是一个奉行“懒惰使人进步”的懒人工程师
    

    社交资料

    微信公众号 binggg_net, 欢迎关注

    展开全文
  • 1、在微信小程序后台配置模板 2、在小程序上让用户触发订阅消息提示 将配好的模板id,使用wx.requestSubscribeMessage,使用户同意订阅消息,获取一次可以发订阅的机会 3、后台发送消息subscribeMessage.send 2.1 ...

    首先说一下思路
    1、在微信小程序后台配置模板
    2、在小程序上让用户触发订阅消息提示
    将配好的模板id,使用wx.requestSubscribeMessage,使用户同意订阅消息,获取一次可以发订阅的机会
    3、后台发送消息subscribeMessage.send

    1 小程序后台配置
    1.1 小程序后台添加我的模板,添加成功后如图,红色部分就是后面发消息需要用到的模板id
    在这里插入图片描述
    1.2 模板配好了,需要注意的就是下面图片中的详情内容,关系到你向小程序发送模板时候的data数据,必须遵循这个格式。
    在这里插入图片描述
    2 小程序前台配置
    2.1 小程序前端,调起小程序订阅消息界面,官方文档
    这里解释一个概念,一次性模板和永久模板,订阅状态和发送订阅消息次数的关系。
    一次性模板:除了特殊行业和游戏,普通使用的模板都是一次性模板,即每一调用都需要用户同意订阅,如果用户点了 总是则默认同意。
    订阅状态:指在弹出的订阅消息界面,用户可以选择同意/不同意订阅【订单发货提醒】和总是保持以上选项,可一次弹出最多三个模板的选择。这是只是用户单方面的选择是否要接受你的消息,如果用户只是点了同意,而没有勾选总是按钮,那个你将获得用户所勾选的模板每个模板一次发送订阅消息的机会;
    例如:你放了三个模板【abc】,用户勾选了a,没有勾选bc点击同意。那个你就只能通过a模板推送一条订阅消息。
    如果用户点了总是,那个下次将不会弹出提示框而是默认用户之前的选择,同意的自动同意,多一次机会,拒绝的自动拒绝。而且用户只能通过小程序设置里面修改通知,开发者没有办法修改这个,最多是通过订阅状态判断,然后提供授权按钮给客户,诱导客户修改授权。
    在这里插入图片描述
    订阅消息次数:图上诉所讲,用户每同意一次按钮,你就有一次机会,可以累加。但是如果用户否一天点了拒收此类信息,那么订阅消息次数将会清零。
    2.2 前端代码
    :调起事件要用bindtap触发。
    按钮

    <button bindtap="saveOrder">去下单</button>
    

    .js代码

    //定义模板id集合
    var tempIdList = ['2rowP6hlpGVa2_GGjS_zPeyEZeRrKMVVRZH851xhqbk','hREKVlK3qkzftKdw_TEVJ7xe3tq2amSWsky5L-B5PNA']
    wx.requestSubscribeMessage({
      tmplIds: tempIdList,
      success (res) { 
        // res格式
        //{
          // errMsg: "requestSubscribeMessage:ok",
          //zun-LzcQyW-edafCVvzPkK4de2Rllr1fFpw2A_x0oXE: "accept"
        // }
        if (res["errMsg"] == "requestSubscribeMessage:ok") {
          console.log("调用订阅消息成功!")
        }
        //下面方法判断用户具体同意或拒绝的模板。可以存放数据库或者做其他操作,我这里只是简单的判断输出
        tempIdList.map(function(item, index){
          var state ="";
          if (res[item] == "accept") {
            state = "用户同意订阅";
          }else if(res[item] == "reject"){
            state = "用户不同意订阅";
          }else if (res[item] == "ban"){
            state = "后台被禁用";
          }
          console.log(“模板” + item + “状态” + state);
        })
      },
      fail (){
        console.log("弹出订阅信息失败")
      },
      complete(){
        console.log("申请订阅结束")
      }
    })
    

    3 推送订阅消息给用户

    3.1获取调用接口凭证Access_token获取AccessToken
    通过appid和secret换取,返回token和有效时间(官方描述俩小时),建议存放redis中,设置时间一小时,没有了就重新获取,有的话就取redis的。

    /**
      * 小程序获取推送订阅消息需要的AccessToken
       * @return
       */
      public static String getAccessToken(String appid, String secret) {
      	String accesstoken = (String) RedisUtil.GetObjectByTiket("message_accesstoken");
      	if (StringUtils.isBlank(accesstoken)) {
      		String params = "grant_type=" + "client_credential" + "&appid=" + appid + "&secret=" + secret;
          	String sr = HttpRequestHelper.sendGet("https://api.weixin.qq.com/cgi-bin/token", params);
          	//解析相应内容(转换成json对象)
      		JSONObject json = JSONObject.fromObject(sr);
      		//获取会话密钥(session_key)
      		String access_token = json.get("access_token").toString();
      		if (StringUtils.isNotBlank(access_token)) {
    		accesstoken = access_token;
    		RedisUtil.SetTiketObject("message_accesstoken", access_token, RedisUtil.EXRP_HOUR);
    	}
    }
      	return accesstoken;
      }
    

    3.2向订阅消息接口推送消息
    参数格式一定要按照消息模板中的参数格式去配置,不然的话会报错,请求接口基础参数如下:
    touser——用户openid
    template_id——模板ID
    page——配置则跳转小程序中对应的页面,路径以app.json中配置的路径为准,可以通过?传参;不配置则无跳转
    miniprogram_state——代表订阅消息跳转小程序的类型:developer为开发版;trial为体验版;formal为正式版;默认为正式版,
    lang——进入小程序查看”的语言类型,支持zh_CN(简体中文)、en_US(英文)、zh_HK(繁体中文)、zh_TW(繁体中文),默认为zh_CN
    进入小程序查看”的语言类型,支持zh_CN(简体中文)、en_US(英文)、zh_HK(繁体中文)、zh_TW(繁体中文),默认为zh_CN。
    注: 参数设置建议采用JSONObject对象进行封装,我下面的参数结构是亲测成功的,可以正常使用,这里踩了很多坑,好多数据结构都不对,参数错误。
    发送成功errcode为0,失败则有具体的errcode。

    /**
    	 * 订单发货通知
    	 * @param openid  购买人openid
    	 * @param accesstoken 接口调用凭证
    	 * @param orderno 32位以内数字、字母或符号
    	 * @param goodsthind 20以内字符
    	 * @param expressname 10个以内纯汉字或20个以内纯字母或符号
    	 * @param expressno 32位以内数字、字母或符号
    	 * @param delivertime 2019年10月1日 15:01
    	 * @return 
    	 */
    	public static MessageResult sendOderFahuoMessage(String miniprogram_state, String messageTempId, String openid,String accesstoken,String orderno,String goodsthind, String expressname, String expressno, String delivertime) {
    		
    		
    		//消息内容
    		JSONObject all = new JSONObject();
    		all.put("touser", openid);
    		all.put("template_id", messageTempId);
    		all.put("page", "pages/follipoo/order-info/order-info?orderno="+orderno);
    		all.put("miniprogram_state",miniprogram_state);
    		all.put("lang", "zh_CN");
    		
    		JSONObject character_string1 = new JSONObject();
    		character_string1.put("value", orderno);
    		JSONObject thing2 = new JSONObject();
    		thing2.put("value", goodsthind);
    		JSONObject name3 = new JSONObject();
    		name3.put("value", expressname);
    		JSONObject character_string4 = new JSONObject();
    		character_string4.put("value", expressno);
    		JSONObject date10 = new JSONObject();
    		date10.put("value", delivertime);
    		
    		
    		JSONObject data = new JSONObject();
    		data.put("character_string1", character_string1);
    		data.put("thing2", thing2);
    		data.put("name3", name3);
    		data.put("character_string4", character_string4);
    		data.put("date10", date10);
    		all.put("data", data);
    		
    		
    		
    		//正式环境无需miniprogram_state
    		String params = JsonUtil.objectToJson(all);
    		String sr = HttpRequestHelper.sendPost2("https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token="+accesstoken, params);
    		
    		//解析相应内容(转换成json对象)
    		JSONObject json = JSONObject.fromObject(sr);
    		//获取会话密钥(session_key)
    		String errcode = json.get("errcode").toString();
    		String errmsg = json.get("errmsg").toString();
    		MessageResult result = new MessageResult();
    		if (errcode.equals("0")) {
    			result.setState(true);
    		}else {
    			result.setState(false);
    			result.setErrCode(errcode);
    			if (!errcode.equals("47003")) {
    				//这里是我按照官方的错误代码提示自己写了一个根据code区分报错信息的方法,这里就不放出来了。
    				errmsg = parseErrCode(errcode);
    			}
    			result.setErrMsg(errmsg);
    		}
    		return result;
    	};
    

    发送请求的工具
    HttpRequestHelper

    /**
    * 向指定URL发送GET方法的请求
     * 
     * @param url
     *            发送请求的URL
     * @param param
     *            请求参数,请求参数应该是 name1=value1&name2=value2 的形式。
     * @return URL 所代表远程资源的响应结果
     */
    public static String sendGet(String url, String param) {
        String result = "";
        BufferedReader in = null;
        try {
        	String urlNameString = url +  (StringHelp.IsNullOrEmpty(param)?"": "?" + param);
            URL realUrl = new URL(urlNameString);
            // 打开和URL之间的连接
            URLConnection connection = realUrl.openConnection();
            // 设置通用的请求属性
            connection.setRequestProperty("accept", "*/*");
            connection.setRequestProperty("connection", "Keep-Alive");
            connection.setRequestProperty("user-agent",
                    "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
            // 建立实际的连接
            connection.connect();
            // 获取所有响应头字段
            Map<String, List<String>> map = connection.getHeaderFields();
            // 遍历所有的响应头字段
            for (String key : map.keySet()) {
                System.out.println(key + "--->" + map.get(key));
            }
            // 定义 BufferedReader输入流来读取URL的响应
            in = new BufferedReader(new InputStreamReader(
                    connection.getInputStream()));
            String line;
            while ((line = in.readLine()) != null) {
                result += line;
            }
        } catch (Exception e) {
            System.out.println("发送GET请求出现异常!" + e);
            e.printStackTrace();
        }
        // 使用finally块来关闭输入流
        finally {
            try {
                if (in != null) {
                    in.close();
                }
            } catch (Exception e2) {
                e2.printStackTrace();
            }
        }
        return result;
    }
    /**
    *用于请求订阅消息接口
    *注:"connectionType", "application/json"
    **/
    public static String sendPost2(String url, String param) {
        	PrintWriter out = null;
        	BufferedReader in = null;
        	String result = "";
        	try {
        		URL realUrl = new URL(url);
        		// 打开和URL之间的连接
        		URLConnection conn = realUrl.openConnection();
        		// 设置通用的请求属性
        		conn.setRequestProperty("accept", "*/*");
        		conn.setRequestProperty("connectionType", "application/json");
        		conn.setRequestProperty("connection", "Keep-Alive");
        		conn.setRequestProperty("user-agent",
        				"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
        		// 发送POST请求必须设置如下两行
        		conn.setDoOutput(true);
        		conn.setDoInput(true);
        		// 获取URLConnection对象对应的输出流
        		out = new PrintWriter(conn.getOutputStream());
        		// 发送请求参数
        		out.print(param);
        		// flush输出流的缓冲
        		out.flush();
        		// 定义BufferedReader输入流来读取URL的响应
        		in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
        		String line;
        		while ((line = in.readLine()) != null) {
        			result += line;
        		}
        	} catch (Exception e) {
        		System.out.println("发送 POST 请求出现异常!"+e);
        		e.printStackTrace();
        	}
        	//使用finally块来关闭输出流、输入流
        	finally{
        		try{
        			if(out!=null){
        				out.close();
        			}
        			if(in!=null){
        				in.close();
        			}
        		}
        		catch(IOException ex){
        			ex.printStackTrace();
        		}
        	}
        	return result;
        }    
    

    最后整理一下遇到的问题:
    1、用户未同意订阅消息,则消息推送的错误code为43101,提示用户拒绝接受消息。
    2、如果用户选择了不同意订阅消息,并勾选了总是保持以上操作的话,微信是不会再弹出授权订阅消息提示的,只能用户自己手动修改小程序设置里的授权管理。可以通过wx.getString()获取用户点击了总是操作的模板订阅情况。
    3、网上有网友遇到过在推送消息时,data里面参数的值value存在空格的话会提示数据类型不满足规范,但是我没有遇到过,单纯记录一下。
    4、获取access_token时官方返回接口为 {“access_token”:“ACCESS_TOKEN”,“expires_in”:7200},所以时间是2小时,官方也不建议频繁的去获取,所以我才用redis存放,设置一小时的生命周期。
    5、用户每同意一次授权,则同意的模板将会获得一次推送消息的机会,暂时不确定有没有时间限制,次数可以累加;但是如果用户再授权设置中选择拒收此类消息的话推送机会会清零,即使用户重新选择接受。
    6、个人建议appid,secret,模板id,发送版本等最好写在配置文件里,然后传给接口,毕竟小程序从开发版-体验版-正式版要经历好几个过程,很多东西需要重新搞。

    展开全文
  • 本课程是一个系列入门教程,目标是从 0 开始带领读者上手实战,课程以微信小程序的核心概念作为主线,介绍配置文件、页面样式文件、JavaScript 的基本知识并以指南针为例对基本知识进行扩展,另外加上开发工具的安装...
  • 微信小程序里不免需要列表显示,有时候需要两排或者三排并列 我的想法是显示一个大view,里面再包含一个wx:for 循环,里面的cell(姑且这么叫),肯定是一个float:left。 关键是这个大的view属性该如何写, 这样写...
  • 微信小程序的布局css样式 参考自 珺L 文字 width: fit-content;font-size:20px; /*设置文字字号*/color:red; /*设置文字颜色*/font-weight:bold; /*设置字体加粗*/border:1px solid red;/*添加边框样式(粗细为1...
  • 微信小程序中,按钮也是<button></button>标签,它通过bindtap属性绑定点击事件: 然后在js里面注册这个回调函数: 回调函数里面通过 wx.navigateTo({ url: '/pages/index/talkPage', })跳转到...
  • 微信小程序连接蓝牙教程(目录) 1、新建小程序项目 2、初始化蓝牙适配器(wx.openBluetoothAdapter) 3、获取蓝牙适配器状态(getBluetoothAdapterState) 4、搜索蓝牙设备(startBluetoothDevicesDiscovery) 5、...
  • 微信小程序入门教程+案例demo 尊重原创,转载请注明出处:原文查看惊喜更多 http://blog.csdn.net/qq137722697 首先摆在好姿态,——微信小程序开发也就那么回事。你只需要一点点css(真的只要一点点)的基础就...
  • 微信小程序+java后台

    2018-03-21 21:30:58
    博主是大四学生,毕业设计做的是微信小程序+java后台。陆陆续续经历了三个月(因为白天要实习又碰上过年玩了一阵子),从对微信小程序一无所知到完成毕设,碰到许多问题,在跟大家分享一下自己的经历和一个小程序...
  • 都是些小程序源码,有的还有后台,适合小白、也适合学过了的、也适合做外包的,要的可以取...https://www.douban.com/group/topic/113284790/o2o微信小程序源码-专门针对o2o类别的小程序源码集合【更新整理中...】ht...
  • 做任何程序开发要首先找到...这里就是做微信小程序开发的全部官方文档。 知道了文档的位置,下面我们来介绍下如何做一个微信小程序开发: 第一步: 下载微信小程序开发者工具并安装,下载路径: https://mp.weix...
  • ... 1,reload()方法刷新当前页面; 2,replace() 方法刷新当前页面; ... 3,页面自动刷新当前页面;... 三种实现js 刷新当前... 1,在实现效果之前,需要知道微信小程序的页面生命周期,不是很清楚的可以看微信小程序
  • 微信小程序开发交流qq群 173683895 承接微信小程序开发。扫码加微信。 正文: 一:微信小程序跳转 使用限制 需要用户触发跳转 从 2.3.0 版本开始,若用户未点击小程序页面任意位置,则开发者将无法调用此接口...
  • 很多朋友都认为微信小程序申请、部署、发布很难,需要很长时间。 实际上,微信和腾讯云同是腾讯产品,已经提供了10分钟(根据准备资源情况,已完成小程序申请认证)完成小程序开发、部署、发布的方式。当然,实现的...
1 2 3 4 5 ... 20
收藏数 247,065
精华内容 98,826
关键字:

微信小程序