Как передать данные пользователя из Telegram бота в приложение Flet
При разработке связки Telegram-бота (на библиотеке telebot) и WebApp на Flet часто возникает задача синхронизации данных. Пользователь пишет боту, бот сохраняет его ID, имя и баланс монет в базу данных SQLite. Затем пользователь переходит в игру на Flet, где ему нужно показать текущее количество монет и обновлять его при нажатии кнопки. Разберём, как организовать передачу данных и обратную запись в БД.
Архитектура взаимодействия: Telegram бот, Flet WebApp и база данных
Основная сложность - Flet-приложение запускается отдельно (например, через ngrok) и не имеет прямого доступа к переменным бота. Данные нужно передавать через URL-параметры или Webhook. Рассмотрим пошагово.
Шаг 1: Инициализация пользователя в Telegram боте
Когда пользователь отправляет любое сообщение боту, используйте message.from_user.id и message.from_user.first_name. Проверьте, есть ли запись в таблице SQLite. Если нет - добавьте с coins = 0.
import sqlite3
conn = sqlite3.connect('game.db')
c = conn.cursor()
c.execute('''CREATE TABLE IF NOT EXISTS users (user TEXT, id INTEGER PRIMARY KEY, coins INTEGER)''')
user_id = message.from_user.id
c.execute('SELECT * FROM users WHERE id=?', (user_id,))
if c.fetchone() is None:
c.execute('INSERT INTO users (user, id, coins) VALUES (?, ?, 0)', (message.from_user.first_name, user_id))
conn.commit()Шаг 2: Генерация ссылки на игру с параметрами
При нажатии на кнопку в боте, формируйте URL для Flet-приложения, содержащий user_id и coins. Например, через ngrok ваш Flet-сервер доступен по адресу https://ваш-адрес.ngrok.io. Добавьте параметры: ?user_id=123&coins=0.
import telebot
from telebot.types import InlineKeyboardMarkup, InlineKeyboardButton
user_id = message.from_user.id
coins = c.execute('SELECT coins FROM users WHERE id=?', (user_id,)).fetchone()[0]
url = f'https://ваш-адрес.ngrok.io/?user_id={user_id}&coins={coins}'
keyboard = InlineKeyboardMarkup()
keyboard.add(InlineKeyboardButton('Играть', url=url))
bot.send_message(message.chat.id, 'Нажми, чтобы начать игру!', reply_markup=keyboard)Шаг 3: Получение параметров в Flet-приложении
В Flet используйте page.client_storage или напрямую разбирайте URL. Самый простой способ - передать параметры через query string и прочитать их в page.on_connect или в функции main.
import flet as ft
import urllib.parse
def main(page: ft.Page):
params = urllib.parse.parse_qs(page.platform.views[0].url.query)
user_id = int(params.get('user_id', [0])[0])
coins = int(params.get('coins', [0])[0])
coin_counter = ft.Text(f'Монеты: {coins}', size=30)
def on_click(e):
nonlocal coins
coins += 1
coin_counter.value = f'Монеты: {coins}'
# Здесь будет вызов обновления БД
update_db(user_id, coins)
page.update()
page.add(coin_counter, ft.ElevatedButton('Нажми меня!', on_click=on_click))
ft.app(target=main)Шаг 4: Обновление базы данных из Flet
Flet-приложение должно напрямую подключаться к той же базе данных SQLite. Для этого разместите файл game.db в общей папке или на сервере. При каждом нажатии кнопки вызывайте функцию обновления.
import sqlite3
def update_db(user_id, coins):
conn = sqlite3.connect('game.db')
c = conn.cursor()
c.execute('UPDATE users SET coins=? WHERE id=?', (coins, user_id))
conn.commit()
conn.close()Важно: если бот и Flet запущены на разных серверах, используйте общую базу данных (например, через SQLite на общем сетевом диске) или переходите на MySQL/PostgreSQL для одновременного доступа.
Какие базы данных лучше использовать: SQLite vs MySQL
SQLite отлично подходит для небольших проектов и тестирования. Однако при одновременных запросах от бота и Flet возможны конфликты блокировок. Рекомендуем использовать MySQL или PostgreSQL для продакшена - они поддерживают параллельные подключения и транзакции. Пример с MySQL:
import mysql.connector
conn = mysql.connector.connect(host='localhost', user='root', password='pass', database='game')Код запросов останется практически тем же, изменится только подключение.
Альтернативный подход: централизованный API-сервер
Вместо прямого доступа к БД из Flet, создайте простой HTTP-сервер (на FastAPI или Flask), который будет обрабатывать запросы на получение и обновление монет. Бот и Flet будут общаться через этот API. Это повышает безопасность и упрощает масштабирование.
Заключение
Передача данных между Telegram ботом и Flet-приложением возможна через URL-параметры. Для синхронизации используйте общую базу данных (SQLite для малых проектов, MySQL/PostgreSQL для серьёзных). Обновляйте баланс монет напрямую из Flet, подключаясь к той же БД. Не забывайте экранировать параметры и проверять ID пользователя для безопасности.