折腾 Mojo-WebQQ 以及 Rikka 的 FCM for Mojo

2019 年开始 Mojo-WebQQ 所以依赖的 WebQQ 停止服务, 所以本文没用啦.

昨天在 TG 上看到 Rikka 发了 FCM for Mojo 看起来贼好用 就想折腾一下所以就有了这篇日志
( Rikka 大法好!!! )

准备所需

一个能够访问 Google Firebase 的机器, 对于国内的机器 FFM 服务端现在支持 push_proxy 参数, 可以通过设置 http 代理来访问 Firebase.
我使用的是位于日本友人私宅内的独立服务器.

安装基础依赖

1
2
3
4
5
6
7
8
9
10
11
12
#Ubuntu/Debian
#Node.js 8 或 9 自行选择
#curl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash -
#curl -sL https://deb.nodesource.com/setup_9.x | sudo -E bash -
sudo apt install -y build-essential vim git libssl-dev perl libcrypt-openssl-bignum-perl libcrypt-openssl-rsa-perl nodejs

#CentOS/RedHat
#Node.js 8 或 9 自行选择
#curl --silent --location https://rpm.nodesource.com/setup_8.x | sudo bash -
#curl --silent --location https://rpm.nodesource.com/setup_9.x | sudo bash -
sudo yum -y groupinstall "Development Tools"
sudo yum install -y vim git openssl-devel make gcc gcc-c++ perl cpan perl-Crypt-OpenSSL-RSA perl-Crypt-OpenSSL-Bignum nodejs

安装 Mojo-Webqq

1
2
3
4
5
6
7
#通过 cpan 安装 cpanm
sudo cpan -i App::cpanminus
#或者在线安装 cpanm, 一个国外一个国内自行选择
#curl -kL https://cpanmin.us | perl - --sudo App::cpanminus
#curl http://share-10066126.cos.myqcloud.com/cpanm.pl|perl - --sudo App::cpanminus
cpanm --sudo Mojo::Webqq
cpanm --sudo Webqq::Encryption

日后更新再次执行 cpanm --sudo Mojo::Webqq 即可

搭建 FCM for Mojo 服务端

1
2
3
4
5
cd ~
git clone https://github.com/RikkaApps/FCM-for-Mojo-Server.git
cd FCM-for-Mojo-Server
cp config.example.js config.js
npm install

(以后更新进入 FCM-for-Mojo-Server 目录执行 git pull 然后 npm start 或者重启进程守护即可)

配置文件各参数都有注释, 自行根据需要修改, 因为我使用 Nginx 作为反代, 所以会更改 hostname 参数为 127.0.0.1

1
vim config.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
const fs = require('fs');

const config = {
"mojo": {
"webqq": {
// openqq plugin local port
"openqq": 5003
}
},

// local http server port, FFM plugin will send messages to this port
"local_port": 5004,

// client config file, must be a valid json, do not need to edit it manually
"client_config": "client.json",

// http server port for client
"port": 5005,

// http proxy, FFM will connect to Google FCM Server with this proxy if you set it.
//"push_proxy": 'http://127.0.0.1:8080',

// hostname, 0.0.0.0 default (IPv4)
"hostname": "127.0.0.1",

// basic auth config, see https://github.com/http-auth/http-auth#configuration
/*"basic_auth": {
"file": ""
},*/

// https config, see https://nodejs.org/dist/latest/docs/api/https.html
/*"https": {
"key": fs.readFileSync(""),
"cert": fs.readFileSync("")
}*/
};

module.exports = config;

注意: 最好等客户端配置 ( 服务器 URL ) 完毕后再启动服务端( npm start ), 当然此时你也可以直接启动服务端.

安全性(可选)
HTTP 基本认证
HTTP 基本认证通过 http-auth 模块 实现,在这里可以看到所有可用选项,下文只说明最简单的配置方法。
创建一个任意文件名,内容为用户名:密码的文件,下面是一个简单的例子:

1
>username:passsword

在上面的例子中,客户端中的用户名填写为:username,密码填写为:password。 你也可以通过写入多行实现多个用户名和密码
编辑 config.js,找到有 basic_auth 那几行并去掉附近的注释(即 /**/):

1
2
3
"basic_auth": {
"file": "<密码文件路径>"
},

HTTPS
HTTPS 通过 https 模块 实现,在这里可以看到所有可用选项,下文只说明最简单的配置方法。
编辑 config.js,找到有 https 的那几行并去掉附近的注释(即 /**/):

1
2
3
4
5
6
"https": {
"key": fs.readFileSync("<证书私钥路径>"),
/* 如果你有 CA 证书,就加上这行
"ca": fs.readFileSync("<CA 证书路径>"), */
"cert": fs.readFileSync("<含完整证书链证书(fullchain)或服务端证书(server cert)的路径>")
}

配置 Nginx (可选)

生成 auth_basic 文件

1
htpasswd -c -s ~/FCM-for-Mojo-Server/auth_file your_username

新建 Nginx 配置

