Как бороться с превышением в 64 байта API в callback_data (PyTelegramBotAPI)
Пишу бота для отслеживания посылок. Когда юзер отправляет трекномер ему возвращается 3 переменные(Индекс, Статус, Трекномер), появляется кнопка отследить посылку и мне надо передать эти 3 переменные в call.data, но тут появляется проблема, существует ограничение в 64 байта для call.data, я просто не могу передать так много переменных, а мне очень нужно их передать, что можно придумать? Пытался преобразовать все переменные в 1 кортеж, дабы сократить размер, но не прокатило.
Ошибка: A request to the Telegram API was unsuccessful. Error code: 400. Description: Bad Request: BUTTON_DATA_INVALID
#main
track = message.text
bot.send_message(message.chat.id,f'{st,ind}',reply_markup=trackme(ind,st,track))
#keyboard
def trackme(ind,st,track):
data = (ind,st,track)
print(data.__sizeof__())
trackme = types.InlineKeyboardMarkup()
button = types.InlineKeyboardButton(text="Отслеживать посылку", callback_data=f"trackme-{data}")
trackme.row(button)
return trackme
Как можно в def trackme() передать все 3 переменные по нажатию кнопки "Отслеживать посылку"
Ответы (1 шт):
Когда юзер отправляет трекномер ему возвращается 3 переменные(Индекс, Статус, Трекномер), появляется кнопка отследить посылку и мне надо передать эти 3 переменные в call.data, но тут появляется проблема, существует ограничение в 64 байта для call.data
Если для идентификации нужно несколько полей, что не влезают в ограничение, то нужно еще поле для привязки.
Я бы хранил эти данные в базе данных. И привязывал их к одним данным: id или guid
Например, завел бы таблицу Track с полями:
id INTEGER PRIMARY KEYindex TEXTstatus TEXTnumber TEXT- Уникальный индекс для полей
index+number. Полеstatus, наверняка, меняется, поэтому его не включаем.
Тогда, имея index и number можно проверить есть ли посылка в базе. И по id, который можно в callback-data положить, можно получить информацию по посылке
Для peewee та таблица могла бы выглядеть так:
import time
# pip install peewee
from peewee import Model, TextField
from playhouse.sqliteq import SqliteQueueDatabase
DB_FILE_NAME = 'db.sqlite'
# This working with multithreading
# SOURCE: http://docs.peewee-orm.com/en/latest/peewee/playhouse.html#sqliteq
db = SqliteQueueDatabase(
DB_FILE_NAME,
pragmas={
'foreign_keys': 1,
'journal_mode': 'wal', # WAL-mode
'cache_size': -1024 * 64 # 64MB page-cache
},
use_gevent=False, # Use the standard library "threading" module.
autostart=True,
queue_max_size=64, # Max. # of pending writes that can accumulate.
results_timeout=5.0, # Max. time to wait for query to be executed.
)
class BaseModel(Model):
class Meta:
database = db
class Track(BaseModel):
index = TextField()
status = TextField()
number = TextField()
class Meta:
indexes = (
(('index', 'number'), True),
)
db.connect()
db.create_tables([Track])
# Задержка в 50мс, чтобы дать время на запуск SqliteQueueDatabase и создание таблиц
# Т.к. в SqliteQueueDatabase запросы на чтение выполняются сразу, а на запись попадают в очередь
time.sleep(0.050)
index = '1111'
number = '2222'
status = 'Ready'
track = Track.get_or_none(index=index, number=number)
print(track)
# None
track = Track.create(index=index, number=number, status=status)
print(track)
# 1
Это простая реализация с многопоточным SQLite, которую использовал в некоторых ботах. Для чего-то более сложного можно перейти поменяв db, например на postgres