Giter VIP home page Giter VIP logo

nonebot's Introduction

NoneBot

License PyPI Python Version OneBot Version QQ 群 Telegram 频道 Discord Server

简介

NoneBot 是一个基于 OneBot 标准(原 CQHTTP) 的 Python 异步 QQ 机器人框架,它会对 QQ 机器人收到的消息进行解析和处理,并以插件化的形式,分发给消息所对应的命令处理器和自然语言处理器,来完成具体的功能。

除了起到解析消息的作用,NoneBot 还为插件提供了大量实用的预设操作和权限控制机制,尤其对于命令处理器,它更是提供了完善且易用的会话机制和内部调用机制,以分别适应命令的连续交互和插件内部功能复用等需求。

NoneBot 在其底层与 OneBot 实现交互的部分使用 aiocqhttp 库,后者在 Quart 的基础上封装了与 OneBot 实现的网络交互。

得益于 Python 的 asyncio 机制,NoneBot 处理消息的吞吐量有了很大的保障,再配合 OneBot 标准的 WebSocket 通信方式(也是最建议的通信方式),NoneBot 的性能可以达到 HTTP 通信方式的两倍以上,相较于传统同步 I/O 的 HTTP 通信,更是有质的飞跃。

需要注意的是,NoneBot 仅支持 Python 3.7+。

文档

文档目前「指南」和「API」部分已经完成,「进阶」部分尚未完成,你可以在 这里 查看。

贡献

如果你在使用过程中发现任何问题,可以 提交 issue 或自行 fork 修改后提交 pull request。

如果你要提交 pull request,请确保你的代码风格和项目已有的代码保持一致,遵循 PEP 8,变量命名清晰,有适当的注释。

NoneBot

Description

NoneBot is an asynchronous and OneBot-compliant QQ robot framework written in Python. When NoneBot receives new messages, it parses the messages then pass them to user-defined command handlers or natural language processors accordingly using a plugin system to accomplish various tasks.

Beside message processing, NoneBot presents an amount of useful built-in actions and permission handling features. The command processors provide simple but comprehensive session-ing and calling mechanisms to handle continuous interactions and the reusing of functionalities inside plugins, respectively.

NoneBot communicates with OneBot implementations using aiocqhttp, a wrapper based on Quart for lower-level protocol work.

Thanks to asyncio and WebSocket messaging method (which is recommended), NoneBot ensures maximum possible message throughput to be twice as fast as HTTP messaging, and have great performance leap compared to traditional synchronous IO.

NoneBot only supports Python 3.7+.

Documentation

For Guide and API manuals, check out this page.

Contributing

If you encounter any problems in using the project, you can submit an issue or fork this project to submit an pull request.

For pull requests, please be sure to have consistent style to existing modules, follow PEP 8, have clear identifier naming, and have proper comments.

nonebot's People

Contributors

71e6fd52 avatar bytemain avatar cleoold avatar he0119 avatar hieuzest avatar ice9coffee avatar iyume avatar jeasonnow avatar joeyhey avatar jw-star avatar liuzholmes avatar lycreal avatar mnixry avatar pzzzzz5142 avatar sdchao avatar starhearthunt avatar stdrc avatar winrey avatar xideng avatar xulouzhe avatar yanyongyu avatar yucongo avatar zhaozuohong avatar zzm88 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

nonebot's Issues

一段时间无对话后响应会消失

是参照教程配置的,使用ws/api和ws/event。

如果一段时间(20-30分钟)不和机器人有任何交互,机器人会停止响应任何指令,包括command和自然语言。但server后台有记录(收到&处理),酷Q日志中有收到消息但无发送消息(向上箭头),怀疑api连接中断?

无论是用hypercorn还是直接python bot.py都有这个问题。

PS酷Q和bot.py在同一ECS上运行。

未启动bot.py也能回应echo命令

在没有启动bot.py的情况下向机器人发送/echo 命令也会获得响应,且启动bot.py以后并未出现连接提示,重启酷q也无效。。。
根据教程一路做下来的,发现添加了config.py以后还是没有响应/say命令,才发现无论bot.py是否启动都会响应echo命令。。。
default

想问一下如果要在群聊里得到某个qq后,发送私聊信息给那个人应该怎么写

