Bypass Web Restrictions and Build a WeChat Bot with Wechaty’s PuppetPuppeteer
This article explains how to use Wechaty’s PuppetPuppeteer to create a WeChat chatbot by intercepting login requests, injecting interaction scripts, and leveraging Angular services in the web client, while highlighting the risks of web‑client changes.
Previously an article introduced Wechaty as a simple way to build a WeChat chatbot; this follow‑up focuses on using the web version of WeChat to implement the bot and includes a video demonstration.
Wechaty has been developed for five to six years and is relatively stable, but it can become unusable when WeChat updates its web client. As of September 2022 it still works.
Wechaty is a popular chatbot SDK; its npm download count and GitHub stars are shown below.
GitHub stars trend:
Overview
Wechaty is a universal SDK for building chatbots that works with different Puppet Providers to support platforms such as WhatsApp, WeChat, WeCom, Gitter, and Lark. This article concentrates on the WeChat provider.
Web : PuppetPuppeteer
Windows : PuppetWxwork
Mock : PuppetMock
Web : PuppetWechat4u
iPad : PuppetRock
iPad : PuppetPadLocal
Windows : PuppetDonut
iPad : DEPRECATED PuppetPadpro
iPad : DEPRECATED PuppetPadchat
iPad : DEPRECATED PuppetPadplus
Mac : DEPRECATED PuppetMacpro
Many providers support WeChat, each with a different implementation approach; this article only covers PuppetPuppeteer (wechaty-puppet-puppeteer).
Implementation Idea
1. Bypass Web Restrictions
PuppetPuppeteer uses Puppeteer to control the web version of WeChat. The web client normally blocks login with a message prompting the user to download the desktop client. The restriction is lifted by enabling the UOS protocol and intercepting the
/cgi-bin/mmwebwx-bin/webwxnewloginpagerequest, adding
client-versionand
extspamheaders.
<code>const uosHeaders = { 'client-version': UOS_PATCH_CLIENT_VERSION, extspam: UOS_PATCH_EXTSPAM, }
page.on('request', (req) => {
const url = new URL(req.url())
if (url.pathname === '/cgi-bin/mmwebwx-bin/webwxnewloginpage') {
const override = { headers: { ...req.headers(), ...uosHeaders } }
this.wrapAsync(req.continue(override))
}
})</code>After this handling, the bot can log in via QR code and reach the chat page. To run the bot in headless mode, configure the options as follows:
<code>const bot = WechatyBuilder.build({
name: 'wechat-bot',
puppetOptions: {
head: true, // disable headless mode
uos: true, // enable UOS protocol
},
puppet: 'wechaty-puppet-wechat',
})</code>2. Inject Interaction Script
Once the chat page loads, PuppetPuppeteer injects a script that enables actions such as sending messages and creating groups. The injection reads
wechaty-bro.jsfrom the project and evaluates it in the page context.
<code>const WECHATY_BRO_JS_FILE = path.join(codeRoot, 'src', 'wechaty-bro.js')
const sourceCode = fs.readFileSync(WECHATY_BRO_JS_FILE).toString()
let retObj = await page.evaluate(sourceCode) as undefined | InjectResult</code>The script does not manipulate the DOM directly; instead it accesses Angular services that the web client uses.
<code>// Example of accessing an Angular service
angular.module('Services').factory('chatroomFactory', [ /* ... */ ])</code>Factories can be retrieved with:
<code>angular.element(document).injector().get('chatroomFactory');</code>These factories are then exposed via
WechatyBro.glue:
<code>const injector = angular.element(...)
const accountFactory = injector.get('accountFactory')
const chatroomFactory = injector.get('chatroomFactory')
const chatFactory = injector.get('chatFactory')
const contactFactory = injector.get('contactFactory')
WechatyBro.glue = { accountFactory, chatFactory, chatroomFactory, contactFactory, /* ... */ }
</code>From the Puppeteer backend, a group operation can be performed like this:
<code>this.page.evaluate(`
WechatyBro.glue.chatroomFactory.addMember.apply(undefined, { /* parameters */ })
`)</code>Conclusion
The two critical techniques are enabling the UOS login protocol and reusing the internal code of the WeChat web client. When the web client’s implementation changes, the chatbot may stop working.
KooFE Frontend Team
Follow the latest frontend updates
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.