WeChat applet subscription news and solutions to various pits encountered (full)

The difference
from the "template message" is that after the user clicks the trigger or the payment is successful, the developer can push 1-3 service notifications within 7 days. "Subscription message" requires the user to actively subscribe to the message notification before the developer can push it to the user, but it is not limited by time. The specific number of messages sent depends on different types of capabilities.

In addition, it is worth noting that after using "Subscribe to Messages", the original Mini Program template message interface will be offline on January 10, 2020, and it will no longer be possible to use the original interface to push template messages. Developers need to pay attention to timely adjustment of the interface . However, the WeChat service account template message will not be affected for the time being.

Features
1. The right to choose returns to the hands of the user. In the applet, "subscribe to news" is like a switch. Only after the user actively clicks on the authorization, the applet can push the service notification to it. Of course, the user can also refuse to receive the service notification of the applet at any time. Previously, users could only receive messages passively.

2. The duration is not limited. "Subscription Message" cancels the time limit for pushing messages within 7 days. As long as the user does not actively refuse to receive message pushes, developers can push service notifications at any time. For small programs whose service cycle exceeds 7 days, this perfectly solves the previous doubts.

Ok, let's take a look at how to use this subscription message~

Briefly describe the general process.
The authorization pop-up window process initiated by the applet.
By the way, how to obtain the user authorization information wx.getting , and how to jump to the setting authorization page when the user closes the authorization.

After the authorization, the server sends the subscription message process
to sort out the specific meaning of each parameter sent by the subscription. Although there are documents, it is better to understand if there are examples.

Collect and solve various intractable diseases.
The authorization pop-up window process initiated by the applet terminal
invokes the client applet subscription message interface, and returns the operation result of the user's subscription message. When the user checks "Always keep the above selection and don't ask again" in the subscription panel, the template message will be added to the user's applet setting page, and the user's subscription status for the relevant template message can be obtained through the wx.getSetting interface .

Pay attention to this sentence in the document → If the user has set not to ask before, the authorization pop-up window cannot be adjusted, so how do we obtain the user's authorization information?

wx.getSetting can obtain this information: the corresponding wx.getting document
has sample code at the back of the document and will not post it here

If you want to get the subscription status of the subscription message, you need to set withSubscriptions to true (the default is false, if you don’t open it, you can’t get it). After successful acquisition, authSetting has some permissions about the user, and subscriptionsSetting is the subscription permission information we need. Inside There is a main switch, mainSwitch, which is whether you accept the subscription information of the current applet. If this is false, you can’t actually adjust the pop-up window at all, so the little friend will ask if I want to let him know that the permission is closed and how to guide him to open?

Post the code first:

Send subscription message logic processing

const SUBSCRIBE_ID = 'RHPuVfEyGe0q0n7lZyzz4r-zyGe07lZyzz4r3' // 模板ID
goCollectSet() {
    let that = this;
    if (wx.requestSubscribeMessage) {
      wx.requestSubscribeMessage({
        tmplIds: [SUBSCRIBE_ID],
        success(res) {
          if (res[SUBSCRIBE_ID] === 'accept') {
            // 用户主动点击同意...do something
          } else if (res[SUBSCRIBE_ID] === 'reject') {
            // 用户主动点击拒绝...do something
          } else {
            wx.showToast({
              title: '授权订阅消息有误',
              icon: 'none'
            })
          }
        },
        fail(res) {
          // 20004:用户关闭了主开关,无法进行订阅,引导开启
          if (res.errCode == 20004) {
          	// 显示引导设置弹窗
            that.setData({
              isShowSetModel: true
            })
          }else{
          	// 其他错误信息码,对应文档找出原因
            wx.showModal({
              title: '提示',
              content: res.errMsg,
              showCancel: false
            })
          }
        }
      });
    } else {
      wx.showModal({
        title: '提示',
        content: '请更新您微信版本,来获取订阅消息功能',
        showCancel: false
      })
    }
  }

[wx.requestSubscribeMessage document]

Briefly describe the above code. The goCollectSet method is the method to authorize the execution of the subscription message permission. Since wx.requestSubscribeMessage needs to be supported after the basic library 2.4.4, we have to make a judgment. If we find that the user’s current WeChat does not have this method, then Prompt to update the WeChat version; then fill in the corresponding subscription template ID in the tmplIds Array field

[Q] Where can I get the subscription template ID and create a new one?
·
[Answer]
After logging in to the WeChat official account platform, if there are multiple applets, select the currently developed applet, and after successfully entering the interface, go to the function section -> subscribe news, and you can create a new template or use a public subscription template. For the template, just copy the corresponding ID directly