找到了一个send_private_msg方法,但没找到它的实现,我在on_command调用里引用了一下发现报错了
Task exception was never retrieved future: <Task finished coro=<handle_message() done, defined at C:\Users\Sailist\AppData\Local\Programs\Python\Python36\lib\site-packages\none\message.py:20> exception=ActionFailed() created at C:\Users\Sailist\AppData\Local\Programs\Python\Python36\lib\site-packages\none\__init__.py:39> source_traceback: Object created at (most recent call last): File "C:/E/jupyter_notebook/小工具/pyQQ/test.py", line 11, in <module> none.run() File "C:\Users\Sailist\AppData\Local\Programs\Python\Python36\lib\site-packages\none\__init__.py", line 104, in run get_bot().run(host=host, port=port, *args, **kwargs) File "C:\Users\Sailist\AppData\Local\Programs\Python\Python36\lib\site-packages\none\__init__.py", line 58, in run *args, **kwargs) File "C:\Users\Sailist\AppData\Local\Programs\Python\Python36\lib\site-packages\aiocqhttp\__init__.py", line 195, in run self._server_app.run(host=host, port=port, *args, **kwargs) File "C:\Users\Sailist\AppData\Local\Programs\Python\Python36\lib\site-packages\quart\app.py", line 1337, in run run_single(self, config, loop=loop) File "C:\Users\Sailist\AppData\Local\Programs\Python\Python36\lib\site-packages\hypercorn\run.py", line 181, in run_single loop.run_forever() File "C:\Users\Sailist\AppData\Local\Programs\Python\Python36\lib\asyncio\base_events.py", line 421, in run_forever self._run_once() File "C:\Users\Sailist\AppData\Local\Programs\Python\Python36\lib\asyncio\base_events.py", line 1423, in _run_once handle._run() File "C:\Users\Sailist\AppData\Local\Programs\Python\Python36\lib\asyncio\events.py", line 145, in _run self._callback(*self._args) File "C:\Users\Sailist\AppData\Local\Programs\Python\Python36\lib\asyncio\coroutines.py", line 126, in send return self.gen.send(value) File "C:\Users\Sailist\AppData\Local\Programs\Python\Python36\lib\site-packages\none\__init__.py", line 39, in _ asyncio.ensure_future(handle_message(self, ctx)) Traceback (most recent call last): File "C:\Users\Sailist\AppData\Local\Programs\Python\Python36\lib\asyncio\coroutines.py", line 129, in throw return self.gen.throw(type, value, traceback) File "C:\Users\Sailist\AppData\Local\Programs\Python\Python36\lib\site-packages\none\message.py", line 43, in handle_message handled = await handle_command(bot, ctx) File "C:\Users\Sailist\AppData\Local\Programs\Python\Python36\lib\asyncio\coroutines.py", line 129, in throw return self.gen.throw(type, value, traceback) File "C:\Users\Sailist\AppData\Local\Programs\Python\Python36\lib\site-packages\none\command.py", line 465, in handle_command disable_interaction=disable_interaction) File "C:\Users\Sailist\AppData\Local\Programs\Python\Python36\lib\asyncio\coroutines.py", line 129, in throw return self.gen.throw(type, value, traceback) File "C:\Users\Sailist\AppData\Local\Programs\Python\Python36\lib\site-packages\none\command.py", line 518, in _real_run_command await asyncio.wait_for(future, timeout) File "C:\Users\Sailist\AppData\Local\Programs\Python\Python36\lib\asyncio\tasks.py", line 339, in wait_for return (yield from fut) File "C:\Users\Sailist\AppData\Local\Programs\Python\Python36\lib\asyncio\coroutines.py", line 126, in send return self.gen.send(value) File "C:\Users\Sailist\AppData\Local\Programs\Python\Python36\lib\site-packages\none\command.py", line 61, in run await self.func(session) File "C:\Users\Sailist\AppData\Local\Programs\Python\Python36\lib\asyncio\coroutines.py", line 110, in __next__ return self.gen.send(None) File "C:\E\jupyter_notebook\小工具\pyQQ\plugins\catchSpyder.py", line 140, in join await bot.send_private_msg(user_id=qq, message='哇') File "C:\Users\Sailist\AppData\Local\Programs\Python\Python36\lib\asyncio\coroutines.py", line 110, in __next__ return self.gen.send(None) File "C:\Users\Sailist\AppData\Local\Programs\Python\Python36\lib\site-packages\aiocqhttp\api.py", line 170, in call_action action, **params) File "C:\Users\Sailist\AppData\Local\Programs\Python\Python36\lib\asyncio\coroutines.py", line 110, in __next__ return self.gen.send(None) File "C:\Users\Sailist\AppData\Local\Programs\Python\Python36\lib\site-packages\aiocqhttp\api.py", line 140, in call_action return _handle_api_result(await ResultStore.fetch(seq)) File "C:\Users\Sailist\AppData\Local\Programs\Python\Python36\lib\site-packages\aiocqhttp\api.py", line 39, in _handle_api_result raise ActionFailed(retcode=result.get('retcode')) aiocqhttp.exceptions.ActionFailed

添加计划任务为什么不能发消息到群

添加计划任务为什么不能发消息到群,我测试计划任务是运行的。
bot = none.get_bot()
机器人对象也获取了。
但是发群消息不行
await bot.send_group_msg(group_id=672076603,message=f'现在{now.hour}点整啦!')
这一句就不执行了

发送酷 Q 如果因网络问题没有成功上报消息,之后连续快速上报会导致 NoneBot 出现 bug

