https://maskray.me/blog/2016-04-11-webqqircd
webqqircd 类似于 bitlbee ,在 WebQQ(SmartQQ)和 IRC 间建起桥梁,可以使用 IRC 客户端收发消息。大部分代码来自wechatircd,为适配 QQ 做了一些修改,去除了 wechatircd 中的 token ,因此只支持单客户端。
修改 WebQQ 用的 JS ,通过 WebSocket 把信息发送到服务端,服务端兼做 IRC 服务端,把 IRC 客户端的命令通过 WebSocket 传送到网页版 JS 执行。未实现 IRC 客户端,因此无法把 QQ 群的消息转发到另一个 IRC 服务器(打通两个群的 bot)。
需要 Python 3.5 或以上,支持async/await
语法
pip install -r requirements.txt
安装依赖
Arch Linux 可以安装https://aur.archlinux.org/packages/webqqircd-git,会自动在/etc/webqqircd/
下生成自签名证书(见下文),导入浏览器即可。
推荐使用 TLS 。
openssl req -newkey rsa:2048 -nodes -keyout a.key -x509 -out a.crt -subj '/CN=127.0.0.1' -dates 9999
创建密钥与证书。chrome://settings/certificates
,导入 a.crt ,在 Authorities 标签页选择该证书, Edit->Trust this certificate for identifying websites../webqqircd.py --tls-cert a.crt --tls-key a.key
,会监听 127.1:6668 的 IRC 和 127.1:9002 的 HTTPS 与 WebSocket over TLS如果嫌 X.509 太麻烦的话可以不用 TLS ,但 Chrome 会在 console 里给出警告。
./webqqircd.py
,会监听 127.1:6668 的 IRC 和 127.1:9002 的 HTTP 与 WebSocket , HTTP 用于伺服项目根目录下的mq.js
。mq.js
var ws = new MyWebSocket('wss://127.0.0.1:9002')
行单引号里面的部分修改成ws://127.0.0.1:9002
/server add qq 127.1/6668
),会自动加入+status
channel+status
channel ,在这个 channel 发信并不会群发,只是为了方便查看有哪些朋友。RemarkName
),其次为DisplayName
(原始 JS 根据昵称等自动填写的一个名字)在+status
channel 可以执行一些命令:
help
,帮助status
,已获取的 QQ 朋友、群列表eval $password $expr
: 如果运行时带上了--password $password
选项,这里可以 eval ,方便调试,比如eval $password client.uin2qq_user
若服务端或客户端重启,刷新 WebQQ 。
webqqircd 是个简单的 IRC 服务器,可以执行通常的 IRC 命令,可以对其他客户端私聊。
以下命令会有特殊作用:
--join auto
,收到某个 QQ 群的第一条消息后会自动加入对应的 channel ,即开始接收该 QQ 群的消息。/join [channel]
表示开始接收该 QQ 群的消息/list
,列出所有 QQ 群/names
,更新当前群成员列表/part [channel]
的 IRC 原义为离开 channel ,转换为 QQ 代表在当前 IRC 会话中不再接收该 QQ 群的消息。不用担心, webqqircd 并没有主动退出群的功能/query nick
打开与$nick
的私聊窗口,与之私聊即为在 QQ 上和他 /她 /它对话/who channel
,查看群成员列表原始文件mq.js
在 Chrome DevTools 里格式化后得到orig/mq.pretty.js
,可以用diff -u orig/mq.pretty.js mq.js
查看改动。
修改的地方都有//@
标注,结合 diff ,方便 WebQQ 更新后重新应用这些修改。增加的代码中大多数地方都用try catch
保护,出错则consoleerr(ex.stack)
。
目前的改动如下:
mq.js
开头创建到服务端的 WebSocket 连接,若onerror
则自动重连。监听onmessage
,收到的消息为服务端发来的控制命令:send_text_message
等。
获取所有联系人(朋友、订阅号、群),deliveredContact
记录投递到服务端的联系人,deliveredContact
记录同处一群的非直接联系人。
每隔一段时间把未投递过的联系人发送到服务端。
messageProcess
原有代码会更新未读标记数及声音提醒,现在改为若成功发送到服务端则不再提醒,以免浏览器的这个标签页造成干扰。
当前只有一个文件webqqircd.py
,从 miniircd 抄了很多代码,后来自己又搬了好多 RFC 上的用不到的东西……
.
├── Web HTTP(s)/WebSocket server
├── Server IRC server
├── Channel
│ ├── StandardChannel `#`开头的 IRC channel
│ ├── StatusChannel `+status`,查看控制当前 QQ 会话
│ └── WeChatRoom QQ 群对应的 channel ,仅该客户端可见
├── (User)
│ ├── Client IRC 客户端连接
│ ├── WeChatUser QQ 用户对应的 user ,仅该客户端可见
├── (IRCCommands)
│ ├── UnregisteredCommands 注册前可用命令: NICK USER QUIT
│ ├── RegisteredCommands 注册后可用命令
https://wiki.archlinux.org/index.php/Systemd/User
~/.config/systemd/user/webqqircd.service
:
[Unit]
Description=webqqircd
Documentation=https://github.com/MaskRay/webqqircd
After=network.target
[Service]
WorkingDirectory=%h/projects/webqqircd
ExecStart=/home/ray/projects/webqqircd/webqqircd.py --tls-key a.key --tls-cert a.crt --password a --ignore 不想自动加入的群名 0 不想自动加入的群名 1
[Install]
WantedBy=multi-user.target
WeeChat:
/server add qq 127.1/6668 -autoconnect
1
oott123 2016-04-12 07:47:25 +08:00
听起来是依赖 Chrome 插件的?_(:з」∠)_不知道有没有想过做 headless 呢…
|