Then, if the user has enabled the subscription message notification permission at this time, a window for authorizing the subscription message will appear, as shown in the figure:
insert image description here

 If the user clicks [Allow] at this time,  accept the status will be returned at this time, otherwise, the status will be returned if the user clicks [Cancel]  reject. The specific status field is shown in the figure

insert image description here

We can find that this return value uses your template id as the key, so when you get it, you need to get it according to the template ID. Here we only talk about the return of permission and rejection. The return of filter is filtered because the template title has the same name, so When creating a new one, remember to distinguish the templates with the same name from the existing titles. Success is generally the same, mainly due to the user’s own operation. After [Allow], you will subscribe once. Note that this is a subscription message for one-time subscription. About The difference can be seen below:

[Q] What is the difference between a one-time subscription template and a permanent subscription? What if I need to use a perpetual subscription?
·
[Answer]
1. One-time message subscription: After the user subscribes once, the developer can send a message without a time limit. If the user checks "Always keep the above selection, don't ask again" and clicks Allow, then they will agree to subscribe to this message by default in the future. Users no longer make multiple choices, and developers avoid more cumbersome reminders.
2.
Long-term subscription to messages: After a user subscribes once, they can send multiple messages for a long time. At present, long-term subscription news is open to offline public services such as government affairs, medical care, transportation, finance, and education. In the future, we will comprehensively evaluate industry needs and continue to improve user experience. (Long-term subscription messages are only available for specific industries, so ordinary developers cannot use them)

Okay, back to the topic, at this time, one click by the user is equivalent to a subscription once, which is equivalent to having a ticket for obtaining system notifications once. In theory, multiple clicks by the user is equivalent to subscribing multiple times. At this time, these The number of subscriptions is stored, and if the server sends a notification, it will consume one subscription (theoretically, this is the case, and the document does not say, just make sure to trigger a subscription interaction before each delivery, so think about long-term subscriptions) , once authorized for lifetime use~)

Secondly, let’s talk about [Always keep the above selection, don’t ask again] under the pop-up window. If it is not checked, the window will pop up every time you subscribe. If the user checks it, the logic executed at this time will not change. , you check it and click [Allow] to directly execute the logic in 'accept', otherwise, if you check it and click [Cancel], it will always execute the logic in reject, so some friends will say, why Every time I authorize, there is no pop-up window and it is automatically rejected. In fact, [Cancel] means rejection, and it will be embarrassing if you check it and don’t ask again...

The cost of this misoperation is very high. In the future, there will be no more pop-up windows and direct rejection. If the user wants to subscribe one day, he will not know where to subscribe. It is good to know where the setting (setting page) is turned on. Some friends said that if we add a guide pop-up window to the logic of rejection, wouldn’t it be enough? But from the perspective of execution logic, it is the logic of reject whether to check the no longer ask and click to reject. Is it a bit strange to guide the user to the settings page here, so this is actually a pain in the ass, and I can only pray for WeChat How good it is for the small program development brother to add a rejection return sign that does not ask no more questions, so that our development can also judge whether the user is a normal rejection or a no-question rejection based on the corresponding logo return

The corresponding prayer forum can be viewed here → https://developers.weixin.qq.com/community/develop/doc/00044c5ef086b0c616594cb9651809

Of course, the above problem is not without a solution, it just needs to customize a pop-up window, which will be explained in detail below, let's take it slowly... Let's talk about the logic of fail failure first

You can directly check the error code table of the document for the logic of fail failure. Here are a few common ones.

[Question] What do the returned error codes 20001, 20002, 20003, and 20004 mean and how to solve them?
·
[Answer]
20001: There is no template data, usually the template ID does not exist or does not correspond to the template type.
20001 solution: generally pay attention to whether the template id written in the code is in the WeChat official account, if not, create a new one; Pay attention to tmplIds: ['subscription template id1', 'subscription template id2'] Do not make mistakes in this format.
20002
: The template message type has both one-time and permanent
20002 solutions: the document has stated that they cannot be mixed, so check and write Whether the ids entered in tmplIds are of the same type
.
20003: The number of template messages exceeds the upper limit.
20003 Solution: A collection of ids of message templates that need to be subscribed, and a maximum of 3 messages can be subscribed in one call (Note: iOS client version 7.0.6, Android Only one-time subscription/long-term subscription after version 7.0.7 of the client supports multiple template messages, and a subscription before version 7.0.5 of the iOS client and Android client version 7.0.6 only supports one template message)
. If you encounter it, first find a product to start working on. Why do you have to subscribe so many at once for users to choose, and separate them if you can; secondly, if users of low-level WeChat only support one template message, if it is necessary at this time. If you subscribe together, just remind the user to update the version, otherwise it will affect the function. 20004
: The user turned off the main switch
and cannot subscribe .
The edge can guide the user to the settings page to open

