Article Directory
Test Number Application
Ask your own test number for testing
Open Developer Mode
The various message interactions mentioned here refer to the message interaction in developer mode. If the developer mode has not been turned on, you can refer to the previous article to turn on Public Number Developer mode.
Short Book
Nuggets
CSDN
Open Source China
It is very simple to interact with various messages of WeChat Public Number in TNW as follows:
- Receive various messages
- Call the WeChat.handleMsg(...) method to process the distribution message
- Implement the MsgAdapter interface, business logic, and various message replies
Receive various messages
The implementation code for receiving various messages under the POST method of the developer URL is as follows
An example of Express is as follows:
// Receive WeChat Message Entry app.post('/msg', function (req: any, res: any) { console.log('post...', req.query); // Support multi-public numbers let appId: string = req.query.appId; if (appId) { ApiConfigKit.setCurrentAppId(appId); } // Get signature-related parameters for message decryption (test number and clear text mode do not have this parameter) let msgSignature = req.query.msg_signature, timestamp = req.query.timestamp, nonce = req.query.nonce; //Listen for data events to receive data let buffer: Uint8Array[] = []; req.on('data', function (data: any) { buffer.push(data); }); req.on('end', function () { let msgXml = Buffer.concat(buffer).toString('utf-8'); // Process the message and respond to the corresponding reply // .... }); });
Nest example is as follows:
@Post("/msg") PostMsg(@Req() req: Request, @Res() res: Response) { let that = this; console.log('post...', req.query); // Support multi-public numbers let appId: string = req.query.appId; if (appId) { ApiConfigKit.setCurrentAppId(appId); } // Get signature-related parameters for message decryption (test number and clear text mode do not have this parameter) let msgSignature = req.query.msg_signature, timestamp = req.query.timestamp, nonce = req.query.nonce; //Listen for data events to receive data let buffer: Uint8Array[] = []; req.on('data', function (data: any) { buffer.push(data); }); req.on('end', function () { let msgXml = Buffer.concat(buffer).toString('utf-8'); // Process the message and respond to the corresponding reply // ... }); }
Process and distribute messages
WeChat.handleMsg(msgAdapter: MsgAdapter, msgXml: string, msgSignature?: string, timestamp?: string, nonce?: string)
handleMsg contains message decryption, various message distribution, message encryption, and various message replies.The source code is not pasted here. If you are interested, you can see the source code. The source code also has detailed comments.
Among them, msgXml, msgSignature, timestamp, nonce have been obtained in the various messages received above, which is inferior to MsgAdapter.
Introduction to MsgAdapter
The methods defined in the MsgAdapter interface are as follows:
export interface MsgAdapter { // Processing text messages processInTextMsg(inTextMsg: InTextMsg): OutMsg; // Processing picture messages processInImageMsg(inImageMsg: InImageMsg): OutMsg; // Processing sound messages processInVoiceMsg(inVoiceMsg: InVoiceMsg): OutMsg; // Processing video messages processInVideoMsg(inVideoMsg: InVideoMsg): OutMsg; // Processing small video messages processInShortVideoMsg(inShortVideoMsg: InShortVideoMsg): OutMsg; // Processing geographic location messages processInLocationMsg(inLocationMsg: InLocationMsg): OutMsg; // Processing link messages processInLinkMsg(inLinkMsg: InLinkMsg): OutMsg; // Processing speech recognition results processInSpeechRecognitionResults(inSpeechRecognitionResults: InSpeechRecognitionResults): OutMsg; // Handle undefined messages (other messages... Brother should expand) processIsNotDefinedMsg(inNotDefinedMsg: InNotDefinedMsg): OutMsg; // Handle Attention, Remove Attention Events processInFollowEvent(inFollowEvent: InFollowEvent): OutMsg; // Handle Scavenging Events processInQrCodeEvent(inQrCodeEvent: InQrCodeEvent): OutMsg; // Handling geographic location events processInLocationEvent(inLocationEvent: InLocationEvent): OutMsg; // Handling geographic location events processInMenuEvent(inMenuEvent: InMenuEvent): OutMsg; // Handle template message events processInTemplateMsgEvent(inTemplateMsgEvent: InTemplateMsgEvent): OutMsg; // Handle a shake peripheral event processInShakearoundUserShakeEvent(inShakearoundUserShakeEvent: InShakearoundUserShakeEvent): OutMsg; }
InXxxxMsg is uniformly inherited from InMsg, InXxxEvent is uniformly inherited from EventInMsg and EventInMsg is inherited from InMsg, so it is easy to get toUserName (developer microsign, appId) and fromUserName (sender account openId) in any inXxxxx.TNW supports multiple public, and this appId will be used later to enable different public numbers to reply to different messages
Response to the corresponding reply
Code implementation is relatively simple, not too much introduced, see the source code
Reminder: You can respond to messages with special handling of different public numbers
export class MsgController implements MsgAdapter { processInTextMsg(inTextMsg: InTextMsg): OutMsg { let outMsg: any; let content: string = "IJPay Make payments within reach \n\nhttps://gitee.com/javen205/IJPay"; if ("Quick Development of WeChat Public Number" == inTextMsg.getContent) { // Multiple public numbers support sending different messages to different public numbers if (ApiConfigKit.getApiConfig.getAppId == 'wx614c453e0d1dcd12') { content = "Quick Development of WeChat Public Number \n\nhttps://github.com/javen205/weixin_guide" outMsg = new OutTextMsg(inTextMsg); outMsg.setContent(content); } else { content = "Quick Development of WeChat Public Number \n\nhttps://github.com/javen205/TNW" outMsg = new OutTextMsg(inTextMsg); outMsg.setContent(content); } } else if ("Aggregate Payment" == inTextMsg.getContent) { // Latest rule: Developer can only reply to one message; other scenes can reply to up to eight messages outMsg = new OutNewsMsg(inTextMsg); outMsg.addArticle("Understanding Aggregate Payment", "IJPay Make payments within reach", "https://gitee.com/javen205/IJPay/raw/master/assets/img/IJPay-t.png", "https://gitee.com/javen205/IJPay") outMsg.addArticle("jfinal-weixin", "Quick Development of WeChat Public Number", "https://gitee.com/javen205/IJPay/raw/master/assets/img/IJPay-t.png", "https://gitee.com/JFinal/jfinal-weixin") } else { // outMsg = new OutTextMsg(inTextMsg); // outMsg.setContent(content); // Forward to Multi-Service PC Client outMsg = new OutCustomMsg(inTextMsg); console.log("Forward to Multi-Service PC Client"); } return outMsg; } processInImageMsg(inImageMsg: InImageMsg): OutMsg { let outMsg = new OutImageMsg(inImageMsg); outMsg.setMediaId = inImageMsg.getMediaId; return outMsg; } processInVoiceMsg(inVoiceMsg: InVoiceMsg): OutMsg { let outMsg = new OutVoiceMsg(inVoiceMsg); outMsg.setMediaId = inVoiceMsg.getMediaId; return outMsg; } processInVideoMsg(inVideoMsg: InVideoMsg): OutMsg { let outMsg = new OutVideoMsg(inVideoMsg); outMsg.setMediaId = inVideoMsg.getMediaId; outMsg.setDescription = "IJPay Make payments within reach"; outMsg.setTitle = "Video message"; return outMsg; } processInShortVideoMsg(inShortVideoMsg: InShortVideoMsg): OutMsg { let outMsg = new OutVideoMsg(inShortVideoMsg); outMsg.setMediaId = inShortVideoMsg.getMediaId; outMsg.setDescription = "TypeScript + Node.js Develop WeChat Public Number"; outMsg.setTitle = "Short Video Message"; return outMsg; } processInLocationMsg(inLocationMsg: InLocationMsg): OutMsg { return this.renderOutTextMsg(inLocationMsg, "Location message... \n\nX:" + inLocationMsg.getLocation_X + " Y:" + inLocationMsg.getLocation_Y + "\n\n" + inLocationMsg.getLabel); } processInLinkMsg(inLinkMsg: InLinkMsg): OutMsg { let text = new OutTextMsg(inLinkMsg); text.setContent("Link Frequency Message..." + inLinkMsg.getUrl); return text; } processInSpeechRecognitionResults(inSpeechRecognitionResults: InSpeechRecognitionResults): OutMsg { let text = new OutTextMsg(inSpeechRecognitionResults); text.setContent("Speech Recognition Messages..." + inSpeechRecognitionResults.getRecognition); return text; } processInFollowEvent(inFollowEvent: InFollowEvent): OutMsg { if (InFollowEvent.EVENT_INFOLLOW_SUBSCRIBE == inFollowEvent.getEvent) { return this.renderOutTextMsg(inFollowEvent, "Thanks for your attention \n\n Exchange Group: 114196246"); } else if (InFollowEvent.EVENT_INFOLLOW_UNSUBSCRIBE == inFollowEvent.getEvent) { console.error("De-focus:" + inFollowEvent.getFromUserName); return this.renderOutTextMsg(inFollowEvent); } else { return this.renderOutTextMsg(inFollowEvent); } } processInQrCodeEvent(inQrCodeEvent: InQrCodeEvent): OutMsg { if (InQrCodeEvent.EVENT_INQRCODE_SUBSCRIBE == inQrCodeEvent.getEvent) { console.debug("Scavenger not concerned:" + inQrCodeEvent.getFromUserName); return this.renderOutTextMsg(inQrCodeEvent, "Thank you for your attention, QR code content:" + inQrCodeEvent.getEventKey); } else if (InQrCodeEvent.EVENT_INQRCODE_SCAN == inQrCodeEvent.getEvent) { console.debug("Scavenger is concerned:" + inQrCodeEvent.getFromUserName); return this.renderOutTextMsg(inQrCodeEvent); } else { return this.renderOutTextMsg(inQrCodeEvent); } } processInLocationEvent(inLocationEvent: InLocationEvent): OutMsg { console.debug("Send geographic location events:" + inLocationEvent.getFromUserName); return this.renderOutTextMsg(inLocationEvent, "The geographic location is:" + inLocationEvent.getLatitude); } processInMenuEvent(inMenuEvent: InMenuEvent): OutMsg { console.debug("Menu events:" + inMenuEvent.getFromUserName); return this.renderOutTextMsg(inMenuEvent, "The menu event content is:" + inMenuEvent.getEventKey); } processInTemplateMsgEvent(inTemplateMsgEvent: InTemplateMsgEvent): OutMsg { console.debug("Template message events:" + inTemplateMsgEvent.getFromUserName + " " + inTemplateMsgEvent.getStatus); return this.renderOutTextMsg(inTemplateMsgEvent, "Message sending status:" + inTemplateMsgEvent.getStatus); } processInShakearoundUserShakeEvent(inShakearoundUserShakeEvent: InShakearoundUserShakeEvent): OutMsg { console.debug("Shake Event:" + inShakearoundUserShakeEvent.getFromUserName + " " + inShakearoundUserShakeEvent.getUuid); return this.renderOutTextMsg(inShakearoundUserShakeEvent, "uuid: " + inShakearoundUserShakeEvent.getUuid); } processIsNotDefinedMsg(inNotDefinedMsg: InNotDefinedMsg): OutMsg { return this.renderOutTextMsg(inNotDefinedMsg, "Unknown message"); } renderOutTextMsg(inMsg: InMsg, content?: string): OutTextMsg { let outMsg = new OutTextMsg(inMsg); outMsg.setContent(content ? content : " "); return outMsg; } }
Open source recommendation
- TNW WeChat Public Development Scaffold: https://gitee.com/javen205/TNW
- IJPay puts payments within reach: https://gitee.com/javen205/IJPay
- SpringBoot Micro Services Efficient Development mica Toolset: https://gitee.com/596392912/mica
- Avue is a magical framework based on vue configurability: https://gitee.com/smallweigit/avue
- pig Universe's Most Micro Service (required by architects): https://gitee.com/log4j/pig
- Complete online solution for SpringBlade (essential for enterprise development): https://gitee.com/smallc/SpringBlade