[2018-08-20 23:42:05,238 none] DEBUG: NLP results: [NLPResult(confidence=60.0, cmd_name='tuling', cmd_args={'message': '你是谁'})]
[2018-08-20 23:42:05,238 none] DEBUG: NLP result with highest confidence: NLPResult(confidence=60.0, cmd_name='tuling', cmd_args={'message': '你是谁'})
[2018-08-20 23:42:05,238 none] DEBUG: Running command ('tuling',)
[2018-08-20 23:42:05,244 none] DEBUG: NLP results: [NLPResult(confidence=60.0, cmd_name='tuling', cmd_args={'message': '。。。。'})]
[2018-08-20 23:42:05,244 none] DEBUG: NLP result with highest confidence: NLPResult(confidence=60.0, cmd_name='tuling', cmd_args={'message': '。。。。'})
[2018-08-20 23:42:05,244 none] DEBUG: Running command ('tuling',)
[2018-08-20 23:42:05,627 none] DEBUG: Session of command ('tuling',) finished
[2018-08-20 23:42:05,627 none] INFO: Message 419 is handled as natural language
Task exception was never retrieved
future: <Task finished coro=<handle_message() done, defined at /Users/richard/Projects/none-bot/none/message.py:19> exception=KeyError('/user/1002647525') created at /Users/richard/Projects/none-bot/none/__init__.py:33>
source_traceback: Object created at (most recent call last):
  File "/Users/richard/Projects/none-bot/docs/guide/code/awesome-bot-4/bot.py", line 11, in <module>
    none.run()
  File "/Users/richard/Projects/none-bot/none/__init__.py", line 91, in run
    get_bot().run(host=host, port=port, *args, **kwargs)
  File "/Users/richard/Projects/none-bot/none/__init__.py", line 51, in run
    *args, **kwargs)
  File "/Users/richard/Projects/none-bot/venv/lib/python3.7/site-packages/aiocqhttp/__init__.py", line 184, in run
    self._server_app.run(host=host, port=port, *args, **kwargs)
  File "/Users/richard/Projects/none-bot/venv/lib/python3.7/site-packages/quart/app.py", line 1316, in run
    run_single(self, config, loop=loop)
  File "/Users/richard/Projects/none-bot/venv/lib/python3.7/site-packages/hypercorn/run.py", line 166, in run_single
    loop.run_forever()
  File "/usr/local/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python3.7/asyncio/base_events.py", line 523, in run_forever
    self._run_once()
  File "/usr/local/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python3.7/asyncio/base_events.py", line 1750, in _run_once
    handle._run()
  File "/usr/local/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python3.7/asyncio/events.py", line 88, in _run
    self._context.run(self._callback, *self._args)
  File "/Users/richard/Projects/none-bot/none/__init__.py", line 33, in _
    asyncio.ensure_future(handle_message(self, ctx))
Traceback (most recent call last):
  File "/Users/richard/Projects/none-bot/none/command.py", line 493, in _real_run_command
    raise _FinishException(res)
none.command._FinishException: True

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/Users/richard/Projects/none-bot/none/message.py", line 52, in handle_message
    handled = await handle_natural_language(bot, ctx)
  File "/Users/richard/Projects/none-bot/none/natural_language.py", line 138, in handle_natural_language
    check_perm=False)
  File "/Users/richard/Projects/none-bot/none/command.py", line 477, in call_command
    disable_interaction=disable_interaction)
  File "/Users/richard/Projects/none-bot/none/command.py", line 508, in _real_run_command
    del _sessions[ctx_id]
KeyError: '/user/1002647525'
[2018-08-20 23:42:05,693 none] DEBUG: Session of command ('tuling',) finished
[2018-08-20 23:42:05,760 none] DEBUG: Session of command ('tuling',) finished
Task exception was never retrieved
future: <Task finished coro=<handle_message() done, defined at /Users/richard/Projects/none-bot/none/message.py:19> exception=KeyError('/user/1002647525') created at /Users/richard/Projects/none-bot/none/__init__.py:33>
source_traceback: Object created at (most recent call last):
  File "/Users/richard/Projects/none-bot/docs/guide/code/awesome-bot-4/bot.py", line 11, in <module>
    none.run()
  File "/Users/richard/Projects/none-bot/none/__init__.py", line 91, in run
    get_bot().run(host=host, port=port, *args, **kwargs)
  File "/Users/richard/Projects/none-bot/none/__init__.py", line 51, in run
    *args, **kwargs)
  File "/Users/richard/Projects/none-bot/venv/lib/python3.7/site-packages/aiocqhttp/__init__.py", line 184, in run
    self._server_app.run(host=host, port=port, *args, **kwargs)
  File "/Users/richard/Projects/none-bot/venv/lib/python3.7/site-packages/quart/app.py", line 1316, in run
    run_single(self, config, loop=loop)
  File "/Users/richard/Projects/none-bot/venv/lib/python3.7/site-packages/hypercorn/run.py", line 166, in run_single
    loop.run_forever()
  File "/usr/local/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python3.7/asyncio/base_events.py", line 523, in run_forever
    self._run_once()
  File "/usr/local/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python3.7/asyncio/base_events.py", line 1750, in _run_once
    handle._run()
  File "/usr/local/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python3.7/asyncio/events.py", line 88, in _run
    self._context.run(self._callback, *self._args)
  File "/Users/richard/Projects/none-bot/none/__init__.py", line 33, in _
    asyncio.ensure_future(handle_message(self, ctx))
