Merge pull request #246 from zhamao-robot/update-docs-and-generator

更新部分文档和新增有关生成器
This commit is contained in:
Jerry 2023-01-06 16:15:10 +08:00 committed by GitHub
commit 3cca24bc8e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 170 additions and 5 deletions

View File

@ -64,11 +64,12 @@ module.exports = {
'/components/': [
{
title: '组件',
collapsable: false,
collapsable: true,
sidebarDepth: 2,
children: [
'bot/bot-context',
'bot/message-segment',
'common/class-alias',
]
}
]

View File

@ -16,7 +16,11 @@ public function sos(\BotContext $ctx)
关于 BotContext 机器人上下文如果你不喜欢上方通过参数绑定的依赖注入DI形式获取还可以在相关事件内使用全局函数 `bot()` 获取:
```php
bot()->reply('牛逼');
#[\BotCommand(match: 'SOS')]
public function sos()
{
bot()->reply('不许求救!');
}
```
## reply() - 快速回复消息
@ -33,7 +37,7 @@ bot()->reply('牛逼');
回复模式说明:
- `ZM_REPLY_NONE`不回复,直接发送消息。
- `ZM_REPLY_NONE`仅回复文本本身,直接发送消息。
- `ZM_REPLY_MENTION`:回复并 @ 消息发送者。
- `ZM_REPLY_QUOTE`:回复并引用消息。

View File

@ -1,3 +1,61 @@
# 机器人消息段格式
TODO。
消息段是 OneBot 12 标准中约定的一部分内容,如果你想对 OneBot 12 标准的消息段部分深入了解,请到 [OneBot - 消息段](https://12.onebot.dev/interface/message/segments/)。
因为聊天信息不仅仅含有文字还会有图片、语音、文件、at、表情包等富文本所以消息段就是用来描述这些富文本的。
## 格式样例
消息段不同于字符串,消息段默认是一个数组,数组中的每个元素都是一个消息段对象,每个消息段对象都有一个 `type` 字段,用来描述这个消息段的类型。
下面是一个以 JSON 格式表达的消息段样例:
```json
[
{
"type": "text",
"data": {
"text": "Hello, World!"
}
},
{
"type": "image",
"data": {
"file_id": "blablablablabla"
}
}
]
```
这个消息段在实际的聊天机器人对应的窗口中可能表示为“Hello, World!\[假设这里是一张图片\]”。
## 使用消息段
一般情况下,框架提供的消息发送和接收接口均会自动识别和转换字符串到消息段,所以你不需要手动构造消息段。
但如果你想发送富文本时,需要通过 `\MessageSegment` 对象进行构造。此对象等同于上方消息段中的单个消息段元素,在传入后发送时会自动转换为数组形式的消息段。
在框架任意位置,你可以使用全局函数 `segment()` 生成一个消息段对象。
- 定义:`segment(string $type, array $daa)`
- 返回:`OneBot\V12\Object\MessageSegment`
```php
#[BotCommand(match: '来个at')]
public function at()
{
bot()->reply([segment('at', ['user_id' => bot()->getEvent()->getUserId()]), segment('text', ['text' => ' 这是一条at你的消息'])]);
}
#[BotCommand(match: '来个图片')]
public function image()
{
// 我们假设你发送的图片已经上传
bot()->reply([segment('image', ['file_id' => 'blablablablabla'])]);
}
```
<chat-box :my-chats="[
{type:0,content:'来个at'},
{type:1,content:'@123456 这是一条at你的消息'},
{type:0,content:'来个图片'},
{type:3,content:'https://zhamao.xin/file/hello.jpg'},
]" />

View File

@ -0,0 +1,40 @@
# 类全局别名
在框架 1.x 和 2.x 老版本中,我们发现许多开发者在使用框架时,往往不会使用 PhpStorm 这类大型 IDE而即使使用 VSCode 这类编辑器的时候也不一定会安装补全插件,
这样在编写机器人模块或插件时会因寻找每个对象的完整命名空间而烦恼。
在 3.0 版本起,框架对常用的注解事件和对象均使用了类别名功能,方便非 IDE 开发者编写插件。
## 别名使用
框架对别名的定义比较简单,由于内部暂时没有不同命名空间下重复类名的情况,所以我们目前只对需要别名类名的命名空间移除,例如:
`\ZM\Annotation\OneBot\BotCommand` 注解事件类,在经过全局别名后,你也可以使用 `\BotCommand` 作为注解事件,效果相同。
## 别名列表
| 全类名 | 别名 |
|--------------------------------------------------------|-------------------------|
| `\ZM\Annotation\Framework\BindEvent` | `BindEvent` |
| `\ZM\Annotation\Framework\Cron` | `Cron` |
| `\ZM\Annotation\Framework\Init` | `Init` |
| `\ZM\Annotation\Framework\Setup` | `Setup` |
| `\ZM\Annotation\Http\Controller` | `Controller` |
| `\ZM\Annotation\Http\Route` | `Route` |
| `\ZM\Annotation\Middleware\Middleware` | `Middleware` |
| `\ZM\Annotation\OneBot\BotAction` | `BotAction` |
| `\ZM\Annotation\OneBot\BotActionResponse` | `BotActionResponse` |
| `\ZM\Annotation\OneBot\BotCommand` | `BotCommand` |
| `\ZM\Annotation\OneBot\BotEvent` | `BotEvent` |
| `\ZM\Annotation\OneBot\CommandArgument` | `CommandArgument` |
| `\ZM\Annotation\OneBot\CommandHelp` | `CommandHelp` |
| `\ZM\Annotation\Closed` | `Closed` |
| `\ZM\Plugin\ZMPlugin` | `ZMPlugin` |
| `\ZM\Context\BotContext` | `BotContext` |
| `\ZM\Store\KV\LightCache` | `LightCache` |
| `\ZM\Store\KV\Redis\KVRedis` | `KVRedis` |
| `\OneBot\Driver\Event\WebSocket\WebSocketOpenEvent` | `WebSocketOpenEvent` |
| `\OneBot\Driver\Event\WebSocket\WebSocketCloseEvent` | `WebSocketCloseEvent` |
| `\OneBot\Driver\Event\WebSocket\WebSocketMessageEvent` | `WebSocketMessageEvent` |
| `\OneBot\Driver\Event\Http\HttpRequestEvent` | `HttpRequestEvent` |
| `\OneBot\V12\Object\OneBotEvent` | `OneBotEvent` |

View File

@ -3,17 +3,25 @@
declare(strict_types=1);
class_alias(\ZM\Annotation\Framework\BindEvent::class, 'BindEvent');
class_alias(\ZM\Annotation\Framework\Cron::class, 'Cron');
class_alias(\ZM\Annotation\Framework\Init::class, 'Init');
class_alias(\ZM\Annotation\Framework\Setup::class, 'Setup');
class_alias(\ZM\Annotation\Http\Controller::class, 'Controller');
class_alias(\ZM\Annotation\Http\Route::class, 'Route');
class_alias(\ZM\Annotation\Middleware\Middleware::class, 'Middleware');
class_alias(\ZM\Annotation\OneBot\BotAction::class, 'BotAction');
class_alias(\ZM\Annotation\OneBot\BotActionResponse::class, 'BotActionResponse');
class_alias(\ZM\Annotation\OneBot\BotCommand::class, 'BotCommand');
class_alias(\ZM\Annotation\OneBot\BotEvent::class, 'BotEvent');
class_alias(\ZM\Annotation\OneBot\CommandArgument::class, 'CommandArgument');
class_alias(\ZM\Annotation\OneBot\CommandHelp::class, 'CommandHelp');
class_alias(\ZM\Annotation\Closed::class, 'Closed');
class_alias(\ZM\Plugin\ZMPlugin::class, 'ZMPlugin');
class_alias(\OneBot\V12\Object\OneBotEvent::class, 'OneBotEvent');
class_alias(\ZM\Context\BotContext::class, 'BotContext');
class_alias(\ZM\Store\KV\LightCache::class, 'LightCache');
class_alias(\ZM\Store\KV\Redis\KVRedis::class, 'KVRedis');
@ -23,3 +31,5 @@ class_alias(\OneBot\Driver\Event\WebSocket\WebSocketOpenEvent::class, 'WebSocket
class_alias(\OneBot\Driver\Event\WebSocket\WebSocketCloseEvent::class, 'WebSocketCloseEvent');
class_alias(\OneBot\Driver\Event\WebSocket\WebSocketMessageEvent::class, 'WebSocketMessageEvent');
class_alias(\OneBot\Driver\Event\Http\HttpRequestEvent::class, 'HttpRequestEvent');
class_alias(\OneBot\V12\Object\OneBotEvent::class, 'OneBotEvent');

View File

@ -0,0 +1,52 @@
<?php
declare(strict_types=1);
namespace ZM\Command\Generate;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Input\InputArgument;
use ZM\Command\Command;
#[AsCommand(name: 'generate:text', description: '生成一些文本(内部)')]
class TextGenerateCommand extends Command
{
protected function configure()
{
$this->addArgument('name', InputArgument::REQUIRED, '生成的文本内容');
}
/**
* {@inheritDoc}
*/
protected function handle(): int
{
return match ($this->input->getArgument('name')) {
'class-alias-md' => $this->generateClassAliasDoc(),
default => static::FAILURE,
};
}
private function generateClassAliasDoc(): int
{
$file = file_get_contents(FRAMEWORK_ROOT_DIR . '/src/Globals/global_class_alias.php');
// 提取class_alias函数的参数
preg_match_all('/class_alias\((.+?), \'(.+?)\'\);/', $file, $matches);
$full_maxlen = 0;
$short_maxlen = 0;
$line = [];
foreach ($matches[1] as $k => $v) {
$full_class = substr($v, 0, -7);
$short_class = $matches[2][$k];
$line[] = [$full_class, $short_class];
$full_maxlen = max($full_maxlen, strlen('`' . $full_class . '`'));
$short_maxlen = max($short_maxlen, strlen('`' . $short_class . '`'));
}
$this->write('| ' . str_pad('全类名', $full_maxlen) . ' | ' . str_pad('别名', $short_maxlen) . ' |');
$this->write('| ' . str_pad('', $full_maxlen, '-') . ' | ' . str_pad('', $short_maxlen, '-') . ' |');
foreach ($line as $v) {
$this->write('| ' . str_pad('`' . $v[0] . '`', $full_maxlen) . ' | ' . str_pad('`' . $v[1] . '`', $short_maxlen) . ' |');
}
return static::SUCCESS;
}
}