日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

微信小程序 - 云开发轮询实现定时推送订阅消息

發(fā)布時(shí)間:2023/12/8 编程问答 45 豆豆
生活随笔 收集整理的這篇文章主要介紹了 微信小程序 - 云开发轮询实现定时推送订阅消息 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

前言

受眾:已有小程序和云開發(fā)經(jīng)驗(yàn)(沒有的話照著流程和官方文檔也應(yīng)該可以實(shí)現(xiàn))

關(guān)于小程序的消息推送,我了解到的有以下幾種實(shí)現(xiàn)方式
1、模板消息,已于2020 年 1 月 10 日下線
2、通過服務(wù)端的統(tǒng)一服務(wù)消息下發(fā)推送,因?yàn)槟0逑F(xiàn)已下線,現(xiàn)只支持公眾號(hào)。統(tǒng)一服務(wù)消息官方文檔
2、通過關(guān)注公眾號(hào)通過公眾號(hào)實(shí)現(xiàn)長(zhǎng)期的消息推送
3、訂閱消息,包含一次性訂閱消息和長(zhǎng)期訂閱消息
訂閱消息官方文檔

關(guān)于技術(shù)實(shí)現(xiàn)的選擇

關(guān)于小程序的消息推送的幾種實(shí)現(xiàn)方式,先簡(jiǎn)單說一下各自的優(yōu)缺點(diǎn):

1、統(tǒng)一服務(wù)消息

優(yōu)點(diǎn):可以長(zhǎng)期多次發(fā)送
缺點(diǎn):因?yàn)槟0逑F(xiàn)已下線,現(xiàn)只支持公眾號(hào)

2、通過公眾號(hào)實(shí)現(xiàn)

優(yōu)點(diǎn):可以長(zhǎng)期多次發(fā)送
缺點(diǎn):需要引導(dǎo)關(guān)注公眾號(hào),沒有公眾號(hào)還得注冊(cè)一個(gè),以下還有一些注意事項(xiàng)

1、公眾號(hào)和小程序需要在同一個(gè)微信開放平臺(tái)下,保證拿到相同的UnionID
2、如果需要在消息模板上加上小程序的入口,需要微信公眾號(hào)和小程序做關(guān)聯(lián)
3、小程序和公眾號(hào)都必須是認(rèn)證過的
4、小程序需要提前知道公眾號(hào)的appid和appsecret
5、發(fā)送消息之前需要拿到用戶對(duì)應(yīng)于公眾號(hào)的openid

3、訂閱消息實(shí)現(xiàn)

訂閱消息,包含一次性訂閱消息和長(zhǎng)期訂閱消息,可惜長(zhǎng)期訂閱消息只對(duì)指定類目開放

一次性訂閱消息
優(yōu)點(diǎn):服務(wù)端,云開發(fā)都可以實(shí)現(xiàn)推送
缺點(diǎn):每次需要授權(quán),每次授權(quán)同意只推送一次

哎,沒什么可挑的,最終選擇的是訂閱消息的一次性訂閱消息,下面是微信官方介紹

小程序訂閱消息

功能介紹

消息能力是小程序能力中的重要組成,我們?yōu)殚_發(fā)者提供了訂閱消息能力,以便實(shí)現(xiàn)服務(wù)的閉環(huán)和更優(yōu)的體驗(yàn)。

  • 訂閱消息推送位置:服務(wù)通知
  • 訂閱消息下發(fā)條件:用戶自主訂閱
  • 訂閱消息卡片跳轉(zhuǎn)能力:點(diǎn)擊查看詳情可跳轉(zhuǎn)至該小程序的頁面

消息類型

1. 一次性訂閱消息

一次性訂閱消息用于解決用戶使用小程序后,后續(xù)服務(wù)環(huán)節(jié)的通知問題。用戶自主訂閱后,開發(fā)者可不限時(shí)間地下發(fā)一條對(duì)應(yīng)的服務(wù)消息;每條消息可單獨(dú)訂閱或退訂。

2. 長(zhǎng)期訂閱消息

一次性訂閱消息可滿足小程序的大部分服務(wù)場(chǎng)景需求,但線下公共服務(wù)領(lǐng)域存在一次性訂閱無法滿足的場(chǎng)景,如航班延誤,需根據(jù)航班實(shí)時(shí)動(dòng)態(tài)來多次發(fā)送消息提醒。為便于服務(wù),我們提供了長(zhǎng)期性訂閱消息,用戶訂閱一次后,開發(fā)者可長(zhǎng)期下發(fā)多條消息。