Traceback (most recent call last):
  File "/Users/richard/Projects/none-bot/none/command.py", line 493, in _real_run_command
    raise _FinishException(res)
none.command._FinishException: True

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/Users/richard/Projects/none-bot/none/message.py", line 52, in handle_message
    handled = await handle_natural_language(bot, ctx)
  File "/Users/richard/Projects/none-bot/none/natural_language.py", line 138, in handle_natural_language
    check_perm=False)
  File "/Users/richard/Projects/none-bot/none/command.py", line 477, in call_command
    disable_interaction=disable_interaction)
  File "/Users/richard/Projects/none-bot/none/command.py", line 508, in _real_run_command
    del _sessions[ctx_id]
KeyError: '/user/1002647525'
[2018-08-20 23:42:05,840 none] DEBUG: Session of command ('tuling',) exists
[2018-08-20 23:42:05,840 none] DEBUG: Running command ('tuling',)
[2018-08-20 23:42:05,959 none] DEBUG: Session of command ('tuling',) finished
[2018-08-20 23:42:05,960 none] INFO: Message 416 is handled as natural language
[2018-08-20 23:42:06,338 none] DEBUG: Session of command ('tuling',) finished
Task exception was never retrieved
future: <Task finished coro=<handle_message() done, defined at /Users/richard/Projects/none-bot/none/message.py:19> exception=KeyError('/user/1002647525') created at /Users/richard/Projects/none-bot/none/__init__.py:33>
source_traceback: Object created at (most recent call last):
  File "/Users/richard/Projects/none-bot/docs/guide/code/awesome-bot-4/bot.py", line 11, in <module>
    none.run()
  File "/Users/richard/Projects/none-bot/none/__init__.py", line 91, in run
    get_bot().run(host=host, port=port, *args, **kwargs)
  File "/Users/richard/Projects/none-bot/none/__init__.py", line 51, in run
    *args, **kwargs)
  File "/Users/richard/Projects/none-bot/venv/lib/python3.7/site-packages/aiocqhttp/__init__.py", line 184, in run
    self._server_app.run(host=host, port=port, *args, **kwargs)
  File "/Users/richard/Projects/none-bot/venv/lib/python3.7/site-packages/quart/app.py", line 1316, in run
    run_single(self, config, loop=loop)
  File "/Users/richard/Projects/none-bot/venv/lib/python3.7/site-packages/hypercorn/run.py", line 166, in run_single
    loop.run_forever()
  File "/usr/local/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python3.7/asyncio/base_events.py", line 523, in run_forever
    self._run_once()
  File "/usr/local/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python3.7/asyncio/base_events.py", line 1750, in _run_once
    handle._run()
  File "/usr/local/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python3.7/asyncio/events.py", line 88, in _run
    self._context.run(self._callback, *self._args)
  File "/Users/richard/Projects/none-bot/none/__init__.py", line 33, in _
    asyncio.ensure_future(handle_message(self, ctx))
Traceback (most recent call last):
  File "/Users/richard/Projects/none-bot/none/command.py", line 493, in _real_run_command
    raise _FinishException(res)
none.command._FinishException: True

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/Users/richard/Projects/none-bot/none/message.py", line 42, in handle_message
    handled = await handle_command(bot, ctx)
  File "/Users/richard/Projects/none-bot/none/command.py", line 442, in handle_command
    return await _real_run_command(session, ctx_id, check_perm=check_perm)
  File "/Users/richard/Projects/none-bot/none/command.py", line 508, in _real_run_command
    del _sessions[ctx_id]
KeyError: '/user/1002647525'

有没有办法存储一些仅在机器人运行期间有效的数据?

比如是否自动接收好友申请,我本是想写在redis里,每次收到请求就on_request查询一次,但考虑到潜在的如果短时间内频繁收到好友申请就会造成redis频繁读写DDOS,因此如果能读取以后把这个数据存储到机器人当前的运行实例中会好很多。

预备发布 0.1.0

加上收到事件的日志,优化全局 bot 实例的访问,之后,大概就可以发 0.1.0 了,算是第一个基本可用的版本,文档先不急,等 maruko 写差不多了,再写 None Bot 的文档,同时 aiocqhttp 的接口应该可以稳定,可发布 1.0.0,把文档重新整理一下。

酷Q pro 版遇到的bug

