Git Product home page Git Product logo

alicebot's People

Contributors

fengnkt avatar github-actions[bot] avatar marlenejiang avatar matt-wzy avatar nenocat avatar shenyiw avatar st1020 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

alicebot's Issues

[Feature] 添加详细报错

在写插件的过程中难免出错,而alicebot的报错机制过于笼统,希望添加更完美的报错

至少在alicebot\__init__.py的283与287行添加更详细的报错

loguru中有集成一个better_exceptions的库,可以更加详细地输出方法报错的所有信息,只需要将logger.error()改为logger.exception()即可

MiraiMessage 富文本组合时出现错误

尝试让

MiraiMessageSegment.at(self.event.sender.id) + MiraiMessageSegment.plain("ABC")

组合时,出现如下错误:

Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "~\site-packages\alicebot\message.py", line 379, in __add__
    return self._message_class(self) + other
TypeError: _message_class() takes 1 positional argument but 2 were given

环境为

  • Windows 10 Home Edition 22H2 19045.2604 with Windows Feature Experience Pack 120.2212.4190.0
  • Python 3.9.5 64bit

谢谢!

关于pypi

pypi那里是自动更新吗,还是说手动更新

pip install alicebot[all] --upgrade的时候,一直是环境满足,怀疑自己没更新上

对消息段的组织发生错误

以下为源代码

image

以下为标错行报错信息

2022-07-19 09:59:21.824 | ERROR | alicebot:_handle_event:283 - Exception in plugin "<freegame.FreeGame object at 0x00000161236DACE0>": TypeError("MessageSegment.__init__() missing 1 required positional argument: 'type'")

以下为文档内容

image

来自 https://docs.alicebot.dev/guide/builtin-message.html

问题

1.经实际使用发现不符
2.缺少富文本特性支持

关于 Pypi 仓库中的一些问题

我根据「快速上手 | AliceBot」一文中讲述的方法,使用了如下命令安装的 Alicebot 轮子以及其 Mirai Adaptor:

pip install alicebot
pip install alicebot-adapter-mirai

然后当我 from alicebot import Bot 的时候,出现了如下问题:

>>> from alicebot import Bot
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "%appdata%\..\Local\Programs\Python\Python38\lib\site-packages\alicebot\__init__.py", line 14, in <module>
    from alicebot.adapter import Adapter
  File "%appdata%\..\Local\Programs\Python\Python38\lib\site-packages\alicebot\adapter\__init__.py", line 23, in <module>
    from alicebot.utils import is_config_class
  File "%appdata%\..\Local\Programs\Python\Python38\lib\site-packages\alicebot\utils.py", line 60, in <module>
    StrOrBytesPath: TypeAlias = Union[str, bytes, PathLike[str], PathLike[bytes]]
TypeError: 'ABCMeta' object is not subscriptable

然后当我打开文件 alicebot\utils.py 的时候,发现其内容与仓库中的代码不一致,具体地说,仓库中所编写的内容为:

# At Line 60
StrOrBytesPath: TypeAlias = Union[str, bytes, "PathLike[str]", "PathLike[bytes]"]

而 pip 下下来的是:

# At Line 60
StrOrBytesPath: TypeAlias = Union[str, bytes, PathLike[str], PathLike[bytes]]

我不是很清楚这个情况是不是只有在 Python 3.8.X 系列版本中出现的问题,但是它确确实实出现在了使用 Python 3.8.X 的 PC 上。

环境配置如下:

  • Windows 7 x64 Service Pack 1
  • Python 3.8.10
  • pip 21.1.1

由于我不是专业的,可能有一些地方说的不是很严谨,也请大家多多海涵 ;)

mirai适配器成功连接,但似乎接受不到消息

mirai成功接受到消息,测试Bot没有反应输出
test code

from alicebot import Plugin
from alicebot.exceptions import GetEventTimeout
from alicebot.log import logger
from alicebot.adapter.mirai.event.base import FriendInfo
from alicebot.typing import T_State
from typing import Type, Union, Generic, TypeVar
from .config import BasePluginConfig, RegexPluginConfig, CommandPluginConfig
T_Config = TypeVar("T_Config", bound=BasePluginConfig)

class TestPlugin(Plugin):
    priority: int = 0
    block: bool = False

    async def handle(self) -> None:
        pass

    async def rule(self) -> bool:
        logger.info(self.event.adapter.name)
        return True

config.toml

[bot]
plugins = ["chatgpt-qqbot"]
plugin_dirs = ["plugins"]
adapters = ["alicebot.adapter.mirai"]

[bot.log]
verbose_exception = true

[adapter.mirai]
adapter_type = "reverse-ws"
verify_key = "password"
qq = qq
host = "127.0.0.1"
port = 5700
url = "/mirai/ws"

setting.yml

adapters:
  - reverse-ws
enableVerify: true
verifyKey: password
singleMode: true
adapterSettings:
  reverse-ws:
    destinations:
    - host: 127.0.0.1
      port: 5700
      path: /mirai/ws
      protocol: ws
      method: GET
    reservedSyncId: -1

请问怎么发送多张图片

我在文档中似乎没找到发送图片的方法,示例里也没看见,所以想请教一下,我很喜欢这个框架,谢谢

logger自定义

对logger的自定义会被bot.py中的_update_config中的logger.remove()删除˃ ˄ ˂̥̥

加载插件过程中会执行plugins中的文件两次

为了确认插件被成功加载,我在plugins目录下的xxx.py文件中写了一句代码print('xxx插件已加载成功'),然后发现启动程序时这个打印出现了两次,单步调试时发现utils.py中的get_classes_from_module_name函数中有这样一段代码:

importlib.invalidate_caches()
module = importlib.import_module(name)
importlib.reload(module)
return [(x, module) for x in get_classes_from_module(module, super_class)]

这里的module = importlib.import_module(name)importlib.reload(module)都会导致xxx.py文件被执行一次,所以xxx.py就被执行了两次

这个问题还导致我之后的另一种应用场景出现问题,简化代码如下:
我在plugins之外创建了一个comm目录,供所有的插件使用,其中提供了一个注册函数接口

fun_arr=[]
def add_fun(fun):
    fun_arr.append(fun)

在plugins中的一个文件中调用

class MyPlugin(Plugin):
    def f(self):
        ...
add_fun(MyPlugin.f)

在这种场景下,会导致add_fun被调用两次,同一个函数会被注册两次

功能建议

建议新增一个可以遍历插件名和 usage 的类,可以用来写插件帮助图

收到好友撤回事件后出现报错

报错信息如下:

  File "D:\Python310\lib\site-packages\alicebot\bot.py", line 173, in run
    asyncio.run(self._run())
    │       │   │    └ <function Bot._run at 0x0000021A5CC930A0>
    │       │   └ <alicebot.bot.Bot object at 0x0000021A5C97D4B0>
    │       └ <function run at 0x0000021A5B8BE9E0>
    └ <module 'asyncio' from 'D:\\Python310\\lib\\asyncio\\__init__.py'>
  File "D:\Python310\lib\asyncio\runners.py", line 44, in run
    return loop.run_until_complete(main)
           │    │                  └ <coroutine object Bot._run at 0x0000021A5CC5C580>
           │    └ <function BaseEventLoop.run_until_complete at 0x0000021A5B99F0A0>
           └ <ProactorEventLoop running=True closed=False debug=False>
  File "D:\Python310\lib\asyncio\base_events.py", line 633, in run_until_complete
    self.run_forever()
    │    └ <function ProactorEventLoop.run_forever at 0x0000021A5B9F1240>
    └ <ProactorEventLoop running=True closed=False debug=False>
  File "D:\Python310\lib\asyncio\windows_events.py", line 321, in run_forever
    super().run_forever()
  File "D:\Python310\lib\asyncio\base_events.py", line 600, in run_forever
    self._run_once()
    │    └ <function BaseEventLoop._run_once at 0x0000021A5B9A0B80>
    └ <ProactorEventLoop running=True closed=False debug=False>
  File "D:\Python310\lib\asyncio\base_events.py", line 1896, in _run_once
    handle._run()
    │      └ <function Handle._run at 0x0000021A5B9105E0>
    └ <Handle Task.task_wakeup(<Future finished result=None>)>
  File "D:\Python310\lib\asyncio\events.py", line 80, in _run
    self._context.run(self._callback, *self._args)
    │    │            │    │           │    └ <member '_args' of 'Handle' objects>
    │    │            │    │           └ <Handle Task.task_wakeup(<Future finished result=None>)>
    │    │            │    └ <member '_callback' of 'Handle' objects>
    │    │            └ <Handle Task.task_wakeup(<Future finished result=None>)>
    │    └ <member '_context' of 'Handle' objects>
    └ <Handle Task.task_wakeup(<Future finished result=None>)>
