QQBOT个人开发实践 - 02 BOT的第一个命令

QQBOT个人开发实践 - 02 BOT的第一个命令

前言

如今,对话机器人我认为大可分为两类,其中一种是模型驱动型,而QQBOT则是命令驱动型

这篇就来做我们BOT的第一个命令。

尝试

首先,在QQBOT管理平台页面配置一个新的指令,如图:

在这里插入图片描述

接着,根据上一篇文章的目录结构,我们在func文件夹中新建weather.py文件,并删除sendMsg.py文件。随后,在bot.py文件中添加以下代码:

class MyClient(botpy.Client):
    async def on_at_message_create(self, message: Message):
        # 注册指令handler
        handlers = [hello, weather]
        for handler in handlers:
            if await handler(api=self.api, message=message):
                return

这段代码用作注册指令用,大概的实现原理与nonebot中@on_command和@handler用法差不多,都是通过装饰器来做一个闭包,然后执行命令。具体原理可以参考Python教程闭包和装饰器。

接下来,编写命令的方法:

_log = logging.get_logger()
@Commands(name=("你好", "hello"))
async def hello(api: BotAPI, message: Message, params=None):
    _log.info(params)
    # 第一种用reply发送消息
    await message.reply(content='宝宝')
    # 第二种用api.post_message发送消息
    await api.post_message(channel_id=message.channel_id, content='宝宝', msg_id=message.id)
    return True

官方一共给出两种回复消息的方式,任选其一即可。

而命令驱动则是使用@Commands装饰器来完成。这里我们可以看一下@Commands的代码:

class Commands:
    """
    指令装饰器

    Args:
      name (Union[tuple, str]): 字符串元组或单个字符串。
    """

    def __init__(self, name: Union[tuple, str]):
        self.commands = name

    def __call__(self, func):
        @wraps(func)
        async def decorated(*args, **kwargs):
            api: BotAPI = kwargs["api"]
            message: Message = kwargs["message"]
            if isinstance(self.commands, tuple):
                for command in self.commands:
                    if command in message.content:
                        # 分割指令后面的指令参数
                        params = message.content.split(command)[1].strip()
                        return await func(api=api, message=message, params=params)
            elif self.commands in message.content:
                # 分割指令后面的指令参数
                params = message.content.split(self.commands)[1].strip()
                return await func(api=api, message=message, params=params)
            else:
                return False

        return decorated

注意:

@Commands(name=('a','b'))

装饰器中name只能传字符串元组或者单个字符串,其意义是配置多条命令或者单条命令。装饰器必须位于方法的上面一行。这条装饰器通过输入a或b都能触发下方的方法。

@Commands(name='hello')

当name仅为一个字符串时,只有输入这个字符串才能触发。

第一次运行

此时我们运行bot.py测试一下功能

[INFO]	(client.py:159)_bot_login	[botpy] 登录机器人账号中...
[INFO]	(client.py:178)_bot_init	[botpy] 程序启动...
[INFO]	(connection.py:59)multi_run	[botpy] 最大并发连接数: 1, 启动会话数: 1
[INFO]	(client.py:236)bot_connect	[botpy] 会话启动中...
[INFO]	(gateway.py:110)ws_connect	[botpy] 启动中...
[INFO]	(gateway.py:136)ws_identify	[botpy] 鉴权中...
[INFO]	(gateway.py:80)on_message	[botpy] 机器人「KumaBot-测试中」启动成功!
[INFO]	(gateway.py:217)_send_heart	[botpy] 心跳维持启动...

此时我们在频道中输入@BOT 你好可以成功触发指令。

在这里插入图片描述

这里带不带/都一样,因为在装饰器里规定了,接收到"你好"和"hello"就会触发指令。

在这里插入图片描述

此时我们可以观察到控制台中通过logging函数输出了params,是我们的方法名hello。

[INFO]	(bot.py:23)hello	

有关log的打印我还没有开始研究,在未来不久会出一篇博客说明一下log的作用。

也有些同学会在控制台输出timeout,这可能是官方的一个bug,尚未解决,回头我也会研究一下这个问题

[WARNING]	(http.py:188)request	请求超时,请求连接: https://api.sgroup.qq.com/channels/******/messages
[WARNING]	(http.py:188)request	请求超时,请求连接: https://api.sgroup.qq.com/channels/******/messages

2023-12-6 编辑

放弃原生Py-QQBOT开发,bug过多,后续将转为Nonebot-Adapter-QQ继续进行开发。感谢开发者频道群老哥提出的建议和帮助

  • 17
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值