Well, here we mainly talk about the error return of 20004, that is, how to guide the user to set the page; instead of using patterns to guide the operation on the Internet, we directly use the button label open-type="openSetting" in WeChat to go directly, first of all Let's take a look at the basic library 2.0.7 of this function. If you don't panic, you can use the subscription template message 2.4.4. Then this function can also be used. Then let's take a look at wxml. The corresponding style is not posted. Customize DIY

Bootstrap authorization settings wxml
 

  <!-- 自定义模态框 -- 引导跳授权设置页面 -->
  <view class="jumpSetModel" wx:if="{
   
   {isShowSetModel}}">
    <view class="jumpSetBox">
     <view class="m-title">提示</view>
      <view class="m-content">检测到您未开启订阅消息通知权限,是否去设置?</view>
      <view class="m-control">
        <button class="m-cancel" catchtap="closeSetModel">取消</button>
        <button class="m-confirm" open-type="openSetting" bindopensetting="openSetCallback">去设置</button>
      </view>
    </view>
  </view>

 insert image description here

As shown in the picture above, if we return to 20004, we will display the pop-up window, click on the setting and it will jump to the setting page, which is comfortable~ Some friends will say,
if the setting is turned on, will the gesture return be monitored, this You don't have to worry, the status of the master switch of the subscription notification is automatically refreshed, and it does not affect the logic of re-execution

Well, those who read carefully, do you remember that there is a question left above: if the user clicks no more questions and cancels, we can play like this (used together with ordinary rejection)
insert image description here

After authorization, the server sends the subscription message process
Call the message subscription interface wx.requestSubscribeMessage, after obtaining the sending permission, the next step is to send the subscription message~

Document through train:
After authorization, the server sends a subscription message process

From the documentation, we can know that there are two delivery methods, one is HTTPS calls, and the other is using cloud functions

Mini Program · Cloud Development – ​​Cloud Function
Cloud Call is the ability provided by Mini Program · Cloud Development to call the WeChat open interface in the cloud function. It needs to be used in the cloud function through wx-server-sdk, and the cloud call can also avoid the access_token the acquisition of

code show as below:
 

const cloud = require('wx-server-sdk')
cloud.init()
exports.main = async (event, context) => {
  try {
    const result = await cloud.openapi.subscribeMessage.send({
        touser: 'wx12345645645zawqead',  // 接受当前模板消息的用户openid
        templateId: 'TEMPLATE_ID',   // 当前下发的模板ID,不可写多个,目前只支持一个
        page: 'index?id=666',   // 定义用户点击该模板消息跳转的小程序路径
        // 模板所需要的键值
        data: {
          thing1: {
            value: '情感咨询课程'
          },
          amount1: {
            value: '9.99'
          },
          date1: {
            value: '2020-03-10 15:24:08'
          }
        }
      })
    return result
  } catch (err) {
    return err
  }
}

 

In this way, the corresponding template can be sent to the specified user~

The backend server sends a subscription message

<?php 
$data = json_decode(file_get_contents('php://input'), true);
 
$post_data = array(
  // 用户的 openID,可用过 wx.getUserInfo 获取
  "touser"           => $data["touser"],
  // 小程序后台申添加的订阅消息模板 ID
  "template_id"      => $data["template_id"],
  // 点击模板消息后跳转到的页面,可以传递参数
  "page"             => $data["page"],
  // 发送给用户的数据
  "data"             => $data["data"]
 
);
 
// 发送 POST 请求的函数
function send_post($url, $post_data)
{
  $options = array(
    'http' => array(
      'method'  => 'POST',
      'header'  => 'Content-type:application/json',
      'content' => $post_data,
      'timeout' => 60
    )
  );
 
  $context = stream_context_create($options);
  $result = file_get_contents($url, false, $context);
 
  return $result;
}
 
// 小程序 appID 和 appSecret 获取 token
function getAccessToken($appid, $appsecret)
{
  $url = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=' . $appid . '&secret=' . $appsecret;
  $html = file_get_contents($url);
  $output = json_decode($html, true);
  $access_token = $output['access_token'];
 
  return $access_token;
}
 
