uni-app + .NET 7 implements WeChat applet subscription message push

The subscription message of WeChat Mini Program is one of the important capabilities of the Mini Program, which provides a better experience for realizing the closed-loop service. We should often see subscription messages. For example, after the order is successfully placed and 服务通知the payment is successful 支付成功通知, they all belong to the subscription message of the applet.

This article only implements 一次性订阅the functions, as for 长期订阅and 设备订阅, if you have the opportunity to meet and then conduct research.

Before we start, let's take a look at the introduction of the WeChat applet subscription message:

Features

The message capability is an important part of the applet capability. We provide developers with the ability to subscribe to messages in order to achieve a closed-loop service and a better experience.

  • Subscription message push location: service notification
  • Conditions for sending subscription messages: user self-subscription
  • Subscription message card jump ability: click to view details to jump to the page of the applet

insert image description here

message type

1. One-time subscription to news

The one-time subscription message is used to solve the notification problem of the follow-up service link after the user uses the Mini Program. After the user subscribes independently, the developer can send a corresponding service message for an unlimited time; each message can be subscribed or unsubscribed separately.

2. Long-term subscription news

One-time subscription to messages can meet the needs of most service scenarios of Mini Programs, but there are scenarios in the field of offline public services that cannot be satisfied by one-time subscription, such as flight delays, and multiple notifications need to be sent according to the real-time status of the flight. To facilitate the service, we provide long-term subscription messages. After the user subscribes once, the developer can send multiple messages for a long time.

目前长期性订阅消息仅向政务民生、医疗、交通、金融、教育等线下公共服务开放,后期将逐步支持到其他线下公共服务业务。

Therefore, for our ordinary applets, after successful registration, the template selection of subscription news only has the option of one-time subscription, and there is no option of long-term subscription.
insert image description here

3. Device subscription message

Device subscription message is a special type of subscription message, which belongs to the long-term subscription message type and needs to complete "device access" before it can be used.

After learning about subscribing to news from the applet, let's get down to business!

basic process

Precautions

Since the following article is still very long, the precautions are issued first, and you may see that your problem has been solved here.

  • One-time template id and permanent template id cannot be used at the same time.
  • The lower version basic library 2.4.4~2.8.3 already supports the subscription message interface call, and only supports passing in a one-time tmplId/permanent tmplId.
  • Starting from version 2.8.2, the subscription message interface can only be invoked after the user clicks or initiates a payment callback
  • Starting from version 2.10.0, the development version and trial version of the applet will prohibit the use of the template message formId.
  • In an authorization call, the template titles corresponding to each tmplId cannot exist the same, if there are the same, only one will be kept.
  • Starting from version 2.10.0, it supports subscribing to voice message reminders

Pay special attention to the third item. When the version library is 2.8.2 or above, the subscription message interface must be invoked after a click action or a payment callback is initiated. There are no special requirements for this click behavior. For example, for a form, after clicking the submit button, the subscription message interface can also be invoked. The callback after payment does not need to be clicked, and the subscription message interface can also be invoked.

Get template ID

Log in to the mini program on the WeChat public platform, under the subscription message function, enter My template, find the template, and copy the template id. If there is no template, you need to add the template first, and then get the template id
insert image description here

To add a new template, click 选用the button, select the desired template in the public template library, and add it.
insert image description here

There are many articles that say that if there is no suitable template, you can create a custom template . But if you really want to create a custom template, you will find that there is nowhere to be found.
If you want to create a custom template, you can do it in the following ways.
1. Click 选用the button to come to the public template library. (The templates in the public template library are related to the service category of your Mini Program)
2. In the search box, enter a relatively long keyword.
3. Click Search, if the template can still be matched, then re-adjust the keywords until there is no search result.
4. Click on the page 帮忙我们完善模板库to set the custom template.
insert image description here
insert image description here

When creating a custom template, be sure to carefully read the process of applying for a template, especially Article 1. I just pulled it out and highlighted it, because I didn't read Article 1 carefully, and I waited for several days for the first few templates for the first application.
The title of the template needs to reflect specific service scenarios, 要求以“通知”或“提醒”结尾such as: logistics arrival notification, transaction reminder.

Seeing this, you will find that most of the above are no different from the articles on the Internet. Don't worry, the main text is here!

uni-app code

The front-end implementation is to click the submit button, save the form, and send a subscription message after the save is successful. Write the following code pages/index/index.vuebelow :