目前長(zhǎng)期性訂閱消息僅向政務(wù)民生、醫(yī)療、交通、金融、教育等線下公共服務(wù)開放,后期將逐步支持到其他線下公共服務(wù)業(yè)務(wù)。

3. 設(shè)備訂閱消息

設(shè)備訂閱消息是一種特殊類型的訂閱消息,它屬于長(zhǎng)期訂閱消息類型,且需要完成「設(shè)備接入」才能使用。
設(shè)備訂閱消息用于在設(shè)備觸發(fā)某些需要人工介入的事件時(shí)(例如設(shè)備發(fā)生故障、設(shè)備耗材不足等),向用戶發(fā)送消息通知。詳見設(shè)備訂閱消息文檔。

使用說明

步驟一:獲取模板 ID

在微信公眾平臺(tái)手動(dòng)配置獲取模板 ID:
登錄 https://mp.weixin.qq.com 獲取模板,如果沒有合適的模板,可以申請(qǐng)?zhí)砑有履0?#xff0c;審核通過后可使用。

步驟二:獲取下發(fā)權(quán)限

一次性訂閱消息、長(zhǎng)期訂閱消息,詳見接口 wx.requestSubscribeMessage

設(shè)備訂閱消息,詳見接口 wx.requestSubscribeDeviceMessage

步驟三:調(diào)用接口下發(fā)訂閱消息

一次性訂閱消息、長(zhǎng)期訂閱消息,詳見服務(wù)端接口 subscribeMessage.send

設(shè)備訂閱消息,詳見服務(wù)端接口 hardwareDevice.send

注意事項(xiàng)

  • 用戶勾選 “總是保持以上選擇,不再詢問” 之后,下次訂閱調(diào)用 wx.requestSubscribeMessage 不會(huì)彈窗,保持之前的選擇,修改選擇需要打開小程序設(shè)置進(jìn)行修改。

實(shí)現(xiàn)

設(shè)計(jì)思路

我這里的需求是紀(jì)念日的推送,到用戶設(shè)置的紀(jì)念日當(dāng)天或者前幾天,需要給用戶推送一條消息,提醒用戶紀(jì)念日已到。因?yàn)槭且淮涡允跈?quán),首先要考慮授權(quán)的時(shí)機(jī),因此考慮是在用戶新增或者編輯紀(jì)念日信息那里,設(shè)置一個(gè)開關(guān),開啟時(shí)判斷通知權(quán)限,無權(quán)限提醒到設(shè)置頁開啟通知,有權(quán)限請(qǐng)求授權(quán),授權(quán)成功開關(guān)開啟,失敗或者未開啟通知權(quán)限開關(guān)關(guān)閉,最后提交信息到數(shù)據(jù)庫,推送的接口會(huì)每天輪詢一次,根據(jù)這個(gè)狀態(tài)和是否到紀(jì)念日提醒時(shí)間判斷是否進(jìn)行推送,推送成功重置狀態(tài)。推送之后用戶再次開啟推送開關(guān)可實(shí)現(xiàn)下一次推送,形成一個(gè)閉環(huán)。

實(shí)現(xiàn)流程

  • 首先要去小程序后臺(tái)選擇一個(gè)模板
  • 然后在新增編輯頁面實(shí)現(xiàn)設(shè)計(jì)的邏輯(包含通知權(quán)限的判斷,請(qǐng)求一次性訂閱,失敗關(guān)閉開關(guān)狀態(tài),保存數(shù)據(jù)到數(shù)據(jù)庫)
  • 云開發(fā)輪詢推送消息(先查出需要推送的數(shù)據(jù),然后對(duì)應(yīng)模板的數(shù)據(jù)格式發(fā)送推送)

具體實(shí)現(xiàn)

1、選擇模板

登錄小程序開發(fā)后臺(tái) - 訂閱消息 - 公共模板庫搜索選擇一個(gè)合適的模板,然后在我的模板那里可以查看模板詳情,模板id和詳情里的字段在云開發(fā)那里需要使用



2、編輯頁代碼實(shí)現(xiàn)

