mirror of
https://github.com/lkddi/Xboard.git
synced 2026-04-24 03:57:27 +08:00
refactor: core plugins to plugins-core
This commit is contained in:
@@ -1,437 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Plugin\Telegram;
|
||||
|
||||
use App\Models\Order;
|
||||
use App\Models\Ticket;
|
||||
use App\Models\User;
|
||||
use App\Services\Plugin\AbstractPlugin;
|
||||
use App\Services\Plugin\HookManager;
|
||||
use App\Services\TelegramService;
|
||||
use App\Services\TicketService;
|
||||
use App\Utils\Helper;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class Plugin extends AbstractPlugin
|
||||
{
|
||||
protected array $commands = [];
|
||||
protected TelegramService $telegramService;
|
||||
|
||||
protected array $commandConfigs = [
|
||||
'/start' => ['description' => '开始使用', 'handler' => 'handleStartCommand'],
|
||||
'/bind' => ['description' => '绑定账号', 'handler' => 'handleBindCommand'],
|
||||
'/traffic' => ['description' => '查看流量', 'handler' => 'handleTrafficCommand'],
|
||||
'/getlatesturl' => ['description' => '获取订阅链接', 'handler' => 'handleGetLatestUrlCommand'],
|
||||
'/unbind' => ['description' => '解绑账号', 'handler' => 'handleUnbindCommand'],
|
||||
];
|
||||
|
||||
public function boot(): void
|
||||
{
|
||||
$this->telegramService = new TelegramService();
|
||||
$this->registerDefaultCommands();
|
||||
|
||||
$this->filter('telegram.message.handle', [$this, 'handleMessage'], 10);
|
||||
$this->listen('telegram.message.unhandled', [$this, 'handleUnknownCommand'], 10);
|
||||
$this->listen('telegram.message.error', [$this, 'handleError'], 10);
|
||||
$this->filter('telegram.bot.commands', [$this, 'addBotCommands'], 10);
|
||||
$this->listen('ticket.create.after', [$this, 'sendTicketNotify'], 10);
|
||||
$this->listen('ticket.reply.user.after', [$this, 'sendTicketNotify'], 10);
|
||||
$this->listen('payment.notify.success', [$this, 'sendPaymentNotify'], 10);
|
||||
}
|
||||
|
||||
public function sendPaymentNotify(Order $order): void
|
||||
{
|
||||
if (!$this->getConfig('enable_payment_notify', true)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$payment = $order->payment;
|
||||
if (!$payment) {
|
||||
Log::warning('支付通知失败:订单关联的支付方式不存在', ['order_id' => $order->id]);
|
||||
return;
|
||||
}
|
||||
|
||||
$message = sprintf(
|
||||
"💰成功收款%s元\n" .
|
||||
"———————————————\n" .
|
||||
"支付接口:%s\n" .
|
||||
"支付渠道:%s\n" .
|
||||
"本站订单:`%s`",
|
||||
$order->total_amount / 100,
|
||||
Helper::escapeMarkdown($payment->payment),
|
||||
Helper::escapeMarkdown($payment->name),
|
||||
$order->trade_no
|
||||
);
|
||||
$this->telegramService->sendMessageWithAdmin($message, true);
|
||||
}
|
||||
|
||||
public function sendTicketNotify(Ticket $ticket): void
|
||||
{
|
||||
if (!$this->getConfig('enable_ticket_notify', true)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$message = $ticket->messages()->latest()->first();
|
||||
$user = User::find($ticket->user_id);
|
||||
if (!$user)
|
||||
return;
|
||||
$user->load('plan');
|
||||
$transfer_enable = $this->transferToGBString($user->transfer_enable);
|
||||
$remaining_traffic = $this->transferToGBString($user->transfer_enable - $user->u - $user->d);
|
||||
$u = $this->transferToGBString($user->u);
|
||||
$d = $this->transferToGBString($user->d);
|
||||
$expired_at = $user->expired_at ? date('Y-m-d H:i:s', $user->expired_at) : '长期有效';
|
||||
$money = $user->balance / 100;
|
||||
$affmoney = $user->commission_balance / 100;
|
||||
$plan = $user->plan;
|
||||
$ip = request()?->ip() ?? '';
|
||||
$region = $ip ? (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) ? (new \Ip2Region())->simple($ip) : 'NULL') : '';
|
||||
$TGmessage = "📮 *工单提醒* #{$ticket->id}\n";
|
||||
$TGmessage .= "━━━━━━━━━━━━━━━━━━━━\n";
|
||||
$TGmessage .= "📧 邮箱: `{$user->email}`\n";
|
||||
$TGmessage .= "📍 位置: `{$region}`\n";
|
||||
|
||||
if ($plan) {
|
||||
$TGmessage .= "📦 套餐: `" . Helper::escapeMarkdown($plan->name) . "`\n";
|
||||
$TGmessage .= "📊 流量: `{$remaining_traffic}G / {$transfer_enable}G` (剩余/总计)\n";
|
||||
$TGmessage .= "⬆️⬇️ 已用: `{$u}G / {$d}G`\n";
|
||||
$TGmessage .= "⏰ 到期: `{$expired_at}`\n";
|
||||
} else {
|
||||
$TGmessage .= "📦 套餐: `未订购任何套餐`\n";
|
||||
}
|
||||
|
||||
$TGmessage .= "💰 余额: `{$money}元`\n";
|
||||
$TGmessage .= "💸 佣金: `{$affmoney}元`\n";
|
||||
$TGmessage .= "━━━━━━━━━━━━━━━━━━━━\n";
|
||||
$TGmessage .= "📝 *主题*: `" . Helper::escapeMarkdown($ticket->subject) . "`\n";
|
||||
$TGmessage .= "💬 *内容*: `" . Helper::escapeMarkdown($message->message) . "`";
|
||||
$this->telegramService->sendMessageWithAdmin($TGmessage, true);
|
||||
}
|
||||
|
||||
protected function registerDefaultCommands(): void
|
||||
{
|
||||
foreach ($this->commandConfigs as $command => $config) {
|
||||
$this->registerTelegramCommand($command, [$this, $config['handler']]);
|
||||
}
|
||||
|
||||
$this->registerReplyHandler('/(📮.*?工单提醒.*?#?|工单ID: ?)(\\d+)/', [$this, 'handleTicketReply']);
|
||||
}
|
||||
|
||||
public function registerTelegramCommand(string $command, callable $handler): void
|
||||
{
|
||||
$this->commands['commands'][$command] = $handler;
|
||||
}
|
||||
|
||||
public function registerReplyHandler(string $regex, callable $handler): void
|
||||
{
|
||||
$this->commands['replies'][$regex] = $handler;
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送消息给用户
|
||||
*/
|
||||
protected function sendMessage(object $msg, string $message): void
|
||||
{
|
||||
$this->telegramService->sendMessage($msg->chat_id, $message, 'markdown');
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查是否为私聊
|
||||
*/
|
||||
protected function checkPrivateChat(object $msg): bool
|
||||
{
|
||||
if (!$msg->is_private) {
|
||||
$this->sendMessage($msg, '请在私聊中使用此命令');
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取绑定的用户
|
||||
*/
|
||||
protected function getBoundUser(object $msg): ?User
|
||||
{
|
||||
$user = User::where('telegram_id', $msg->chat_id)->first();
|
||||
if (!$user) {
|
||||
$this->sendMessage($msg, '请先绑定账号');
|
||||
return null;
|
||||
}
|
||||
return $user;
|
||||
}
|
||||
|
||||
public function handleStartCommand(object $msg): void
|
||||
{
|
||||
$welcomeTitle = $this->getConfig('start_welcome_title', '🎉 欢迎使用 XBoard Telegram Bot!');
|
||||
$botDescription = $this->getConfig('start_bot_description', '🤖 我是您的专属助手,可以帮助您:\\n• 绑定您的 XBoard 账号\\n• 查看流量使用情况\\n• 获取最新订阅链接\\n• 管理账号绑定状态');
|
||||
$footer = $this->getConfig('start_footer', '💡 提示:所有命令都需要在私聊中使用');
|
||||
|
||||
$welcomeText = $welcomeTitle . "\n\n" . $botDescription . "\n\n";
|
||||
|
||||
$user = User::where('telegram_id', $msg->chat_id)->first();
|
||||
if ($user) {
|
||||
$welcomeText .= "✅ 您已绑定账号:{$user->email}\n\n";
|
||||
$welcomeText .= $this->getConfig('start_unbind_guide', '📋 可用命令:\\n/traffic - 查看流量使用情况\\n/getlatesturl - 获取订阅链接\\n/unbind - 解绑账号');
|
||||
} else {
|
||||
$welcomeText .= $this->getConfig('start_bind_guide', '🔗 请先绑定您的 XBoard 账号:\\n1. 登录您的 XBoard 账户\\n2. 复制您的订阅链接\\n3. 发送 /bind + 订阅链接') . "\n\n";
|
||||
$welcomeText .= $this->getConfig('start_bind_commands', '📋 可用命令:\\n/bind [订阅链接] - 绑定账号');
|
||||
}
|
||||
|
||||
$welcomeText .= "\n\n" . $footer;
|
||||
$welcomeText = str_replace('\\n', "\n", $welcomeText);
|
||||
|
||||
$this->sendMessage($msg, $welcomeText);
|
||||
}
|
||||
|
||||
public function handleMessage(bool $handled, array $data): bool
|
||||
{
|
||||
list($msg) = $data;
|
||||
if ($handled)
|
||||
return $handled;
|
||||
|
||||
try {
|
||||
return match ($msg->message_type) {
|
||||
'message' => $this->handleCommandMessage($msg),
|
||||
'reply_message' => $this->handleReplyMessage($msg),
|
||||
default => false
|
||||
};
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Telegram 命令处理意外错误', [
|
||||
'command' => $msg->command ?? 'unknown',
|
||||
'chat_id' => $msg->chat_id ?? 'unknown',
|
||||
'error' => $e->getMessage(),
|
||||
'file' => $e->getFile(),
|
||||
'line' => $e->getLine()
|
||||
]);
|
||||
|
||||
if (isset($msg->chat_id)) {
|
||||
$this->telegramService->sendMessage($msg->chat_id, '系统繁忙,请稍后重试');
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
protected function handleCommandMessage(object $msg): bool
|
||||
{
|
||||
if (!isset($this->commands['commands'][$msg->command])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
call_user_func($this->commands['commands'][$msg->command], $msg);
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function handleReplyMessage(object $msg): bool
|
||||
{
|
||||
if (!isset($this->commands['replies'])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach ($this->commands['replies'] as $regex => $handler) {
|
||||
if (preg_match($regex, $msg->reply_text, $matches)) {
|
||||
call_user_func($handler, $msg, $matches);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function handleUnknownCommand(array $data): void
|
||||
{
|
||||
list($msg) = $data;
|
||||
if (!$msg->is_private || $msg->message_type !== 'message')
|
||||
return;
|
||||
|
||||
$helpText = $this->getConfig('help_text', '未知命令,请查看帮助');
|
||||
$this->telegramService->sendMessage($msg->chat_id, $helpText);
|
||||
}
|
||||
|
||||
public function handleError(array $data): void
|
||||
{
|
||||
list($msg, $e) = $data;
|
||||
Log::error('Telegram 消息处理错误', [
|
||||
'chat_id' => $msg->chat_id ?? 'unknown',
|
||||
'command' => $msg->command ?? 'unknown',
|
||||
'message_type' => $msg->message_type ?? 'unknown',
|
||||
'error' => $e->getMessage(),
|
||||
'file' => $e->getFile(),
|
||||
'line' => $e->getLine()
|
||||
]);
|
||||
}
|
||||
|
||||
public function handleBindCommand(object $msg): void
|
||||
{
|
||||
if (!$this->checkPrivateChat($msg)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$subscribeUrl = $msg->args[0] ?? null;
|
||||
if (!$subscribeUrl) {
|
||||
$this->sendMessage($msg, '参数有误,请携带订阅地址发送');
|
||||
return;
|
||||
}
|
||||
|
||||
$token = $this->extractTokenFromUrl($subscribeUrl);
|
||||
if (!$token) {
|
||||
$this->sendMessage($msg, '订阅地址无效');
|
||||
return;
|
||||
}
|
||||
|
||||
$user = User::where('token', $token)->first();
|
||||
if (!$user) {
|
||||
$this->sendMessage($msg, '用户不存在');
|
||||
return;
|
||||
}
|
||||
|
||||
if ($user->telegram_id) {
|
||||
$this->sendMessage($msg, '该账号已经绑定了Telegram账号');
|
||||
return;
|
||||
}
|
||||
|
||||
$user->telegram_id = $msg->chat_id;
|
||||
if (!$user->save()) {
|
||||
$this->sendMessage($msg, '设置失败');
|
||||
return;
|
||||
}
|
||||
|
||||
HookManager::call('user.telegram.bind.after', [$user]);
|
||||
$this->sendMessage($msg, '绑定成功');
|
||||
}
|
||||
|
||||
protected function extractTokenFromUrl(string $url): ?string
|
||||
{
|
||||
$parsedUrl = parse_url($url);
|
||||
|
||||
if (isset($parsedUrl['query'])) {
|
||||
parse_str($parsedUrl['query'], $query);
|
||||
if (isset($query['token'])) {
|
||||
return $query['token'];
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($parsedUrl['path'])) {
|
||||
$pathParts = explode('/', trim($parsedUrl['path'], '/'));
|
||||
$lastPart = end($pathParts);
|
||||
return $lastPart ?: null;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function handleTrafficCommand(object $msg): void
|
||||
{
|
||||
if (!$this->checkPrivateChat($msg)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$user = $this->getBoundUser($msg);
|
||||
if (!$user) {
|
||||
return;
|
||||
}
|
||||
|
||||
$transferUsed = $user->u + $user->d;
|
||||
$transferTotal = $user->transfer_enable;
|
||||
$transferRemaining = $transferTotal - $transferUsed;
|
||||
$usagePercentage = $transferTotal > 0 ? ($transferUsed / $transferTotal) * 100 : 0;
|
||||
|
||||
$text = sprintf(
|
||||
"📊 流量使用情况\n\n已用流量:%sG\n总流量:%sG\n剩余流量:%sG\n使用率:%.2f%%",
|
||||
$this->transferToGBString($transferUsed),
|
||||
$this->transferToGBString($transferTotal),
|
||||
$this->transferToGBString($transferRemaining),
|
||||
$usagePercentage
|
||||
);
|
||||
|
||||
$this->sendMessage($msg, $text);
|
||||
}
|
||||
|
||||
public function handleGetLatestUrlCommand(object $msg): void
|
||||
{
|
||||
if (!$this->checkPrivateChat($msg)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$user = $this->getBoundUser($msg);
|
||||
if (!$user) {
|
||||
return;
|
||||
}
|
||||
|
||||
$subscribeUrl = Helper::getSubscribeUrl($user->token);
|
||||
$text = sprintf("🔗 您的订阅链接:\n\n%s", $subscribeUrl);
|
||||
|
||||
$this->sendMessage($msg, $text);
|
||||
}
|
||||
|
||||
public function handleUnbindCommand(object $msg): void
|
||||
{
|
||||
if (!$this->checkPrivateChat($msg)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$user = $this->getBoundUser($msg);
|
||||
if (!$user) {
|
||||
return;
|
||||
}
|
||||
|
||||
$user->telegram_id = null;
|
||||
if (!$user->save()) {
|
||||
$this->sendMessage($msg, '解绑失败');
|
||||
return;
|
||||
}
|
||||
|
||||
$this->sendMessage($msg, '解绑成功');
|
||||
}
|
||||
|
||||
public function handleTicketReply(object $msg, array $matches): void
|
||||
{
|
||||
$user = $this->getBoundUser($msg);
|
||||
if (!$user) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isset($matches[2]) || !is_numeric($matches[2])) {
|
||||
Log::warning('Telegram 工单回复正则未匹配到工单ID', ['matches' => $matches, 'msg' => $msg]);
|
||||
$this->sendMessage($msg, '未能识别工单ID,请直接回复工单提醒消息。');
|
||||
return;
|
||||
}
|
||||
|
||||
$ticketId = (int) $matches[2];
|
||||
$ticket = Ticket::where('id', $ticketId)->first();
|
||||
if (!$ticket) {
|
||||
$this->sendMessage($msg, '工单不存在');
|
||||
return;
|
||||
}
|
||||
|
||||
$ticketService = new TicketService();
|
||||
$ticketService->replyByAdmin(
|
||||
$ticketId,
|
||||
$msg->text,
|
||||
$user->id
|
||||
);
|
||||
|
||||
$this->sendMessage($msg, "工单 #{$ticketId} 回复成功");
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加 Bot 命令到命令列表
|
||||
*/
|
||||
public function addBotCommands(array $commands): array
|
||||
{
|
||||
foreach ($this->commandConfigs as $command => $config) {
|
||||
$commands[] = [
|
||||
'command' => $command,
|
||||
'description' => $config['description']
|
||||
];
|
||||
}
|
||||
|
||||
return $commands;
|
||||
}
|
||||
|
||||
private function transferToGBString(float $transfer_enable, int $decimals = 2): string
|
||||
{
|
||||
return number_format(Helper::transferToGB($transfer_enable), $decimals, '.', '');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,84 +0,0 @@
|
||||
# Telegram 插件
|
||||
|
||||
XBoard 的 Telegram Bot 插件,提供用户账号绑定、流量查询、订阅链接获取等功能。
|
||||
|
||||
## 功能特性
|
||||
|
||||
- ✅ 工单通知功能(可配置开关)
|
||||
- ✅ 支付通知功能(可配置开关)
|
||||
- ✅ 用户账号绑定/解绑
|
||||
- ✅ 流量使用情况查询
|
||||
- ✅ 订阅链接获取
|
||||
- ✅ 工单回复支持
|
||||
|
||||
## 可用命令
|
||||
|
||||
### `/start` - 开始使用
|
||||
|
||||
欢迎新用户并显示帮助信息,支持动态配置。
|
||||
|
||||
### `/bind` - 绑定账号
|
||||
|
||||
绑定用户的 XBoard 账号到 Telegram。
|
||||
|
||||
```
|
||||
/bind [订阅链接]
|
||||
```
|
||||
|
||||
### `/traffic` - 查看流量
|
||||
|
||||
查看当前绑定账号的流量使用情况。
|
||||
|
||||
### `/getlatesturl` - 获取订阅链接
|
||||
|
||||
获取最新的订阅链接。
|
||||
|
||||
### `/unbind` - 解绑账号
|
||||
|
||||
解绑当前 Telegram 账号与 XBoard 账号的关联。
|
||||
|
||||
## 配置选项
|
||||
|
||||
### 基础配置
|
||||
|
||||
| 配置项 | 类型 | 默认值 | 说明 |
|
||||
| ------------ | ------- | ------------------------------------------------------------------------------------------ | -------------------- |
|
||||
| `auto_reply` | boolean | true | 是否自动回复未知命令 |
|
||||
| `help_text` | text | '请使用以下命令:\\n/bind - 绑定账号\\n/traffic - 查看流量\\n/getlatesturl - 获取最新链接' | 未知命令的回复文本 |
|
||||
|
||||
### `/start` 命令动态配置
|
||||
|
||||
| 配置项 | 类型 | 说明 |
|
||||
| ----------------------- | ---- | ------------------------ |
|
||||
| `start_welcome_title` | text | 欢迎标题 |
|
||||
| `start_bot_description` | text | 机器人功能介绍 |
|
||||
| `start_bind_guide` | text | 未绑定用户的绑定指导 |
|
||||
| `start_unbind_guide` | text | 已绑定用户显示的命令列表 |
|
||||
| `start_bind_commands` | text | 未绑定用户显示的命令列表 |
|
||||
| `start_footer` | text | 底部提示信息 |
|
||||
|
||||
### 工单通知配置
|
||||
|
||||
| 配置项 | 类型 | 默认值 | 说明 |
|
||||
| ---------------------- | ------- | ------ | -------------------- |
|
||||
| `enable_ticket_notify` | boolean | true | 是否开启工单通知功能 |
|
||||
|
||||
### 支付通知配置
|
||||
|
||||
| 配置项 | 类型 | 默认值 | 说明 |
|
||||
| ----------------------- | ------- | ------ | -------------------- |
|
||||
| `enable_payment_notify` | boolean | true | 是否开启支付通知功能 |
|
||||
|
||||
## 使用流程
|
||||
|
||||
### 新用户使用流程
|
||||
|
||||
1. 用户首次使用 Bot,发送 `/start`
|
||||
2. 根据提示绑定账号:`/bind [订阅链接]`
|
||||
3. 绑定成功后即可使用其他功能
|
||||
|
||||
### 日常使用流程
|
||||
|
||||
1. 查看流量:`/traffic`
|
||||
2. 获取订阅链接:`/getlatesturl`
|
||||
3. 管理绑定:`/unbind`
|
||||
@@ -1,66 +0,0 @@
|
||||
{
|
||||
"name": "Telegram Bot 集成",
|
||||
"code": "telegram",
|
||||
"version": "1.0.1",
|
||||
"description": "Telegram Bot 消息处理和命令系统",
|
||||
"author": "XBoard Team",
|
||||
"require": {
|
||||
"xboard": ">=1.0.0"
|
||||
},
|
||||
"config": {
|
||||
"enable_ticket_notify": {
|
||||
"type": "boolean",
|
||||
"default": true,
|
||||
"label": "开启工单通知",
|
||||
"description": "是否开启工单创建和回复的 Telegram 通知功能"
|
||||
},
|
||||
"enable_payment_notify": {
|
||||
"type": "boolean",
|
||||
"default": true,
|
||||
"label": "开启支付通知",
|
||||
"description": "是否开启支付成功的 Telegram 通知功能"
|
||||
},
|
||||
"start_welcome_title": {
|
||||
"type": "string",
|
||||
"default": "🎉 欢迎使用 XBoard Telegram Bot!",
|
||||
"label": "欢迎标题",
|
||||
"description": "/start 命令显示的欢迎标题"
|
||||
},
|
||||
"start_bot_description": {
|
||||
"type": "text",
|
||||
"default": "🤖 我是您的专属助手,可以帮助您:\\n• 绑定您的 XBoard 账号\\n• 查看流量使用情况\\n• 获取最新订阅链接\\n• 管理账号绑定状态",
|
||||
"label": "机器人描述",
|
||||
"description": "/start 命令显示的机器人功能介绍"
|
||||
},
|
||||
"start_bind_guide": {
|
||||
"type": "text",
|
||||
"default": "🔗 请先绑定您的 XBoard 账号:\\n1. 登录您的 XBoard 账户\\n2. 复制您的订阅链接\\n3. 发送 /bind + 订阅链接",
|
||||
"label": "绑定指导",
|
||||
"description": "未绑定用户显示的绑定指导文本"
|
||||
},
|
||||
"start_unbind_guide": {
|
||||
"type": "text",
|
||||
"default": "📋 可用命令:\\n/traffic - 查看流量使用情况\\n/getlatesturl - 获取订阅链接\\n/unbind - 解绑账号",
|
||||
"label": "已绑定用户命令列表",
|
||||
"description": "已绑定用户显示的命令列表"
|
||||
},
|
||||
"start_bind_commands": {
|
||||
"type": "text",
|
||||
"default": "📋 可用命令:\\n/bind [订阅链接] - 绑定账号",
|
||||
"label": "未绑定用户命令列表",
|
||||
"description": "未绑定用户显示的命令列表"
|
||||
},
|
||||
"start_footer": {
|
||||
"type": "text",
|
||||
"default": "💡 提示:所有命令都需要在私聊中使用",
|
||||
"label": "底部提示",
|
||||
"description": "/start 命令底部的提示信息"
|
||||
},
|
||||
"help_text": {
|
||||
"type": "text",
|
||||
"default": "请使用以下命令:\\n/bind - 绑定账号\\n/traffic - 查看流量\\n/getlatesturl - 获取最新链接",
|
||||
"label": "帮助文本",
|
||||
"description": "未知命令时显示的帮助文本"
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user