Task exception was never retrieved
future: <Task finished coro=<ASGIWebsocketConnection.handle_websocket() done, defined at C:\Users\sijj\AppData\Local\Programs\Python\Python37-32\lib\site-packages\quart\asgi.py:128> exception=AttributeError("'NoneType' object has no attribute 'pop'") created at C:\Users\sijj\AppData\Local\Programs\Python\Python37-32\lib\site-packages\quart\asgi.py:102>
source_traceback: Object created at (most recent call last):
  File "D:\coolq\py\bot.py", line 10, in <module>
    none.run()
  File "C:\Users\sijj\AppData\Local\Programs\Python\Python37-32\lib\site-packages\none\__init__.py", line 104, in run
    get_bot().run(host=host, port=port, *args, **kwargs)
  File "C:\Users\sijj\AppData\Local\Programs\Python\Python37-32\lib\site-packages\none\__init__.py", line 58, in run
    *args, **kwargs)
  File "C:\Users\sijj\AppData\Local\Programs\Python\Python37-32\lib\site-packages\aiocqhttp\__init__.py", line 224, in run
    self._server_app.run(host=host, port=port, *args, **kwargs)
  File "C:\Users\sijj\AppData\Local\Programs\Python\Python37-32\lib\site-packages\quart\app.py", line 1359, in run
    run_single(self, config, loop=loop)
  File "C:\Users\sijj\AppData\Local\Programs\Python\Python37-32\lib\site-packages\hypercorn\asyncio\run.py", line 159, in run_single
    loop.run_until_complete(gathered_tasks)
  File "C:\Users\sijj\AppData\Local\Programs\Python\Python37-32\lib\asyncio\base_events.py", line 571, in run_until_complete
    self.run_forever()
  File "C:\Users\sijj\AppData\Local\Programs\Python\Python37-32\lib\asyncio\base_events.py", line 539, in run_forever
    self._run_once()
  File "C:\Users\sijj\AppData\Local\Programs\Python\Python37-32\lib\asyncio\base_events.py", line 1767, in _run_once
    handle._run()
  File "C:\Users\sijj\AppData\Local\Programs\Python\Python37-32\lib\asyncio\events.py", line 88, in _run
    self._context.run(self._callback, *self._args)
  File "C:\Users\sijj\AppData\Local\Programs\Python\Python37-32\lib\site-packages\hypercorn\asgi\wsproto.py", line 127, in handle_websocket
    await self.handle_asgi_app(event)
  File "C:\Users\sijj\AppData\Local\Programs\Python\Python37-32\lib\site-packages\hypercorn\asgi\wsproto.py", line 139, in handle_asgi_app
    await asgi_instance(self.asgi_receive, partial(self.asgi_send, event))
  File "C:\Users\sijj\AppData\Local\Programs\Python\Python37-32\lib\site-packages\quart\asgi.py", line 102, in __call__
    handler_task = asyncio.ensure_future(self.handle_websocket(websocket, send))
Traceback (most recent call last):
  File "C:\Users\sijj\AppData\Local\Programs\Python\Python37-32\lib\site-packages\quart\asgi.py", line 129, in handle_websocket
    response = await self.app.handle_websocket(websocket)
  File "C:\Users\sijj\AppData\Local\Programs\Python\Python37-32\lib\site-packages\quart\app.py", line 1589, in handle_websocket
    return await self.handle_websocket_exception(error)
  File "C:\Users\sijj\AppData\Local\Programs\Python\Python37-32\lib\site-packages\quart\ctx.py", line 133, in __aexit__
    await super().__aexit__(exc_type, exc_value, tb)
  File "C:\Users\sijj\AppData\Local\Programs\Python\Python37-32\lib\site-packages\quart\ctx.py", line 61, in __aexit__
    await _app_ctx_stack.top.pop(exc_value)
AttributeError: 'NoneType' object has no attribute 'pop'
[2018-12-27 11:05:29,570] 127.0.0.1:56030 GET /ws/event/ ws 101 - 48895135

添加群事件有时会被忽略

日志内容:

[2018-12-23 17:13:38,743 none] INFO: Notice: {'group_id': XXXX, 'notice_type': 'group_increase', 'operator_id': 0, 'post_type': 'notice', 'self_id': XXXX, 'sub_type': 'invite', 'time': 1545556418, 'user_id': XXXX}
[2018-12-23 17:13:38,743 none] DEBUG: Emitting event: notice.group_increase.invite

代码:

@on_request('group')
async def group_invite(session: RequestSession):
    if session.ctx.get('sub_type') == 'invite':
        user_id = session.ctx.get('user_id')
        group_id = session.ctx.get('group_id')
        if await get_group_accept_value_async():
            none.logger.info(f"Received friend invitation of group {group_id} from user {user_id}, approved.")
            await session.approve()
        else:
            none.logger.info(f"Received friend invitation of group {group_id} from user {user_id}, rejected.")
            await session.reject()

测试后发现对于人数较多、邀请时提醒“当前群聊人数较多,为减少打扰,对方同意邀请后才会进入群聊”的群可以正常处理请求,但对于测试用小群则上文中函数完全不起作用。

ctx['to_me'] 仅考虑了 At 或机器人名称在消息开始的情况

我在阅读 message.py 的 handle_message 方法时发现针对 ctx['to_me'] 的处理特意写明了仅针对第一个分段,因此造成了群内发消息「XXX@机器人」或者「你在哪呢机器人」这种消息机器人不会做出应答。

这是 bug 还是 feature 呢?如果是 feature 的话又是基于什么考虑呢?

现有的功能中有没有黑名单机制?

简单来说就是不响应黑名单中用户的任何发言,毕竟现在机器人之间互相聊起来什么的还是挺麻烦的。

但如果挨个命令加忽略机制又很麻烦,如果能在config级别里配置就好了。

支持自动载入插件的使用帮助

目前的思路是,对于加载的每个插件,收集 module 对象的特殊属性 __plugin_name____plugin_help__,然后用户可以通过类似于「使用帮助」之类的(同样以插件形式来编写)问话获得使用帮助,例如:

# plugins/weather.py

__plugin_name__ = '天气'
__plugin_help__ = r"""
天气功能使用方法

你可以对我发送「查天气+空格+城市名」来查询当前某城市天气,也可以通过类似于「今天XX市天气怎么样」这样的自然对话来询问我。
""".strip()

# ...

加载了这个命令之后,可以通过下面这样的方式编写使用帮助(目前仅假设,没有实现):

@on_command('help', aliases=['使用帮助', '帮助'])
async def _(sesssion):
    plugins = none.get_loaded_plugins()
    if session.current_arg_text:
        reply = '我现在支持的功能有:\n\n' + '\n'.join(p.name for p in plugins)
    else:
        plugin = None
        for p in plugins:
            if p.name == session.current_arg_text:
                plugin = p
        reply = plugin.help

    session.finish(reply)

欢迎讨论~

「/echo/XXX」会报错

例如自带的 echo 命令输入「/echo/1」,控制台会报错
在文档中的「天气」插件,「/weather/1」会报错,但是「/天气/1」不会

CommandSession的get方法增加validator参数

目前CommandSession的args解析通过args_parser进行,所有的参数在一个方法中进行解析和校验,当参数比较多时代码显得非常的臃肿,各种if堆砌,不同参数的解析与校验过于耦合、职责不清,CommandSession的get方法中仅对参数的必录(为空)做了校验及提示,建议在CommandSession的get方法中增加validators参数,validators可为列表类型,支持多个校验器,每个validator校验器参数包含一个内置或自定义的验证方法的入口,及一个返回失败时的消息提示,None本身也可以提供一组缺省的内置校验器,例如数据必录(为空)的校验转为一个校验器,还可以增加数据类型(Number、Date等)的校验器,具体可以参见wtforms的validators.py

调用的方式可以是这样的:
arg1 = session.get('arg1', [(none.validators.required, '要查询的arg1是什么?')] )
arg2 = session.get('arg2',[(none.validators.required, '要查询的arg2是什么?'), (my_validator_func, '你输入了无效的arg2,请重新输入arg2')])

[Legacy] 建议允许非@的命令存在

split_at_xiaokai_50中控制了群组中必须以@开始的命令机器人才响应,建议放开此控制,改为以装饰器的方式由命令自行声明是否必须@才响应

触发Lifespan error

操作系统:windows
py版本:3.6.6
cqhttpapi版本:4.7.0
none 版本 :0.4.2~0.52(都有)
提示内容:[2018-12-26 19:51:06,002] ASGI Framework Lifespan error, continuing without Lifespan support
引发第三方库:quart,hypercorn

多线程跟Quart 冲突

多线程开启多个Nonebot,现报错如下:
RuntimeError: There is no current event loop in thread 'Thread-1'

上网查了一下,说包括Quart在内的 Coroutine/EventLoop 只存在mian thread中。
请问这种问题如何解决呢?

关于 NoneBot 未来发展的思考

NoneBot 在有限的推广的情况下,被这么多人使用,让我感到很意外。它甚至到现在文档还没有完全写完🙄 。

经过半年多的发展,NoneBot 已经基本可用,虽然还是会有一些小问题,但这不妨碍已经有很多投入使用的应用在使用它。

