微信小程序-发送模板消息
1 添加一个小程序的消息模板,获取到模板id,存储到数据库中,方便以后修改调用
2. https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/template-message/templateMessage.send.html 小程序模板消息 官网文档,直接调用send方法就行
这里有个坑,就是 form_id, 这个是用户触发表单事件的表单id,需要存储到数据库中,给这个表单提交以后的数据,添加一个字段叫做form_id(7天过期), 这个formid 是和提交时的openid有关联的,只能是提交的那个人才能用,别人用不了
也就是说,想要给谁发送模板消息,就要存储谁的form_id。
例如 剑圣给守望者提交了一个 爱你呦 的表单(数据库里会存储这个表单的form_id),但是守望者回复这个表单,并且向给 剑圣发送一个提醒的模板消息,就需要从剑圣提交的表单中获取存储的form_id,然后拼接url,发送post请求才能成功
守望者提交表单时的 form_id,只能给守望者自己发送模板消息
3. 代码正文:
剑圣端:
Form表单属性
bindsubmit="sendClick" 提交方法
report-submit="true" 必须有,用来获取form_id
button
formType="submit" 使用这个属性,进行表单提交,不用bindtap提交
Wxml:
<form bindsubmit="sendClick" bindreset="inputReset" report-submit="true">
<input focus="true" name="send-input" adjust-position='{{false}}' value='{{inputValue}}' bindfocus='focus' bindblur='blur' bindconfirm="sendClick" bindinput="getcontent" />
<image src='./../../../centent/img/camera.png' bindtap="chooseBanner"></image>
<button formType="submit" bindtap="addquestion">发送</button>
</form>
Js:
sendClick: function(e) {
var formId = e.detail.formId;//获取form_id,存储到数据库
hcxcx.requestPost(hcxcx.apiUrl.addquestion, { formId : formId },function(){
})
}
守望者端:
执行回复操作,C#代码:
//发送模板消息
Public void Addquestion(){
//获取用户的formid,这个就是剑圣端提交保单时存储的formId
var list = questionbll.GetList("IsNoTeam:1,MemberId:'" + memberid + "',XcxFormIdNoNull:1");
var fid = list.OrderByDescending(x => x.CreateTime).FirstOrDefault().XcxFormId;
var openid=memberid.openid;//这个是需要发送的用户(剑圣的openid,必须是小程序的openid)
//拼接模板消息主体
XcxRequestData xr = new XcxRequestData();
XcxRequestDataKeyword xcxRequest1 = new XcxRequestDataKeyword();
xcxRequest1.value = createTime.ToString("yyyy-MM-dd HH:mm:ss");
XcxRequestDataKeyword xcxRequest2 = new XcxRequestDataKeyword();
xcxRequest2.value = user.RealName;
XcxRequestDataKeyword xcxRequest3 = new XcxRequestDataKeyword();
xcxRequest3.value = "尊敬的用户您好,您的咨询已经被" + user.RealName + "解答,请及时查看";
xr.keyword1 = xcxRequest1;
xr.keyword2 = xcxRequest2;
xr.keyword3 = xcxRequest3;
//获取消息模板
TemplateMesEntity templateMesEntity = templateMesCache.GetEntityByTeamIdAndTypeId(teamid.ToInt(), 30);
//延迟4秒发送,否则苹果收不到消息
System.Timers.Timer timer = new System.Timers.Timer(4000);
timer.Elapsed += delegate (object sender, System.Timers.ElapsedEventArgs e)
{
timer.Enabled = false;
XcxSendTemplateMsg xcxSend = new XcxSendTemplateMsg();
xcxSend.form_id = fid;
xcxSend.page = "pages/GroupTools/UserClient/UserClient";
xcxSend.template_id = templateMesEntity.TemplateId;
xcxSend.touser = openid;
xcxSend.data = xr;
XcxSendTemplateMsg(xcxSend);
};
timer.Enabled = true;
}
/// <summary>
/// 获取小程序token
/// </summary>
/// <returns></returns>
public static string GetXcxAccessToken()
{
var token = "";
var tw = twCache.GetDataItemList("1001");
if (tw != null)
{
if (string.IsNullOrEmpty(tw.XcxAccessToken) || (!string.IsNullOrEmpty(tw.XcxAccessToken) && tw.XcxExpires != null && tw.XcxExpires <= DateTime.Now))
{
//获取新的token,存储到数据库
var url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + tw.XcxAppId + "&secret=" + tw.XcxAppSecret + "";
var accesstokenstr = HcCrm.Util.HttpMethods.HttpGet(url);
var xcxtoken = JsonConvert.DeserializeObject<XcxAccessToken>(accesstokenstr);
if (xcxtoken.errcode == 0)
{
token = xcxtoken.access_token;
tw.XcxAccessToken = xcxtoken.access_token;
tw.XcxExpires = DateTime.Now.AddSeconds(xcxtoken.expires_in);
teamwechatBLL.SaveForm(tw.TeamWcId, tw);
}
}
else
{
token = tw.XcxAccessToken;
}
}
return token;
}
/// <summary>
/// 发送小程序模板消息
/// </summary>
/// <param name="xcxSendTemplateMsg"></param>
/// <returns></returns>
public static XcxReturnResult XcxSendTemplateMsg(XcxSendTemplateMsg xcxSendTemplateMsg)
{
try
{
var token = GetXcxAccessToken();
var url = "https://api.weixin.qq.com/cgi-bin/message/wxopen/template/send?access_token=" + token;
var data = JsonConvert.SerializeObject(xcxSendTemplateMsg);
var resultstr = HcCrm.Util.HttpMethods.HttpPost(url, data);
// using Newtonsoft.Json;
var result = JsonConvert.DeserializeObject<XcxReturnResult>(resultstr);
LogEntity log = new LogEntity();
log.ExecuteResultJson = result.errmsg;
LogBLL.WriteLog(log);
return result;
}
catch (Exception ex)
{
LogEntity log = new LogEntity();
log.ExecuteResultJson = "XcxSendTemplateMsg Exception:" + ex.Message;
LogBLL.WriteLog(log);
throw;
}
}
/// <summary>
/// HTTP POST方式请求数据
/// </summary>
/// <param name="url">URL.</param>
/// <param name="param">POST的数据</param>
/// <returns></returns>
public static string HttpPost(string url, string param = null)
{
HttpWebRequest request;
//如果是发送HTTPS请求
if (url.StartsWith("https", StringComparison.OrdinalIgnoreCase))
{
ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult);
request = WebRequest.Create(url) as HttpWebRequest;
request.ProtocolVersion = HttpVersion.Version10;
}
else
{
request = WebRequest.Create(url) as HttpWebRequest;
}
request.Method = "POST";
//request.ContentType = "application/x-www-form-urlencoded";
request.ContentType = "application/x-www-form-urlencoded;charset=unicode";//解决中文乱码问题
request.Accept = "*/*";
request.Timeout = 15000;
request.AllowAutoRedirect = false;
StreamWriter requestStream = null;
WebResponse response = null;
string responseStr = null;
try
{
requestStream = new StreamWriter(request.GetRequestStream());
requestStream.Write(param);
requestStream.Close();
response = request.GetResponse();
if (response != null)
{
// StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.Default);
StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.UTF8);//解决中文乱码问题
responseStr = reader.ReadToEnd();
reader.Close();
}
}
catch (Exception)
{
throw;
}
finally
{
request = null;
requestStream = null;
response = null;
}
return responseStr;
}
/// <summary>
/// 小程序token类
/// </summary>
public class XcxAccessToken
{
public string access_token { get; set; }
public double expires_in { get; set; }
public int errcode { get; set; }
public string errmsg { get; set; }
}
public class XcxSendTemplateMsg
{
/// <summary>
/// 接收者(用户)的 openid
/// </summary>
public string touser { get; set; }
/// <summary>
/// 所需下发的模板消息的id
/// </summary>
public string template_id { get; set; }
/// <summary>
/// 点击模板卡片后的跳转页面,仅限本小程序内的页面。支持带参数,(示例index?foo=bar)。该字段不填则模板无跳转。
/// </summary>
public string page { get; set; }
/// <summary>
/// 表单提交场景下,为 submit 事件带上的 formId;支付场景下,为本次支付的 prepay_id
/// </summary>
public string form_id { get; set; }
/// <summary>
/// 模板内容,不填则下发空模板。具体格式请参考示例。
/// </summary>
public XcxRequestData data { get; set; }
/// <summary>
/// 模板需要放大的关键词,不填则默认无放大
/// </summary>
public string emphasis_keyword { get; set; }
}
public class XcxRequestData
{
public XcxRequestDataKeyword keyword1 { get; set; }
public XcxRequestDataKeyword keyword2 { get; set; }
public XcxRequestDataKeyword keyword3 { get; set; }
}
public class XcxRequestDataKeyword
{
public string value { get; set; }
}
public class XcxReturnResult
{
public int errcode { get; set; }
public string errmsg { get; set; }
}
微信小程序-发送模板消息的更多相关文章
- 微信小程序发送模板消息
微信小程序发送模板消息 标签(空格分隔): php 看小程序文档 [模板消息文档总览]:https://developers.weixin.qq.com/miniprogram/dev/framewo ...
- 微信小程序 发送模板消息的功能实现
背景 - 小程序开发的过程中,绝大多数会满足微信支付 - 那么,作为友好交互的体现,自然就会考虑到支付后的消息通知咯 - 所以,我的小程序项目也要求完成这个效果,so.分享一下自己的实现步骤,以方便道 ...
- 微信小程序-发送模板消息(C#)
步骤一:获取模板ID 有两个方法可以获取模版ID 通过模版消息管理接口获取模版ID 在微信公众平台手动配置获取模版ID 步骤二:页面的 <form/> 组件,属性report-submit ...
- 微信小程序开发模板消息的时候 出现 errcode: 41028, errmsg: "invalid form id hint:
小程序开发模板消息的时候 出现 errcode: 41028, errmsg: "invalid form id hint: 我是使用的微信支付发送模板消息,提示的formid无效的 大家 ...
- Python 发送微信小程序的模板消息
在小程序的开发过程中,会存在模板消息的发送,具体文档见 这里,模板消息的发送是和语言无关的,这里将简要写一下怎么用 Python 给用户发送模板消息. 通过文档可以知道,发送的时候,需要使用小 ...
- 微信小程序 发送模版消息
微信小程序开发之发送模板消息 1,小程序wxml页面form表单添加 report-submit="true" <form bindsubmit="sub" ...
- 微信小程序的模板消息与小程序订阅消息
小程序订阅消息 功能介绍 消息能力是小程序能力中的重要组成,我们为开发者提供了订阅消息能力,以便实现服务的闭环和更优的体验. 订阅消息推送位置:服务通知 订阅消息下发条件:用户自主订阅 订阅消息卡片跳 ...
- 微信小程序之模板消息推送
最近在用sanic框架写微信小程序,其中写了一个微信消息推送,还挺有意思的,写了个小demo 具体见官方文档:https://developers.weixin.qq.com/miniprogram/ ...
- .netcore 3.1 C# 微信小程序发送订阅消息
一.appsettings.json定义小程序配置信息 "WX": { "AppId": "wx88822730803edd44", &qu ...
随机推荐
- git 修改分支 删除分支 新增分支
一.修改分支名 1.本地分支重命名 git branch -m oldName newName 2.将重命名后的分支推送到远程 git push origin newName 3.重新更新所有分支 g ...
- GO判断输入
判断用户密码输入: package main import"fmt" func main(){ var a int var b int fmt.Printf("请输入密码 ...
- Vases and Flowers-HDU4614 二分+线段树
题意: 给你N个花瓶,编号是0 到 N - 1 ,一开始每个花瓶都是空的,你有两个操作: 第一个操作: 从第x个花瓶起开始插花,总共插y束,如果遇到花瓶中有花就跳过这个花瓶,直到花插完或者 插到第N ...
- swoole 父子进程间通信
<?php /** * 场景: * 监控订单表状态 父子进程通信 * 一个主进程 两个子进程实现 */ //设置主进程名 echo '主进程id:' . posix_getpid() . PHP ...
- python爬虫(四) 内涵段子
import requests import time import json from urllib import request from urllib import parse url = 'h ...
- Manthan, Codefest 19 (open for everyone, rated, Div. 1 + Div. 2)B(SET)
#define HAVE_STRUCT_TIMESPEC#include<bits/stdc++.h>using namespace std;int a[2007];set<int& ...
- 利用django打造自己的工作流平台(一):从EXCEL到流程化运作
因工作所需以及管理个人一些日常事项,自己基于django(一个基于python的web框架,详细介绍可查阅相关资料)开发了一个简易的工作流平台[平台地址].本文首先简要介绍工作流平台的设计思想及其在项 ...
- 大数据萌新的Python学习之路(一)
笔记开始简介 从2018年9月份正式进入大学的时代,大数据和人工智能的崛起让我选择了计算机专业学习数据科学与大数据技术专业,接触的第一门语言就是C语言,后来因为同学推荐的原因进入了学校的人工智能研究协 ...
- [转]ubuntu备份与恢复
在 使用Ubuntu之前,相信很多人都有过使用Windows系统的经历.如果你备份过Windows系统,那么你一定记忆犹新:首先需要找到一个备份工 具(通常都是私有软件),然后重启电脑进入备份工具提供 ...
- 读取json文件
//读取json文件 var obji = File.ReadAllText(@"E:\test.json"); var resultdata = JsonConvert.Dese ...