async def _send_album(self: 'TelegramClient', entity, files, caption='',
formatting_entities=None,
progress_callback=None, reply_to=None,
parse_mode=(), silent=None, schedule=None,
supports_streaming=None, clear_draft=None,
force_document=False, background=None, ttl=None):
formatted_entities
result = []
while file:
result += await self._send_album(
entity, file[:10], caption=captions[:10], formatting_entities=formatting_entities,
progress_callback=used_callback, reply_to=reply_to,
parse_mode=parse_mode, silent=silent, schedule=schedule,
supports_streaming=supports_streaming, clear_draft=clear_draft,
force_document=force_document, background=background,
)
file = file[10:]
captions = captions[10:]
sent_count += 10
return result
formatted_entities
к первому сообщению, если оно содержит текст:if captions and captions[0]:
captions[0] = (captions[0][0], formatting_entities)
getpass.getpass()
не работает в консоли PyCharm в которой запускается бот, на этом месте программа и зависает.password: typing.Union[typing.Callable[[], str], str] = lambda: getpass.getpass('Please enter your password: '),
наpassword: typing.Union[typing.Callable[[], str], str] = lambda: input('Please enter your password: '),
start()
, то он должен работать, НО при проверке кода, внутри того же файла, атрибут password
почему-то всеравно остаётся lambda-функцией. Позже попробую найти почему так и как это исправить. from aiogram import Router, types, F
from aiogram.utils import formatting as fmt
# Редактор постов канала в отдельном роутере
router = Router()
# Это понадобится, чтобы в медиагруппе редактировалось только описание первого медиа
check_mg = set()
#Фильтры: проверим что пост не переслан и что это медиа имеющие caption
@router.channel_post(~F.forward_from_chat, ~F.forward_from, (F.text | F.photo | F.video | F.animation | F.document))
async def redactor(message: types.Message):
# Собираем текстовые данные из поста
text = message.text or message.caption or ''
# Собираем те entities которые уже есть в посте
ent = message.entities or message.caption_entities or []
# Удаляем встроенные ссылки если они есть
ent = [e for e in ent if e.type != 'text_link']
# Через инструмент formatting создаём внешний вид будущего поста
content = fmt.Text(
# Старый текст
text,
'\n\n',
# В моём случае я добавляю три ссылки на канал, чат и админа с эмодзи-разделителем
fmt.as_line(
fmt.Bold(fmt.TextLink("Канал", url='https://t.me/1')),
fmt.Bold(fmt.TextLink("Чат", url='https://t.me/2')),
fmt.Bold(fmt.TextLink("Админ", url='https://t.me/3')),
# Тут эмодзи который будет между ссылками
sep=' '
)
)
# Собираем новый текст и новые entities в кучу
text, new_ent = content.render()
# Тут расписывать не буду, разные проверки и разные варианты отправки отредактированного сообщения
if message.text is not None:
if len(text) <= 4096:
await message.edit_text(text, entities=ent + new_ent, disable_web_page_preview=True)
else:
print("Can't edit Text, length exceeded.")
elif message.media_group_id is None:
if len(text) <= 1024:
await message.edit_caption(caption=text, caption_entities=ent + new_ent, disable_web_page_preview=True)
else:
print("Can't edit Caption, length exceeded.")
elif message.media_group_id not in check_mg:
check_mg.add(message.media_group_id)
if len(text) <= 1024:
await message.edit_caption(caption=text, caption_entities=ent + new_ent, disable_web_page_preview=True)
await asyncio.sleep(1)
check_mg.remove(message.media_group_id)
else:
print("Can't edit Caption, length exceeded.")
For this to work, your audio must be in an .OGG file encoded with OPUS
import subprocess
import io
def mp3_to_ogg(filename, path=''):
with open(f'{path}{filename}.mp3', 'rb') as input_file, open(f'{path}{filename}.ogg', 'wb') as output_file:
mp3_io = io.BytesIO(input_file.read())
ffmpeg_command = ['ffmpeg', '-i', 'pipe:0', '-c:a', 'libopus', '-f', 'ogg', 'pipe:1']
result = subprocess.run(ffmpeg_command, input=mp3_io.read(), capture_output=True)
ogg_bytes = result.stdout
output_file.write(ogg_bytes)
await bot.answer_callback_query(callback_query_id=cmd.id, text="Уведомление", show_alert=True)
await callback_query.answer("Уведомление", show_alert=True)
print(f”Пропускаем уже обработанное message _id={msg.id}”)
async def dl_last_photo(target): #передаём в функцию ID или Username чата
async for msg in app.get_chat_history(target, limit = 50, offset_id = -1): #ищем в истории с конца, обрабатываем 50 сообщений
if msg.photo: #если есть фото
print(msg.photo.file_id) #в консоль выводим ID - не обязательно
await app.download_media(msg.photo) #скачиваем фото из сообщения в стандартный каталог (папка_бота/downloads)
Выдаёт ошибку: if (msg.from_user is None and msg.forward_from_chat.id == public.id):
AttributeError: ‘NoneType’ object has no attribute ‘I’d’
if (msg.from_user is None) # если сообщение не имеет автора
# и это репост из паблика (проверка по id)
any_sender_id = message.from_user.id if message.from_user else message.sender_chat.id #вытаскиваем ID
if any_sender_id == public.id: #проверяем что это нужный паблик
#дальше твоя логика
any_sender_id = None #объявляем переменную для хранения ID
if message.from_user: #если у нас есть параметр from_user
any_sender_id = message.from_user.id #присваеваем ID юзера
else: #иначе
any_sender_id = message.sender_chat.id #присваеваем ID канала или чата
if any_sender_id == public.id: #проверяем что это нужный паблик
#дальше твоя логика
# к тому что есть добавил это
from time import sleep
# список, где будет храниться message.media_group_id
check_mess = []
@dp.channel_post_handler(content_types=['any'])
async def auto_redactor(message: types.Message):
text = message.text
if isinstance(message.caption, str):
caption = message.caption
else:
caption = ''
if hasattr(message, 'text') and isinstance(text, str):
await message.edit_text(f'{text}\n\nподпись к тексту',parse_mode="HTML")
# добавил проверку, что media_group_id ещё не в списке
elif hasattr(message, 'caption') and message.media_group_id not in check_mess:
# добавляем в список наш media_group_id
check_mess.append(message.media_group_id)
await message.edit_caption(f'подпись к медиа',parse_mode="HTML")
# чищу список после 5 сек ожидания, чтобы хендлер успел обработать все медиа
sleep(5)
check_mess.clear()