NTQQ + LLOneBot(5.0以上)+ NoneBot2 实现你的QQ机器人
工具介绍
- NTQQ 是腾讯的新一代QQ桌面版(NT架构),不是工具,而是QQ软件本身。
- LLOneBot(5.0以上) 是一个为 NTQQ 设计的机器人协议工具,用于连接 QQ 和你的机器人程序(如 NoneBot2)。它支持 OneBot V11 和 Satori 协议,负责接收 QQ 消息(如群聊消息)并转发给你的代码,或者将代码的回复发送回 QQ。
- NoneBot2 是一个Python开发的通用机器人框架,社区插件丰富,适合快速开发简单功能。它专注逻辑开发,接收LLOneBot传来的消息,运行你的代码。不负责QQ连接(需搭配NapCat或LLOneBot)。
快速开始
从腾讯QQ官网下载最新NTQQ客户端,安装并登录你的QQ账号。
安装 LLOneBot(参考官方文档)
- 下载 LLOneBot-win-x64-ffmpeg.zip
- 解压后双击 llonebot.exe 会启动 QQ,登录后会在 llonebot.exe 所在目录生成一个 data 文件夹(注意在登录的时候不能勾选多个账号,LLOneBot 不支持这种登录方式)
安装NoneBot2,打开命令行运行:
pip install nonebot2
创建 NoneBot2 项目:
- 运行命令:
nb create
- 选择
simple(插件开发者)
- 输入项目名称
- 选择
One Bot V11 协议
- 选择
FastAPI 驱动器
- 插件存储位置随意
- 立即安装依赖
- 是否创建虚拟环境看你自己(笔者的nonebot本来就是在虚拟环境里的,所以就选择了no)
- 内置插件选择
echo
(便于测试机器人是否正常)
- 运行命令:
启动机器人
你会看到一条日志:1
2
3# 运行以下命令来启动你的机器人:
cd (你之前输入的项目名)
nb run --reload[INFO] uvicorn | Uvicorn running on http://127.0.0.1:8080 (Press CTRL+C to quit)
,记住这个8080端口配置 LLOneBot:
- 浏览器打开 http://localhost:3080 进行配置
- 添加反向 WS 地址为:
ws://127.0.0.1:8080/onebot/v11/ws
, 这里的 8080 是 NoneBot 输出的端口号,/onebot/v11/ws 是 NoneBot onebot 适配器默认的路径 - 点击保存配置
- 这时在nonebot的日志中就能看到你的bot connected了,并且会显示接收到的消息
向你的bot发送
/echo hello
进行测试(群聊中需要先@bot)
编写Bot代码(以CF比赛推送为例)
创建插件:
nb plugin create
- 输入插件名称,这里以
Codeforces
为例 - 选择no,这里不使用嵌套插件
- 插件存储位置,默认第一个
- 输入插件名称,这里以
在
plugins\codeforces
目录下新建一个文件fetcher.py
,内容如下: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
47import requests
from datetime import datetime
# 简化比赛名称的函数
def simplify_name(name):
if 'Codeforces ' in name:
name = name.replace('Codeforces ', '')
if 'Round ' in name:
name = name.replace('Round ', '')
if 'Educational' in name:
name = name.replace('Educational', 'Edu')
return name
# 转换Unix时间戳为指定日期格式
def format_time(start_time):
dt = datetime.fromtimestamp(start_time)
return dt.strftime('%Y-%m-%d %H:%M')
def fetch_contest_info():
url = 'https://codeforces.com/api/contest.list'
response = requests.get(url, timeout=10)
data = response.json()
if data['status'] != 'OK':
return "无法获取比赛信息"
contests = data['result']
# 筛选phase为"BEFORE"的比赛,并按startTimeSeconds升序排序(最近的先)
upcoming_contests = [c for c in contests if c['phase'] == 'BEFORE']
upcoming_contests.sort(key=lambda x: x['startTimeSeconds'])
# 使用列表收集输出内容
output_lines = []
num_contests = len(upcoming_contests)
output_lines.append(f'已找到 {num_contests} 条最近的比赛:')
for contest in upcoming_contests:
simple_name = simplify_name(contest['name'])
date_time = format_time(contest['startTimeSeconds'])
output_lines.append(f'◉ {simple_name}')
output_lines.append(f' {date_time}\n')
# 将列表中的所有行连接成一个字符串
return '\n'.join(output_lines)修改
__init__.py
文件内容如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25from nonebot import get_plugin_config
from nonebot.plugin import PluginMetadata
from .config import Config
__plugin_meta__ = PluginMetadata(
name="Codeforces",
description="",
usage="",
config=Config,
)
config = get_plugin_config(Config)
from nonebot import on_command
from .fetcher import fetch_contest_info
CF = on_command("cf")
async def handle_function():
await CF.finish(fetch_contest_info())此时你向bot发送
/cf
就可以获取到比赛信息了
其他功能参考NoneBot2官方指南