import 'dart:convert'; import 'package:http/http.dart' as http; class TelegramClient { final String token; final http.Client _http; final String _base; TelegramClient(this.token) : _http = http.Client(), _base = 'https://api.telegram.org/bot$token'; // Долгий polling — ждёт до timeout секунд, возвращает новые апдейты Future>> getUpdates({ required int offset, int timeout = 30, }) async { try { final response = await _http.get( Uri.parse('$_base/getUpdates?offset=$offset&timeout=$timeout&allowed_updates=["message"]'), headers: {'content-type': 'application/json'}, ).timeout(Duration(seconds: timeout + 5)); final data = jsonDecode(response.body) as Map; if (data['ok'] != true) return []; return (data['result'] as List).cast>(); } catch (_) { return []; } } Future sendMessage(int chatId, String text, {int? replyToMessageId}) async { final chunks = _splitMessage(text); for (final chunk in chunks) { final payload = { 'chat_id': chatId, 'text': chunk, 'parse_mode': 'Markdown', }; if (replyToMessageId != null) payload['reply_to_message_id'] = replyToMessageId; try { await _http.post( Uri.parse('$_base/sendMessage'), headers: {'content-type': 'application/json'}, body: jsonEncode(payload), ); } catch (_) { try { final plain = {'chat_id': chatId, 'text': chunk}; if (replyToMessageId != null) plain['reply_to_message_id'] = replyToMessageId; await _http.post( Uri.parse('$_base/sendMessage'), headers: {'content-type': 'application/json'}, body: jsonEncode(plain), ); } catch (_) {} } } } Future sendTyping(int chatId) async { try { await _http.post( Uri.parse('$_base/sendChatAction'), headers: {'content-type': 'application/json'}, body: jsonEncode({'chat_id': chatId, 'action': 'typing'}), ); } catch (_) {} } List _splitMessage(String text) { const maxLen = 4000; if (text.length <= maxLen) return [text]; final chunks = []; var start = 0; while (start < text.length) { final end = (start + maxLen).clamp(0, text.length); chunks.add(text.substring(start, end)); start = end; } return chunks; } void dispose() => _http.close(); }