首先先把開關(guān)相關(guān)的頁面和邏輯實(shí)現(xiàn),這里就不細(xì)說。
然后是判斷通知權(quán)限和請(qǐng)求一次性訂閱

2.1、判斷通知權(quán)限

判斷通知權(quán)限使用的是wx.getSetting

wx.getSetting({withSubscriptions: true,success (res) {console.log(res.authSetting)// res.authSetting = {// "scope.userInfo": true,// "scope.userLocation": true// }console.log(res.subscriptionsSetting)// res.subscriptionsSetting = {// mainSwitch: true, // 訂閱消息總開關(guān)// itemSettings: { // 每一項(xiàng)開關(guān)// SYS_MSG_TYPE_INTERACTIVE: 'accept', // 小游戲系統(tǒng)訂閱消息// SYS_MSG_TYPE_RANK: 'accept'// zun-LzcQyW-edafCVvzPkK4de2Rllr1fFpw2A_x0oXE: 'reject', // 普通一次性訂閱消息// ke_OZC_66gZxALLcsuI7ilCJSP2OJ2vWo2ooUPpkWrw: 'ban',// }// }} })

2.2、請(qǐng)求一次性訂閱

請(qǐng)求一次性訂閱使用的是wx.requestSubscribeMessage

wx.requestSubscribeMessage({tmplIds: [''], // 模板idsuccess (res) { } })

2.3、把數(shù)據(jù)存儲(chǔ)到云數(shù)據(jù)庫

每個(gè)項(xiàng)目數(shù)據(jù)結(jié)構(gòu)不一樣,這里也不展開說

核心代碼

// 是否提醒onSwitchChange: function (event) {this.setData({["dict.isPush"]: event.detail.value})if (!event.detail.value) {this.setData({["dict.pushTime"]: ''})}if (event.detail.value) {this.checkAndRequestSubscribeMessage()}},// 檢查訂閱消息權(quán)限,未開啟提示前往開啟,已開啟請(qǐng)求訂閱消息checkAndRequestSubscribeMessage() {let that = thiswx.getSetting({withSubscriptions: true,success(res) {console.log(res.subscriptionsSetting)// 訂閱消息總開關(guān)是否開啟if (!res.subscriptionsSetting.mainSwitch) {that.subscriptionFailed()wx.showModal({title: '提示',content: '當(dāng)前暫未開啟接消息提醒,是否前往設(shè)置頁開啟?',success(res) {if (res.confirm) {wx.openSetting()}}})} else {let templateId = 'c64Gp5-89xyD55rnDr0oBWQNphWlNm_l4MX-Sduuj2c' // 模板IDwx.requestSubscribeMessage({tmplIds: [templateId],success(res) {console.log(res)// 申請(qǐng)訂閱成功,將訂閱信息調(diào)用云函數(shù)存入云開發(fā)數(shù)據(jù)if (res.errMsg === 'requestSubscribeMessage:ok') {// res[templateId]: 'accept'、'reject'、'ban'、'filter'if (res[templateId] == 'accept') {} else {that.subscriptionFailed()}}},fail(err) {console.log(err)that.subscriptionFailed()wx.showToast({title: '訂閱失敗',icon: 'none'})}})}}})},// 訂閱失敗subscriptionFailed() {this.setData({["dict.isPush"]: false})},

3、云開發(fā)輪詢推送

這里才是重點(diǎn)!!!首先在項(xiàng)目中選擇云函數(shù)目錄右鍵新建一個(gè)云函數(shù),然后就需要在這個(gè)云函數(shù)中實(shí)現(xiàn)輪詢推送的代碼了,我這里建的云函數(shù)是push

3.1、推送

推送使用的是服務(wù)端的subscribeMessage.send方法。
這里是的是云調(diào)用進(jìn)行推送,這樣可以使用云開發(fā)
subscribeMessage.send使用需要在云函數(shù)代碼的config.json文件中配置 subscribeMessage.send API 的權(quán)限,詳情

配置如下

"permissions": {"openapi": ["subscribeMessage.send"]},

請(qǐng)求參數(shù)

屬性類型默認(rèn)值必填說明
touserstring接收者(用戶)的 openid
templateIdstring所需下發(fā)的訂閱模板id
pagestring點(diǎn)擊模板卡片后的跳轉(zhuǎn)頁面,僅限本小程序內(nèi)的頁面。支持帶參數(shù),(示例index?foo=bar)。該字段不填則模板無跳轉(zhuǎn)。
dataObject模板內(nèi)容,格式形如 { “key1”: { “value”: any }, “key2”: { “value”: any } }
miniprogramStatestring跳轉(zhuǎn)小程序類型:developer為開發(fā)版;trial為體驗(yàn)版;formal為正式版;默認(rèn)為正式版
langstring進(jìn)入小程序查看”的語言類型,支持zh_CN(簡(jiǎn)體中文)、en_US(英文)、zh_HK(繁體中文)、zh_TW(繁體中文),默認(rèn)為zh_CN

官方請(qǐng)求示例

const cloud = require('wx-server-sdk') cloud.init({env: cloud.DYNAMIC_CURRENT_ENV, }) exports.main = async (event, context) => {try {const result = await cloud.openapi.subscribeMessage.send({"touser": 'OPENID',"page": 'index',"lang": 'zh_CN',"data": {"number01": {"value": '339208499'},"date01": {"value": '2015年01月05日'},"site01": {"value": 'TIT創(chuàng)意園'},"site02": {"value": '廣州市新港中路397號(hào)'}},"templateId": 'TEMPLATE_ID',"miniprogramState": 'developer'})return result} catch (err) {return err} }

miniprogramState在正式環(huán)境要換成formal或注釋掉這行

3.2、輪詢

輪詢使用的云開發(fā)的定時(shí)觸發(fā)器

定時(shí)觸發(fā)器官方介紹

該功能需開發(fā)者工具 1.02.1811270 及以上版本方可使用 從開發(fā)者工具 1.02.1910182 開始,新上傳的定時(shí)觸發(fā)器內(nèi)支持使用云調(diào)用

  • 如果云函數(shù)需要定時(shí) / 定期執(zhí)行,也就是定時(shí)觸發(fā),我們可以使用云函數(shù)定時(shí)觸發(fā)器。配置了定時(shí)觸發(fā)器的云函數(shù),會(huì)在相應(yīng)時(shí)間點(diǎn)被自動(dòng)觸發(fā),函數(shù)的返回結(jié)果不會(huì)返回給調(diào)用方。

  • 在需要添加觸發(fā)器的云函數(shù)目錄下新建文件 config.json,格式如下:

{// triggers 字段是觸發(fā)器數(shù)組,目前僅支持一個(gè)觸發(fā)器,即數(shù)組只能填寫一個(gè),不可添加多個(gè)"triggers": [{// name: 觸發(fā)器的名字,規(guī)則見下方說明"name": "myTrigger",// type: 觸發(fā)器類型,目前僅支持 timer (即 定時(shí)觸發(fā)器)"type": "timer",// config: 觸發(fā)器配置,在定時(shí)觸發(fā)器下,config 格式為 cron 表達(dá)式,規(guī)則見下方說明"config": "0 0 2 1 * * *"}] }
官方示例

下面展示了一些 Cron 表達(dá)式和相關(guān)含義的示例:

  • */5 * * * * * * 表示每5秒觸發(fā)一次
  • 0 0 2 1 * * * 表示在每月的1日的凌晨2點(diǎn)觸發(fā)
  • 0 15 10 * * MON-FRI * 表示在周一到周五每天上午10:15觸發(fā)
  • 0 0 10,14,16 * * * * 表示在每天上午10點(diǎn),下午2點(diǎn),4點(diǎn)觸發(fā)
  • 0 */30 9-17 * * * * 表示在每天上午9點(diǎn)到下午5點(diǎn)內(nèi)每半小時(shí)觸發(fā)
  • 0 0 12 * * WED * 表示在每個(gè)星期三中午12點(diǎn)觸發(fā)

triggers中的config字段可以控制觸發(fā)的頻率,具體開發(fā)測(cè)試時(shí)我使用的是50秒調(diào)用一次

"config": "*/50 * * * * * *"

這里有個(gè)坑,如果代碼實(shí)現(xiàn)上傳并部署云函數(shù)之后,左等右等在日志中看不到日志,因?yàn)樯倭艘粋€(gè)步驟,在上傳并部署云函數(shù)之后,需要右鍵云函數(shù)上傳觸發(fā)器,這樣才生效,想關(guān)閉可以刪除觸發(fā)器

輪詢推送完整代碼

config.json

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

index.js

// 云函數(shù)入口文件 const cloud = require('wx-server-sdk')// 初始化 cloud cloud.init({// API 調(diào)用都保持和云函數(shù)當(dāng)前所在環(huán)境一致env: cloud.DYNAMIC_CURRENT_ENV })const db = cloud.database() const _ = db.command const $ = db.command.aggregate const kTableName = '換成自己的表名'// 云函數(shù)入口函數(shù) exports.main = async (event, context) => {try {// 從云開發(fā)數(shù)據(jù)庫中查詢等待發(fā)送的消息列表const msgArr = await db.collection(kTableName)// 查詢條件,已開啟推送,并且提醒時(shí)間為今天.where({A_IsPush: true,A_PushTime: timeStampToTime(new Date().getTime(), '{y}/{m}/ozvdkddzhkzd')}).get()// 循環(huán)消息列表const sendPromises = msgArr.data.map(async msgData => {try {// 發(fā)送訂閱消息await cloud.openapi.subscribeMessage.send({touser: msgData._openid, // 要發(fā)送用戶的openidpage: 'pages/home/home', // 用戶通過消息通知點(diǎn)擊進(jìn)入小程序的頁面lang: 'zh_CN',templateId: 'c64Gp5-89xyD55rnDr0oBWQNphWlNm_l4MX-Sduuj2c', // 訂閱消息模板ID// 跳轉(zhuǎn)小程序類型:developer為開發(fā)版;trial為體驗(yàn)版;formal為正式版;默認(rèn)為正式版// miniprogramState: 'developer',// 要發(fā)送的數(shù)據(jù),要和模板一致data: {// 紀(jì)念日名稱thing5: {value: msgData.A_Title},// 紀(jì)念日時(shí)間time2: {value: msgData.A_Time},// 備注thing4: {value: msgData.A_Remarks ? msgData.A_Remarks : '無'},}})// 發(fā)送成功后將數(shù)據(jù)狀態(tài)重置return db.collection(kTableName).doc(msgData._id).update({data: {A_IsPush: false,A_PushTime: '',A_NextTime: '',},})} catch (e) {return e}})return Promise.all(sendPromises)} catch (err) {console.log(err)return err} }function timeStampToTime(time, cFormat) {if (arguments.length === 0) {return null}const format = cFormat || '{y}-{m}-ozvdkddzhkzd {h}:{i}:{s}'let dateif (typeof time === 'object') {} else {if (('' + time).length === 10) time = parseInt(time) * 1000date = new Date(time)}const formatObj = {y: date.getFullYear(),m: date.getMonth() + 1,d: date.getDate(),h: date.getHours(),i: date.getMinutes(),s: date.getSeconds(),w: date.getDay()}const time_str = format.replace(/{(y|m|d|h|i|s|w)+}/g, (result, key) => {let value = formatObj[key]if (key === 'w') {return ['日', '一', '二', '三', '四', '五', '六'][value]}if (result.length > 0 && value < 10) {value = '0' + value}return value || 0})return time_str }// 定時(shí)觸發(fā)器 // https://developers.weixin.qq.com/miniprogram/dev/wxcloud/guide/functions/triggers.html// 50秒一次 // "config": "*/50 * * * * * *"// 每天上午8點(diǎn)一次 // "config": "0 0 8 * * * *"

package.json

{"name": "push","version": "1.0.0","description": "","main": "index.js","scripts": {"test": "echo \"Error: no test specified\" && exit 1"},"author": "","license": "ISC","dependencies": {"wx-server-sdk": "~2.6.1"} }

3.3、上傳并部署云函數(shù)

所有代碼實(shí)現(xiàn)之后,可以先把項(xiàng)目環(huán)境設(shè)置為開發(fā)環(huán)境,然后右鍵上傳并部署云函數(shù),然后上傳觸發(fā)器

然后打開云函數(shù)控制臺(tái),選擇云函數(shù)-日志,進(jìn)行查看狀態(tài),如果成功并且有需要推送的數(shù)據(jù),手機(jī)會(huì)收到推送消息,失敗的話根據(jù)日志進(jìn)行修改。


至此結(jié)束

最后推薦一下我的小程序,我的紀(jì)念日小助手

總結(jié)

以上是生活随笔為你收集整理的微信小程序 - 云开发轮询实现定时推送订阅消息的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。