How the WeChat Message Template Sending System Works in mini-shop-server
The WeChat message template sending system in mini-shop-server implements a three-layer architecture that retrieves an access token via WxToken, constructs a JSON payload using the WxMessage base class and its subclasses, and prepares the data for the official WeChat template message API endpoint.
The mini-shop-server repository provides a lightweight Flask-based implementation for sending WeChat Mini Program template messages. The system handles authentication, payload construction, and API communication through a series of service classes located in the app/service/ directory. While the final HTTP POST is currently stubbed in the source, the infrastructure demonstrates the complete flow required to notify users about order status changes.
Token Retrieval with WxToken
The authentication flow begins in app/service/wx_token.py with the WxToken class. This service obtains a short-lived access token required for all WeChat API interactions.
The class constructs a login URL using Flask configuration values (APP_ID, APP_SECRET, and LOGIN_URL). It then executes an HTTP GET request via the generic helper HTTP.get (defined in app/libs/httper.py) to fetch the token JSON. If the WeChat API returns an error code, the service raises a WeChatException to halt processing and prevent invalid API calls.
# Conceptual flow based on wx_token.py implementation
from app.service.wx_token import WxToken
# Raises WeChatException if credentials are invalid or API returns error
token_data = WxToken.get_token(code="wechat_login_code")
access_token = token_data.get("access_token")
Building the Message Payload
The message construction logic resides in app/service/wx_message.py, which defines the WxMessage base class. This class stores the WeChat template message endpoint template: https://api.weixin.qq.com/cgi-bin/message/wxopen/template/send?access_token=%s.
Concrete implementations like DeliveryMessage in app/service/delivery_message.py inherit from WxMessage and set specific fields:
tlp_id: The WeChat template ID configured for the specific notification typeform_id: Collected fromorder.prepay_id, this unique identifier allows the Mini Program to push messages to the userpage: The Mini Program page path users navigate to when tapping the messageemphasis_keyword: Specifies which keyword to highlight in the notification
The __prepare_message_data method constructs the data dictionary following WeChat's schema, mapping values to keyword1 through keyword4 fields with optional color specifications.
# Example from delivery_message.py showing payload preparation
class DeliveryMessage(WxMessage):
def send_delivery_message(self, order, tpl_jump_page=None):
self.tlp_id = "your_template_id_here"
self.form_id = order.prepay_id # Critical: must be recent prepay_id
self.page = tpl_jump_page # e.g., "pages/order/detail?id=123"
self.__prepare_message_data(order)
# Payload now ready for transmission
The Sending Flow (Current Implementation)
The final transmission step is currently stubbed in DeliveryMessage.send_delivery_message, which returns an empty string '' instead of executing the HTTP request. In a complete production deployment, the method would execute the following sequence:
- Retrieve fresh token: Call
WxTokento obtain a validaccess_token - Format endpoint URL: Insert the token into
self.__send_url % access_token - Execute POST: Use
HTTP.post(fromapp/libs/httper.py) to transmit the JSON body:
{
"touser": "OPENID",
"template_id": "TEMPLATE_ID",
"page": "pages/index/index",
"form_id": "PREPAY_ID",
"data": {
"keyword1": {"value": "Product Name"},
"keyword2": {"value": "Shipped"},
"keyword3": {"value": "2024-01-15"}
},
"emphasis_keyword": "keyword2.value"
}
The HTTP helper in app/libs/httper.py provides the underlying GET and POST methods used throughout the application for external API communication.
Integration Example: Order Delivery Notifications
In practice, the system triggers when an order status changes. The order service instantiates DeliveryMessage and passes the order object along with an optional navigation page.
from app.service.delivery_message import DeliveryMessage
from app.models.order import Order
def notify_user_of_shipment(order_id):
order = Order.query.get(order_id)
if not order:
raise OrderException("Order not found")
messenger = DeliveryMessage()
messenger.send_delivery_message(
order=order,
tpl_jump_page=f"pages/order/detail?id={order.id}"
)
# In current implementation, returns empty string
# In production, would return WeChat API response
The method validates the order's existence and raises OrderException if falsy, ensuring that only valid transactions generate notification attempts.
Summary
WxTokenmanages OAuth2 authentication with WeChat, fetching access tokens usingAPP_IDandAPP_SECRETfrom Flask configWxMessageprovides the base structure for template messages, including the official WeChat API endpoint URL patternDeliveryMessagedemonstrates concrete implementation, mapping order data to WeChat's keyword-based template format usingprepay_idas theform_id- The architecture follows the token → payload → POST pattern required by WeChat's template message API, though the final HTTP transmission requires implementation in the stubbed
send_delivery_messagemethod - All HTTP operations rely on the generic
HTTPhelper located inapp/libs/httper.py
Frequently Asked Questions
What is the role of the form_id in WeChat template messages?
The form_id is a unique identifier that authorizes the Mini Program to send a template message to a specific user. In mini-shop-server, this value is extracted from order.prepay_id, which is generated during the WeChat payment process. Each form_id can only be used once and expires after seven days, making it essential to send notifications promptly after payment completion.
Why is the final HTTP POST request stubbed in the current source code?
The send_delivery_message method in app/service/delivery_message.py currently ends with return '', indicating the repository is either a demonstration template or awaiting completion. The stub preserves the business logic and data preparation layers while allowing developers to implement the actual HTTP call using the HTTP.post method from app/libs/httper.py when integrating with live WeChat credentials.
How does mini-shop-server handle WeChat API authentication errors?
The WxToken class in app/service/wx_token.py validates the JSON response from WeChat's token endpoint. If the response contains an errcode field, the service raises WeChatException with the error details. This prevents the application from attempting to send template messages with invalid credentials and allows upstream error handling to manage retries or user notifications.
What configuration values are required to enable WeChat template messaging?
The system requires three Flask configuration variables defined in the application config: APP_ID (WeChat Mini Program AppID), APP_SECRET (corresponding secret key), and LOGIN_URL (WeChat's jscode2session endpoint). These values are consumed by WxToken to authenticate with WeChat's servers and obtain the access_token necessary for all template message API calls.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →