mirror of
https://github.com/EDeev/vkrepost_to_tg.git
synced 2026-10-07 20:49:50 +03:00
- фоновая рассылка падала на каждом новом посте: NameError: name 'types' is not defined (видно в логе сервера) — бот не пересылал ничего; - пост с одной картинкой не отправлялся: send_media_group принимает от 2 до 10 элементов; больше 10 фото — тоже ошибка; теперь одиночное фото — send_photo, альбом обрезается до 10; - подпись длиннее 1024 символов ломала отправку — длинный текст уходит отдельными сообщениями (с делением по строкам, чтобы не рвать HTML); - если первым вложением была ссылка или опрос, текст поста терялся (подпись ставилась только на вложение с индексом 0); - текст и названия из ВК подставлялись в HTML без экранирования; ссылки оформлялись Markdown-синтаксисом ([..](..)) при разметке HTML; - post_message[0] у одиночного сообщения, logging.danger, /notif без подписок — падения; - у видео без photo_800 разбор поста падал; «Лайков» у видео на самом деле были просмотры; - синхронные вызовы vk_api и time.sleep блокировали бота — теперь в отдельном потоке и asyncio.sleep; ошибка у одного подписчика не мешает остальным. Новое: /logout — удалить сохранённый токен VK; сообщение со ссылкой-токеном удаляется из переписки. Токены бота и VK — из переменных окружения, таблицы SQLite создаются при первом запуске (пустые базы убраны из репозитория), ссылка «АВТОР» — на EDeev.
66 lines
2.5 KiB
Python
66 lines
2.5 KiB
Python
import asyncio
|
||
import logging
|
||
import random
|
||
|
||
import scripts
|
||
import vk_scripts
|
||
from init import bot, dp, du, db
|
||
from config import serviceToken
|
||
from handlers import router
|
||
|
||
|
||
async def check_group(group_id, activ_user, sub_user):
|
||
tokens = [x[0] for x in activ_user if group_id in x[1]]
|
||
users = [x[0] for x in sub_user if group_id in x[1]]
|
||
|
||
# токен случайного подписчика даёт доступ к закрытым страницам, иначе — сервисный ключ
|
||
if tokens:
|
||
vk = vk_scripts.VkParser(db.get_token(random.choice(tokens)))
|
||
else: vk = vk_scripts.VkParser(serviceToken)
|
||
|
||
# vk_api синхронный — в отдельном потоке, чтобы не замирал весь бот
|
||
output = await asyncio.to_thread(vk.last_post, owner_id=du.get_vk_id(group_id))
|
||
last_post = db.get_postGroup(group_id)
|
||
|
||
if output[3] > last_post:
|
||
text, audio, media = scripts.pars_post(output)
|
||
db.update_postGroup(group_id, output[3])
|
||
|
||
for sub in users:
|
||
try:
|
||
await scripts.send_post(bot, du.get_tg_id(sub), text, audio, media)
|
||
except Exception:
|
||
# подписчик мог заблокировать бота — остальным пост всё равно уходит
|
||
logging.warning("Не удалось отправить пост подписчику %s", sub, exc_info=True)
|
||
|
||
|
||
async def timer(wait_for) -> None:
|
||
while True:
|
||
await asyncio.sleep(wait_for)
|
||
|
||
notif_group = [x[0] for x in db.all_notifGroup()]
|
||
activ_user = [[x[0], list(map(int, x[1].split(';')))] for x in db.all_activUser() if x[1]]
|
||
sub_user = [[x[0], list(map(int, x[1].split(';')))] for x in db.all_subUser() if x[1]]
|
||
|
||
for group_id in notif_group:
|
||
await asyncio.sleep(1) # пауза между страницами — лимиты VK API
|
||
|
||
try:
|
||
await check_group(group_id, activ_user, sub_user)
|
||
except Exception:
|
||
logging.error("Ошибка обновления поста:", exc_info=True)
|
||
|
||
|
||
async def main() -> None:
|
||
dp.include_router(router)
|
||
await bot.delete_webhook(drop_pending_updates=True)
|
||
await dp.start_polling(bot, allowed_updates=dp.resolve_used_update_types())
|
||
|
||
|
||
async def process() -> None:
|
||
await asyncio.gather(main(), timer(60))
|
||
|
||
|
||
if __name__ == "__main__":
|
||
try: asyncio.run(process())
|
||
except KeyboardInterrupt: pass
|