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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

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

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

前言

受眾:已有小程序和云開發經驗(沒有的話照著流程和官方文檔也應該可以實現)

關于小程序的消息推送,我了解到的有以下幾種實現方式
1、模板消息,已于2020 年 1 月 10 日下線
2、通過服務端的統一服務消息下發推送,因為模板消息現已下線,現只支持公眾號。統一服務消息官方文檔
2、通過關注公眾號通過公眾號實現長期的消息推送
3、訂閱消息,包含一次性訂閱消息和長期訂閱消息
訂閱消息官方文檔

關于技術實現的選擇

關于小程序的消息推送的幾種實現方式,先簡單說一下各自的優缺點:

1、統一服務消息

優點:可以長期多次發送
缺點:因為模板消息現已下線,現只支持公眾號

2、通過公眾號實現

優點:可以長期多次發送
缺點:需要引導關注公眾號,沒有公眾號還得注冊一個,以下還有一些注意事項

1、公眾號和小程序需要在同一個微信開放平臺下,保證拿到相同的UnionID
2、如果需要在消息模板上加上小程序的入口,需要微信公眾號和小程序做關聯
3、小程序和公眾號都必須是認證過的
4、小程序需要提前知道公眾號的appid和appsecret
5、發送消息之前需要拿到用戶對應于公眾號的openid

3、訂閱消息實現

訂閱消息,包含一次性訂閱消息和長期訂閱消息,可惜長期訂閱消息只對指定類目開放

一次性訂閱消息
優點:服務端,云開發都可以實現推送
缺點:每次需要授權,每次授權同意只推送一次

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

小程序訂閱消息

功能介紹

消息能力是小程序能力中的重要組成,我們為開發者提供了訂閱消息能力,以便實現服務的閉環和更優的體驗。

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

消息類型

1. 一次性訂閱消息

一次性訂閱消息用于解決用戶使用小程序后,后續服務環節的通知問題。用戶自主訂閱后,開發者可不限時間地下發一條對應的服務消息;每條消息可單獨訂閱或退訂。

2. 長期訂閱消息

一次性訂閱消息可滿足小程序的大部分服務場景需求,但線下公共服務領域存在一次性訂閱無法滿足的場景,如航班延誤,需根據航班實時動態來多次發送消息提醒。為便于服務,我們提供了長期性訂閱消息,用戶訂閱一次后,開發者可長期下發多條消息。

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

3. 設備訂閱消息

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

使用說明

步驟一:獲取模板 ID

在微信公眾平臺手動配置獲取模板 ID:
登錄 https://mp.weixin.qq.com 獲取模板,如果沒有合適的模板,可以申請添加新模板,審核通過后可使用。

步驟二:獲取下發權限

一次性訂閱消息、長期訂閱消息,詳見接口 wx.requestSubscribeMessage

設備訂閱消息,詳見接口 wx.requestSubscribeDeviceMessage

步驟三:調用接口下發訂閱消息

一次性訂閱消息、長期訂閱消息,詳見服務端接口 subscribeMessage.send

設備訂閱消息,詳見服務端接口 hardwareDevice.send

注意事項

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

實現

設計思路

我這里的需求是紀念日的推送,到用戶設置的紀念日當天或者前幾天,需要給用戶推送一條消息,提醒用戶紀念日已到。因為是一次性授權,首先要考慮授權的時機,因此考慮是在用戶新增或者編輯紀念日信息那里,設置一個開關,開啟時判斷通知權限,無權限提醒到設置頁開啟通知,有權限請求授權,授權成功開關開啟,失敗或者未開啟通知權限開關關閉,最后提交信息到數據庫,推送的接口會每天輪詢一次,根據這個狀態和是否到紀念日提醒時間判斷是否進行推送,推送成功重置狀態。推送之后用戶再次開啟推送開關可實現下一次推送,形成一個閉環。

實現流程

  • 首先要去小程序后臺選擇一個模板
  • 然后在新增編輯頁面實現設計的邏輯(包含通知權限的判斷,請求一次性訂閱,失敗關閉開關狀態,保存數據到數據庫)
  • 云開發輪詢推送消息(先查出需要推送的數據,然后對應模板的數據格式發送推送)

具體實現

1、選擇模板

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



2、編輯頁代碼實現

首先先把開關相關的頁面和邏輯實現,這里就不細說。
然后是判斷通知權限和請求一次性訂閱

2.1、判斷通知權限

判斷通知權限使用的是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, // 訂閱消息總開關// itemSettings: { // 每一項開關// SYS_MSG_TYPE_INTERACTIVE: 'accept', // 小游戲系統訂閱消息// SYS_MSG_TYPE_RANK: 'accept'// zun-LzcQyW-edafCVvzPkK4de2Rllr1fFpw2A_x0oXE: 'reject', // 普通一次性訂閱消息// ke_OZC_66gZxALLcsuI7ilCJSP2OJ2vWo2ooUPpkWrw: 'ban',// }// }} })

2.2、請求一次性訂閱

請求一次性訂閱使用的是wx.requestSubscribeMessage

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

2.3、把數據存儲到云數據庫

