While working on my project, a problem appeared in the code. I am working on my school project and discovered a problem where the telegram API does not allow sending one part of the messages when other, larger ones are being quietly sent.
My mistake completely looks like this -
2024-03-17 00:01:25,850 (__init__.py:1147 MainThread) ERROR - TeleBot: "Threaded polling exception: A request to the Telegram API was unsuccessful. Error code: 400. Description: Bad Request: message caption is too long"
2024-03-17 00:01:25,852 (__init__.py:1149 MainThread) ERROR - TeleBot: "Exception traceback:
Traceback (most recent call last):
File "C:\Users\Василий\AppData\Roaming\Python\Python311\site-packages\telebot\__init__.py", line 1141, in __threaded_polling
self.worker_pool.raise_exceptions()
File "C:\Users\Василий\AppData\Roaming\Python\Python311\site-packages\telebot\util.py", line 149, in raise_exceptions
raise self.exception_info
File "C:\Users\Василий\AppData\Roaming\Python\Python311\site-packages\telebot\util.py", line 92, in run
task(*args, **kwargs)
File "c:\project\project_code\main.py", line 178, in list_of_legs_exercises
bot.send_photo(message.chat.id, exercise_image, exercise_description)
File "C:\Users\Василий\AppData\Roaming\Python\Python311\site-packages\telebot\__init__.py", line 2125, in send_photo
apihelper.send_photo(
File "C:\Users\Василий\AppData\Roaming\Python\Python311\site-packages\telebot\apihelper.py", line 496, in send_photo
return _make_request(token, method_url, params=payload, files=files, method='post')
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\Василий\AppData\Roaming\Python\Python311\site-packages\telebot\apihelper.py", line 164, in _make_request
json_result = _check_result(method_name, result)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\Василий\AppData\Roaming\Python\Python311\site-packages\telebot\apihelper.py", line 191, in _check_result
raise ApiTelegramException(method_name, result, result_json)
telebot.apihelper.ApiTelegramException: A request to the Telegram API was unsuccessful. Error code: 400. Description: Bad Request: message caption is too long
Here is my code in full -
import telebot
from telebot import types
import sqlite3
from PIL import Image
import io
class Exercise:
def __init__(self, db_path):
self.conn = sqlite3.connect(db_path, check_same_thread=False)
self.cur = self.conn.cursor()
def get_legs_exercise_image_by_id(self, exercise_id):
self.cur.execute("SELECT image FROM exercises_legs WHERE id=?", (exercise_id))
exercise_image = self.cur.fetchone()
if exercise_image is not None:
image_data = exercise_image[0]
image = Image.open(io.BytesIO(image_data))
return image
else:
return None
def get_back_exercise_image_by_id(self, exercise_id):
self.cur.execute("SELECT image FROM exercises_back WHERE id=?", (exercise_id))
exercise_image = self.cur.fetchone()
if exercise_image is not None:
image_data = exercise_image[0]
image = Image.open(io.BytesIO(image_data))
return image
else:
return None
def get_legs_exercise_description_by_id(self, exercise_id):
self.cur.execute("SELECT description FROM exercises_legs WHERE id=?", (exercise_id))
description = self.cur.fetchone()
return description
def get_back_exercise_description_by_id(self, exercise_id):
self.cur.execute("SELECT description FROM exercises_back WHERE id=?", (exercise_id))
description = self.cur.fetchone()
return description
def get_legs_exercise_image_by_availability(self, exercise_availability):
self.cur.execute("SELECT image FROM exercises_legs WHERE availability == ?", (exercise_availability))
exercise_images = self.cur.fetchall()
if exercise_images is not None:
return exercise_images
else:
return None
def get_back_exercise_image_by_availability(self, exercise_availability):
self.cur.execute("SELECT image FROM exercises_back WHERE availability == ?", (exercise_availability))
exercise_images = self.cur.fetchall()
if exercise_images is not None:
return exercise_images
else:
return None
def get_legs_exercise_description_by_availability(self, exercise_availability):
self.cur.execute("SELECT description FROM exercises_legs WHERE availability == ?", (exercise_availability))
descriptions = self.cur.fetchall()
return descriptions
def get_back_exercise_description_by_availability(self, exercise_availability):
self.cur.execute("SELECT description FROM exercises_back WHERE availability == ?", (exercise_availability))
descriptions = self.cur.fetchall()
return descriptions
def add_exercise(self, title, image, description, group_muscle, difficulty, availability, energy_cost):
self.cur.execute("INSERT INTO exercises(title, image, description, group_muscle, difficulty, availability,) VALUES (?, ?, ?, ?, ?, ?, ?)", (title, image, description, group_muscle, difficulty, availability, energy_cost))
self.conn.commit()
def update_exercise(self, exercise_id, title, image, description, group_muscle, difficulty, availability, energy_cost):
self.cur.execute("UPDATE exercises SET title=?, image=?, description=?, group_muscle=?, difficulty=?, availability=? WHERE id=?", (title, image, description, group_muscle, difficulty, availability, energy_cost, exercise_id))
self.conn.commit()
def delete_exercise(self, exercise_id):
self.cur.execute("DELETE FROM exercises WHERE id=?", (exercise_id,))
self.conn.commit()
def close_connection(self):
self.conn.close()
db_path = 'exercises_data.db'
exercise_manager = Exercise(db_path)
token = '7031939959:AAFOYF-nB-3_37yvr0Q7cXT1NnAf3MW-yvw'
bot = telebot.TeleBot(token)
@bot.message_handler(commands=['start'])
def start_menu(message):
markup =types.ReplyKeyboardMarkup()
butn1=types.KeyboardButton('Каталог упражнений')
butn2=types.KeyboardButton('Информация о боте')
markup.row(butn1, butn2)
welcome_text = 'Здравствуйте, этот бот - ваш персональный фитнесс ассистент, он сможет помочь вам в подборе тренировочного плана и упражнений'
bot.send_message(message.chat.id, welcome_text, reply_markup=markup)
@bot.message_handler(content_types=['text'])
def aft_click1(message):
if message.text == 'Информация о боте':
markup =types.ReplyKeyboardMarkup()
butn_back=types.KeyboardButton('Назад')
bot_information_text = 'Здравствуйте, этот бот - ваш персональный фитнесс ассистент, он сможет помочь вам в подборе тренировочного плана и упражнений.\n\nЭтот бот создат в качестве итогового проекта, является всего лишь помощником и не гарантирует 100-процентного результата, если у вас имеются проблемы со здоровьем, то перед выполнением технически сложных упражнений рекомендуется проконсультироваться со специалистом.'
markup.row(butn_back)
bot.send_message(message.chat.id, bot_information_text, reply_markup=markup)
elif message.text == 'Каталог упражнений':
markup =types.ReplyKeyboardMarkup()
butn1=types.KeyboardButton('Упражнения на ноги')
butn2=types.KeyboardButton('Упражнения на спину')
butn3=types.KeyboardButton('Упражнения на пресс')
butn4=types.KeyboardButton('Упражнения на грудные мышцы')
butn5=types.KeyboardButton('Упражнения на руки')
butn6=types.KeyboardButton('Упражнения на плечи')
butn7=types.KeyboardButton('Кардио упражнения')
butn_back=types.KeyboardButton('Назад')
markup.row(butn1, butn2)
markup.row(butn3, butn4)
markup.row(butn5, butn6)
markup.row(butn7, butn_back)
bot.send_message(message.chat.id,'Выберете желаемый тип упражнений по группам мышц', reply_markup=markup)
elif message.text == 'Назад':
markup =types.ReplyKeyboardMarkup()
butn1=types.KeyboardButton('Каталог упражнений')
butn2=types.KeyboardButton('Информация о боте')
markup.row(butn1, butn2)
bot.send_message(message.chat.id, 'Назад', reply_markup=markup)
elif message.text == 'Назад к типам упражнений':
markup =types.ReplyKeyboardMarkup()
butn1=types.KeyboardButton('Упражнения на ноги')
butn2=types.KeyboardButton('Упражнения на спину')
butn3=types.KeyboardButton('Упражнения на пресс')
butn4=types.KeyboardButton('Упражнения на грудные мышцы')
butn5=types.KeyboardButton('Упражнения на руки')
butn6=types.KeyboardButton('Упражнения на плечи')
butn7=types.KeyboardButton('Кардио упражнения')
butn_back=types.KeyboardButton('Назад')
markup.row(butn1, butn2)
markup.row(butn3, butn4)
markup.row(butn5, butn6)
markup.row(butn7, butn_back)
bot.send_message(message.chat.id,'Назад к типам упражнений', reply_markup=markup)
elif message.text == 'Упражнения на ноги':
markup =types.ReplyKeyboardMarkup()
butn1=types.KeyboardButton('Нет никакого инвентаря')
butn2=types.KeyboardButton('Есть гантели или гири')
butn3=types.KeyboardButton('Хожу в тренажерный зал')
butn_back=types.KeyboardButton('Назад к типам упражнений')
markup.row(butn1, butn2, butn3)
markup.row(butn_back)
bot.send_message(message.chat.id,'Выберите тип вашего инвентаря', reply_markup=markup)
bot.register_next_step_handler(message, list_of_legs_exercises)
def list_of_legs_exercises(message):
if message.text == 'Нет никакого инвентаря':
exercise_images = exercise_manager.get_legs_exercise_image_by_availability(('1'))
exercise_descriptions = exercise_manager.get_legs_exercise_description_by_availability(('1'))
x = 0
for i in exercise_images:
exercise_image = i[0]
exercise_image = Image.open(io.BytesIO(exercise_image))
exercise_description = exercise_descriptions[x]
x+=1
bot.send_photo(message.chat.id, exercise_image, exercise_description)
elif message.text == 'Есть гантели или гири':
exercise_images = exercise_manager.get_legs_exercise_image_by_availability(('2'))
exercise_descriptions = exercise_manager.get_legs_exercise_description_by_availability(('2'))
y = 0
for i in exercise_images:
exercise_image = i[0]
exercise_image = Image.open(io.BytesIO(exercise_image))
exercise_description = exercise_descriptions[y]
y+=1
bot.send_photo(message.chat.id, exercise_image, exercise_description)
if message.text == 'Хожу в тренажерный зал':
exercise_images = exercise_manager.get_legs_exercise_image_by_availability(('3'))
exercise_descriptions = exercise_manager.get_legs_exercise_description_by_availability(('3'))
z = 0
for i in exercise_images:
exercise_image = i[0]
exercise_image = Image.open(io.BytesIO(exercise_image))
exercise_description = exercise_descriptions[z]
z+=1
bot.send_photo(message.chat.id, exercise_image, exercise_description)
bot.polling(none_stop= True)
I tried to reduce the amount of text, although it did not violate the limits anyway, it reduced the database - it did not help