<template>
	<view>
		<view class="setp">
			<publishStep :list="setpList" :current="0" mode="number" active-color="#eb3572"></publishStep>
		</view>
		<view class="container">
			<u-form :model="form" ref="uForm" :rules="rules" :error-type="errorType">
				<u-form-item label="姓名" label-width="160rpx" :border-bottom="true" :label-style="{'font-size':'28rpx'}" prop="realName">
					<u-input v-model="form.realName" placeholder="" input-align="right" />
				</u-form-item>
				
				<u-form-item label="服务时间" label-width="160rpx" :border-bottom="true" :label-style="{'font-size':'28rpx'}"
				 right-icon="arrow-right" prop="serviceTime">
					<u-input v-model="form.serviceTime" placeholder="请选择服务时间" :disabled="true" input-align="right" @click="timeShow=true" />
				</u-form-item>
				
				<u-form-item label="服务地址" label-width="160rpx" :border-bottom="true" :label-style="{'font-size':'28rpx'}" prop="serviceAddress">
					<u-input v-model="form.serviceAddress" placeholder="" input-align="right" @click="selectAddress" />
				</u-form-item>
				<u-form-item label="联系电话" label-width="160rpx" :border-bottom="true" :label-style="{'font-size':'28rpx'}"
				 prop="lxtel">
					<u-input v-model="form.lxtel" type="number" placeholder="请输入联系电话" input-align="right" :clearable="false" />
				</u-form-item>
				<u-form-item label="需求描述" label-width="160rpx" :border-bottom="true" :label-style="{'font-size':'28rpx'}"
				 prop="remarks">
					<u-input v-model="form.remarks" type="text" placeholder="请输入您的需求" input-align="right" :clearable="false" />
				</u-form-item>
			</u-form>
		</view>
		<view style="height: 160rpx;"></view>
		<view class="bottom_nav">
			<view class="buttom_box padding-horizontal-20 padding-vertical-10">
				<u-button type="error" @click="submitForm" :loading="submit_loading" style="height: 100rpx; font-weight: bold; font-size: 36rpx;">确认提交</u-button>
			</view>
		</view>
		<u-picker mode="time" v-model="timeShow" :params="timeParams" @confirm="timeConfirm"></u-picker>
	</view>
</template>
<script>
	export default {
      
      
		data() {
      
      
			return {
      
      
				
				form:{
      
      
					realName:"",
					serviceTime:'',
					serviceAddress:"",
					lxtel:"",
					remarks:""
					
				},
				rules:{
      
      
					realName: [{
      
      
						required: true,
						message: "请填写您的姓名",
						trigger: 'change'
					}],
					
					serviceTime: [{
      
      
						required: true,
						message: "请选择服务时间",
						trigger: 'change'
					}],
					
					lxtel: [{
      
      
						required: true,
						message: "请输入联系电话",
						trigger: 'change'
					}],
				},
				errorType: ['toast'],
				
				timeShow:false,
				timeParams:{
      
      
					year: true,
					month: true,
					day: true,
					hour: false,
					minute: false,
					second: false
				},
				submit_loading:false,
			}
		},
		
		
		onReady() {
      
      
			this.$refs.uForm.setRules(this.rules);
		},
		
		onLoad(params) {
      
      
			let that = this;
		},
		methods: {
      
      
			
			timeConfirm(e){
      
      
				let that = this;
				that.form.serviceTime = e.year +"-"+e.month+"-"+e.day
			},
			gotoOrder(){
      
      
			    uni.redirectTo({
      
      
					url:"/pages/order/order"
			    })
			},
			submitForm(){
      
      
				 let that = this;
				this.$refs.uForm.validate(valid=>{
      
      
					if (valid){
      
      
						that.$u.api.submit_order(that.form).then(res => {
      
      
							if (res.success) {
      
      
								let data = res.data;
								uni.showToast({
      
      
									title: '提交成功',
									icon: 'success'
								})
								// #ifdef MP-WEIXIN
								uni.requestSubscribeMessage({
      
      
									tmplIds:['XXXXXXXXXXX'], //这里填写tempid
									success:function(subscribeMessageRes){
      
      
										if(subscribeMessageRes.errMsg=="requestSubscribeMessage:ok"){
      
      
											if(subscribeMessageRes.XXXXXXXXXXX=="accept"){
      
      
												uni.login({
      
      
													provider: 'weixin',
													success:function(loginRes){
      
      
														if(loginRes.errMsg=="login:ok"){
      
      
															const code = loginRes.code;
															that.$u.api.sendSubscribeMessage({
      
      
																"code":code,
																"orderId":data.orderId
															}).then(res=>{
      
      
																that.gotoOrder()
															})
														}else{
      
      
															that.gotoOrder()
														}
													},
													fail() {
      
      
														that.gotoOrder()
													}
												})
											}else{
      
      
												that.gotoOrder()
											}
										}else{
      
      
											that.gotoOrder()
										}
										
									},
									fail:function(){
      
      
										that.gotoOrder()
									}
								})
								// #endif
								
							} else {
      
      
								uni.$u.toast(res.message);
							}
						});
					}
				})
				
			}
		}
	}
