小程序 - 发送模版消息
概述
没有经验的开发者在初次尝试时会遇到很多坑,本文围绕的业务逻辑是B点击按钮进行某项操作后更新了记录的状态,发消息给记录创建人A。
主要内容
- 模版消息的发送实现
- 获取用户信息、获取form_id与转发分享button冲突及回调处理
模版消息的发送实现
api为
/**
* 发送模版消息
*/
wx.sendTemplateMessage({
// 链接上的access_token一定要带上
url: 'https://api.weixin.qq.com/cgi-bin/message/wxopen/template/send?access_token=',
// 不要认为链接上带了这里就可以省略,或者这里带了,链接上的就省略
access_token: accessToken,
// openid,产生form_id人的openid,也就是说openid要与form_id来源一致
touser: params.openId,
// 消息模版id,可以直接登陆后台,从模版库中选择模版然后复制。新建模版审核比较慢
template_id: params.templateId || templateId,
// 该字段必填,文档上写的以为可以省略
form_id: params.formId,
// 小程序页面path
page: params.page,
// 文档上写的string类型,实际不是,为选择模版勾选字段的顺序,填充value即可
data: {
keyword1: {
value: params.value1
},
keyword2: {
value: params.value2
},
keyword3: {
value: params.value3
}
}
// 需要在消息中放大展示的字段,固定的值
emphasis_keyword: 'keyword1.DATA'
})
form_id的获取
依赖<form/>
和<button/>
组件
<form
report-submit="true"
@submit="submit"
>
<button form-type="submit"></button>
</form>
submit事件会接收到e.detail.form_id
,form_id只能被使用一次,有效期为7天。那些可以发送7天后提醒的小程序肯定不是用的这个方法,而是用的公众号里的方法来发送提醒。
点击按钮只能获取一个form_id且只能被使用一次,那如果想发送多条消息怎么办?我们可以嵌套form实现
<form
report-submit="true"
@submit="submit"
>
<button form-type="submit">
<form
report-submit="true"
@submit="submit"
>
<button form-type="submit"></button>
</form>
</button>
</form>
这样就可以获取2个form_id了,用3个字段分别去标记form_id、有效期和该登陆人的openid,在使用时根据登陆时获取的openid做筛选即可。
也就是说,在小程序中基本上你看到页面的按钮都是埋了很多点的,按钮要慎点,一不小心就会给你推送消息。
获取用户信息、获取form_id与转发分享
我们会发现,获取用户信息也是<button/>
组件
<button
open-type="getUserInfo"
@getuserinfo="callback"
/>
其实这2种事件是可以并存的,只不过没有先后顺序
<form
report-submit="true"
@submit="submit"
>
<button
form-type="submit"
open-type="getUserInfo"
@getuserinfo="callback"
>
</button>
</form>
文档上没有说明是否有顺序,但在实际的操作过程中,会发现submit
事件永远先于callback
,但在一种情况下不是,但快速点击这个button时,就不会触发getUserInfo,似乎是一种缓存机制。
当然,正常情况下你可以先在submit
事件中保存得到的form_id,再在getUserInfo后使用,但是为了保险起见,还是用setInterval
比较稳妥
// 页面隐藏时要清除掉timer
onHide() {
this.timer && clearInterval(this.timer)
this.timer = null
console.log('clear timer.')
}
beforeHandle () {
if (!this.timer) {
this.timer = setInterval(() => {
// 在获取到userInfo和formId后再做其它操作
if (this.userInfo && this.formId) {
clearInterval(this.timer)
this.timer = null
console.log('timer is stopped')
} else {
console.log('timer is circling...')
}
}, 10) // 不允许为0
} else {
console.log('timer is exist!')
}
}
那如何做到用户B在操作后,将操作结果发消息给用户A呢?
发消息给用户A肯定需要用户A的form_id而不是点击按钮时用户B获取的。
我们只能在用户A做转发操作分享给B时,获取form_id存在表里,这样就可以了。
这里又会有一个问题,转发时
<button
open-type="share"
/>
并且不会触发@click
事件,如果这个按钮想在做这3件事情后还能触发点击事件怎么办?
<form
report-submit="true"
@submit="submit"
>
<button
form-type="submit"
:open-type="condition ? 'share' : 'getUserInfo'"
@getuserinfo="e => callback(e, 'optionName')"
>
</button>
</form>
...
{
callback(fnName) {
store.commit('setUser', Object.assign(res.mp.detail.userInfo))
this.beforeHandle(fn)
}
}
只能动态bind属性open-type,然后将需要做的操作传递给getuserinfo回调,在回调中再调用上面定义的timer函数beforeHandle
。