> File "D:\Python310\lib\site-packages\alicebot\adapter\__init__.py", line 78, in safe_run
    await self.run()
          │    └ <function WebSocketAdapter.run at 0x0000021A5E15A440>
          └ <alicebot.adapter.mirai.MiraiAdapter object at 0x0000021A5E3420E0>
  File "D:\Python310\lib\site-packages\alicebot\adapter\utils.py", line 207, in run
    await self.websocket_connect()
          │    └ <function MiraiAdapter.websocket_connect at 0x0000021A5E18E440>
          └ <alicebot.adapter.mirai.MiraiAdapter object at 0x0000021A5E3420E0>
  File "D:\Python310\lib\site-packages\alicebot\adapter\mirai\__init__.py", line 90, in websocket_connect
    await self.handle_websocket()
          │    └ <function WebSocketAdapter.handle_websocket at 0x0000021A5E15A710>
          └ <alicebot.adapter.mirai.MiraiAdapter object at 0x0000021A5E3420E0>
  File "D:\Python310\lib\site-packages\alicebot\adapter\utils.py", line 266, in handle_websocket
    await self.handle_websocket_msg(msg)
          │    │                    └ WSMessage(type=<WSMsgType.TEXT: 1>, data='{"syncId":"-1","data":{"type":"FriendRecallEvent","authorId":123456789,"messageId"...
          │    └ <function MiraiAdapter.handle_websocket_msg at 0x0000021A5E18E4D0>
          └ <alicebot.adapter.mirai.MiraiAdapter object at 0x0000021A5E3420E0>
  File "D:\Python310\lib\site-packages\alicebot\adapter\mirai\__init__.py", line 119, in handle_websocket_msg
    await self.handle_mirai_event(msg_dict.get("data"))
          │    │                  │        └ <method 'get' of 'dict' objects>
          │    │                  └ {'syncId': '-1', 'data': {'type': 'FriendRecallEvent', 'authorId': 123456789, 'messageId': 26036, 'time': 1691243648, 'opera...
          │    └ <function MiraiAdapter.handle_mirai_event at 0x0000021A5E18E680>
          └ <alicebot.adapter.mirai.MiraiAdapter object at 0x0000021A5E3420E0>
  File "D:\Python310\lib\site-packages\alicebot\adapter\mirai\__init__.py", line 153, in handle_mirai_event
    mirai_event = self.get_event_model(msg["type"])(adapter=self, **msg)
                  │    │               │                    │       └ {'type': 'FriendRecallEvent', 'authorId': 123456789, 'messageId': 26036, 'time': 1691243648, 'operator': 123456789}
                  │    │               │                    └ <alicebot.adapter.mirai.MiraiAdapter object at 0x0000021A5E3420E0>
                  │    │               └ {'type': 'FriendRecallEvent', 'authorId': 123456789, 'messageId': 26036, 'time': 1691243648, 'operator': 123456789}
                  │    └ <classmethod(<function MiraiAdapter.get_event_model at 0x0000021A5E18E5F0>)>
                  └ <alicebot.adapter.mirai.MiraiAdapter object at 0x0000021A5E3420E0>
  File "D:\Python310\lib\site-packages\alicebot\event.py", line 48, in __init__
    super().__init__(**data)
                       └ {'type': 'FriendRecallEvent', 'authorId': 123456789, 'messageId': 26036, 'time': 1691243648, 'operator': 123456789}
  File "pydantic\main.py", line 341, in pydantic.main.BaseModel.__init__
    raise validation_error
pydantic.error_wrappers.ValidationError: 1 validation error for FriendRecallEvent
friend
  field required (type=value_error.missing)

原因为FriendRecallEvent继承自FriendEvent,FriendEvent中有类成员friend: FriendInfo,导致FriendRecallEvent初始化也必须传一个该字段,而mirai传来的事件中没有该字段

#alicebot\adapter\mirai\event\notice.py
class FriendEvent(NoticeEvent):
    """好友事件"""

    friend: FriendInfo

class FriendRecallEvent(FriendEvent):
    """好友消息撤回"""

    type: Literal["FriendRecallEvent"]
    authorId: int
    messageId: int
    time: int
    operator: int

Mirai adapter无法处理同步消息链类型

复现方法:
1.在Mirai使用ANDROID_PHONE协议登录,并使用Mira适配器连接。
2.在IPad或其他设备登录机器人账号并向群聊发送消息。
3.适配器停止工作。

错误日志:

 to load adapter "MiraiAdapter" from "alicebot.adapter.mirai"
2024-02-28 10:58:33.607 | INFO     | alicebot.bot:_load_adapters:836 - Succeeded
 to load adapter "APSchedulerAdapter" from "alicebot.adapter.apscheduler"
2024-02-28 10:58:33.624 | INFO     | alicebot.bot:_run:213 - Running AliceBot...

2024-02-28 10:58:33.798 | INFO     | alicebot.bot:_run_hot_reload:291 - Hot relo
ad is working!
2024-02-28 10:58:33.813 | INFO     | alicebot.adapter.mirai:websocket_connect:90
 - Trying to verify identity and create connection...
2024-02-28 10:58:33.820 | INFO     | alicebot.adapter.apscheduler:run:74 - Plugi
n DecreasePlugin has been scheduled to run
2024-02-28 10:58:33.890 | INFO     | alicebot.adapter.mirai:handle_websocket_msg
:111 - Verify success! Session key: BBjnUrGX
2024-02-28 10:58:39.804 | INFO     | alicebot.bot:handle_event:456 - Adapter mir
ai received: Event<GroupMessage>: "菜单"
2024-02-28 10:58:39.828 | INFO     | alicebot.bot:_handle_event:507 - Event will
 be handled by <Menu.MenuPlugin object at 0x000000A86E1FEE80>
2024-02-28 10:58:40.953 | INFO     | alicebot.bot:_handle_event:527 - Event Fini
shed
2024-02-28 10:58:41.319 | ERROR    | alicebot.bot:error_or_exception:910 - Run a
dapter MiraiAdapter failed:
Traceback (most recent call last):

  File "C:\Users\Administrator\Desktop\AliceBot\bot.py", line 6, in <module>
    bot.run()
    │   └ <function Bot.run at 0x000000A86BCC64C0>
    └ <alicebot.bot.Bot object at 0x000000A86B035B80>

  File "C:\Users\Administrator\AppData\Local\Programs\Python\Python38\lib\site-p
ackages\alicebot\bot.py", line 174, in run
    asyncio.run(self._run())
    │       │   │    └ <function Bot._run at 0x000000A86BCC65E0>
    │       │   └ <alicebot.bot.Bot object at 0x000000A86B035B80>
    │       └ <function run at 0x000000A86BA72820>
    └ <module 'asyncio' from 'C:\\Users\\Administrator\\AppData\\Local\\Program
s\\Python\\Python38\\lib\\asyncio\\__init__.py'>

  File "C:\Users\Administrator\AppData\Local\Programs\Python\Python38\lib\asynci
o\runners.py", line 44, in run
    return loop.run_until_complete(main)
           │    │                  └ <coroutine object Bot._run at 0x000000A8
6BC35DC0>
           │    └ <function BaseEventLoop.run_until_complete at 0x000000A86BA6
FAF0>
           └ <ProactorEventLoop running=True closed=False debug=False>

  File "C:\Users\Administrator\AppData\Local\Programs\Python\Python38\lib\asynci
o\base_events.py", line 603, in run_until_complete
    self.run_forever()
    │    └ <function ProactorEventLoop.run_forever at 0x000000A86BAF7790>
    └ <ProactorEventLoop running=True closed=False debug=False>

  File "C:\Users\Administrator\AppData\Local\Programs\Python\Python38\lib\asynci
o\windows_events.py", line 316, in run_forever
    super().run_forever()

  File "C:\Users\Administrator\AppData\Local\Programs\Python\Python38\lib\asynci
o\base_events.py", line 570, in run_forever
    self._run_once()
    │    └ <function BaseEventLoop._run_once at 0x000000A86BA725E0>
    └ <ProactorEventLoop running=True closed=False debug=False>

  File "C:\Users\Administrator\AppData\Local\Programs\Python\Python38\lib\asynci
o\base_events.py", line 1859, in _run_once
    handle._run()
    │      └ <function Handle._run at 0x000000A86BA06940>
    └ <Handle <TaskWakeupMethWrapper object at 0x000000A86E1FE700>(<Future fini
shed result=None>)>

  File "C:\Users\Administrator\AppData\Local\Programs\Python\Python38\lib\asynci
o\events.py", line 81, in _run
    self._context.run(self._callback, *self._args)
    │    │            │    │           │    └ <member '_args' of 'Handle'
objects>
    │    │            │    │           └ <Handle <TaskWakeupMethWrapper obj
ect at 0x000000A86E1FE700>(<Future finished result=None>)>
    │    │            │    └ <member '_callback' of 'Handle' objects>
    │    │            └ <Handle <TaskWakeupMethWrapper object at 0x000000A86E
1FE700>(<Future finished result=None>)>
    │    └ <member '_context' of 'Handle' objects>
    └ <Handle <TaskWakeupMethWrapper object at 0x000000A86E1FE700>(<Future fini
shed result=None>)>

> File "C:\Users\Administrator\AppData\Local\Programs\Python\Python38\lib\site-p
ackages\alicebot\adapter\__init__.py", line 78, in safe_run
    await self.run()
          │    └ <function WebSocketAdapter.run at 0x000000A86D2B6F70>
          └ <alicebot.adapter.mirai.MiraiAdapter object at 0x000000A86BECFA00>

  File "C:\Users\Administrator\AppData\Local\Programs\Python\Python38\lib\site-p
ackages\alicebot\adapter\utils.py", line 217, in run
    await self.websocket_connect()
          │    └ <function MiraiAdapter.websocket_connect at 0x000000A86D34216
0>
          └ <alicebot.adapter.mirai.MiraiAdapter object at 0x000000A86BECFA00>

  File "C:\Users\Administrator\AppData\Local\Programs\Python\Python38\lib\site-p
ackages\alicebot\adapter\mirai\__init__.py", line 95, in websocket_connect
    await self.handle_websocket()
          │    └ <function WebSocketAdapter.handle_websocket at 0x000000A86D2B
F280>
          └ <alicebot.adapter.mirai.MiraiAdapter object at 0x000000A86BECFA00>

  File "C:\Users\Administrator\AppData\Local\Programs\Python\Python38\lib\site-p
ackages\alicebot\adapter\utils.py", line 271, in handle_websocket
    await self.handle_websocket_msg(msg)
          │    │                    └ WSMessage(type=<WSMsgType.TEXT: 1>, dat
a='{"syncId":"-1","data":{"type":"GroupSyncMessage","messageChain":[{"type":"Sou
rce","...
          │    └ <function MiraiAdapter.handle_websocket_msg at 0x000000A86D34
21F0>
          └ <alicebot.adapter.mirai.MiraiAdapter object at 0x000000A86BECFA00>

  File "C:\Users\Administrator\AppData\Local\Programs\Python\Python38\lib\site-p
ackages\alicebot\adapter\mirai\__init__.py", line 122, in handle_websocket_msg
    await self.handle_mirai_event(msg_dict.get("data"))
          │    │                  │        └ <method 'get' of 'dict' objects
>
          │    │                  └ {'syncId': '-1', 'data': {'type': 'GroupS
yncMessage', 'messageChain': [{'type': 'Source', 'id': 907, 'time': 1709089125},
 {'t...
          │    └ <function MiraiAdapter.handle_mirai_event at 0x000000A86D3F4F
70>
          └ <alicebot.adapter.mirai.MiraiAdapter object at 0x000000A86BECFA00>

  File "C:\Users\Administrator\AppData\Local\Programs\Python\Python38\lib\site-p
ackages\alicebot\adapter\mirai\__init__.py", line 158, in handle_mirai_event
    mirai_event = self.get_event_model(msg["type"])(adapter=self, **msg)
                  │    │               │                    │       └ {'typ
e': 'GroupSyncMessage', 'messageChain': [{'type': 'Source', 'id': 907, 'time': 1
709089125}, {'type': 'Image', 'imageId':...
                  │    │               │                    └ <alicebot.adap
ter.mirai.MiraiAdapter object at 0x000000A86BECFA00>
                  │    │               └ {'type': 'GroupSyncMessage', 'messag
eChain': [{'type': 'Source', 'id': 907, 'time': 1709089125}, {'type': 'Image', '
imageId':...
                  │    └ <classmethod object at 0x000000A86D42C4F0>
                  └ <alicebot.adapter.mirai.MiraiAdapter object at 0x000000A86B
ECFA00>

  File "C:\Users\Administrator\AppData\Local\Programs\Python\Python38\lib\site-p
ackages\alicebot\adapter\mirai\__init__.py", line 148, in get_event_model
    return cls.event_models[event_type]
           │   │            └ 'GroupSyncMessage'
           │   └ {'BotEvent': <class 'alicebot.adapter.mirai.event.meta.BotEve
nt'>, 'BotGroupPermissionChangeEvent': <class 'alicebot.adapter....
           └ <class 'alicebot.adapter.mirai.MiraiAdapter'>

KeyError: 'GroupSyncMessage'
2024-02-28 10:58:43.332 | INFO     | alicebot.bot:_handle_exit:432 - Stopping Al
iceBot...```

有没有交流群

如题。
顺便说一个我目前遇到的问题:就是在制作自定义合并转发的时候似乎出了点问题,但是我不知道错在了哪里,有没有例子参考一下
7Y(AL71%U`LSOEX}5)3HJY

E`L4 PGI8$5V7D10R_GM2F1

使用mirai http方式无法返回消息

2022-12-16_23-04-46
你好,我在尝试mirai http的方式进行使用这个框架,我在爬虫这个测试用例时,发现我发了消息,没有回应,不知道是哪里的问题

这是一个小建议

  1. 可不可以增加一个超级管理员配置文件字段 master,通过 self.bot.master 快速访问,很多管理性的插件都要用到此配置
  2. 能不能增加一个快速修改配置文件的方法,可以让超级管理员在QQ就发消息就可以修改配置文件,比如把一个插件的功能限制仅在一个列表里面的群可以启用,超级管理员通过QQ给机器人发消息就可以动态修改该列表

alicebot 0.8.1 版本运行报错

系统: windows 11
py版本: 3.10.11
alicebot 版本:0.8.1
(alicebot 0.7.1 版本正常运行无报错)

报错详情:
每次接收到消息就会报错.

2023-10-01 07:44:17.739 | INFO     | alicebot.adapter.cqhttp:reverse_ws_connection_hook:88 - WebSocket connected!
2023-10-01 07:44:17.742 | INFO     | alicebot.adapter.cqhttp:handle_cqhttp_event:195 - WebSocket connection from CQHTTP Bot xxx accepted!
Error handling request
Traceback (most recent call last):
  File "c:\ziyii\bot\bot\venv\lib\site-packages\aiohttp\web_protocol.py", line 433, in _handle_request
    resp = await request_handler(request)
  File "c:\ziyii\bot\bot\venv\lib\site-packages\aiohttp\web_app.py", line 504, in _handle
    resp = await handler(request)
  File "c:\ziyii\bot\bot\venv\lib\site-packages\alicebot\adapter\utils.py", line 250, in handle_reverse_ws_response
    await self.handle_websocket()
  File "c:\ziyii\bot\bot\venv\lib\site-packages\alicebot\adapter\utils.py", line 271, in handle_websocket
    await self.handle_websocket_msg(msg)
  File "c:\ziyii\bot\bot\venv\lib\site-packages\alicebot\adapter\cqhttp\__init__.py", line 122, in handle_websocket_msg
    await self.handle_cqhttp_event(msg_dict)
  File "c:\ziyii\bot\bot\venv\lib\site-packages\alicebot\adapter\cqhttp\__init__.py", line 187, in handle_cqhttp_event
    cqhttp_event = event_class(adapter=self, **msg)
  File "c:\ziyii\bot\bot\venv\lib\site-packages\pydantic\main.py", line 164, in __init__
    __pydantic_self__.__pydantic_validator__.validate_python(data, self_instance=__pydantic_self__)
pydantic_core._pydantic_core.ValidationError: 2 validation errors for GroupMessageEvent
message.is-instance[CQHTTPMessage]
  Input should be an instance of CQHTTPMessage [type=is_instance_of, input_value='xxx', input_type=str]
    For further information visit https://errors.pydantic.dev/2.4/v/is_instance_of
message.function-after[CQHTTPMessage(), list[CQHTTPMessageSegment]]
  Input should be a valid list [type=list_type, input_value='xxx', input_type=str]
    For further information visit https://errors.pydantic.dev/2.4/v/list_type
2023-10-01 07:44:27.957 | INFO     | alicebot.adapter.cqhttp:reverse_ws_connection_hook:88 - WebSocket connected!
2023-10-01 07:44:27.958 | INFO     | alicebot.adapter.cqhttp:handle_cqhttp_event:195 - WebSocket connection from CQHTTP Bot xxx accepted!

AliceBot 插件商店实现计划

项目名称:AliceBot 插件商店实现
项目主导师:迷糊小梦神
申请人:Marlene
日期:2023.5.10
邮箱:[email protected]

项目背景

项目基本需求

基于VitePress开发插件商店

AliceBot 使用了非常灵活且易于使用的插件编写方式,用户只需要编写两个方法即可实现一个功能强大的插件。随着 AliceBot 用户量的提高,许多用户都编写了自己的插件和适配器,为了方便用户交流,避免“重复造轮子”,急需开发一个商店页面用于用户分享自己编写插件和适配器。

基于GitHub Apps开发插件自动化提交Bot

用户想要分享自己的插件或者适配器,可以通过github仓库进行开源分享。为了更方便插件审核以及插件商店的插件提交。急需一个基于GitHub Apps开发的自动化bot,用于插件的提交和审核。

基于Vercel/Netlify+Cloudflare代码自动部署

由于用户需要通过issue和pr,提交自己的插件相关内容至插件商店的github仓库。更新后的代码需要及时生成文档站并进行部署。这方面急需一个基于vercel/netlify以及clodeflare(cdn加速)实现自动化部署,方便文档站(插件商店)能够及时更新。

项目相关仓库

主仓库:https://github.com/AliceBotProject/alicebot
该项目已有一个基于vitepress的项目文档,以及一些基础构建的workflow。
所有内容基本都在master分支。

项目实现细节梳理

插件商店

插件商店的需求是聚合相关插件、适配器、样例的资源站,提供插件等内容的浏览与链接跳转。
资源信息主要包含名称、类型(插件/适配器/样例)、模组名、描述、作者、仓库链接、标签、是否为官方出品等元信息。这些内容课通过pr合并至文档仓库的plugins.json文件内,用于存储相关信息。

界面可以采用vue3.3+vitepress开发,无需引入额外的库。
由于vitepress并无直接的内容聚合型展示功能,需要进行额外开发。主要思路是在vitepress上开发一个插件商店页面,包含多个相关组件。通过vitepress的markdown内置vue功能开发相关组件及页面功能和样式。通过vitepress提供的数据加载器功能实现插件商店数据的实时获取。
以下为实际操作的部分过程:
image.png
image.png
md文件可以使用内置vue语法编写相关页面样式以及引用相关组件,具体示例如下:

---
hello: world
---

<script setup>
import { ref } from 'vue'
import StoreTab from '../components/StoreTab.vue'
import Adapter from '../components/adapter.vue'
import Example from '../components/example.vue'
import Plugin from '../components/plugin.vue'
</script>

## Markdown Content

<store-tab class="tab">
	<plugin></plugin>
  <adapter></adapter>
  <example></example>
</store-tab>
<style module>
.tab{
  ...
}
</style>

下图为商店界面的原型设计,UI的设计充分考虑移动设备的布局,做好自适应和暗黑配色。

额外功能

当插件多起来之后,或许可以增加搜索功能。可以提供发布插件的引导页面,方便新手提交和分享插件。
更有甚至,直接在商店页面增加提交插件功能,一步到位,不过这可能不再是静态网站,需要额外资源进行存储。

GithubApp

用户提交插件的主要流程如下:

当用户新增issue,并提交相关pr,该pr关联issue时。issue相关信息更新,出发bot进行插件审核,pr自动合并,并自动close issue。当用户需要更新插件信息,只需要再次提交pr,关联原先的issue,即可
建立issue必须符合规范,否则bot直接进行close。
当然,bot并不会对所有issue进行如此操作。针对issue标题或者issue的主体中, 如果出现一些常见关键词, 譬如plugin, 那么在标题或者issue的主体内容中出现【plugin】这个词时,通过编写相应的工作流,也可以自动为该issue添加plugin标签。
这里我们也可以建立一个issue模板,具体可以在github repo 的settings里面设置:
image.png
image.png
这里的github bot(apps)主要参与的时检查代码规范,提交信息规范,在pr中合并,自动检查issue。
我们可以使用webhook来实现issue信息更新的监听,触发相关事件。

Bot注册及上架

需要新建一个bot,然后审核后上架这个bot,再在仓库中使用。

自动化部署

部署主要分为测试环境部署和生产环境部署。自动化部署主要应用于pr提交后,可进行测试环境部署,展示该pr的具体效果。当整个pr merge后进行生产环境部署,用于线上环境。
我们可以使用vercel和netlify提供的静态站点部署功能,将每次commit后都进行自动化部署展示,节约人工成本。当然,使用这些服务需要设置一些自身的信息,比如需要绑定自定义域名,使得最新部署站点能够及时显示在官网中。
由于vercel会被墙,这里推荐使用cloudflare做cdn加速,当然也可以使用其他cdn服务。

规划

非常希望能够参加本次项目开发,由于学校有亚运会项目,可以有暑假三个月假期时间开发,非常充裕,当然项目整体难度不高,开发周期也不是很长。所以完成后,或许可以再开发一些相关插件玩玩。

第一阶段

  • 完成插件商店UI的设计和开发(1~2周)
  • Github App开发及审核上架

第二阶段

  • 实现Vercel/Netlify自动化部署
  • 解决项目验收中的问题,对整个流程进行详细测试
  • 思考可以改进和补充的地方

期望

非常希望参加这样一个全新项目的开发,AliceBot旨在减轻NoneBot这类框架开发的一个负担,我非常认同这个理念。我在之前的bot插件开发使用中也经常为此头疼。希望我能够为这个项目做出贡献,丰富项目生态。

指南笔误?

在指南协议适配器部分,Mirai协议适配器一节的发送富文本例子中

https://docs.alicebot.dev/guide/mirai-adapter.html

image

from alicebot.adapter.mirai.message import CQHTTPMessageSegment

是否应该为

from alicebot.adapter.mirai.message import MiraiMessageSegment

之后的

msg = CQHTTPMessageSegment.plain("Hello, Alice!") + \
              CQHTTPMessageSegment.image(url="https://www.example.org/1.jpg")

则应为相应的

msg = MiraiMessageSegment.plain("Hello, Alice!") + \
              MiraiMessageSegment.image(url="https://www.example.org/1.jpg")

用于插件中的自定义配置在插件执行过程中被修改应如何保存?

感谢您制作了alicebot,它对新手真的很友好。但是我遇上了个问题,config.toml中配置自定义字段,例如group_list={"grout1":string1,"group2":string2},在使用过程中需要增加键值group3:string3进去,在程序中self.bot.config.group_list['group3']=string3之后关闭程序,发现其内容没有被写入到文件中,但是程序运行状态时却是能正确读出修改后的配置,请问这种情况下是程序bug还是本就没有设计修改配置后的保存功能?我看说明文档中也没有提示相关的内容。期待回复。

更新后错误

2022-08-21 23:03:22.697 | ERROR | alicebot.log:error_or_exception:15 - Config dict parse error: ValidationError(model='MainConfig', errors=[{'loc': ('plugins',), 'msg': 'none is not an allowed value', 'type': 'type_error.none.not_allowed'}])

以上为报错
以下为config.json

{
    "plugins": null,
    "plugin_dir": [
        "plugins",
        "plugins/osu"
    ],
    "adapters": ["alicebot.adapter.cqhttp"],
    "cqhttp": {
        "host": "127.0.0.1",
        "port": 9999,
        "url": "/cqhttp/ws",
        "api_timeout": 10000
    },
    "superuser": [1483492332],
    "osu": {
        "api":{
            "v2": {
                "id": 6322,
                "secret": "G5Dpfd1hAgAt8zkt0aFklV8bteaZITv1vC2bxcfO"
            }
        }
    }
}

[Feature] 添加重载函数

为插件添加self.bot.reload()重载函数,可以热重载,也可以整个重启


有一种设想,可以实施,但是少了这个函数无法便捷地实施,具体如下:

1.开发机的文件系统分两部分,一部分为开发项目,一部分为生产环境用的项目文件
2.生产环境用项目文件与服务器端开发环境项目文件使用rsync进行绑定
3.在本地开发完毕后,将新的插件文件或更改的文件放入开发机的生产环境项目文件中使用rsync进行同步

好处也就只有方便懒人了,而且做一个重载,应该不会非常难,实现退出函数再重新运行bot.run()即可,但我不了解alicebot的代码结构,没办法帮忙,请求加入这个功能

配置定时任务的时候会自动配置多一个重复的

配置定时任务的时候会自动配置多一个重复的
这是插件源代码(部分)

`from alicebot import Plugin, MessageEvent
from .service import get_today_courses, get_tomorrow_courses
from alicebot.adapter.apscheduler import scheduler_decorator

@scheduler_decorator(
trigger="cron", trigger_args={"day_of_week": "sun,mon,wed,thu", "hour": 22, "minute": 0}, override_rule=False
)
class CourseSchedule(Plugin):
async def handle(self) -> None:
data = get_tomorrow_courses()
await self.bot.get_adapter("cqhttp").send(data, "private", self.bot.config.superuser)

async def rule(self) -> bool:
    return (
            self.event.adapter.name == "apscheduler"
            and type(self) == self.event.plugin_class
    )

class CourseRemindPlugin(Plugin):
async def handle(self) -> None:
data = ""
if self.event.get_plain_text()[0] == '今':
data = get_today_courses()
elif self.event.get_plain_text()[0] == '明':
data = get_tomorrow_courses()
await self.event.reply(data)

async def rule(self) -> bool:
    return (
            isinstance(self.event, MessageEvent)
            and self.event.user_id == self.bot.config.superuser
            and (self.event.get_plain_text() == "今日课表"
                 or self.event.get_plain_text() == "明日课表")
    )

`

image
image

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.