Home

Awesome

简体中文

wechatircd IRC Telegram Gitter

wechatircd injects JavaScript (injector.js) to wx.qq.com, which uses WebSocket to communicate with an IRC server (wechatircd.py), thus enable IRC clients connected to the server to send and receive messages from WeChat, set topics, invite/delete members, ...

           IRC               WebSocket                 HTTPS
IRC client --- wechatircd.py --------- browser         ----- wx.qq.com
                                       injector.user.js
                                       injector.js

Discuss wechatircd by joining #wechatircd on freenode, or the user group on Telegram. Video on using WeChat in WeeChat

Installation

Arch Linux

wechatircd.py (the server) will listen on 127.0.0.1:6667 (IRC) and 127.0.0.1:9000 (HTTPS + WebSocket over TLS).

If you run the server on another machine, it is recommended to set up IRC over TLS and an IRC connection password with a few more options: --irc-cert /path/to/irc.key --irc-key /path/to/irc.cert --irc-password yourpassword. As an alternative to the IRC connection password, you may specify --sasl-password yourpassword and authenticate with SASL PLAIN. You can reuse the HTTPS certificate+key. If you use WeeChat and find it difficult to set up a valid certificate (gnutls checks the hostname), type the following lines in WeeChat:

/set irc.server.wechat.ssl on
/set irc.server.wechat.ssl_verify off
/set irc.server.wechat.password yourpassword

Not Arch Linux

The IP address or the domain name used to serve injector.js and injector.user.js should match the subjectAlternativeName fields. Chrome has removed support for commonName matching in certificates since version 58. See https://developers.google.com/web/updates/2017/03/chrome-58-deprecations#remove_support_for_commonname_matching_in_certificates for detail.

Userscript and self-signed CA certificate

Chrome/Chromium

Firefox

The server serves injector.js and WebSocket connections on 127.0.0.1:9000 by default, which can be overriden with --http-listen 0.0.0.0 --http-port 9000.

You can enable HTTPS in two ways:

Usage

You will join +wechat channel automatically and find your contact list there. Some commands are available:

The server can only be bound to one wx.qq.com account, however, you may have more than one IRC clients connected to the server.

IRC features

!m , @3 , nick: can be arranged in any order.

For WeeChat, its anti-flood mechanism will prevent two user messages sent to IRC server in the same time. Disable anti-flood to enable paste detection.

/set irc.server.wechat.anti_flood_prio_high 0

server-time extension from IRC version 3.1, 3.2. wechatircd.py includes the timestamp (obtained from JavaScript) in messages to tell IRC clients that the message happened at the given time. See http://ircv3.net/irc/. Seehttp://ircv3.net/software/clients.html for Client support of IRCv3.

Configuration for WeeChat:

/set irc.server_default.capabilities "account-notify,away-notify,cap-notify,multi-prefix,server-time,znc.in/server-time-iso,znc.in/self-message"

Supported IRC commands:

Display

QQ emojis are displayed as <img class="qqemoji qqemoji0" text="[Smile]_web" src="/zh_CN/htmledition/v2/images/spacer.gif">, [Smile] in sent messages will be replaced to emoticon.

Emojis are rendered as <img class="emoji emoji1f604" text="_web" src="/zh_CN/htmledition/v2/images/spacer.gif">. Each emoji will be converted to a single character before delivered to the IRC client. Emojis may overlap as terminal emulators may not know emojis are of width 2,see 终端模拟器下使用双倍宽度多色Emoji字体.

Server options

See wechatircd.service for a template of /etc/systemd/system/wechatircd.service.

Changes in injector.js

wechatircd.py

.
├── Web                      HTTP(s)/WebSocket server
├── Server                   IRC server
├── Channel
│   ├── StandardChannel      IRC channels
│   ├── StatusChannel        `+wechat`
│   └── SpecialChannel       WeChat groups
├── (User)
│   ├── Client               IRC clients
│   ├── SpecialUser          WeChat users
├── (IRCCommands)
│   ├── UnregisteredCommands available commands: CAP NICK PASS USER QUIT
│   ├── RegisteredCommands

FAQ

Motivation

If you cannot tolerant scanning QR codes with your phone everyday, see 无需每日扫码的IRC版微信和QQ:wechatircd、webqqircd.

Fetch data & control wx.qq.com

Some special accounts' UserName do not have the @ prefix: newsapp,fmessage,filehelper,weibo,qqmail,fmessage。Standard accounts' UserName start with @; Groups' UserName start with @@UserName are different among sessions. Uin looks like an unique identifier, but most of the time its value is 0. A group's OwnerUin is the owners's Uin,but most of the time Uin is 0.

My account

angular.element(document.body).scope().account

List of all contacts

angular.element($('#navContact')[0]).scope().allContacts

Delete a member from a group

var injector = angular.element(document).injector()
# 这里获取了chatroomFactory,还可用于获取其他factory、service、controller等
var chatroomFactory = injector.get('chatroomFactory')
# 设置其中的`room`与`userToRemove`
chatroomFactory.delMember(room.UserName, userToRemove.UserName)`

Send a message to the current chat

angular.element('pre:last').scope().editAreaCtn = "Hello,微信";
angular.element('pre:last').scope().sendTextMessage();

Headless browser on Linux

If you cannot tolerant scanning QR codes with your phone everyday, you can run the browser and wechatircd on a server.

You can interact with the browser using VNC:

An alternative is x2go, see 无需每日扫码的IRC版微信和QQ:wechatircd、webqqircd.

How are nicks generated?

On the mobile application, users' On-screen Names are resolved in this order:

Contact information is given in APIs batchgetcontact and webwxsync. The JSON serialization uses misleading field names.

WeChat friend in contactFactory#addContact:

WeChat friend/non-contact in .MemberList:

JSON for one user may be returned repeatedly and all these fields may be empty. Users' nicks are generated by looking for the first non-empty value from these fields: .RemarkName, .NickName, .DisplayName. You may see xx now known as yy in your IRC client if a room contact shares multple rooms with you.

Known issues

Uncaught TypeError: angular.extend is not a function

You may see these messages in the DevTools console:

Uncaught TypeError: angular.extend is not a function
    at Object.setUserInfo (index_0c7087d.js:4)
    at index_0c7087d.js:2
    at c (vendor_2de5d3a.js:11)
    at vendor_2de5d3a.js:11
    at c.$eval (vendor_2de5d3a.js:11)
    at c.$digest (vendor_2de5d3a.js:11)
    at c.$apply (vendor_2de5d3a.js:11)
    at l (vendor_2de5d3a.js:11)
    at m (vendor_2de5d3a.js:11)
    at XMLHttpRequest.C.onreadystatechange (vendor_2de5d3a.js:11)
Uncaught TypeError: angular.forEach is not a function

injector.js should be executed after vendor_*.js and before index_*.js. However, TamperMonkey cannot finely control the execution time due to the limitation of Chrome.

Cannot send/receive new messages when the webpage disconnects from wx.qq.com

The WebSocket connection to wechatircd.py should be closed in this case, let users know they should reload the webpage.

Others

References