Почему не получается отправить фото альбомом в библиотеке telebot через file_id и функцию InputMediaPhoto?
Я перепробовал очень много способов, как отправлять альбомы с помощью file_id
Остановился на сохранении file_id в базу данных и из нее брать эти айдишники(они записываются с самого начала при отправке фотографии), и если они совпадают с теми, которые люди отправляют, то они будут записываться в массив, но увы это не сработало, айдишники записываются отдельно друг от друга.
Если кто-то знает как сделать так, чтобы они записывались в 1 массив и выводились методом send_media_group молю о помощи и прикладываю часть кода снизу.
Правка: таблица содержит данные file_id, по типу
@bot.channel_post_handler(content_types=['photo', 'text']) #хендлер на отправку фотографий
def channelphoto(idphoto):
file_id = idphoto.photo[-1].file_id #file_id из фотографий
medcaption = idphoto.caption #нереализованная подпись для альбомов
data = sqlite3.connect('photo.txt')
cur = data.cursor()
cur.execute(" INSERT INTO photo (fileid) VALUES ('%s')" % (file_id)) #запись всех вводимых file_id до начала их использования
cur.execute("DELETE FROM photo WHERE rowid NOT IN(SELECT MIN(rowid) FROM photo GROUP BY fileid)")
data.commit()
cur.close()
data.close()
data = sqlite3.connect('photo.txt')
cur = data.cursor()
cur.execute('SELECT * FROM photo')
photo = cur.fetchall()
media_album = []
score = 0
for el1 in photo:
if file_id == el1[1]:
media_album.append(telebot.types.InputMediaPhoto(file_id)) #моя задумка с использованием базы данных
print(el1[1]) #это я пытался смотреть, что оно выводит и как именно
cur.close()
data.close()
data = sqlite3.connect('text.txt')
cur = data.cursor()
cur.execute('SELECT * FROM users')
users = cur.fetchall()
info = 0
for el in users:
info = el[1]
bot.send_media_group(info, media_album)#вывод фоток альбомом, который увы не работает. info - переменная со всеми id пользователей
cur.close()
data.close()
Ответы (1 шт):
Когда ты получаешь сообщение с несколькими фото/видео, у этого сообщения есть media_group_id, это идентификатор для всей группы
В этом коде ты сохраняешь file_id
и при попытке собрать альбом ты сравниваешь file_id самим с собой и получаешь просто массив одного элемента.
Тебе нужно сохранять media_group_idи file_id в связке и делать что-то типа
cur.execute('SELECT file_id FROM photos WHERE media_group_id = ?', (media_group_id,))
таблица albums
CREATE TABLE IF NOT EXISTS albums (
media_group_id TEXT PRIMARY KEY,
caption TEXT,
created_at REAL
)
таблица photos
CREATE TABLE IF NOT EXISTS photos (
id INTEGER PRIMARY KEY AUTOINCREMENT,
media_group_id TEXT,
file_id TEXT,
FOREIGN KEY(media_group_id) REFERENCES albums(media_group_id)
);
#функция для очистки старых альбомов
def cleanup_old_albums():
while True:
time.sleep(60) #раз в минуту
conn = sqlite3.connect('albums.db')
cur = conn.cursor()
now = time.time()
cur.execute("DELETE FROM albums WHERE created_at < ?", (now - 10,)) #удаляем старше 10 сек
conn.commit()
conn.close()
#запускаем фоновую очистку
threading.Thread(target=cleanup_old_albums, daemon=True).start()
@bot.channel_post_handler(content_types=['photo'])
def handle_channel_post(message):
file_id = message.photo[-1].file_id
caption = message.caption if message.caption else None
media_group_id = getattr(message, 'media_group_id', None)
conn = sqlite3.connect('albums.db')
cur = conn.cursor()
if media_group_id:
now = time.time()
cur.execute('''
INSERT OR IGNORE INTO albums (media_group_id, caption, created_at)
VALUES (?, ?, ?)
''', (media_group_id, caption, now))
cur.execute('''
INSERT INTO photos (media_group_id, file_id)
VALUES (?, ?)
''', (media_group_id, file_id))
conn.commit()
conn.close()
#задержка нужна потому что в там какие-то интервалы с отправкой альбома, не сильно углублялся, но по идее этого должно хватить, тк максимум 10 фотографий в альбоме
threading.Timer(1.2, send_album_if_ready, args=(media_group_id,)).start()
else:
#это если одно фото
conn.close()
send_album_to_users([file_id], caption)
def send_album_if_ready(media_group_id):
conn = sqlite3.connect('albums.db')
cur = conn.cursor()
cur.execute('SELECT file_id FROM photos WHERE media_group_id = ?', (media_group_id,))
photos = cur.fetchall()
cur.execute('SELECT caption FROM albums WHERE media_group_id = ?', (media_group_id,))
row = cur.fetchone()
caption = row[0] if row else None
conn.close()
if photos:
file_ids = [p[0] for p in photos]
send_album_to_users(file_ids, caption)
#удаляем альбом из бд после отправки
conn = sqlite3.connect('albums.db')
cur = conn.cursor()
cur.execute('DELETE FROM albums WHERE media_group_id = ?', (media_group_id,))
conn.commit()
conn.close()
def send_album_to_users(file_ids, caption=None):
if not file_ids:
return
#формируем медиа-группу
media = []
for i, fid in enumerate(file_ids):
if i == 0 and caption:
media.append(telebot.types.InputMediaPhoto(fid, caption=caption))
else:
media.append(telebot.types.InputMediaPhoto(fid))
#получаем пользователей из бд
try:
conn_users = sqlite3.connect('text.txt')
cur_users = conn_users.cursor()
cur_users.execute('SELECT user_id FROM users')
users = cur_users.fetchall()
conn_users.close()
for (user_id,) in users:
try:
bot.send_media_group(user_id, media)
except Exception as e:
print(f"Ошибка отправки альбому {user_id}: {e}")
except Exception as e:
print(f"Ошибка при получении пользователей: {e}")
