Function Overview
You can authorize a official account to be sent to Quick Tracking. You can report official account behavior events (such as following, menu access, and unfollowing) to Quick Tracking for user behavior analysis of official accounts.
The tracking of WeChat official accounts depends on the rules customized by the WeChat platform. The following table describes the important information about the tracking of WeChat official accounts. Before you track such events, read the following information in detail. For more information, see WeChat official instructions.
WeChat official account events are defined, generated, and sent by WeChat. Developers only subscribe to these data and cannot customize them. Click 2 Events and Event Attributes to view the available event list.
If you want to track WeChat official account events, you must become an official account developer. After you become an official account developer, the 「Automatic Replies and Custom Menus」 on the official account platform become unavailable, and the configured information becomes invalid. You must maintain the custom information. For more information, see WeChat Official Instructions.
The WeChat platform eventually sends the events subscribed by the developer to the server maintained by the developer. The developer needs to forward the events to Quick Tracking.
1. Operation description
The following forms are the necessary steps for official account event tracking, please follow the sequence:
Step | Description | Action details |
1 | Enable developer configuration on the WeChat official account platform |
WeChat official account platform can be clicked to jump. Warning Note: If you want to track WeChat official account events, you must become an official account developer. After you become an official account developer, the 「Automatic Reply and Custom Menu」 of the official account cannot be used, and the configured information becomes invalid. You need to maintain the information. For the operation process, see WeChat Official Description. |
2 | Configure official account tracking on the QuickTracking |
You can click View to view the operation details. |
3 | Forward events of WeChat official account to QuickTracking | For more information, see View. |
4 | Data analysis in QuickTracking | You can click 2 Events and Event Attributes to view the specific event list that can be analyzed. |
1.1 Integrate into official account
Product path: 「Data tracking」-「Data Source Management」-「Official Account Management」

Click 「Integrate into Official Account」 button. On the right 「ntegrate into Data Source」 page to complete creation, the following information is required:
「Basic information」
Name of official account: fill in the name of the official account to be accessed
official account ID: Enter the official account ID. The official account ID must be unique. The following figure shows how to obtain the data:

「Analysis settings」
Belonged organization: By default, the current organization cannot be modified. If you want to add an official account to a different organization, you must switch the organization from the left-side Group drop-down list.
Belonged application: Select an application in the current organization from the drop-down list.
「Receive WeChat messages」
Encryption mode: divided into security mode and plaintext mode;
Security mode: EncodingAESKey is used to message body the encryption and decryption key, which is the same as the WeChat public number platform.
Plaintext mode: does not use the message body encryption and decryption function, low security factor.
To obtain the EncodingAESKey, run the following code: official account backend-basic configurations-copy EncodingAESKey.
Token acquisition address: official account backend-basic configuration-copy Token
(Note: The backend URL of WeChat official account is the address filled in by the user. WeChat official account sends the data to the filled in address and then synchronizes it to Quick Tracking. Reference Documentation)

「Anonymous user unique identifier」
Required. The union or OpenID is used as the unique identifier for anonymous users.
OpenID: the unique identifier of the user.
UnionID: a unique value used to distinguish users. After you set this parameter to UnionID, you must obtain the access_token.
「Obtain access_token」
If other businesses use tokens at the same time, you need to build the central control service to obtain and maintain the access_token. In the analysis platform, you can obtain the access_token from the central control service. (Note: If you select unionID as the unique identifier for anonymous users, users must configure a control center. Quick Tracking obtains the token through the central control center and obtains the corresponding unionID in WeChat official account (because the token will be refreshed after each call to obtain the token, the token used in other locations will also be refreshed and changed. And the number of token acquisition WeChat development platform has restrictions, users can obtain token from the control center, and can control the period of token))
Central control server address: Enter the self-built central control service address to obtain the token central control service address;
Access_token parsing: The Access_Token parameter is parsed from the return value obtained from the central control server. The Access_Token parameter is parsed by using the JSONPah expression. Enter the JSONPath expression and click Test to test whether the Access_Token parameter is parsed. If the Access_Token parameter is parsed, the Access_Token parameter can be obtained normally.

