mirror of
https://github.com/zhamao-robot/zhamao-framework.git
synced 2026-03-17 20:54:52 +08:00
Merge pull request #248 from zhamao-robot/prompt-mode
新增 prompt 方法的选项参数
This commit is contained in:
commit
a5275a2575
@ -36,6 +36,13 @@ const ZM_REPLY_NONE = 0; // 默认回复,不带任何东西
|
||||
const ZM_REPLY_MENTION = 1; // 回复时 @ 该用户
|
||||
const ZM_REPLY_QUOTE = 2; // 回复时引用该消息
|
||||
|
||||
const ZM_PROMPT_NONE = 0; // 使用 prompt() 不附加任何内容
|
||||
const ZM_PROMPT_MENTION_USER = 1; // 回复提示语句时 at 该用户
|
||||
const ZM_PROMPT_QUOTE_USER = 2; // 回复提示语句时引用该用户的消息
|
||||
const ZM_PROMPT_TIMEOUT_MENTION_USER = 4; // 回复超时时 at 该用户
|
||||
const ZM_PROMPT_TIMEOUT_QUOTE_SELF = 8; // 回复超时时引用自己回复的提示语句
|
||||
const ZM_PROMPT_TIMEOUT_QUOTE_USER = 16; // 回复超时时引用用户的消息
|
||||
|
||||
const LOAD_MODE_VENDOR = 0; // 从 vendor 加载
|
||||
const LOAD_MODE_SRC = 1; // 从 src 加载
|
||||
|
||||
|
||||
@ -9,6 +9,7 @@ use DI\NotFoundException;
|
||||
use OneBot\Driver\Coroutine\Adaptive;
|
||||
use OneBot\Driver\Event\Http\HttpRequestEvent;
|
||||
use OneBot\Driver\Event\WebSocket\WebSocketMessageEvent;
|
||||
use OneBot\V12\Object\ActionResponse;
|
||||
use OneBot\V12\Object\MessageSegment;
|
||||
use OneBot\V12\Object\OneBotEvent;
|
||||
use ZM\Context\Trait\BotActionTrait;
|
||||
@ -85,14 +86,15 @@ class BotContext implements ContextInterface
|
||||
*
|
||||
* @param array|MessageSegment|string|\Stringable $prompt 等待前发送的消息文本
|
||||
* @param int $timeout 等待超时时间(单位为秒,默认为 600 秒)
|
||||
* @param string $timeout_prompt 超时后提示的消息内容
|
||||
* @param array|MessageSegment|string|\Stringable $timeout_prompt 超时后提示的消息内容
|
||||
* @param bool $return_string 是否只返回 text 格式的字符串消息(默认为 false)
|
||||
* @param int $option prompt 功能的选项参数
|
||||
* @throws DependencyException
|
||||
* @throws NotFoundException
|
||||
* @throws OneBot12Exception
|
||||
* @throws WaitTimeoutException
|
||||
*/
|
||||
public function prompt(string|\Stringable|MessageSegment|array $prompt = '', int $timeout = 600, string $timeout_prompt = '', bool $return_string = false): array|string
|
||||
public function prompt(string|\Stringable|MessageSegment|array $prompt = '', int $timeout = 600, string|\Stringable|MessageSegment|array $timeout_prompt = '', bool $return_string = false, int $option = ZM_PROMPT_NONE): array|string
|
||||
{
|
||||
if (!container()->has('bot.event')) {
|
||||
throw new OneBot12Exception('bot()->prompt() can only be used in message event');
|
||||
@ -105,7 +107,8 @@ class BotContext implements ContextInterface
|
||||
// 开始等待输入
|
||||
logger()->debug('Waiting user for prompt...');
|
||||
if ($prompt !== '') {
|
||||
$this->reply($prompt);
|
||||
$prompt = $this->applyPromptMode($option, $prompt, $event);
|
||||
$reply_resp = $this->reply($prompt);
|
||||
}
|
||||
if (($co = Adaptive::getCoroutine()) === null) {
|
||||
throw new OneBot12Exception('Coroutine is not supported yet, prompt() not works');
|
||||
@ -121,7 +124,13 @@ class BotContext implements ContextInterface
|
||||
$result = $co->suspend();
|
||||
OneBot12Adapter::removeContextPrompt($cid);
|
||||
if ($result === '') {
|
||||
throw new WaitTimeoutException($this, $timeout_prompt);
|
||||
throw new WaitTimeoutException(
|
||||
$this,
|
||||
$timeout_prompt,
|
||||
prompt_response: isset($reply_resp) && $reply_resp instanceof ActionResponse ? $reply_resp : null,
|
||||
user_event: $event,
|
||||
prompt_option: $option
|
||||
);
|
||||
}
|
||||
if ($result instanceof OneBotEvent && $result->type === 'message') {
|
||||
return $return_string ? $result->getMessageString() : $result->getMessage();
|
||||
@ -214,4 +223,30 @@ class BotContext implements ContextInterface
|
||||
array_unshift($message_segments, new MessageSegment('mention', ['user_id' => $event->getUserId()]));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 匹配更改 prompt reply 的特殊格式
|
||||
*
|
||||
* @param int $option prompt 模式
|
||||
* @param array|MessageSegment|string|\Stringable $prompt 消息或消息段
|
||||
* @param OneBotEvent $event 事件对象
|
||||
* @return array 消息段
|
||||
*/
|
||||
private function applyPromptMode(int $option, array|string|\Stringable|MessageSegment $prompt, OneBotEvent $event): array
|
||||
{
|
||||
// 先格式化消息
|
||||
if ($prompt instanceof MessageSegment) {
|
||||
$prompt = [$prompt];
|
||||
} elseif (is_string($prompt) || $prompt instanceof \Stringable) {
|
||||
$prompt = [strval($prompt)];
|
||||
}
|
||||
// 然后这里只验证 MENTION 和 QUOTE
|
||||
if (($option & ZM_PROMPT_MENTION_USER) === ZM_PROMPT_MENTION_USER) {
|
||||
$prompt = [new MessageSegment('mention', ['user_id' => $event->getUserId()]), ...$prompt];
|
||||
}
|
||||
if (($option & ZM_PROMPT_QUOTE_USER) === ZM_PROMPT_QUOTE_USER) {
|
||||
$prompt = [new MessageSegment('reply', ['message_id' => $event->getMessageId(), 'user_id' => $event->getUserId()]), ...$prompt];
|
||||
}
|
||||
return $prompt;
|
||||
}
|
||||
}
|
||||
|
||||
@ -4,13 +4,51 @@ declare(strict_types=1);
|
||||
|
||||
namespace ZM\Exception;
|
||||
|
||||
use OneBot\V12\Object\ActionResponse;
|
||||
use OneBot\V12\Object\MessageSegment;
|
||||
use OneBot\V12\Object\OneBotEvent;
|
||||
|
||||
class WaitTimeoutException extends ZMException
|
||||
{
|
||||
public $module;
|
||||
private ?array $timeout_prompt;
|
||||
|
||||
public function __construct($module, $message = '', $code = 0, \Throwable $previous = null)
|
||||
public function __construct(
|
||||
public mixed $module,
|
||||
string|\MessageSegment|array|\Stringable $timeout_prompt = '',
|
||||
private ?ActionResponse $prompt_response = null,
|
||||
private ?OneBotEvent $user_event = null,
|
||||
private int $prompt_option = ZM_PROMPT_NONE,
|
||||
\Throwable $previous = null
|
||||
) {
|
||||
parent::__construct('wait timeout!', 0, $previous);
|
||||
if ($timeout_prompt === '') {
|
||||
$this->timeout_prompt = null;
|
||||
} elseif ($timeout_prompt instanceof MessageSegment) {
|
||||
$this->timeout_prompt = [$timeout_prompt];
|
||||
} elseif (is_string($timeout_prompt) || $timeout_prompt instanceof \Stringable) {
|
||||
$this->timeout_prompt = [strval($timeout_prompt)];
|
||||
} else {
|
||||
$this->timeout_prompt = $timeout_prompt;
|
||||
}
|
||||
}
|
||||
|
||||
public function getTimeoutPrompt(): ?array
|
||||
{
|
||||
parent::__construct($message, $code, $previous);
|
||||
$this->module = $module;
|
||||
return $this->timeout_prompt;
|
||||
}
|
||||
|
||||
public function getPromptResponse(): ?ActionResponse
|
||||
{
|
||||
return $this->prompt_response;
|
||||
}
|
||||
|
||||
public function getUserEvent(): ?OneBotEvent
|
||||
{
|
||||
return $this->user_event;
|
||||
}
|
||||
|
||||
public function getPromptOption(): int
|
||||
{
|
||||
return $this->prompt_option;
|
||||
}
|
||||
}
|
||||
|
||||
@ -46,7 +46,7 @@ class Framework
|
||||
public const VERSION_ID = 669;
|
||||
|
||||
/** @var string 版本名称 */
|
||||
public const VERSION = '3.0.0-beta5';
|
||||
public const VERSION = '3.0.0-beta6';
|
||||
|
||||
/** @var array 传入的参数 */
|
||||
protected array $argv;
|
||||
|
||||
@ -343,7 +343,19 @@ class OneBot12Adapter extends ZMPlugin
|
||||
try {
|
||||
$handler->handleAll($obj);
|
||||
} catch (WaitTimeoutException $e) {
|
||||
bot()->reply($e->getMessage());
|
||||
// 这里是处理 prompt() 下超时的情况的
|
||||
if ($e->getTimeoutPrompt() === null) {
|
||||
return;
|
||||
}
|
||||
if (($e->getPromptOption() & ZM_PROMPT_TIMEOUT_MENTION_USER) === ZM_PROMPT_TIMEOUT_MENTION_USER && ($ev = $e->getUserEvent()) !== null) {
|
||||
$prompt = [MessageSegment::mention($ev->getUserId()), ...$e->getTimeoutPrompt()];
|
||||
}
|
||||
if (($e->getPromptOption() & ZM_PROMPT_TIMEOUT_QUOTE_SELF) === ZM_PROMPT_TIMEOUT_QUOTE_SELF && ($rsp = $e->getPromptResponse()) !== null && ($ev = $e->getUserEvent()) !== null) {
|
||||
$prompt = [MessageSegment::reply($rsp->data['message_id'], $ev->self['user_id']), ...$e->getTimeoutPrompt()];
|
||||
} elseif (($e->getPromptOption() & ZM_PROMPT_TIMEOUT_QUOTE_USER) === ZM_PROMPT_TIMEOUT_QUOTE_USER && ($ev = $e->getUserEvent()) !== null) {
|
||||
$prompt = [MessageSegment::reply($ev->getMessageId(), $ev->getUserId()), ...$e->getTimeoutPrompt()];
|
||||
}
|
||||
bot()->reply($prompt ?? $e->getTimeoutPrompt());
|
||||
}
|
||||
} elseif (isset($body['status'], $body['retcode'])) {
|
||||
// 如果含有 status,retcode 字段,表明是 action 的 response
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user