// 这里替换为你的 appID 和 appSecret
$url = "https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=" . getAccessToken($appid, $appsecret);
 
$data = json_encode($post_data, true);
 
$return = send_post($url, $data);
var_dump($return);

 Posted here is the php demo code to send the applet subscription message, about  appID and  can be obtained in  the development settings in the appSecret corresponding  applet official account

insert image description here

If the back-end friends use java to write, you can refer to this article, and the code will not be posted here >>> WeChat applet subscription message (java back-end implementation)

[Q] How to create a Mini Program cloud function?
·
[Answer]
Regarding the steps to create a cloud using Mini Program Cloud Development, you can refer to this article: Creation and Environment Configuration of Cloud Functions for WeChat Mini Program Cloud Development
·
[Q] What's wrong with the report of the delivery, and how to solve it?
·
【Answer】
40003 The openid in the touser field is empty or incorrect
40003 Solution: Note that the openid here is for the user who accepts the subscription message.
43101
The user refuses to accept the message. If the user has subscribed before, it means that the user has canceled the subscription relationship
. : This error should pay attention to whether the user subscription authorization is successfully obtained during the authorization pop-up window initiated by the applet.
If not, please find the problem in the authorization operation.
47003
The template parameter is inaccurate, it may be empty or does not meet the rules, errmsg will prompt which field is wrong
47003 Solution: Subscribe to a one-time message, but it may fail when sending. This may be related to the content. The template data parameter must refer to the template field opened by the corresponding template id to fill in ( The content parameters of the subscription message template are very strict, one more character or inconsistent with the specified value of the parameter will cause the sending failure, remember to judge the number of words. When filling in the corresponding parameters, fill in according to the template in the background, such as thing03, name05, followed by digital)

insert image description here

41030 The page path is incorrect. It needs to be guaranteed to exist in the online version of the applet, consistent with app.json
41030 Solution: must be filled in correctly, the path must be in the applet

This is about the process of sending subscription messages from the server~

Collecting and resolving various intractable diseases
and subscribing to news is a great function. It is inevitable that various problems will arise during development. Some problems and corresponding solutions have been posted in the process described above. I will not repeat what I wrote above here. Here to add what is not mentioned

1. Developer tools cannot be debugged

Later, I tried that the authorization pop-up window can be lifted on the real machine. After browsing the development community, I found that this is a common problem.

But now the prompt is very straightforward, we will not take this blame, remember to debug on the real machine!

2. If I initiate two subscription template messages, but the user only receives one of them, what happens?
First of all, make sure that two template ids of the same type ['template id1', 'template id2'] are written in the tmplIds field, and the authorization window will be lifted normally if there is no mistake in the code (provided that the user does not check Always keep the above option), if the user wants to receive two templates, they must check the two templates. If the user cancels one of them, of course the corresponding template message cannot be received, so it can be corresponding in the success logic in wx.requestSubscribeMessage Process the return value. If the request authorizes multiple template ids, the corresponding return is also returned based on the template id as the key, so it can be processed accordingly.

Well, the above is the case where the user did not check "Always keep the above options, do not ask". If it is checked, the pop-up window will not be prompted, and it can only be reopened in the "Settings" interface, because it will not be displayed at this time. For the pop-up window, the guide has been mentioned above, so I won’t complain here

In addition, the user can also cancel the subscription notification in the WeChat service account that sends the subscription notification. This will directly turn off the corresponding notification reception in the settings. The guidance is the same as above.
 

success(res) {
   // 模板id1的处理逻辑
   if (res['模板id1'] === 'accept') {
     // 用户主动点击同意...do something
   } else if (res['模板id1'] === 'reject') {
     // 用户主动点击拒绝...do something
   }
	
   // 模板id2的处理逻辑
   if (res['模板id2'] === 'accept') {
     // 用户主动点击同意...do something
   } else if (res['模板id2'] === 'reject') {
     // 用户主动点击拒绝...do something
     wx.showModal({
       title: '提示',
       content: '你取消了xxx的通知',
       showCancel: false
     })
  }
 }

insert image description here 

3. Why did I not lift the authorization box when I used wx.requestSubscribeMessage to debug successfully?
First of all, you must ensure that the call is successful (supported by the basic library, and the code is error-free). At this time, the option "Always keep the above options, do not ask" has been checked before, and the second is that your template id belongs to the long-term subscription type. This type, as long as you confirm, the authorization window will not pop up for you. You can only let the user open it in the settings according to the status.