Complete the above steps and click Save to complete the creation.
1.2 Official account management
The official account action area is mainly composed of the following parts:
Organization screening area on the left: switch official accounts accessed under different organizations
Data display area: displays the list of connected official accounts. The data includes the official account name, official account APPID, creator, application, and actions. Note: In the analysis settings, a public number can only belong to one application.
Action area: The action area contains 「Edit」 and 「Action」. After clicking 「Edit」, it is the same as the new interface. If you click Delete, the association of the official account is removed from the application.
1.3 Data analysis
For applications after accessing the official account, as well as analysis views and small stations with "applications after accessing the official account", official account events need to be included in the system attributes to participate in the analysis. The system attributes participating in the analysis are as follows:
System Attributes | The attribute value. |
Platform | Official account AppID@wechatoa |
Platform Type | WeChat Official Accounts |
Event Type | Custom event |
Event Name&Event Code | For more information, see 2 Events and Event Attributes. |
Device ID. | openid (default), which can be changed to Unionid in public number management |
Whether the equipment is started on the first day | Marking together according to the data in the application to which it belongs |
The analysis models for revealing official account events include: event analysis, funnel analysis, retention analysis, distribution analysis, interval analysis, path analysis, lifecycle analysis, attribution analysis, and audience management.
2 Events and event attributes
WeChat official account events are defined, generated, and sent by WeChat. Developers only subscribe to these data and cannot customize them. Specific event list that can be subscribed are as follows:
Event name | Event code | Event attribute name (analysis display) | Attribute Key | Attribute type | Notes | |
Menu click (preset) | $$_menu_click | Message type | MsgType | string | Message type: event | |
Event type | Event | string | Event type: CLICK | |||
Event key | EventKey | string | The event KEY value, which corresponds to the KEY value in the custom menu interface. | |||
Menu ID | MenuID | string | Refers to the menu ID. If it is a personalized menu, you can use this field to know which rule's menu was clicked. | |||
Scan information | ScanCodeInfo | string | Scan information | |||
Scan type | ScanType | string | Scan type: generally qrcode | |||
Scan results | ScanResult | string | Scan result, that is, the string information corresponding to the two-dimensional code | |||
Sent image information | SendPicsInfo | string | Sent image information | |||
Number of images sent | Count | number | Number of images sent | |||
Sent location information | SendLocationInfo | string | Sent location information | |||
X coordinate information | Location_X | string | X coordinate information | |||
Y coordinate information | Location_Y | string | Y coordinate information | |||
Precision | Scale | number | Precision, which can be understood as precision or scale. The finer the scale, the higher the scale. | |||
Geographical location | Label | string | String information of geographical location | |||
Wechat moments POI name | Poiname | string | The name of the circle of friends POI may be empty. | |||
Follow the official account (preset) | $$_official_account_follow | Whether to scan code to follow | is_scan | string | Whether to scan code to follow (merging the attention public number of the original event with the code scanning attention public number) | |
Event key | EventKey | string | The event key value, which is prefixed with qrscene_, followed by the parameter value of the QR code | |||
Event type | Event | string | Event type: subscribe | |||
QR code ticket | Ticket | string | The ticket of the two-dimensional code can be used to exchange the two-dimensional code picture. | |||
Unfollow the official account (preset) | $$_official_account_unfollow | Message type | MsgType | string | Message type: event | |
Event Type | Event | string | Event type: unsubscribe | |||
Scan code to open the official account (preset) | $$_scan_open_official_account | Message type | MsgType | string | Message type: event | |
Event type | Event | string | Event type: SCAN | |||
Event key | EventKey | string | The event KEY value, which is a 32-bit unsigned integer, that is, the QR code scene_id when the QR code is created. | |||
QR code ticket | Ticket | string | The ticket of the two-dimensional code can be used to exchange the two-dimensional code picture. | |||
Report geographic location (preset) | $$_send_localtion | Event Type | Event | string | Event type: LOCATION | |
Latitude (geographic location) | Latitude | number | Geographic Location Latitude | |||
Longitude (geographic location) | Longitude | number | Geographical location longitude | |||
Accuracy (geographic location) | Precision | number | Geographical location accuracy | |||
Subscribe to message sending (preset) | $$_send_msg_popup | Template id | TemplateId | string | Template id (a subscription may have multiple notifications with multiple IDs) | |
Message ID | MsgID | string | The message ID. | |||
Push result code | ErrorCode | string | Push result status code (0 indicates success) | |||
Push results | ErrorStatus | string | Text meaning status code push result | |||
Subscribe pop-up click (preset) | $$_click_msg_popup | Template id | TemplateId | string | Template id (a subscription may have multiple notifications with multiple IDs) | |
Action behavior | SubscribeStatusString | string | User click behavior (agree to "accept", cancel "reject" to send notifications) | |||
Action scenario | PopupScene | string | 1 : The pop-up window comes from H5 page 2 : pop-up window from graphic messages | |||
Manage subscription messages (preset) | $$_manager_msg_popup | Template id | TemplateId | string | Template id (a subscription may have multiple notifications with multiple IDs) | |
Action behavior | SubscribeStatusString | string | User click behavior (push user rejection notifications only) | |||
Template message delivery (preset) | $$_template_send_finish | Message type | MsgType | string | Message type: event | |
Event type | Event | string | The event is the end of sending a template message. | |||
Message ID | MsgID | string | The ID of the message. | |||
Sending status | Status | string | The status of the message is success, user block, or system failed. | |||
Broadcast message delivery (preset) | $$_mass_send_finish | Message type | MsgType | string | Message type: event | |
Event type | Event | string | Event Type: MASSSENDJOBFINISH | |||
Message ID | MsgID | string | The ID of the group-sent message. | |||
Sending status | Status | string | The result of the mass sending, which is "send success" or "send fail" or "err(num)". However, when sending success, a small number of users may fail to receive messages due to reasons such as user rejection of public number messages and system errors. Err (num) is the specific reason for the failure of the audit. The possible situations are as follows: err(10001): suspected advertisement, err(20001): suspected politics, err(20004): suspected society, err(20002): suspected pornography, err(20006): suspected crime, err(20008): suspected fraud, err(20013): suspected copyright, err(22000): suspected of mutual pushing (mutual propaganda), err (21000): Suspected of other, err(30001): There is a system error in the original check and the user chooses not to send it in groups if it is judged to be reprinted. err (30002): Original verification is determined to be unable to send in groups. err (30003): The original verification is determined to be reprinted and the user chooses to be judged to be reprinted without mass sending. err (40001): Administrator refuses, err(40002): Administrator does not respond within 30 minutes and times out | |||
Total number of fans | TotalCount | number | The number of fans in the tag_id field or the number of fans in the openid_list field. | |||
Actual number of sent fans | FilterCount | number | The number of fans to be sent after filtering (filtering refers to filtering for specific regions and genders, filtering for rejection set by users, and filtering for which users have received more than 4 entries). In principle, FilterCount is approximately equal to SentCount + ErrorCount | |||
Number of successfully sent fans | SentCount | number | Number of successfully sent fans | |||
Number of Fans failed to Send | ErrorCount | number | Number of Fans Failed to Send | |||
Article number | ArticleIdx | string | The serial number of the mass-posted article, starting from 1. | |||
Article status | UserDeclareState | string | The user claims the status of the article | |||
System verification status | AuditState | string | Status of system check | |||
Similar original URL | OriginalArticleUrl | string | URL of similar original | |||
Similar original text type | OriginalArticleType | string | Types of similar original articles | |||
Whether it can be reproduced | CanReprint | string | Whether it can be reproduced | |||
Whether to replace with original content | NeedReplaceContent | string | Whether the original content needs to be replaced | |||
Whether it is necessary to indicate the source of reprint | NeedShowReprintSource | string | Whether it is necessary to indicate the source of reprint | |||
Overall verification result | CheckState | string | Overall verification result 1-not judged to be reprinted, can be sent in groups, 2-judged to be reprinted, can be sent in groups, 3-judged to be reprinted, cannot be sent in groups | |||
Article URL | ArticleUrl | string | The URL of the mass article. | |||
Publish official account Tweets (preset) | $$_publish_job_finish | Publish task id | publish_id | string | publish task id | |
Publish status | publish_status | string | Publishing status: 0: successful, 1: publishing, 2: original creation failed, 3: regular failed, 4: platform review failed, 5: user deletes all articles after successful, 6: system bans all articles after successful | |||
Article id | article_id | string | When the publishing status is 0 (that is, successful), the article_id of the graphic is returned, which can be used in the "customer service message" scenario. | |||
Number of articles | count | number | When the publishing status is 0 (that is, successful), the number of articles returned | |||
Article number | idx | string | When the publishing status is 0 (that is, successful), the number corresponding to the article is returned | |||
Article URL | article_URL | string | When the publish status is 0 (that is, successful), returns the permanent link of the graphic | |||
Publish failed article number | fail_idx | string | When the publishing status is 2 or 4, the number of the failed article is returned, and the first article is 1; other publishing statuses are empty | |||
Official account message reception (preset) | $$_receive_msg | Message type | MsgType | string | Message type: text | |
Text message content | Content | string | Text message content | |||
Message ID | MsgId | string | Message ID, 64-bit integer | |||
Data ID of the message | MsgDataId | string | Data ID of the message (only if the message is from an article) | |||
Article number | Idx | string | Which article is the number of multiple pictures, starting from 1 (only if the message comes from the article) | |||
Image URL | PicUrl | string | Image link (generated by the system) | |||
Media ID | MediaId | string | the media id of the image message. you can call the operation to obtain temporary materials to pull data. | |||
Voice format | Format | string | Voice format: amr | |||
Voice recognition results | Recognition | string | Voice recognition result, encoded in UTF8 | |||
Thumbnail media id | ThumbMediaId | string | the media id of the video message thumbnail. you can call the multimedia file download operation to pull the data. | |||
X coordinate information | Location_X | number | Geographic Location Latitude | |||
Y coordinate information | Location_Y | number | Geographical location longitude | |||
Precision | Scale | number | Map zoom size | |||
Geographical location | Label | string | The geography location. The following information is supported: | |||
Message title | Title | string | Message Title | |||
Message description | Description | string | Message description | |||
Message URL | Url | string | Message Link | |||
3 Event tracking
3.1 server tracking parameters tracking
Go to the management console --> Click track information
Primary domain name: the address for reporting server tracking data
Sub-domain: The default domain is the same as the primary domain. Private deployment customers can provide sub-domain names as alternate domain names.
The ServiceSecret and ServiceID are verification parameters. Do not disclose the secret.
The code parameter specifies the developer ID(AppID). This parameter is required from the WeChat public ID platform and must be configured in the tracking management-data source management-official account management.
Note: Because the above information involves system security, only administrator rights can see it!



