// 云函数 sendReminder — 每日定时给「今天还没遛」的主人发订阅提醒(云调用) // 依赖:① 公众平台创建订阅消息模板,把 ID 填到下方 TEMPLATE_ID(与前端 utils/config.js 一致) // ② 定时触发器(见 cloudbaserc.json 的 triggers / 或控制台配置) // ③ 用户在成果卡点「完成」时已 requestSubscribeMessage 授权(一次授权=一次可发) const cloud = require('wx-server-sdk'); cloud.init({ env: cloud.DYNAMIC_CURRENT_ENV }); const db = cloud.database(); const _ = db.command; const TEMPLATE_ID = ''; // TODO: 填入订阅消息模板 ID function todayStr(tz = 8) { const d = new Date(Date.now() + tz * 3600 * 1000); const p = (n) => String(n).padStart(2, '0'); return `${d.getUTCFullYear()}-${p(d.getUTCMonth() + 1)}-${p(d.getUTCDate())}`; } exports.main = async () => { if (!TEMPLATE_ID) return { ok: true, skipped: true, msg: '未配置 TEMPLATE_ID,跳过' }; const today = todayStr(); // 今天 lastWalkDate 不是今天的狗 → 其主人需要提醒 const dogs = await db.collection('dogs') .where({ 'stats.lastWalkDate': _.neq(today) }) .field({ _openid: true }) .get(); const owners = [...new Set(dogs.data.map((d) => d._openid))]; let sent = 0; let failed = 0; for (const openid of owners) { try { await cloud.openapi.subscribeMessage.send({ touser: openid, templateId: TEMPLATE_ID, page: 'pages/home/home', // data 字段需与实际模板字段一一对应,下面为占位示例 data: { thing1: { value: '该带狗狗出门遛一圈啦' } }, }); sent++; } catch (e) { failed++; // 多为「无有效订阅授权」,属正常 } } return { ok: true, sent, failed, owners: owners.length }; };