4. I filled in multiple template id fields at the same time, and reported an error: Templates count out of max bounds
(Note: Only one-time subscriptions/long-term subscriptions after iOS client version 7.0.6 and Android client version 7.0.7 support multiple Template message, iOS client version 7.0.5, and Android client version 7.0.6, a subscription only supports one template message) The
message template id is configured in [WeChat Public Platform-Function-Subscription Message]. The template title corresponding to each tmplId needs to be different, otherwise it will be filtered, so some friends said why I filled in three template ids and only two were displayed in the end, so I went to the official account platform to see if the same title appeared problem~

-------------------------------------------------- -- Update 2021.01.30 ----------------------------------------------- -------

I don’t know why my reply comment is gone, it’s weird... well, I’m here to update and sort out the questions asked in the comment area

5. For the one-time subscription authorization pop-up window, why do I not see the subscription message in the applet settings after I click allow?
For one-time subscription messages, if you don't check "Always keep the above selection, don't prompt again", it will not be added to the applet settings page. Otherwise, the applet will store the user in the The default authorization operation in the applet;

Similarly, for long-term subscription messages, the user will directly store them in the settings after allowing or rejecting them (you can see the subscription status of the long-term subscription in the settings)

And we can obtain the subscription status of user-related template messages through the wx.getSetting interface.
For details, please refer to the official document: wx.getSetting

6. How to get user openid?
First of all, corresponding to the acquisition of openid, there are three methods:

The code user login credentials (valid for five minutes) obtained by the foreground applet through wx.login(). Then you need to call auth.code2Session in the background of the developer server, and use the code to exchange information such as openid and session_key;
[This operation does not require user authorization]

If you are using cloud development, you can call cloud functions to obtain this information. The specific code is as follows:

Just use this cloud function cloud.getWXContext() (I won’t go into details about cloud deployment and the like, if you have any questions, you can refer to the cloud function deployment article mentioned above)

Remember to upload and deploy the cloud function after writing it in the index.js of the getopenid cloud function
 

// 云函数入口文件
const cloud = require('wx-server-sdk')

cloud.init()

// 云函数入口函数
exports.main = async (event, context) => {
  const wxContext = cloud.getWXContext()

  return {
    event,
    openid: wxContext.OPENID,
    appid: wxContext.APPID,
    unionid: wxContext.UNIONID,
  }
}

 Then call the cloud on the interface you need

page{
	data{
		openid:'',
	},
	onLuanch(){
		this.getopenid()
	}
	// 定义调用云函数获取openid
	getOpenid(){
	  let page = this;
	  wx.cloud.callFunction({
	    name:'getOpenid',
	    complete:res=>{
	      var openid = res.result.openid
	      page.setData({
	        openid:openid
	      })
	    }
	  })
	},
}

 

[This operation also does not require user authorization]

Obtain user information through the wx.getUserInfo interface

Calling this method requires user authorization (that is, the drawer authorization information pop-up window we usually see), and if you want to obtain openid and other sensitive information, you must also set the parameter withCredentials to true, and require that you have called wx before. .login and the login status has not expired, the data returned at this time will contain sensitive information such as encryptedData, iv, etc. However, the openid returned by the interface is not transmitted in plain text, and the encrypted data decryption algorithm is required to get the plain text value; so if you just simply If you want to get openid, you don't need to spend so much trouble, just use the first and second methods;

In addition, this operation also requires the user's authorization and consent. If the user refuses to go directly to the fail logic; you can read this article (product direction >>> WeChat login ability optimization)

Off-topic supplement: Will the user's openid change or is it a unique value?
This question will be addressed on a case-by-case basis:

When the same user visits the same applet, his openid will not change. What is the first entry, and the applet that comes in after that is the same openid (uniqueness). When the same user visits different applets,
his The openid is different in each applet
. Different users access the same applet, and the openid of each user is different.
Summary: each applet has an identity value and is unique, and it is the appid (just like RMB. There may be the same code, which appears to be fake money), and openid is managed in association with appid, so openid is actually a unique value
[Extension] 7. How to realize the click-to-subscribe message is sent at a specific time point? (Updated on 2021.4.13)
This question is included in @qq_32921557's question. Here I will briefly talk about how the cloud function implements this step. If you are a backend, you can directly trigger the delivery at regular intervals.

Guess you like

Origin blog.csdn.net/aaa123aaasqw/article/details/132023408
Recommended