1
sudo vim /etc/nginx/conf.d/fcmqq.love4taylor.me.conf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
server{
listen 80;
server_name fcmqq.love4taylor.me;
root /home/wwwroot/fcmqq.love4taylor.me;

location / {
set $LE 0;
if ($request_uri ~ /.well-known/) {
set $LE 1;
}

if ($LE = 0) {
return 301 https://$server_name$request_uri;
}
}
}
server{
listen 443 ssl http2;
server_name fcmqq.love4taylor.me;
root /home/wwwroot/fcmqq.love4taylor.me;
access_log /var/log/nginx/fcmqq.love4taylor.me.log main;

# headers
# HTST
add_header Strict-Transport-Security "max-age=31536000; includeSubdomains; preload";

# certs sent to the client in SERVER HELLO are concatenated in ssl_certificate
ssl_certificate /etc/letsencrypt/live/fcmqq.love4taylor.me/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/fcmqq.love4taylor.me/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/fcmqq.love4taylor.me/chain.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers 'TLS13-AES-256-GCM-SHA384:TLS13-AES-128-GCM-SHA256:TLS13-CHACHA20-POLY1305-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256';
ssl_dhparam dhparam.4096.pem;
ssl_prefer_server_ciphers on;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_session_tickets off;

# OCSP Stapling fetch OCSP records from URL in ssl_certificate and cache them
ssl_stapling on;
ssl_stapling_verify on;
resolver 127.0.0.1 valid=300s;
resolver_timeout 5s;

location / {
auth_basic "FCM for Mojo";
auth_basic_user_file /home/love4taylor/FCM-for-Mojo-Server/auth_file;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host localhost;
proxy_pass http://127.0.0.1:5005;
proxy_redirect off;
}
1
2
nginx -t
nginx -s reload

配置客户端

进入 GitHub Releases 或者 Google Play 下载 最新客户端
客户端主界面

进入 Server settingsServer URL 填入你服务器地址
服务器地址设置

此时进入服务器 FCM-for-Mojo-Server 目录 执行 npm start

然后返回 App 主页面 点 Server status 刷新状态, 变绿即成功连上服务器
进入 Server settingsManage devices 点击右上角的加号然后点旁边的上传
设备管理界面

进入 Account settings 设置账号密码登陆
注意: FFM 默认会以明文保存至服务器, 可自行修改服务端, 参考 明文保存密码的问题
账号密码设置

进入 Notification settings 设置通知相关的参数
通知详情设置

Select QQ application : 选择你目前用的 QQ 版本
How FFM get foreground package : 没 root 需要选择 Usage stats API , root 后可选用 Shizuku (需要搭配 Shizuku App)

如果你登录过程中碰到如下异常:
[18/01/08 17:21:28] [warn] 更群扩展信息授权失败: 可能因为登录环境变化引起
或者
[18/01/08 17:21:28] [warn] 更群扩展信息授权失败: check!=0
可能的原因是,基于账号密码的登录方式,一旦登录所在地发生较大变化,则腾讯服务器可能需要你输入图片验证码,这样就很难实现自动化操作,为了避免这种情况,你需要尽量在pl脚本所在的网络中用浏览器多登录一下 http://qun.qq.com 让腾讯服务器消除登录异常的判断
你可以在服务端搭建ssh隧道,socks5代理,支持SSL转发(CONNECT方法)的http代理等方式,然后浏览器通过服务端代理访问

进程守护与服务

Supervisor 与 Systemd 二选一

Supervisor

1
2
3
4
5
6
7
#Ubuntu/Debian
sudo apt install -y supervisor
sudo systemctl enable supervisor

#CentOS/RedHat
sudo yum install -y supervisor
sudo systemctl enable supervisord
1
2
3
4
5
#Ubuntu/Debian
sudo vim /etc/supervisor/conf.d/FCM-for-Mojo-Server.conf

#CentOS/RedHat
sudo vim /etc/supervisord.d/FCM-for-Mojo-Server.ini
1
2
3
4
5
6
7
8
9
[program:FCM-for-Mojo-Server]
directory=/home/love4taylor/FCM-for-Mojo-Server
command=node node/index.js
user=love4taylor
autostart = true
autorestart = true
stderr_logfile = NONE
stdout_logfile = NONE
startsecs=3
1
2
3
4
5
#Ubuntu/Debian
sudo systemctl restart supervisor

#CentOS/RedHat
sudo systemctl restart supervisord

Systemd

1
2
3
4
5
#Debian
sudo vim /lib/systemd/system/fcm-for-mojo.service

#CentOS/RedHat
sudo vim /usr/lib/systemd/system/fcm-for-mojo.service
1
2
3
4
5
6
7
8
9
10
11
12
13
14
[Unit]
Description=FCM-for-Mojo Server
After=network.target

[Service]
Type=simple
User=love4taylor
WorkingDirectory=/home/love4taylor/FCM-for-Mojo-Server
ExecStart=/usr/bin/npm start
PrivateTmp=true
Restart=on-failure

[Install]
WantedBy=multi-user.target
1
2
sudo systemctl enable fcm-for-mojo
sudo systemctl start fcm-for-mojo

明文保存密码的问题

默认 FFM 服务端会以明文保存你填入的 QQ 密码, 如果洁癖请参考以下修改, 改完后记得重启服务端

1
vim ~/FCM-for-Mojo-Server/perl/start.pl
1
2
-    pwd => defined $passwd ? Digest::MD5::md5_hex($passwd) : undef
+ pwd => defined $passwd ? $passwd : undef

计算你的 QQ 密码

1
echo -n your_password|md5sum

得出 32 位 md5 值, 填入 FFM Android App 中

效果图

锁屏下的通知 展开的通知 快速回复通知