每個項目數據結構不一樣,這里也不展開說

核心代碼

// 是否提醒onSwitchChange: function (event) {this.setData({["dict.isPush"]: event.detail.value})if (!event.detail.value) {this.setData({["dict.pushTime"]: ''})}if (event.detail.value) {this.checkAndRequestSubscribeMessage()}},// 檢查訂閱消息權限,未開啟提示前往開啟,已開啟請求訂閱消息checkAndRequestSubscribeMessage() {let that = thiswx.getSetting({withSubscriptions: true,success(res) {console.log(res.subscriptionsSetting)// 訂閱消息總開關是否開啟if (!res.subscriptionsSetting.mainSwitch) {that.subscriptionFailed()wx.showModal({title: '提示',content: '當前暫未開啟接消息提醒,是否前往設置頁開啟?',success(res) {if (res.confirm) {wx.openSetting()}}})} else {let templateId = 'c64Gp5-89xyD55rnDr0oBWQNphWlNm_l4MX-Sduuj2c' // 模板IDwx.requestSubscribeMessage({tmplIds: [templateId],success(res) {console.log(res)// 申請訂閱成功,將訂閱信息調用云函數存入云開發數據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、云開發輪詢推送

這里才是重點!!!首先在項目中選擇云函數目錄右鍵新建一個云函數,然后就需要在這個云函數中實現輪詢推送的代碼了,我這里建的云函數是push

3.1、推送

推送使用的是服務端的subscribeMessage.send方法。
這里是的是云調用進行推送,這樣可以使用云開發
subscribeMessage.send使用需要在云函數代碼的config.json文件中配置 subscribeMessage.send API 的權限,詳情

配置如下

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

請求參數

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

官方請求示例

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創意園'},"site02": {"value": '廣州市新港中路397號'}},"templateId": 'TEMPLATE_ID',"miniprogramState": 'developer'})return result} catch (err) {return err} }

miniprogramState在正式環境要換成formal或注釋掉這行

3.2、輪詢

輪詢使用的云開發的定時觸發器

定時觸發器官方介紹

該功能需開發者工具 1.02.1811270 及以上版本方可使用 從開發者工具 1.02.1910182 開始,新上傳的定時觸發器內支持使用云調用

  • 如果云函數需要定時 / 定期執行,也就是定時觸發,我們可以使用云函數定時觸發器。配置了定時觸發器的云函數,會在相應時間點被自動觸發,函數的返回結果不會返回給調用方。

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

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

下面展示了一些 Cron 表達式和相關含義的示例:

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

triggers中的config字段可以控制觸發的頻率,具體開發測試時我使用的是50秒調用一次

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

這里有個坑,如果代碼實現上傳并部署云函數之后,左等右等在日志中看不到日志,因為少了一個步驟,在上傳并部署云函數之后,需要右鍵云函數上傳觸發器,這樣才生效,想關閉可以刪除觸發器

輪詢推送完整代碼

config.json

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

index.js

// 云函數入口文件 const cloud = require('wx-server-sdk')// 初始化 cloud cloud.init({// API 調用都保持和云函數當前所在環境一致env: cloud.DYNAMIC_CURRENT_ENV })const db = cloud.database() const _ = db.command const $ = db.command.aggregate const kTableName = '換成自己的表名'// 云函數入口函數 exports.main = async (event, context) => {try {// 從云開發數據庫中查詢等待發送的消息列表const msgArr = await db.collection(kTableName)// 查詢條件,已開啟推送,并且提醒時間為今天.where({A_IsPush: true,A_PushTime: timeStampToTime(new Date().getTime(), '{y}/{m}/ozvdkddzhkzd')}).get()// 循環消息列表const sendPromises = msgArr.data.map(async msgData => {try {// 發送訂閱消息await cloud.openapi.subscribeMessage.send({touser: msgData._openid, // 要發送用戶的openidpage: 'pages/home/home', // 用戶通過消息通知點擊進入小程序的頁面lang: 'zh_CN',templateId: 'c64Gp5-89xyD55rnDr0oBWQNphWlNm_l4MX-Sduuj2c', // 訂閱消息模板ID// 跳轉小程序類型:developer為開發版;trial為體驗版;formal為正式版;默認為正式版// miniprogramState: 'developer',// 要發送的數據,要和模板一致data: {// 紀念日名稱thing5: {value: msgData.A_Title},// 紀念日時間time2: {value: msgData.A_Time},// 備注thing4: {value: msgData.A_Remarks ? msgData.A_Remarks : '無'},}})// 發送成功后將數據狀態重置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 }// 定時觸發器 // https://developers.weixin.qq.com/miniprogram/dev/wxcloud/guide/functions/triggers.html// 50秒一次 // "config": "*/50 * * * * * *"// 每天上午8點一次 // "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、上傳并部署云函數

所有代碼實現之后,可以先把項目環境設置為開發環境,然后右鍵上傳并部署云函數,然后上傳觸發器

然后打開云函數控制臺,選擇云函數-日志,進行查看狀態,如果成功并且有需要推送的數據,手機會收到推送消息,失敗的話根據日志進行修改。


至此結束

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

總結

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

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。