mtflute 0.1.3
mtflute: ^0.1.3 copied to clipboard
Pure-Dart Telegram MTProto client (API layer 225).
mtflute #
Pure-Dart Telegram MTProto client. No native libs, no Bot API — talks directly to Telegram's servers like Telethon, Pyrogram, gogram. Works for bots and user accounts in the same API.
Currently against Telegram API layer 225.
Highlights #
- Auth: bot tokens, phone + OTP + 2FA (SRP), string sessions, file sessions.
- Messaging: send/edit/delete/forward/pin, Markdown + HTML parse modes, reply markup builder.
- Inline buttons:
Keyboard()..row([Button.callback(...), Button.url(...)]). - Updates: socket push +
getDifferencepolling, dedup, auto-reconnect with exponential backoff. - Files: multi-worker parallel up/download, auto cross-DC sender pool, MD5 checksum for small files.
- DC migration: transparent on
USER_MIGRATE,PHONE_MIGRATE,FILE_MIGRATE, etc. - Conversation API:
client.conversation(peer).ask('Name?')for chained prompts. - Helpers:
getMe,getDialogs,getHistory,getFullUser,editMessage,forwardMessages,joinChannel, participant iteration, admin promotion, slow-mode, invites, bot commands, callback/inline query answers. - Logger with TRACE/DEBUG/INFO/WARN/ERROR levels.
Bot quickstart #
import 'package:mtflute/mtflute.dart';
Future<void> main() async {
final client = MtpClient(
appId: YOUR_API_ID,
appHash: 'YOUR_API_HASH',
sessionFile: 'bot.session', // auto-resume on next run
);
await client.loginBot('123:ABC-bot-token');
client.onMessage((msg) async {
if (msg.text == '/start') {
await msg.reply(
'**Hi!** Tap a button:',
parseMode: 'md',
buttons: (Keyboard()
..row([Button.callback('Yes', 'cb:yes'), Button.url('Docs', 'https://t.me')]))
.inline(),
);
}
});
client.onCallbackQuery((cq) async {
await cq.answer(message: 'You picked it!');
});
await client.idle(); // Ctrl+C to stop
}
User quickstart #
final client = MtpClient(
appId: YOUR_API_ID,
appHash: 'YOUR_API_HASH',
sessionFile: 'user.session',
);
await client.login(
codeCallback: (prompt) async { stdout.write(prompt); return stdin.readLineSync()!; },
passwordCallback: (prompt) async { stdout.write(prompt); return stdin.readLineSync()!; },
);
Files #
// Upload + send
await client.sendFile(
peer: peer,
file: File('photo.jpg'),
caption: 'caption',
onProgress: (cur, total) => print('${cur * 100 ~/ total}%'),
);
// Download
await client.downloadToFile(location, 'out.bin', dcId: 4, size: 12345);
Conversation #
final conv = client.conversation(peer);
final reply = await conv.ask('Whats your name?');
await conv.respond('Hi ${reply.text}!');
conv.close();
Status #
v0.1.0 — APIs may change. PRs welcome.