</script>

<style>
	.setp{
      
       padding: 40rpx 0;}
	.bottom_nav {
      
      
		position: fixed;
		width: 100%;
		height: 100rpx;
		left: 0;
		bottom: 0;
		z-index: 9999;
		background: #FFFFFF;
		border-top: 1rpx #f3f3f3 solid;
	}
</style>

The process here is divided into 3 steps:
1. Submit the form, and the server will return the order number (orderId)
2. Use uni.requestSubscribeMessage, call up the authorization box, and enter the third step after clicking Agree. After invoking the authorization, if the user agrees, the parameters of the callback function subscribeMessageReshave two objects: errMsgand XXXXXXXXXXX, errMsg Needless to say. Mainly what this XXXXXXXXXX is. XXXXXXXXXXXX is generated by authorization, which is the template ID by visual inspection.
3. Use uni.login, obtain code.
4. Send codeand orderIdsend to the server, the server codeobtains it openId, and then orderIdobtains the specific order data according to the acquisition.
5. Send template message.

If nothing unexpected happens, after the submission is successful, the following authorization box will pop up
insert image description here

server code

The server-side ORM is used SqlSugar, and the WeChat applet interface uses SKIT.FlurlHttpClient.Wechatthe library.

Generate orders

Submit the order , here is only a demonstration, the specific code can be realized by yourself!

[HttpPost]
public async Task<AjaxResult> SubmitOrder(order model)
{
    
    
//生成订单号
    model.order_no = DateTime.Now.ToString("yyyyMMddHHssfffff");
    model.addtime = DateTime.Now;
    //ExecuteReturnIdentity方法会返回自增id
    var id = await db.Insertable(model).ExecuteReturnIdentity();
    return new AjaxResult(){
    
    
     success=true,
     data = id
    };
}

AjaxResult.cs

public class AjaxResult
{
    
    
/// <summary>
/// 是否成功
/// </summary>
public bool success {
    
     get; set; } = true;

/// <summary>
/// 错误代码
/// </summary>
public int code {
    
     get; set; } = 0;

/// <summary>
/// 返回消息
/// </summary>
public string message {
    
     get; set; }
/// <summary>
/// 返回数据
/// </summary>
public object data{
    
     get; set;}

}

order.cs

[SugarTable("order")]
public class order
{
    
    
     /// <summary>
     /// 主键,自增Id
     /// </summary>
    [SugarColumn(IsPrimaryKey = true)]
    public int id {
    
     get; set; }
     /// <summary>
     /// 订单编号
     /// </summary>
    public string order_no {
    
     get; set; }
    /// <summary>
    /// 姓名
    /// </summary>
    public string realName {
    
     get; set; }
    /// <summary>
    /// 时间
    /// </summary>
	public DateTime serviceTime {
    
     get; set; }
	/// <summary>
    /// 地址
    /// </summary>
	public string serviceAddress {
    
     get; set; }
	/// <summary>
    /// 联系电话
    /// </summary>
	public string lxtel {
    
     get; set; }
	/// <summary>
    /// 备注
    /// </summary>
	public string remarks {
    
     get; set; }
	/// <summary>
    /// 创建时间
    /// </summary>
	public DateTime addtime {
    
     get; set; }
}

send template message

Send a template message for one-time subscription, and the passed parameters are obtained by the front codeend orderId. Obtain the order information according to the order number, so as to set the applet information and open path in the subscription message. codeUsed to get users openId.

