<span class="inline-code author-d-iz88z86z86za0dz67zz78zz78zz74zz68zjz80zz71z9iz90z95lz89zyft2og2z75zez76z3z80zvpz80zz76zz80zz82zz88zz90zz69zez70zp4hw">package.json</span>
<span class="inline-code author-d-iz88z86z86za0dz67zz78zz78zz74zz68zjz80zz71z9iz90z95lz89zyft2og2z75zez76z3z80zvpz80zz76zz80zz82zz88zz90zz69zez70zp4hw">package-lock.json</span>
<span class="inline-code author-d-iz88z86z86za0dz67zz78zz78zz74zz68zjz80zz71z9iz90z95lz89zyft2og2z75zez76z3z80zvpz80zz76zz80zz82zz88zz90zz69zez70zp4hw">node_modules/</span>
<span class="inline-code author-d-iz88z86z86za0dz67zz78zz78zz74zz68zjz80zz71z9iz90z95lz89zyft2og2z75zez76z3z80zvpz80zz76zz80zz82zz88zz90zz69zez70zp4hw">appID</span>
<span class="inline-code author-d-iz88z86z86za0dz67zz78zz78zz74zz68zjz80zz71z9iz90z95lz89zyft2og2z75zez76z3z80zvpz80zz76zz80zz82zz88zz90zz69zez70zp4hw">appsecret</span>
<span class="inline-code author-d-iz88z86z86za0dz67zz78zz78zz74zz68zjz80zz71z9iz90z95lz89zyft2og2z75zez76z3z80zvpz80zz76zz80zz82zz88zz90zz69zez70zp4hw">index.js</span>
<span class="inline-code author-d-iz88z86z86za0dz67zz78zz78zz74zz68zjz80zz71z9iz90z95lz89zyft2og2z75zez76z3z80zvpz80zz76zz80zz82zz88zz90zz69zez70zp4hw">index.js</span>
<span class="inline-code author-d-iz88z86z86za0dz67zz78zz78zz74zz68zjz80zz71z9iz90z95lz89zyft2og2z75zez76z3z80zvpz80zz76zz80zz82zz88zz90zz69zez70zp4hw">WeChat endpoint listening on port 3000...</span>
<span class="inline-code author-d-iz88z86z86za0dz67zz78zz78zz74zz68zjz80zz71z9iz90z95lz89zyft2og2z75zez76z3z80zvpz80zz76zz80zz82zz88zz90zz69zez70zp4hw">wechat.js</span>
<span class="inline-code author-d-iz88z86z86za0dz67zz78zz78zz74zz68zjz80zz71z9iz90z95lz89zyft2og2z75zez76z3z80zvpz80zz76zz80zz82zz88zz90zz69zez70zp4hw">index.js</span>
<span class="inline-code author-d-iz88z86z86za0dz67zz78zz78zz74zz68zjz80zz71z9iz90z95lz89zyft2og2z75zez76z3z80zvpz80zz76zz80zz82zz88zz90zz69zez70zp4hw">echostr</span>
<span class="inline-code author-d-iz88z86z86za0dz67zz78zz78zz74zz68zjz80zz71z9iz90z95lz89zyft2og2z75zez76z3z80zvpz80zz76zz80zz82zz88zz90zz69zez70zp4hw">echostr</span>
<span class="inline-code author-d-iz88z86z86za0dz67zz78zz78zz74zz68zjz80zz71z9iz90z95lz89zyft2og2z75zez76z3z80zvpz80zz76zz80zz82zz88zz90zz69zez70zp4hw">echostr</span>
<span class="inline-code author-d-iz88z86z86za0dz67zz78zz78zz74zz68zjz80zz71z9iz90z95lz89zyft2og2z75zez76z3z80zvpz80zz76zz80zz82zz88zz90zz69zez70zp4hw">echostr</span>
<span class="inline-code author-d-iz88z86z86za0dz67zz78zz78zz74zz68zjz80zz71z9iz90z95lz89zyft2og2z75zez76z3z80zvpz80zz76zz80zz82zz88zz90zz69zez70zp4hw">wechat.js</span>
<span class="inline-code author-d-iz88z86z86za0dz67zz78zz78zz74zz68zjz80zz71z9iz90z95lz89zyft2og2z75zez76z3z80zvpz80zz76zz80zz82zz88zz90zz69zez70zp4hw">index.js</span>
<span class="inline-code author-d-iz88z86z86za0dz67zz78zz78zz74zz68zjz80zz71z9iz90z95lz89zyft2og2z75zez76z3z80zvpz80zz76zz80zz82zz88zz90zz69zez70zp4hw">index.js</span>
<span class="inline-code author-d-iz88z86z86za0dz67zz78zz78zz74zz68zjz80zz71z9iz90z95lz89zyft2og2z75zez76z3z80zvpz80zz76zz80zz82zz88zz90zz69zez70zp4hw">app.get(</span><span class="inline-code">'</span><span class="inline-code author-d-iz88z86z86za0dz67zz78zz78zz74zz68zjz80zz71z9iz90z95lz89zyft2og2z75zez76z3z80zvpz80zz76zz80zz82zz88zz90zz69zez70zp4hw">/</span><span class="inline-code">'</span><span class="inline-code author-d-iz88z86z86za0dz67zz78zz78zz74zz68zjz80zz71z9iz90z95lz89zyft2og2z75zez76z3z80zvpz80zz76zz80zz82zz88zz90zz69zez70zp4hw">)</span>
<span class="inline-code author-d-iz88z86z86za0dz67zz78zz78zz74zz68zjz80zz71z9iz90z95lz89zyft2og2z75zez76z3z80zvpz80zz76zz80zz82zz88zz90zz69zez70zp4hw">node .</span>
<span class="inline-code author-d-iz88z86z86za0dz67zz78zz78zz74zz68zjz80zz71z9iz90z95lz89zyft2og2z75zez76z3z80zvpz80zz76zz80zz82zz88zz90zz69zez70zp4hw">/wechat</span>
Step 5: Process incoming messages
Whenever a user starts following your official accounts, sends a message to your account or unfollows it, you will receive a POST request with some XML describing the message. To handle these messages, we need to add another endpoint to our wechat.js
file, but instead of calling app.get()
to create a handler for GET requests, we will call app.post()
to register a handler for POST requests. As we don’t want to write a lot of XML-parsing boilerplate code ourselves, we will install an XML body parser for Express that can handle this for us. Let’s start with that.
Install body-parser
and body-parser-xml
with the following command in your terminal:
Let’s set up the body parser. In index.js
, change the two top lines (the ones that set up the Express app) so they reflect the following:
<span class="inline-code author-d-iz88z86z86za0dz67zz78zz78zz74zz68zjz80zz71z9iz90z95lz89zyft2og2z75zez76z3z80zvpz80zz76zz80zz82zz88zz90zz69zez70zp4hw">wechat.js</span>
This piece of code sets up a POST handler on the router (line 6), takes the parsed XML out of the body and switches over the message type (line 9, the XML parser puts single text nodes into an array so that’s why we need to access it with index 0). The function then forwards the response object and parsed XML to one of three handlers (line 11, 13 and 15), for handling new events, text messages and any messages of unknown type respectively. The last step will involve implementing these handlers and returning an XML response that will be sent to the user.
This is the final step of implementing our WeChat echo service! As WeChat requires us to respond with XML, we will use template strings to easily create an XML string that can be written to the response object. WeChat then sends our message to the user’s device, so it feels as if they are talking to an actual person.
The function for setting up the template is as follows:
This will inject the receiver, sender and text content into an XML string that can be sent in the handlers. You should add this function above the handlers, by replacing TODO 3.
Next, we’ll set up our handlers. The most complex one is the handler for event type messages, as there can be multiple types of events that are triggered. We are only interested in the subscribe
event, that is triggered when a user scans your QR code and taps ‘Follow’. This is the handler:
The handleEvent
function extracts the event type from the XML data and checks if it is a subscribe
event. It then creates an XML response by flipping the sender and receiver from the XML data and adding a string message. This will welcome new followers with the ‘Welcome to our Official Account!’ message.
While we’re at it, let’s implement the other message handlers:
In the handleText
function, the string that is sent back is the reversed text message sent by the user. In the handleUnknown
function, we just send back a message telling the user that our echo service does not (yet) understand what they’re saying.
And that’s it! After all the hard work it is time to see what happens when we start to follow our own Official Account and send some messages. To start following yourself, scan the QR code that is shown on the WeChat sandbox page, halfway down. On your phone, tab the ‘+’ at the top-right corner in the chat overview, then tap ‘Scan QR code’. After scanning the code, you should see a simple page with a large ‘Follow’ button. If you tap that, WeChat should open a new chat with the echo service. It should welcome you with the message we added earlier. If you send a text message, the echo service should reply with your message reversed. If you send anything else (a picture maybe, or your location) the echo service will tell you that it doesn’t understand that message type. If this all works, good job!
Léon Rodenburg is a full stack development consultant at Xebia. He has a background in Computer Science and Sinology and is always on the lookout for the crossroads between the two. Having lived and studied in China for quite some time, he has put his knowledge of the Chinese language into practice by experiencing on- and offline daily life in Beijing like a local.