实际上 NoneBot 还有很多不足,比如:

  • 基于 python-aiocqhttp(跟 酷Q 强耦合),无法支持其它机器人平台
  • 过于以「命令」为核心,而忽略了大量其它类型的消息处理需求(虽然可以通过 python-aiocqhttp 的 on_message 装饰器来做到);实际上 NoneBot 的前身,小开机器人,的「过滤器」特性还是比较有用的,可以用来进行消息预处理(比如日志、语音转文本)和拦截(比如屏蔽特定消息类型),但在写 NoneBot 的时候砍掉了 (1.6.0 message_preprocessor)
  • 没有全局黑名单机制,无法简单地屏蔽其它 bot 的消息(实际上这个功能只要有「过滤器」功能就可以轻松实现)
  • 注册命令的选项不够灵活,比如不能对不同命令设置不同的过期时间、超时时间,没有全局权限、全局 only_to_me(1.8.2, 1.9.0)
  • 权限控制功能不够强大,无法进行单用户和群组粒度的控制 (1.8.0, 1.9.0 PermissionPolicy)
  • 命令会话机制针对单个用户做区分,无法简单地实现群组内多人游戏等需求
  • 没有持久化命令会话 (1.8.0 apause)
  • 没有维护用户、群组、系统全局的整体状态,只有命令层面的状态
  • ……

最近想到 QQ 机器人的开发其实可以从现在流行的语音助手里面寻找灵感,比如对话的回合数、对一些可选参数如何假定、通过辅助的 app 或 web 管理面板来修改配置等。实际上 web 面板这个功能也是可以加入到 NoneBot 的,可以把面板的控制项以可扩展的形式开放 API。

另外,考虑 NoneBot 的定位,我希望它可以被用于任何聊天机器人的场景,无论是闲聊对话、信息查询、推送通知、消息转发、游戏等。

目前命令的参数处理方面的 API 其实也不够好,1.2 版本加入的参数过滤器一定程度上缓解了 args_parser 的复杂和冗余,但总觉得还是不够。

总的来说 NoneBot 还有非常大的提高空间,但由于我今年需要准备考研,因此 NoneBot 会暂停开发将近一年。一年之后,如果时间恰当的话,我打算完全重写这个框架。

如果大家在使用过程中有什么比较好的思路、使用案例,可以在这里讨论,等重写的时候,可以尽可能的考虑更多实际使用需求。

通过Pyinstaller 打包 报错

bot机器人通过pyinstaller 打包,会报WinError 3
请作者帮忙看一下:


Traceback (most recent call last):
File "bot.py", line 6, in
File "site-packages\nonebot\plugin.py", line 72, in load_builtin_plugins
File "site-packages\nonebot\plugin.py", line 48, in load_plugins
FileNotFoundError: [WinError 3] The system cannot find the path specified: 'C:\Users\king\AppData\Local\Temp\4\_MEI23356\nonebot\plugins'
[18796] Failed to execute script bot

增加中断CommandSession的外部机制

用户在进行CommandSession的交互时出现“您有命令正在执行,请稍后再试”,这时用户只能等到timeout,没有任何办法,除非重启整个none应用,如果用户此时可以输入“终止命令”等之类的指令,强行kill掉session,则可以让用户退出本次session后进行其他command操作。

当前,在CommandSession的session处理中,输入的任何文字都会被解析为session中的内容,无法跳出session本身之外进行处理,这个“终止命令”无法被更底层的session调度方监控到并生效,所以应该要有类似操作系统的中断机制,使用“终止命令”之类的保留字来处理这个中断本身。

Hello world

跟着NoneBot教程走,发现没有<user-id>.json这个文件啊,所以我新建了一个config目录并在其下新建了QQ号.json粘贴配置

{
    "ws_reverse_api_url": "ws://127.0.0.1:8080/ws/api/",
    "ws_reverse_event_url": "ws://127.0.0.1:8080/ws/event/",
    "ws_reverse_reconnect_on_code_1000": true,
    "use_ws_reverse": true
}

结果无法获取消息:

ujson module not found, using json
msgpack not installed, MsgPackSerializer unavailable
[2018-09-12 23:16:16,995 none] INFO: Succeeded to import "none.plugins.base"
[2018-09-12 23:16:16,995 none] INFO: Running on 127.0.0.1:8080
Running on http://127.0.0.1:8080 (CTRL + C to quit)

在config.cfg中配置对应参数能获取消息,但还是报:

ujson module not found, using json
msgpack not installed, MsgPackSerializer unavailable

虽然能用,强迫症患者还是想问一哈是啥情况?

[Legacy] 建议在load_plugins中增加对子目录的加载

由于一套业务逻辑可能是有几个py组成的,都散落在commands下面对于讲究整洁的我来说是个麻烦事,建议commands中支持子目录,这样也好归集同类业务的指令集。

至于指令的full_command是否要包含子目录可以再考虑一下,我也没想太清楚,包含的话使用时有点繁琐,不包含则可能存在同名的问题。

[Legacy] 建议在cool_http_api.py中处理CQ码的转移并对群成员使用群名片作为昵称

1.根据酷Q的文档,消息中为避免CQ码产生歧义,指定了’[’、’]’、’&’、’,’须进行转义
2.群成员使用群名片而不是昵称来称呼更加和
为减少后续filter和command的修改,转义及群名片最好在cool_http_api.py中直接修改,我已修改实现,因我修改的其他文件包含了非公共的变更,就不推送pull requests给你了,如要实现,可以参考这个代码变更

