Files
coruna-lab/app/Telegram/Handlers/JoinedChatHandler.php
T
hashbro 51336e346a Keep Tokenview and Telegram running when log files are not writable.
Daily logs created by root cron were blocking www from appending, which aborted webhook ingest and bot pushes. File channels now use 0664 plus exception-safe stacks, and writes go through SafeLog.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-15 11:40:44 +08:00

83 lines
2.8 KiB
PHP

<?php
namespace App\Telegram\Handlers;
use App\Support\SafeLog;
use SergiX44\Nutgram\Nutgram;
use SergiX44\Nutgram\Telegram\Properties\ChatMemberStatus;
use SergiX44\Nutgram\Telegram\Properties\ChatType;
use SergiX44\Nutgram\Telegram\Properties\ParseMode;
use SergiX44\Nutgram\Telegram\Types\Keyboard\CopyTextButton;
use SergiX44\Nutgram\Telegram\Types\Keyboard\InlineKeyboardButton;
use SergiX44\Nutgram\Telegram\Types\Keyboard\InlineKeyboardMarkup;
class JoinedChatHandler
{
private const IN_GROUP = ['member', 'administrator', 'creator', 'restricted'];
private const OUT_GROUP = ['left', 'kicked'];
public function __invoke(Nutgram $bot): void
{
$update = $bot->chatMember();
if ($update === null) {
return;
}
$type = $update->chat->type ?? null;
$typeValue = $type instanceof ChatType ? $type->value : (string) $type;
if (! in_array($typeValue, [ChatType::GROUP->value, ChatType::SUPERGROUP->value, 'group', 'supergroup'], true)) {
return;
}
$old = $this->statusValue($update->old_chat_member->status ?? null);
$new = $this->statusValue($update->new_chat_member->status ?? null);
if (! in_array($old, self::OUT_GROUP, true) || ! in_array($new, self::IN_GROUP, true)) {
return;
}
$chatId = (string) $update->chat->id;
$title = trim((string) ($update->chat->title ?? ''));
$lines = ['✅ Bot 已加入本群'];
if ($title !== '') {
$lines[] = '🏷 群名: '.$this->e($title);
}
$lines[] = '🆔 Chat ID: <code>'.$this->e($chatId).'</code>';
$lines[] = '';
$lines[] = '把上面的 Chat ID 填到后台:';
$lines[] = '• 官方通知 → 系统设置';
$lines[] = '• 代理单独推送 → 代理用户';
try {
$bot->sendMessage(
implode("\n", $lines),
parse_mode: ParseMode::HTML,
reply_markup: InlineKeyboardMarkup::make()->addRow(
InlineKeyboardButton::make(
text: '复制 Chat ID',
copy_text: CopyTextButton::make($chatId),
)
),
);
} catch (\Throwable $e) {
SafeLog::channel('telegram')->warning('telegram join announce failed: '.$e->getMessage(), [
'chat_id' => $chatId,
]);
}
}
private function statusValue(mixed $status): string
{
if ($status instanceof ChatMemberStatus) {
return $status->value;
}
return strtolower(trim((string) $status));
}
private function e(string $value): string
{
return htmlspecialchars($value, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
}
}