Nikovit <Путешествия и разработка>

Пишем бота пересылки сообщений из VK в Telegram на Python

 
aaf44db7572a2fcafef3ae5ea5c20bb2.png

Очень часто бывает что у вас группа в vk.com и вам бы хотелось завести канал в телеграмм но постить вручную сообщения в два источника не очень удобно. Ниже мы рассмотрим бота для пересылки сообщений из вконтакте в телеграм.



Регистрируем бота в Telegram

Добавляем в список контактов @BotFather

Отправляем ему команду:
/newbot


Придумываем имя боту
Alright, a new bot. How are we going to call it? Please choose a name for your bot.

Придумываем username, должно заканчиваться обязательно на 'bot'
Good. Now let's choose a username for your bot. It must end in `bot`. Like this, for example: TetrisBot or tetris_bot.

Все, бот зарегистрирован, самое важное это последние сообщение с токеном бота, ни кому не сообщайте его т.к. зная токен можно полностью управлять ботом.
Done! Congratulations on your new bot. You will find it at t.me/XXXXbot. You can now add a description, about section and profile picture for your bot, see /help for a list of commands. By the way, when you've finished creating your cool bot, ping our Bot Support if you want a better username for it. Just make sure the bot is fully operational before you do this.


Use this token to access the HTTP API:
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX


For a description of the Bot API, see this page: https://core.telegram.org/bots/api

Пишем бота Telegram

Создаем в нашем проекте файл settings.ini и добавляем в него настройки подключения нашего будущего бота пересылки сообщений из vk.
[Settings]
last_id = 123

[VK]
login = login
password = pass
domain = ghostbustersworldar
count = 20

[Telegram]
bot_token = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
channel = @test
где:
last_id - последний ID сообщения ленты вконтакте, можно оставить 123

login - ваш логин аккаутна вконтакте
password - ваш пароль аккаунта вконтакте
domain - группа или id сообщества вконтакте
count - количество последних забираемых сообщений сообщество (ограничение API вконтакте, максимум 100 за один запрос)

bot_token - токен бота полученный выше
channel - название канала в телеграмме для публикации ботом, важно помнить что для публикации сообщений в канале ботом, его нужно добавить администратором канала


Нам понадобятся библиотеки:

vk_api
pyTelegramBotAPI

configparser и logging из стандартной библиотеки Python, и конечно сам Python, на момент написания статьи у меня была версия 3.6.2

Устанавливаем библиотеки через pip желательно в virtualenv, в консоли набираем:
pip install vk_api
pip install pyTelegramBotAPI

Создаем файл vk_to_tg.py и начинаем в него писать.

Импортируем модули:
import vk_api
import telebot
import configparser
import logging

Считываем данные из settings.ini
config = configparser.ConfigParser()
config.read('settings.ini')
LOGIN = config.get('VK', 'LOGIN')
PASSWORD = config.get('VK', 'PASSWORD')
DOMAIN = config.get('VK', 'DOMAIN')
COUNT = config.get('VK', 'COUNT')
BOT_TOKEN = config.get('Telegram', 'BOT_TOKEN')
CHANNEL = config.get('Telegram', 'CHANNEL')

Считываем настройки
config = configparser.ConfigParser()
config.read('/root/script/bot_teso/settings.ini')
LOGIN = config.get('VK', 'LOGIN')
PASSWORD = config.get('VK', 'PASSWORD')
DOMAIN = config.get('VK', 'DOMAIN')
COUNT = config.get('VK', 'COUNT')
BOT_TOKEN = config.get('Telegram', 'BOT_TOKEN')
CHANNEL = config.get('Telegram', 'CHANNEL')

Инициализируем телеграмм бота vk телеграмм бота
bot = telebot.TeleBot(BOT_TOKEN)

Получаем данные из vk.com для последующей обработки
def get_data(domain_vk, count_vk):
    vk_session = vk_api.VkApi(LOGIN, PASSWORD)
    vk_session.auth()
    vk = vk_session.get_api()
    response = vk.wall.get(domain=domain_vk, count=count_vk)  # Используем метод wall.get из документации по API vk.com
    return response

Проверяем и извлекаем данные по условиям перед отправкой
def check_posts_vk():
    response = get_data(DOMAIN, COUNT)
    response = reversed(response['items'])

    for post in response:

        # Читаем последний извесный id из файла
        id = config.get('Settings', 'LAST_ID')

        # Сравниваем id, пропускаем уже опубликованные
        if int(post['id']) <= int(id):
            continue

        # Записываем id в файл
        config.set('Settings', 'LAST_ID', str(post['id']))
        with open('settings.ini', "w") as config_file:
            config.write(config_file)


        print('--------')
        print(post)

        # Текст
        text = post['text']
        send_posts_text(text)

        # Проверяем есть ли что то прикрепленное к посту
        if 'attachments' in post:
            attach = post['attachments']
            for add in attach:
                if add['type'] == 'photo':
                    add = add['photo']
                    send_posts_img(add)

        # Проверяем есть ли репост другой записи
        if 'copy_history' in post:
            copy_history = post['copy_history']
            copy_history = copy_history[0]
            print('--copy_history--')
            print(copy_history)
            text = copy_history['text']
            send_posts_text(text)

            # Проверяем есть ли у репоста прикрепленное сообщение
            if 'attachments' in copy_history:
                copy_add = copy_history['attachments']
                copy_add = copy_add[0]

                # Если это ссылка
                if copy_add['type'] == 'link':
                    link = copy_add['link']
                    text = link['title']
                    send_posts_text(text)
                    img = link['photo']
                    send_posts_img(img)
                    url = link['url']
                    send_posts_text(url)

                # Если это картинки
                if copy_add['type'] == 'photo':
                    attach = copy_history['attachments']
                    for img in attach:
                        image = img['photo']
                        send_posts_img(image)

