TNW-WeChat Public Number Various Message Interaction

Posted by Afrojojo on Thu, 09 May 2019 16:30:05 +0200

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:

  1. Receive various messages
  2. Call the WeChat.handleMsg(...) method to process the distribution message
  3. 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.

Gitee-TNW-WeChat

GitHub-TNW-WeChat

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

Topics: github TypeScript SpringBoot Vue