We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Bug: Mirai模块处理仅含@Bot的消息时报错
**描述问题：**

对于单独的@bot消息处理时报错。

**如何复现？**

使用mirai模块处理消息，当在群聊中单独@机器人（不跟随其他信息）时消息处理报错

**期望的结果**

能够正常处理

**环境信息：**

 - OS: CentOS & Winodws
 - Python Version: 3.9.2
 - Nonebot Version: nonebot cli version 0.4.0

**截图**
![image](https://user-images.githubusercontent.com/44700327/112746873-7a2cbd80-8fe4-11eb-9b6a-46620c3ee67f.png)



--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `packages/nonebot-adapter-mirai/nonebot/adapters/mirai/utils.py`
Content:
```
1 import re
2 from functools import wraps
3 from typing import TYPE_CHECKING, Any, Callable, Coroutine, Optional, TypeVar
4 
5 import httpx
6 from pydantic import Extra, ValidationError, validate_arguments
7 
8 import nonebot.exception as exception
9 from nonebot.log import logger
10 from nonebot.message import handle_event
11 from nonebot.utils import escape_tag, logger_wrapper
12 
13 from .event import Event, GroupMessage, MessageEvent, MessageSource
14 from .message import MessageType
15 
16 if TYPE_CHECKING:
17     from .bot import Bot
18 
19 _AsyncCallable = TypeVar("_AsyncCallable", bound=Callable[..., Coroutine])
20 _AnyCallable = TypeVar("_AnyCallable", bound=Callable)
21 
22 
23 class Log:
24 
25     @staticmethod
26     def log(level: str, message: str, exception: Optional[Exception] = None):
27         logger = logger_wrapper('MIRAI')
28         message = '<e>' + escape_tag(message) + '</e>'
29         logger(level=level.upper(), message=message, exception=exception)
30 
31     @classmethod
32     def info(cls, message: Any):
33         cls.log('INFO', str(message))
34 
35     @classmethod
36     def debug(cls, message: Any):
37         cls.log('DEBUG', str(message))
38 
39     @classmethod
40     def warn(cls, message: Any):
41         cls.log('WARNING', str(message))
42 
43     @classmethod
44     def error(cls, message: Any, exception: Optional[Exception] = None):
45         cls.log('ERROR', str(message), exception=exception)
46 
47 
48 class ActionFailed(exception.ActionFailed):
49     """
50     :说明:
51 
52       API 请求成功返回数据，但 API 操作失败。
53     """
54 
55     def __init__(self, **kwargs):
56         super().__init__('mirai')
57         self.data = kwargs.copy()
58 
59     def __repr__(self):
60         return self.__class__.__name__ + '(%s)' % ', '.join(
61             map(lambda m: '%s=%r' % m, self.data.items()))
62 
63 
64 class InvalidArgument(exception.AdapterException):
65     """
66     :说明:
67     
68       调用API的参数出错
69     """
70 
71     def __init__(self, **kwargs):
72         super().__init__('mirai')
73 
74 
75 def catch_network_error(function: _AsyncCallable) -> _AsyncCallable:
76     """
77     :说明:
78 
79       捕捉函数抛出的httpx网络异常并释放 ``NetworkError`` 异常
80 
81       处理返回数据, 在code不为0时释放 ``ActionFailed`` 异常
82 
83     \:\:\: warning
84     此装饰器只支持使用了httpx的异步函数
85     \:\:\:
86     """
87 
88     @wraps(function)
89     async def wrapper(*args, **kwargs):
90         try:
91             data = await function(*args, **kwargs)
92         except httpx.HTTPError:
93             raise exception.NetworkError('mirai')
94         logger.opt(colors=True).debug('<b>Mirai API returned data:</b> '
95                                       f'<y>{escape_tag(str(data))}</y>')
96         if isinstance(data, dict):
97             if data.get('code', 0) != 0:
98                 raise ActionFailed(**data)
99         return data
100 
101     return wrapper  # type: ignore
102 
103 
104 def argument_validation(function: _AnyCallable) -> _AnyCallable:
105     """
106     :说明:
107 
108       通过函数签名中的类型注解来对传入参数进行运行时校验
109       
110       会在参数出错时释放 ``InvalidArgument`` 异常
111     """
112     function = validate_arguments(config={
113         'arbitrary_types_allowed': True,
114         'extra': Extra.forbid
115     })(function)
116 
117     @wraps(function)
118     def wrapper(*args, **kwargs):
119         try:
120             return function(*args, **kwargs)
121         except ValidationError:
122             raise InvalidArgument
123 
124     return wrapper  # type: ignore
125 
126 
127 def process_source(bot: "Bot", event: MessageEvent) -> MessageEvent:
128     source = event.message_chain.extract_first(MessageType.SOURCE)
129     if source is not None:
130         event.source = MessageSource.parse_obj(source.data)
131     return event
132 
133 
134 def process_at(bot: "Bot", event: GroupMessage) -> GroupMessage:
135     at = event.message_chain.extract_first(MessageType.AT)
136     if at is not None:
137         if at.data['target'] == event.self_id:
138             event.to_me = True
139         else:
140             event.message_chain.insert(0, at)
141     return event
142 
143 
144 def process_nick(bot: "Bot", event: GroupMessage) -> GroupMessage:
145     plain = event.message_chain.extract_first(MessageType.PLAIN)
146     if plain is not None:
147         text = str(plain)
148         nick_regex = '|'.join(filter(lambda x: x, bot.config.nickname))
149         matched = re.search(rf"^({nick_regex})([\s,，]*|$)", text, re.IGNORECASE)
150         if matched is not None:
151             event.to_me = True
152             nickname = matched.group(1)
153             Log.info(f'User is calling me {nickname}')
154             plain.data['text'] = text[matched.end():]
155         event.message_chain.insert(0, plain)
156     return event
157 
158 
159 def process_reply(bot: "Bot", event: GroupMessage) -> GroupMessage:
160     reply = event.message_chain.extract_first(MessageType.QUOTE)
161     if reply is not None:
162         if reply.data['senderId'] == event.self_id:
163             event.to_me = True
164         else:
165             event.message_chain.insert(0, reply)
166     return event
167 
168 
169 async def process_event(bot: "Bot", event: Event) -> None:
170     if isinstance(event, MessageEvent):
171         event.message_chain.reduce()
172         Log.debug(event.message_chain)
173         event = process_source(bot, event)
174         if isinstance(event, GroupMessage):
175             event = process_nick(bot, event)
176             event = process_at(bot, event)
177             event = process_reply(bot, event)
178     await handle_event(bot, event)
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/packages/nonebot-adapter-mirai/nonebot/adapters/mirai/utils.py b/packages/nonebot-adapter-mirai/nonebot/adapters/mirai/utils.py
--- a/packages/nonebot-adapter-mirai/nonebot/adapters/mirai/utils.py
+++ b/packages/nonebot-adapter-mirai/nonebot/adapters/mirai/utils.py
@@ -11,7 +11,7 @@
 from nonebot.utils import escape_tag, logger_wrapper
 
 from .event import Event, GroupMessage, MessageEvent, MessageSource
-from .message import MessageType
+from .message import MessageType, MessageSegment
 
 if TYPE_CHECKING:
     from .bot import Bot
@@ -64,7 +64,7 @@
 class InvalidArgument(exception.AdapterException):
     """
     :说明:
-    
+
       调用API的参数出错
     """
 
@@ -106,7 +106,7 @@
     :说明:
 
       通过函数签名中的类型注解来对传入参数进行运行时校验
-      
+
       会在参数出错时释放 ``InvalidArgument`` 异常
     """
     function = validate_arguments(config={
@@ -138,6 +138,8 @@
             event.to_me = True
         else:
             event.message_chain.insert(0, at)
+    if not event.message_chain:
+        event.message_chain.append(MessageSegment.plain(''))
     return event
 
 
@@ -175,4 +177,4 @@
             event = process_nick(bot, event)
             event = process_at(bot, event)
             event = process_reply(bot, event)
-    await handle_event(bot, event)
\ No newline at end of file
+    await handle_event(bot, event)

{"golden_diff": "diff --git a/packages/nonebot-adapter-mirai/nonebot/adapters/mirai/utils.py b/packages/nonebot-adapter-mirai/nonebot/adapters/mirai/utils.py\n--- a/packages/nonebot-adapter-mirai/nonebot/adapters/mirai/utils.py\n+++ b/packages/nonebot-adapter-mirai/nonebot/adapters/mirai/utils.py\n@@ -11,7 +11,7 @@\n from nonebot.utils import escape_tag, logger_wrapper\n \n from .event import Event, GroupMessage, MessageEvent, MessageSource\n-from .message import MessageType\n+from .message import MessageType, MessageSegment\n \n if TYPE_CHECKING:\n     from .bot import Bot\n@@ -64,7 +64,7 @@\n class InvalidArgument(exception.AdapterException):\n     \"\"\"\n     :\u8bf4\u660e:\n-    \n+\n       \u8c03\u7528API\u7684\u53c2\u6570\u51fa\u9519\n     \"\"\"\n \n@@ -106,7 +106,7 @@\n     :\u8bf4\u660e:\n \n       \u901a\u8fc7\u51fd\u6570\u7b7e\u540d\u4e2d\u7684\u7c7b\u578b\u6ce8\u89e3\u6765\u5bf9\u4f20\u5165\u53c2\u6570\u8fdb\u884c\u8fd0\u884c\u65f6\u6821\u9a8c\n-      \n+\n       \u4f1a\u5728\u53c2\u6570\u51fa\u9519\u65f6\u91ca\u653e ``InvalidArgument`` \u5f02\u5e38\n     \"\"\"\n     function = validate_arguments(config={\n@@ -138,6 +138,8 @@\n             event.to_me = True\n         else:\n             event.message_chain.insert(0, at)\n+    if not event.message_chain:\n+        event.message_chain.append(MessageSegment.plain(''))\n     return event\n \n \n@@ -175,4 +177,4 @@\n             event = process_nick(bot, event)\n             event = process_at(bot, event)\n             event = process_reply(bot, event)\n-    await handle_event(bot, event)\n\\ No newline at end of file\n+    await handle_event(bot, event)\n", "issue": "Bug: Mirai\u6a21\u5757\u5904\u7406\u4ec5\u542b@Bot\u7684\u6d88\u606f\u65f6\u62a5\u9519\n**\u63cf\u8ff0\u95ee\u9898\uff1a**\r\n\r\n\u5bf9\u4e8e\u5355\u72ec\u7684@bot\u6d88\u606f\u5904\u7406\u65f6\u62a5\u9519\u3002\r\n\r\n**\u5982\u4f55\u590d\u73b0\uff1f**\r\n\r\n\u4f7f\u7528mirai\u6a21\u5757\u5904\u7406\u6d88\u606f\uff0c\u5f53\u5728\u7fa4\u804a\u4e2d\u5355\u72ec@\u673a\u5668\u4eba\uff08\u4e0d\u8ddf\u968f\u5176\u4ed6\u4fe1\u606f\uff09\u65f6\u6d88\u606f\u5904\u7406\u62a5\u9519\r\n\r\n**\u671f\u671b\u7684\u7ed3\u679c**\r\n\r\n\u80fd\u591f\u6b63\u5e38\u5904\u7406\r\n\r\n**\u73af\u5883\u4fe1\u606f\uff1a**\r\n\r\n - OS: CentOS & Winodws\r\n - Python Version: 3.9.2\r\n - Nonebot Version: nonebot cli version 0.4.0\r\n\r\n**\u622a\u56fe**\r\n![image](https://user-images.githubusercontent.com/44700327/112746873-7a2cbd80-8fe4-11eb-9b6a-46620c3ee67f.png)\r\n\r\n\n", "before_files": [{"content": "import re\nfrom functools import wraps\nfrom typing import TYPE_CHECKING, Any, Callable, Coroutine, Optional, TypeVar\n\nimport httpx\nfrom pydantic import Extra, ValidationError, validate_arguments\n\nimport nonebot.exception as exception\nfrom nonebot.log import logger\nfrom nonebot.message import handle_event\nfrom nonebot.utils import escape_tag, logger_wrapper\n\nfrom .event import Event, GroupMessage, MessageEvent, MessageSource\nfrom .message import MessageType\n\nif TYPE_CHECKING:\n    from .bot import Bot\n\n_AsyncCallable = TypeVar(\"_AsyncCallable\", bound=Callable[..., Coroutine])\n_AnyCallable = TypeVar(\"_AnyCallable\", bound=Callable)\n\n\nclass Log:\n\n    @staticmethod\n    def log(level: str, message: str, exception: Optional[Exception] = None):\n        logger = logger_wrapper('MIRAI')\n        message = '<e>' + escape_tag(message) + '</e>'\n        logger(level=level.upper(), message=message, exception=exception)\n\n    @classmethod\n    def info(cls, message: Any):\n        cls.log('INFO', str(message))\n\n    @classmethod\n    def debug(cls, message: Any):\n        cls.log('DEBUG', str(message))\n\n    @classmethod\n    def warn(cls, message: Any):\n        cls.log('WARNING', str(message))\n\n    @classmethod\n    def error(cls, message: Any, exception: Optional[Exception] = None):\n        cls.log('ERROR', str(message), exception=exception)\n\n\nclass ActionFailed(exception.ActionFailed):\n    \"\"\"\n    :\u8bf4\u660e:\n\n      API \u8bf7\u6c42\u6210\u529f\u8fd4\u56de\u6570\u636e\uff0c\u4f46 API \u64cd\u4f5c\u5931\u8d25\u3002\n    \"\"\"\n\n    def __init__(self, **kwargs):\n        super().__init__('mirai')\n        self.data = kwargs.copy()\n\n    def __repr__(self):\n        return self.__class__.__name__ + '(%s)' % ', '.join(\n            map(lambda m: '%s=%r' % m, self.data.items()))\n\n\nclass InvalidArgument(exception.AdapterException):\n    \"\"\"\n    :\u8bf4\u660e:\n    \n      \u8c03\u7528API\u7684\u53c2\u6570\u51fa\u9519\n    \"\"\"\n\n    def __init__(self, **kwargs):\n        super().__init__('mirai')\n\n\ndef catch_network_error(function: _AsyncCallable) -> _AsyncCallable:\n    \"\"\"\n    :\u8bf4\u660e:\n\n      \u6355\u6349\u51fd\u6570\u629b\u51fa\u7684httpx\u7f51\u7edc\u5f02\u5e38\u5e76\u91ca\u653e ``NetworkError`` \u5f02\u5e38\n\n      \u5904\u7406\u8fd4\u56de\u6570\u636e, \u5728code\u4e0d\u4e3a0\u65f6\u91ca\u653e ``ActionFailed`` \u5f02\u5e38\n\n    \\:\\:\\: warning\n    \u6b64\u88c5\u9970\u5668\u53ea\u652f\u6301\u4f7f\u7528\u4e86httpx\u7684\u5f02\u6b65\u51fd\u6570\n    \\:\\:\\:\n    \"\"\"\n\n    @wraps(function)\n    async def wrapper(*args, **kwargs):\n        try:\n            data = await function(*args, **kwargs)\n        except httpx.HTTPError:\n            raise exception.NetworkError('mirai')\n        logger.opt(colors=True).debug('<b>Mirai API returned data:</b> '\n                                      f'<y>{escape_tag(str(data))}</y>')\n        if isinstance(data, dict):\n            if data.get('code', 0) != 0:\n                raise ActionFailed(**data)\n        return data\n\n    return wrapper  # type: ignore\n\n\ndef argument_validation(function: _AnyCallable) -> _AnyCallable:\n    \"\"\"\n    :\u8bf4\u660e:\n\n      \u901a\u8fc7\u51fd\u6570\u7b7e\u540d\u4e2d\u7684\u7c7b\u578b\u6ce8\u89e3\u6765\u5bf9\u4f20\u5165\u53c2\u6570\u8fdb\u884c\u8fd0\u884c\u65f6\u6821\u9a8c\n      \n      \u4f1a\u5728\u53c2\u6570\u51fa\u9519\u65f6\u91ca\u653e ``InvalidArgument`` \u5f02\u5e38\n    \"\"\"\n    function = validate_arguments(config={\n        'arbitrary_types_allowed': True,\n        'extra': Extra.forbid\n    })(function)\n\n    @wraps(function)\n    def wrapper(*args, **kwargs):\n        try:\n            return function(*args, **kwargs)\n        except ValidationError:\n            raise InvalidArgument\n\n    return wrapper  # type: ignore\n\n\ndef process_source(bot: \"Bot\", event: MessageEvent) -> MessageEvent:\n    source = event.message_chain.extract_first(MessageType.SOURCE)\n    if source is not None:\n        event.source = MessageSource.parse_obj(source.data)\n    return event\n\n\ndef process_at(bot: \"Bot\", event: GroupMessage) -> GroupMessage:\n    at = event.message_chain.extract_first(MessageType.AT)\n    if at is not None:\n        if at.data['target'] == event.self_id:\n            event.to_me = True\n        else:\n            event.message_chain.insert(0, at)\n    return event\n\n\ndef process_nick(bot: \"Bot\", event: GroupMessage) -> GroupMessage:\n    plain = event.message_chain.extract_first(MessageType.PLAIN)\n    if plain is not None:\n        text = str(plain)\n        nick_regex = '|'.join(filter(lambda x: x, bot.config.nickname))\n        matched = re.search(rf\"^({nick_regex})([\\s,\uff0c]*|$)\", text, re.IGNORECASE)\n        if matched is not None:\n            event.to_me = True\n            nickname = matched.group(1)\n            Log.info(f'User is calling me {nickname}')\n            plain.data['text'] = text[matched.end():]\n        event.message_chain.insert(0, plain)\n    return event\n\n\ndef process_reply(bot: \"Bot\", event: GroupMessage) -> GroupMessage:\n    reply = event.message_chain.extract_first(MessageType.QUOTE)\n    if reply is not None:\n        if reply.data['senderId'] == event.self_id:\n            event.to_me = True\n        else:\n            event.message_chain.insert(0, reply)\n    return event\n\n\nasync def process_event(bot: \"Bot\", event: Event) -> None:\n    if isinstance(event, MessageEvent):\n        event.message_chain.reduce()\n        Log.debug(event.message_chain)\n        event = process_source(bot, event)\n        if isinstance(event, GroupMessage):\n            event = process_nick(bot, event)\n            event = process_at(bot, event)\n            event = process_reply(bot, event)\n    await handle_event(bot, event)", "path": "packages/nonebot-adapter-mirai/nonebot/adapters/mirai/utils.py"}], "after_files": [{"content": "import re\nfrom functools import wraps\nfrom typing import TYPE_CHECKING, Any, Callable, Coroutine, Optional, TypeVar\n\nimport httpx\nfrom pydantic import Extra, ValidationError, validate_arguments\n\nimport nonebot.exception as exception\nfrom nonebot.log import logger\nfrom nonebot.message import handle_event\nfrom nonebot.utils import escape_tag, logger_wrapper\n\nfrom .event import Event, GroupMessage, MessageEvent, MessageSource\nfrom .message import MessageType, MessageSegment\n\nif TYPE_CHECKING:\n    from .bot import Bot\n\n_AsyncCallable = TypeVar(\"_AsyncCallable\", bound=Callable[..., Coroutine])\n_AnyCallable = TypeVar(\"_AnyCallable\", bound=Callable)\n\n\nclass Log:\n\n    @staticmethod\n    def log(level: str, message: str, exception: Optional[Exception] = None):\n        logger = logger_wrapper('MIRAI')\n        message = '<e>' + escape_tag(message) + '</e>'\n        logger(level=level.upper(), message=message, exception=exception)\n\n    @classmethod\n    def info(cls, message: Any):\n        cls.log('INFO', str(message))\n\n    @classmethod\n    def debug(cls, message: Any):\n        cls.log('DEBUG', str(message))\n\n    @classmethod\n    def warn(cls, message: Any):\n        cls.log('WARNING', str(message))\n\n    @classmethod\n    def error(cls, message: Any, exception: Optional[Exception] = None):\n        cls.log('ERROR', str(message), exception=exception)\n\n\nclass ActionFailed(exception.ActionFailed):\n    \"\"\"\n    :\u8bf4\u660e:\n\n      API \u8bf7\u6c42\u6210\u529f\u8fd4\u56de\u6570\u636e\uff0c\u4f46 API \u64cd\u4f5c\u5931\u8d25\u3002\n    \"\"\"\n\n    def __init__(self, **kwargs):\n        super().__init__('mirai')\n        self.data = kwargs.copy()\n\n    def __repr__(self):\n        return self.__class__.__name__ + '(%s)' % ', '.join(\n            map(lambda m: '%s=%r' % m, self.data.items()))\n\n\nclass InvalidArgument(exception.AdapterException):\n    \"\"\"\n    :\u8bf4\u660e:\n\n      \u8c03\u7528API\u7684\u53c2\u6570\u51fa\u9519\n    \"\"\"\n\n    def __init__(self, **kwargs):\n        super().__init__('mirai')\n\n\ndef catch_network_error(function: _AsyncCallable) -> _AsyncCallable:\n    \"\"\"\n    :\u8bf4\u660e:\n\n      \u6355\u6349\u51fd\u6570\u629b\u51fa\u7684httpx\u7f51\u7edc\u5f02\u5e38\u5e76\u91ca\u653e ``NetworkError`` \u5f02\u5e38\n\n      \u5904\u7406\u8fd4\u56de\u6570\u636e, \u5728code\u4e0d\u4e3a0\u65f6\u91ca\u653e ``ActionFailed`` \u5f02\u5e38\n\n    \\:\\:\\: warning\n    \u6b64\u88c5\u9970\u5668\u53ea\u652f\u6301\u4f7f\u7528\u4e86httpx\u7684\u5f02\u6b65\u51fd\u6570\n    \\:\\:\\:\n    \"\"\"\n\n    @wraps(function)\n    async def wrapper(*args, **kwargs):\n        try:\n            data = await function(*args, **kwargs)\n        except httpx.HTTPError:\n            raise exception.NetworkError('mirai')\n        logger.opt(colors=True).debug('<b>Mirai API returned data:</b> '\n                                      f'<y>{escape_tag(str(data))}</y>')\n        if isinstance(data, dict):\n            if data.get('code', 0) != 0:\n                raise ActionFailed(**data)\n        return data\n\n    return wrapper  # type: ignore\n\n\ndef argument_validation(function: _AnyCallable) -> _AnyCallable:\n    \"\"\"\n    :\u8bf4\u660e:\n\n      \u901a\u8fc7\u51fd\u6570\u7b7e\u540d\u4e2d\u7684\u7c7b\u578b\u6ce8\u89e3\u6765\u5bf9\u4f20\u5165\u53c2\u6570\u8fdb\u884c\u8fd0\u884c\u65f6\u6821\u9a8c\n\n      \u4f1a\u5728\u53c2\u6570\u51fa\u9519\u65f6\u91ca\u653e ``InvalidArgument`` \u5f02\u5e38\n    \"\"\"\n    function = validate_arguments(config={\n        'arbitrary_types_allowed': True,\n        'extra': Extra.forbid\n    })(function)\n\n    @wraps(function)\n    def wrapper(*args, **kwargs):\n        try:\n            return function(*args, **kwargs)\n        except ValidationError:\n            raise InvalidArgument\n\n    return wrapper  # type: ignore\n\n\ndef process_source(bot: \"Bot\", event: MessageEvent) -> MessageEvent:\n    source = event.message_chain.extract_first(MessageType.SOURCE)\n    if source is not None:\n        event.source = MessageSource.parse_obj(source.data)\n    return event\n\n\ndef process_at(bot: \"Bot\", event: GroupMessage) -> GroupMessage:\n    at = event.message_chain.extract_first(MessageType.AT)\n    if at is not None:\n        if at.data['target'] == event.self_id:\n            event.to_me = True\n        else:\n            event.message_chain.insert(0, at)\n    if not event.message_chain:\n        event.message_chain.append(MessageSegment.plain(''))\n    return event\n\n\ndef process_nick(bot: \"Bot\", event: GroupMessage) -> GroupMessage:\n    plain = event.message_chain.extract_first(MessageType.PLAIN)\n    if plain is not None:\n        text = str(plain)\n        nick_regex = '|'.join(filter(lambda x: x, bot.config.nickname))\n        matched = re.search(rf\"^({nick_regex})([\\s,\uff0c]*|$)\", text, re.IGNORECASE)\n        if matched is not None:\n            event.to_me = True\n            nickname = matched.group(1)\n            Log.info(f'User is calling me {nickname}')\n            plain.data['text'] = text[matched.end():]\n        event.message_chain.insert(0, plain)\n    return event\n\n\ndef process_reply(bot: \"Bot\", event: GroupMessage) -> GroupMessage:\n    reply = event.message_chain.extract_first(MessageType.QUOTE)\n    if reply is not None:\n        if reply.data['senderId'] == event.self_id:\n            event.to_me = True\n        else:\n            event.message_chain.insert(0, reply)\n    return event\n\n\nasync def process_event(bot: \"Bot\", event: Event) -> None:\n    if isinstance(event, MessageEvent):\n        event.message_chain.reduce()\n        Log.debug(event.message_chain)\n        event = process_source(bot, event)\n        if isinstance(event, GroupMessage):\n            event = process_nick(bot, event)\n            event = process_at(bot, event)\n            event = process_reply(bot, event)\n    await handle_event(bot, event)\n", "path": "packages/nonebot-adapter-mirai/nonebot/adapters/mirai/utils.py"}]}