3.2 Request parameters
API address: https://<data tracking endpoint + Port> /server/thirdPartyDataSource
request parameters content-type:application/json
Request JSON parameters:
JSON field name | Data types | Required | The field description. | Examples |
sign | string | Yes | Verify the signature | f564cae6a8ad458648id9d607a124322 |
app_id | string | Yes | serviceID in the corresponding server tracking point | OA8kI9Jis7YJNh5uh |
appkey | string | Yes | Application key, obtained from QT management background | 9moqdsuia8hvxm7k8shf82n |
ts | string | Yes | The timestamp that is reported in milliseconds. | 1659493170125 |
code | string | Yes | Developer ID(AppID), WeChat official | wxd66151142ae9b9ae |
weChatOAData | string | Yes | Xml from WeChat Public Number | |
3.3 Authentication sign generation rules
First, encapsulate the keys and values of all request fields except the sign field into a map object
To serialize this map object into JSON characters, the keys need to be sorted according to the natural order, that is, the ASCII code. Java can use JSONObject.toJSONString(mapObject, SerializerFeature.MapSortField),
Get serviceSecret
sign = MD5 (JSON characters generated after sorting + serviceSecret)
Put the calculated sign into the original map object and serialize it into JSON characters, which is the final complete JSON request message.
3.4 Response description
Response data content-type:application/json
The response JSON contains two fields: code and message
code | message | Description |
Httpapi_300_200 | Report success | Success |
Httpapi_300_101 | Illegal signature | Signature verification failed. For more information, see Sign generation rules. |
Httpapi_300_102 | The reported data type is not in JSON format. | The data format request parameters is not in JSON format |
Httpapi_300_103 | Missing required fields | Check whether required parameters are omitted by referring to the request parameter table |
Httpapi_300_104 | The user attribute is missing a required field | Check whether required parameters are omitted by referring to the request parameter table |
Httpapi_300_105 | Illegal event id | Incorrect event ID |
Httpapi_300_106 | Incorrect ak/sk | |
Httpapi_300_107 | Non-standard xml format of WeChat official account reporting log | |
Httpapi_300_108 | The reported WeChat official account message is illegal | |
Httpapi_300_109 | Unrecognized WeChat official account encryption type | |
Httpapi_300_110 | Failed to obtain the unionid. |
3.5 java demo reference

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.google.gson.Gson;
import okhttp3.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.Map;
/**
* ThirdPartyDataSourceApiDemo access the third-party data source demo
*
* @author chengtao
*/
public class ThirdPartyDataSourceApiDemo {
private static final Logger logger = LoggerFactory.getLogger(ThirdPartyDataSourceApiDemo.class);
/**
* Primary domain name
*/
private static final String API_URL = "*****";
/**
* Corresponds to the ServiceID in the server tracking information.
*/
private static final String SERVICE_ID = "*****";
/**
* Corresponds to the ServiceSecret in the server tracking information.
*/
private static final String SERVICE_SECRET = "*****";
/**
* Client logs
*/
private static final OkHttpClient client = new OkHttpClient();
/**
* Obtain WeChat public number log and forward it to QT for tracking (this interface needs to be configured in WeChat public number management background)
*
* @param request
* @throws IOException
*/
@RequestMapping("/token")
@ResponseBody
public void token(HttpServletRequest request) throws IOException {
// Obtain all parameters in the official WeChat public number request and encapsulate them in JSON format.
Map<String, String[]> paramMap = request.getParameterMap();
JSONObject json = paramMapToJson(paramMap);
// Add the service ID to the message.
json.put("app_id",SERVICE_ID);
// Add ts to the message.
json.put("ts", String.valueOf(System.currentTimeMillis()));
// Enter the public ID.
String code = "******";
json.put("code", code);
// Obtain the XML data of the WeChat public number.
String weChatOAData = new String(InputStreamUtil.getBytes(request));
json.put("weChatOAData", weChatOAData);
//Calculate the signature
String sign = MD5Util.md5(JSONObject.toJSONString(json, SerializerFeature.MapSortField) + SERVICE_SECRET);
json.put("sign", sign);
String desJsonString = JSON.toJSONString(json, SerializerFeature.DisableCircularReferenceDetect);
Request newRequest = new Request.Builder()
.URL(API_URL + "/server")
.post(RequestBody.create(MediaType.parse("application/json"),
desJsonString))
.build();
try {
Response response = client.newCall(newRequest).execute();
if (!response.isSuccessful()) {
System.out.printf("[DEMO] Failed to send log %s%n", response);
} else {
System.out.printf("[DEMO] Sent successfully %s%n",
response.body().string());
}
} catch (IOException e) {
e.printStackTrace();
}
}
private static JSONObject paramMapToJson(Map<String, String[]> paramMap) {
Map<String, Object> bodyMap = new HashMap<>();
for (Map.Entry<String, String[]> entry : paramMap.entrySet()) {
String key = entry.getKey();
String[] value = entry.getValue();
if (value.length == 1) {
bodyMap.put(key, value[0]);
} else {
bodyMap.put(key, value);
}
}
return JSON.parseObject(new Gson().toJson(bodyMap));
}
private static String getBodyString(HttpServletRequest request) {
StringBuilder sb = new StringBuilder();
InputStream inputStream = null;
BufferedReader reader = null;
try {
inputStream = request.getInputStream();
reader = new BufferedReader(new InputStreamReader(inputStream, Charset.forName("UTF-8")));
String line = "";
while ((line = reader.readLine()) != null) {
sb.append(line);
}
} catch (IOException e) {
logger.error("read body error", e);
throw new RuntimeException("read body error");
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
logger.error("close inputStream error", e);
}
}
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
logger.error("close reader error", e);
}
}
}
return sb.toString();
}
}
public class MD5Util {
public static String md5(String s) {
char hexDigits[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
try {
byte[] btInput = s.getBytes();
// Obtain the MessageDigest object of the MD5 digest algorithm.
MessageDigest mdInst = MessageDigest.getInstance("MD5");
// Update the digest with the specified bytes
mdInst.update(btInput);
// Obtain the ciphertext.
byte[] md = mdInst.digest();
// Convert the ciphertext into a hexadecimal string.
int j = md.length;
char str[] = new char[j * 2];
int k = 0;
for (int i = 0; i < j; i++) {
byte byte0 = md[i];
str[k++] = hexDigits[byte0 >>> 4 & 0xf];
str[k++] = hexDigits[byte0 & 0xf];
}
return new String(str);
} catch (Exception e) {
return null;
}
}
/**
* Unit testing
*/
public static void main(String[] args) {
StringBuilder dtskey = new StringBuilder("abc12390");
dtskey.append('\0').append("~!@#$%^&*()_+");
System.out.println(MD5Util.md5(dtskey.toString()));
System.out.println(MD5Util.md5("20121221"));
System.out.println(MD5Util.md5("Encryption"));
}
}
