1
0
Fork 0
mirror of https://github.com/EDeev/vkrepost_to_tg.git synced 2026-10-07 20:49:50 +03:00
vkrepost_to_tg/code/bot.py
Egor Deev a38819dee7 Исправлены ошибки пересылки постов
- фоновая рассылка падала на каждом новом посте: 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.
2026-10-05 19:52:45 +00:00

66 lines
2.5 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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