Расширяя базовые возможности Slack, столкнулся с проблемой интеграции некоторых соц.сетей в чаты.

Чтобы подружить Slack и Вконтакте, было решено использовать Python и API. Ниже базовый рецепт того, как научить Slack-бота получать информацию о последних комментариях из постов на стене групп или сообществ Вконтакте.

Slack API


У популярного месенджера Slack есть удобный и простой API. С его помощью можно легко управлять чат-ботами и проводить различные манипуляции с каналами. Здесь представлен самый простой вариант по созданию чат-бота:

1. Откройте Slack.com (вы уже должны быть зарегистрированы в нем, для управления вашей командой).
2. Перейдите в управление приложениями slack.com/apps и откройте "Configure".
3. Откройте «Custom Integrations» и создайте своего первого бота для Slack. (Придумайте имя, выберите комнату, куда он будет отправлять сообщения)
4. Slack выдаст вам API token, который вы будете использовать для авторизации бота.

Slack-Bot.py


Начальная стадия пройдена, приступим к написанию бота. Для работы нам нужен установленный Python 3 и некоторые дополнительные библиотеки для работы c API. Устанавливаем slacker и VK_api:

$ pip install slacker
$ pip install vk_api

Создаем базовый файл Slack-Bot.py в любом редакторе кода и начинаем писать нашего бота.

Импортируем нужные библиотеки:

from slacker import Slacker

import vk_api

Авторизуемся по token в Slack:

slack = Slacker('Полученный ранее API token')

Авторизуемся в VK.com:


    login, password = 'Login', 'pass'
    vk_session = vk_api.VkApi(login, password)

    try:
        vk_session.authorization()
    except vk_api.AuthorizationError as error_msg:
        print(error_msg)
        return


    vk = vk_session.get_api()

А теперь научим нашего бота получить информацию со стены групп Вконтакте:

man_id = str(-29534144) #id группа, с которой будем брать посты и комментарии
postidlist = vk.wall.get(owner_id=man_id, count=1, offset=0) #получаем последний пост со стены
a = str(postidlist['items'][0]['id']) #получаем id поста в виде цифры и записываем
response = vk.wall.getComments(owner_id=man_id, post_id=a, count=1, sort='desc', offset=0) #Получаем последний комментарий в последнем посте со стены

По стандарту ответ приходит в виде массива, чтобы вытащить текст, надо выбрать интересующие нас строки:

b = response['items'][0]['text'] #вытаскиваем из ответа только текст

Теперь полученный текст отправляем ботом в Slack (параметр #vk означает комнату куда бот отправить сообщение):

slack.chat.post_message('#vk', 'Новый комментарий: ' + b) #отправляем сообщение с текстом в Slack

Так мы получили базовый функционал по получению комментариев со стены групп Вконтакте и отправки их в комнаты Slack.

Логика работы скрипта следующая:

1. Авторизуемся в Slack и Вконтакте;
2. Запрашиваем у выбранной группы последний пост;
3. Получаем из поста последний комментарий;
4. Отправляем комментарий в Slack.

Можно модифицировать бота и расширить его функционал, добавив ему проверку стены группы с определенной периодичностью и отправлять новые комментарии в Slack.

Итоговый код работающего бота:

from slacker import Slacker

import vk_api

import time

slack = Slacker('Вставить token Slack bot')

def main():

    login, password = 'login', 'pass'
    vk_session = vk_api.VkApi(login, password)

    try:
        vk_session.authorization()
    except vk_api.AuthorizationError as error_msg:
        print(error_msg)
        return


    vk = vk_session.get_api()


    while True: #зацикливаем
        man_id = str(-29534144) #id группы с которой будем брать посты и комментарии
        postidlist = vk.wall.get(owner_id=man_id, count=1, offset=0) #получаем последний пост
        a = str(postidlist['items'][0]['id']) #получаем id поста в виде цифры и записываем
        time.sleep(5)
        ts = 10
        bts = 10
        while ts == bts: #сравниваем два числа времени комментариев, цикл выполняется до тех пор, пока цифры равны.
            response = vk.wall.getComments(owner_id=man_id, post_id=a, count=1, sort='desc', offset=0) #Получаем последний комментарий
            ts = str(response['items'][0]['date']) #запрашиваем время комментария
            time.sleep(5) #ожидание 5 секунд
            response = vk.wall.getComments(owner_id=man_id, post_id=a, count=1, sort='desc', offset=0)
            bts = str(response['items'][0]['date'])
            print('новых комментариев нет ' + ts + bts)
            time.sleep(5) #если время у комментариев разное цикл прекращается
        response = vk.wall.getComments(owner_id=man_id, post_id=a, count=1, sort='desc', offset=0)  # получаем комментарий со стены
        b = response['items'][0]['text'] #вытаскиваем из него только текст
        slack.chat.post_message('#vk', 'Новый комментарий: ' + b) #отправляем сообщение с текстом в Slack и повторяем цикл
       
if __name__ == '__main__':
    main()

Полный код можно посмотреть тут. Спасибо за внимание.

Комментарии (7)


  1. student_ivan
    14.04.2016 14:04
    +1

    Не хочу показаться через чур критичным, но тем не менее — какой смысл в этой статье?
    Зацикливание это так себе идея, гораздо удобнее в подобной ситуации использовать что-то вроде cron.

    И вот ссылка по теме: https://vk.com/dev/callback_api


    1. Crank
      14.04.2016 22:36

      Какой знакомый аватар =)


    1. alexhouse
      15.04.2016 02:32

      Мне самому цикл не нравится, однако он выполняет свой функционал. За ссылку спасибо, попробую обновить код по этому рецепту.


  1. FantomNotaBene
    15.04.2016 02:24

    А если за 5 секунд ожидания под постом появится 2, 3 или больше комментариев?
    В Slack будет отослан только последний, нет?
    Забирать надо, выходит, явно больше одного комментария за раз(зависит от посещаемости группы, но так и не предскажешь).
    И сравнивать значение date у каждого элемента запрошенного списка, с тем, что сохранили после последней отправки.
    Если оно окажется больше, вызывать функцию отправки сообщения, если меньше — отбрасывать как уже обработанное.


    1. alexhouse
      15.04.2016 02:28

      Про 5 секунд это усредненное значение. В идеале можно сравнивать не время публикации поста, а функцией проверять id комментария — появился новый или нет, если появился публиковать. Настройки Vk_api позволяют гибко настроить получение комментариев.


      1. vetash
        18.04.2016 10:25

        ИД комментариев генерируются последовательно?


        1. alexhouse
          18.04.2016 11:05

          На возрастание, правда шаг неравномерный. Т.е. если сравнивать именно изменение числового значения, то должно сработать. Как писал выше student_ivan оптимально использовать https://vk.com/dev/callback_api