Отправляем посты в телеграмм

Если это текст:
def send_posts_text(text):
    if text == '':
        print('no text')
    else:
        # В телеграмме есть ограничения на длину одного сообщения в 4091 символ, разбиваем длинные сообщения на части
        if len(text) >= 4091:
            text4091 = text[:4091]
            bot.send_message(CHANNEL, text4091)
            if len(text) >= 8182:
                text8182 = text[4091:8182]
                bot.send_message(CHANNEL, text8182)
                text12773 = text[8182:12773]
                bot.send_message(CHANNEL, text12773)
        else:
            bot.send_message(CHANNEL, text)

Если это изображение:
# Отправляем изображения
def send_posts_img(img):
    # Находим картинку с максимальным качеством
    if 'photo_2560' in img:
        print(img['photo_2560'])
        bot.send_photo(CHANNEL, img['photo_2560'])
        logging.info('Image: ' + img['photo_2560'])
    else:
        if 'photo_1280' in img:
            print(img['photo_1280'])
            bot.send_photo(CHANNEL, img['photo_1280'])
            logging.info('Image: ' + img['photo_1280'])
        else:
            if 'photo_807' in img:
                print(img['photo_807'])
                bot.send_photo(CHANNEL, img['photo_807'])
                logging.info('Image: ' + img['photo_807'])
            else:
                if 'photo_604' in img:
                    print(img['photo_604'])
                    bot.send_photo(CHANNEL, img['photo_604'])
                    logging.info('Image: ' + img['photo_604'])

И в самом конце инициализируем наш скрипт:
if __name__ == '__main__':
    check_posts_vk()

Репозиторий бота на github.com

Все, удачного Вам написания собственных Telegram ботов на Python


0
Артур
07.10.2018 04:36:05
Два дня пытался но так и не смог отправить фото со стены вк в телеграм. Текст отправляет нормально но вот картинки никак. Пишет ошибку 400. Помогите пожалуйста понять что не так
Ответить Ссылка 0
0
09.10.2018 14:39:22
Да api действительно изменился, обновил статью, вот рабочая конструкция для отправки фото, обновил статью:
# Отправляем изображения
def send_posts_img(img):
    # Находим картинку с максимальным качеством
    if 'photo_2560' in img:
        print(img['photo_2560'])
        bot.send_photo(CHANNEL, img['photo_2560'])
        logging.info('Image: ' + img['photo_2560'])
    else:
        if 'photo_1280' in img:
            print(img['photo_1280'])
            bot.send_photo(CHANNEL, img['photo_1280'])
            logging.info('Image: ' + img['photo_1280'])
        else:
            if 'photo_807' in img:
                print(img['photo_807'])
                bot.send_photo(CHANNEL, img['photo_807'])
                logging.info('Image: ' + img['photo_807'])
            else:
                if 'photo_604' in img:
                    print(img['photo_604'])
                    bot.send_photo(CHANNEL, img['photo_604'])
                    logging.info('Image: ' + img['photo_604'])

Ответить Родитель Ссылка 0
0
09.10.2018 14:44:57
Пришли свой скрипт если не получиться, я посмотрю в чем может быть проблема)))
Ответить Родитель Ссылка 0
0
Артур
17.10.2018 15:39:37
Наконец то разобрался с выбором нужного фото. Теперь возник вопрос как запустить цикл чтобы он сам проверял новые сообщения
Ответить Ссылка 0
0
19.10.2018 23:11:03
я делал не цикл а просто запускал скрипт раз в час по cron в линукс, или можно воспользоваться "планировщиком заданий" если платформа виндовс
Ответить Родитель Ссылка 0
0
Сергей
18.10.2018 12:13:47
Скажите, а теоритически возможно организовать пересылку сообщений из телеграм чата в ватцап? Гуглил - не нашёл вразумительного ответа
Ответить Ссылка 0
0
19.10.2018 23:12:51
Теоретически можно, но на практике сложно, т.к. у вотцапа закрытый протокол и соответственно нет открытого API.
Ответить Родитель Ссылка 0
0
Иван
03.11.2018 17:51:56
Не работает отправка картинок, с текстом все гуд, и что на счет видео?
Ответить Ссылка 0
0
04.11.2018 22:46:22
Для видео надо парсер написать, все руки не доходят, следите за обновлениями на гитхабе https://github.com/Nikovit/bot_vk_to_telegram
Ответить Родитель Ссылка 0