[HttpPost]
public async Task<AjaxResult> SendSubscribeMessage(string code,string orderId)
{
    
    
    AjaxResult result = new AjaxResult();
    if (string.IsNullOrEmpty(code) || string.IsNullOrEmpty(orderId))
    {
    
    
        result.success = false;
        result.message = "参数错误";
        return result;
    }
    var order_model = await db.Queryable<order>().InSingleAsync(orderId);
    if(order_model is null)
    {
    
    
        result.success = false;
        result.message = "参数错误";
        return result;
    }
    //初始化WechatApiClient
    var options = new WechatApiClientOptions()
    {
    
    
        AppId = "appId",
        AppSecret = "appSecret "
    };
    var client = new WechatApiClient(options);
    //获取openId
    var request = new SnsJsCode2SessionRequest();
    request.JsCode = code;
    var response = await client.ExecuteSnsJsCode2SessionAsync(request);
    string openId = response.OpenId;
    //获取token
    var tokenRequest = new CgibinTokenRequest();
    var tokenResponse = await client.ExecuteCgibinTokenAsync(tokenRequest);
    var token = tokenResponse.AccessToken;
    //发送模板消息
    var messageRequest = new CgibinMessageSubscribeSendRequest();
    IDictionary<string, CgibinMessageSubscribeSendRequest.Types.DataItem> messageData = new Dictionary<string, CgibinMessageSubscribeSendRequest.Types.DataItem>
            {
    
    
                {
    
    
                    "params1",
                     new CgibinMessageSubscribeSendRequest.Types.DataItem() {
    
    Value=order_model.order_no}
                },
                {
    
    
                    "params1",
                    new CgibinMessageSubscribeSendRequest.Types.DataItem(){
    
    Value=order_model.userNmae}
                },
                {
    
    
                    "params3",
                    new CgibinMessageSubscribeSendRequest.Types.DataItem(){
    
    Value=order_model.serviceTime}
                },
                {
    
    
                    "params4",
                    new CgibinMessageSubscribeSendRequest.Types.DataItem(){
    
    Value=order_model.serviceAddress}
                },
                {
    
    
                    "params5",
                    new CgibinMessageSubscribeSendRequest.Types.DataItem(){
    
    Value=order_model.addtime.ToString("yyyy-MM-dd HH:ss")}
                }
            };
     messageRequest.AccessToken = token;
     messageRequest.ToUserOpenId = openId;
     messageRequest.TemplateId = "XXXXXXXXXXX"; 
     messageRequest.MiniProgramState = "developer";
     //微信小程序要跳转的地址。可以加参数
     messageRequest.MiniProgramPagePath = "/pages/order/order_details?id=" + order_model.id;
     messageRequest.Data = messageData;
     var messageResponse = await client.ExecuteCgibinMessageSubscribeSendAsync(messageRequest);
     if(messageResponse.ErrorCode==0)
     {
    
    
         result.success=true;
         result.message = "ok";
         return result;
     }
     result.success = false;
     result.message = "error";
     return result;
}

When constructing a template message, use IDictionary<string, CgibinMessageSubscribeSendRequest.Types.DataItem> messageData = new Dictionary<string, CgibinMessageSubscribeSendRequest.Types.DataItem>to construct,
assuming that the detailed content of a template message is as follows:
insert image description here

  • Then params1 in the above code is character_string22, and params2 is thing7 in the same way. That is. The key of IDictionary is .DATAthe previous content in the template.
  • messageRequest.TemplateId, which must be consistent with the template Id of the front end.
  • messageRequest.MiniProgramStateIndicates the type of redirected WeChat applet. The default is the official version
    • developer is the development version;
    • trial is the trial version;
    • formal is the official version;

If nothing else, your WeChat will receive a service notification. After clicking the card, enter the order details page of the mini program!

Summarize

1. In fact, it is relatively easy to apply for the subscription message of the WeChat applet and the subscription message template of the official account. If you cannot find a template suitable for you in the category templates and history templates, then apply for a template yourself. If it is reviewed, you can receive a notification within 2-3 days.
需要注意的是,申请模板的时候,最好把各项在本地保留一份。因为一旦提交申请,在公众号或小程序后台,你就找不到了。玩意审核没通过,再申请的时候,前面写的啥内容,已经忘的差不多了!

2. Thank you SqlSugarfor providing such a powerful ORM for .Net developers. It's really convenient.
3. Thanks SKIT.FlurlHttpClient.Wechatfor providing such a convenient tool for .Net developers.
4. In order to quickly express the meaning clearly, the above front-end and server-side codes are all simplified and must not be used directly! ,

Click on the official account card below to follow me! Learn together and progress together!

Guess you like

Origin blog.csdn.net/sd2208464/article/details/128857921
Recommended