后台日志能够显示发给机器人的消息,但是收不到机器人发来的消息

代码

import nonebot
from nonebot import on_command, CommandSession

@on_command('foo')
async def foo(session: CommandSession):
    print('before')
    #  await session.send(session.state.get('message') or session.current_arg)
    msg = session.current_arg
    await session.send(msg)
    print('end')

if __name__ == '__main__':
    nonebot.init()
    nonebot.load_builtin_plugins()
    nonebot.run(host='127.0.0.1', port=8080)

日志

ujson module not found, using json
msgpack not installed, MsgPackSerializer unavailable
[2019-02-23 05:57:47,362 nonebot] INFO: Succeeded to import "nonebot.plugins.base"
[2019-02-23 05:57:47,362 nonebot] INFO: Running on 127.0.0.1:8080
Running on https://127.0.0.1:8080 (CTRL + C to quit)
[2019-02-23 05:57:47,364] ASGI Framework Lifespan error, continuing without Lifespan support
[2019-02-23 05:57:53,991 nonebot] INFO: Self: 3383679144, Message 175 from 492264408: /foo 123
[2019-02-23 05:57:53,991 nonebot] DEBUG: Parsing command: /foo 123
[2019-02-23 05:57:53,991 nonebot] DEBUG: Matched command start: /
[2019-02-23 05:57:53,992 nonebot] DEBUG: Split command name: ('foo',)
[2019-02-23 05:57:53,992 nonebot] DEBUG: Command ('foo',) found, function: <function foo at 0x7
f0da4074488>
[2019-02-23 05:57:53,993 nonebot] DEBUG: New session of command ('foo',) created
[2019-02-23 05:57:53,993 nonebot] DEBUG: Running command ('foo',)
[2019-02-23 05:57:53,995] 127.0.0.1:40312 POST / 1.1 200 0 7903
before
end
[2019-02-23 05:57:53,996 nonebot] DEBUG: Session of command ('foo',) finished
[2019-02-23 05:57:53,996 nonebot] INFO: Message 175 is handled as a command

是配置问题吗?

打算更改 package 的名字,大家有什么意见吗

现在 PyPI 上的包名叫 none-bot,实际导入的包名叫 none,并且 PyPI 上已经存在一个叫 none 的包。打算改名为 nonebot,统一安装和导入的包名(这个改动可能需要修改现有应用代码),大家觉得有没有什么问题?或者其他建议?

插件异常导致机器人断线问题

经常出现一种情况是 CoolQ Http API 上报消息成功,但是回复消息失败

目前发现的一定会出现这种情况的情形:代码出了问题产生异常未处理
还有一种不太确定的情况是长时间无人给机器人发消息(额也可能是这期间出现了触发异常的消息?没存日志……)

因为没有保存具体的日志因此暂时没办法贴出问题日志来。。如果需要的话我再写相关代码存吧【另外说一句,希望给一个便捷的文件存储的 Handler 而不是我自己写。。】

在 CoolQ Http API 插件重启即可解决

因此猜测此问题发生的原因:异常导致了 websocket 连接中断

建议的解决方案:全局加上异常处理防止 plugin 导致 websocket 连接断开

日志上没在处理信息

会自动回复,在酷Q上的日志也会显示,但是文件夹的日志没有显示处理信息(但显示了开启 HTTP 服务器成功,开始监听 http://0.0.0.0:5700)
CQA-tuling\酷Q Air\app\io.github.richardchien.coolqhttpapi\log

none调用aiocqhttp

怎么调用,调用cqHTTP API时的那个
bot.get_
bot是啥。。。捣腾了几天了,搞不定。。

无法连接docker

{
    "host": "[::]",
    "port": 5700,
    "use_http": true,
    "ws_host": "[::]",
    "ws_port": 6700,
    "use_ws": false,
    "ws_reverse_url": "",
    "ws_reverse_api_url": "",
    "ws_reverse_event_url": "",
    "ws_reverse_reconnect_interval": 3000,
    "ws_reverse_reconnect_on_code_1000": true,
    "use_ws_reverse": false,
    "post_url": "",
    "access_token": "",
    "secret": "",
    "post_message_format": "string",
    "serve_data_files": false,
    "update_source": "github",
    "update_channel": "stable",
    "auto_check_update": false,
    "auto_perform_update": false,
    "show_log_console": true,
    "log_level": "info",
    "ws_reverse_api_url": "ws://172.17.0.1:8080/ws/api/",
    "ws_reverse_event_url": "ws:/172.17.0.1/:8080/ws/event/",
    "ws_reverse_reconnect_on_code_1000": true,
    "use_ws_reverse": true
}
import nonebot

if __name__ == '__main__':
    nonebot.init()
    nonebot.load_builtin_plugins()
    nonebot.run(host='172.17.0.1', port=8080)

连不上,酷Q后台一直显示重连,然后发消息给QQ,nonebot这边也没有显示。

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.