В ноябре прошлого года Slack выпустила первую версию Python Slack SDK и отправила версию 2.x, SlackClient, на обслуживание. Сегодня мы будем использовать Python Slack SDK вместе со Slack-Bolt и Flask для создания чат-бота в Slack.

Мы увидим, как отправлять сообщения, отвечать в ветке, выполнять действия при определенных условиях, команды с косой чертой и т. Д.

Вы можете найти все коды, использованные в этом руководстве, здесь.

Требования:

  • Python 3.6
  • Аккаунт Slack
  • Python Slack SDK (pip install slack_sdk), Slack-Bolt (pip install slack-bolt), Flask (pip install flask)

Что такое SlackBot?

Бот - это тип приложения Slack, предназначенный для взаимодействия с пользователями посредством разговора.

Бот - это то же самое, что и обычное приложение: он может получить доступ к тому же диапазону API и делать все волшебные вещи, которые может делать приложение Slack.

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

Ваш бот может отправлять личные сообщения, его могут упоминать пользователи, он может публиковать сообщения или загружать файлы, его можно приглашать на каналы - или выгнать.

Создание и установка нашего приложения

Первым делом давайте создадим бота в Slack UI.

  • Перейдите на https://api.slack.com/, затем Создать приложение.
  • Выберите «С нуля».
  • Укажите желаемое имя бота, я назову своего бота Slacky и рабочее пространство, где он будет установлен, мое - Slacky. Slacky и нажмите создать приложение.

После этого вы будете перенаправлены на другую страницу, где сможете настроить свое приложение. Здесь мы внесем некоторые изменения.

  • Перейдите в «OAuth и разрешения». Здесь мы добавим необходимую область действия и разрешения для нашего бота. А пока мы добавим 'chat: write', 'groups: read', 'im: read', ' mpim: прочтите ',' каналы: управление 'и' каналы: прочтите ' в разделе "Области действия токенов бота".

  • После добавления этих областей прокрутите вверх и нажмите «Установить в рабочую область».

  • Это этап проверки, на котором вы можете в последний раз просмотреть все разрешения, которые приложение будет иметь после установки в вашем рабочем пространстве. Когда вы будете удовлетворены, нажмите «разрешить» (игнорируйте здесь имя бота, я случайно удалил исходный снимок экрана для Slacky, поэтому создал новый и сделал этот снимок экрана).

  • После установки приложения вам будет предоставлен «токен OAuth пользователя-бота». Скопируйте и сохраните где-нибудь, мы будем использовать через некоторое время.

  • Выполнив все вышеперечисленные шаги, вы сможете увидеть созданного вами бота в разделе «Приложения» в выбранной рабочей области (для меня Slacky Slacky).

  • Наконец, нам нужно добавить наше приложение в один или несколько каналов, где оно будет иметь все доступы, которые мы добавили ранее. Щелкните правой кнопкой мыши имя бота и выберите «Открыть сведения о приложении». Нажмите «Добавить это приложение в канал» и выберите канал, на который вы хотите добавить своего бота. Я добавлю свое приложение в ‘# slack-bot’.

Написание основных операций

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

Объяснение

  • Строка [3–5]: Импорт всех необходимых библиотек / модулей.
  • Строка 8: Помните токен, который нам предоставил Slack во время установки? Нам нужно использовать этот токен в каждом запросе, который мы отправляем в Slack, поскольку это единственный способ, которым Slack аутентифицирует запрос. Всегда рекомендуется сохранять токены аутентификации как переменные среды, если вы работаете на платформе Windows, используйте set SLACK_BOT_TOKEN=XXX-YYY-ZZZ, а если вы работаете в системе на основе Linux или UNIX, используйте export SLACK_BOT_TOKEN=XXX-YYY-ZZZ. После того, как вы установили переменную среды, мы можем использовать os.environ.get(‘SLACK_BOT_TOKEN’), чтобы использовать ее в нашем приложении.
  • Строка 11: Создание экземпляра класса WebClient. Все методы этого класса будут нажимать «https://www.slack.com/api/». Возвращенный объект (здесь response) будет типа slack_sdk.web.slack_response.SlackResponse.
  • Строка 15: Мы можем использовать slack_sdk.web.client.WebClient.chat_postMessage() для отправки сообщения по каналу. chat_postMessage внутри использует api_call(method, params, simplify = F, debug = F). chat_postMessage требуется название / идентификатор канала и текст (сообщение). Чтобы отправить сообщение, нам нужно добавить область chat: write в нашего бота, что мы уже сделали в начале этого руководства. Чтобы узнать больше о том, какой метод требует какой области видимости, посетите эту страницу. Вы должны получить сообщение, подобное приведенному ниже.

  • Строка 20: chat_postEphemeral отправляет временное сообщение пользователю в канале. Аргументы такие же, как chat_postMessage, только здесь user является обязательным аргументом, а не дополнительным. Необходим тот же объем, что и chat_postMessage . Вы должны увидеть что-то похожее на это,

  • Строка 26: conversations_info используется для получения информации о беседе. Принимает только один аргумент - идентификатор канала. Ему нужны 'groups: read', 'im: read', 'mpim: read' и ' каналы: читать ». Я не собираюсь публиковать здесь результат, так как он довольно большой, но вы должны распечатать его и посмотреть, какую информацию мы получаем от Slack.
  • Строка 30: conversations_list перечисляет все каналы в команде Slack.

Написание продвинутых операций

Функциональность, которую мы добавили до сих пор, - это просто публикация сообщения и получение информации о каналах. А теперь добавим еще крутого функционала. Пойдем шаг за шагом.

Действия после получения определенного сообщения:

До сих пор мы просто отправляли некоторые предопределенные сообщения в канал, независимо от того, что публикуют другие пользователи в канале, но что, если пользователь хочет получить какой-то ответ от нашего бота? Прямо сейчас бот не может ответить или даже подтвердить сообщение пользователя. Добавим это. Каждый раз, когда пользователь говорит «Привет, слабый», «Привет, слабый» или просто «Вялый», наш бот чем-то отвечает.

Но прежде чем мы напишем эту функциональность, нам нужно написать некоторый "не-Slack" код.

  • Сначала перейдите на https://api.slack.com/apps/ и щелкните свое приложение, вы перейдете на страницу конфигурации этого приложения. Здесь в разделе "Основная информация" прокрутите вниз и вы увидите раздел "Учетные данные приложения", скопируйте "Секрет подписи" и сохраните его. в качестве переменной среды я сохранил свою как SLACK_SIGNING_SECRET

Это сложная, но необходимая часть. Нам нужно принимать и отправлять запросы от Slack, а это значит, что нам нужно создать приложение, которое может общаться с внешним миром. Здесь у нас есть 2 варианта: мы можем использовать облачную виртуальную машину, такую ​​как экземпляр EC2 в AWS, или использовать ngrok, который используется для предоставления доступа к серверу разработки внешнему миру.

  • Использование экземпляра Could VM / EC2: если у вас есть активная учетная запись AWS, лучше использовать ее для этой цели. Вам просто нужно запустить экземпляр EC2 и открыть порт 8080. Но помните, что с этого момента вам нужно запускать все наши сценарии python здесь, поэтому установите все зависимости, такие как Slack-Bolt, Slack-SDK, Flask и т. Д., И все готово.
  • Использование Ngrok: если вы не можете использовать AWS, GCP или любого такого облачного провайдера, установите ngrok. Он создаст безопасный туннель. между вашей средой разработки и ngrok. Все запросы сначала поступают в ngrok, а затем ngrok доставит их в нужное место для нас. После загрузки он запускает ./ngrok http 8080, который запускает безопасный HTTP-туннель в вашем порту 8080 .

Мы все закончили с настройкой нашего сервера разработки. Теперь напишем еще код. Здесь мы будем использовать flask для создания приложения, которое будет получать все запросы от Slack и соответствующим образом отвечать. Я объясню код позже, так как нам нужно внести еще несколько изменений в пользовательский интерфейс Slack после написания приведенного ниже скрипта.

import os
from flask import Flask, request
from slack_sdk import WebClient
from slack_bolt import App, Say
from slack_bolt.adapter.flask import SlackRequestHandler
app = Flask(__name__)
client = WebClient(token=os.environ.get("SLACK_BOT_TOKEN")
bolt_app = App(token=os.environ.get("SLACK_BOT_TOKEN"), signing_secret=os.environ.get("SLACK_SIGNING_SECRET"))

handler = SlackRequestHandler(bolt_app)


@app.route("/slacky/events", methods=["POST"])
def slack_events():
    """ Declaring the route where slack will post a request """
    return handler.handle(request)


if __name__ == '__main__':
    app.run(host='0.0.0.0', port=8080, debug=True)
  • Запустите приведенный выше сценарий, который запустит локальный сервер WSGI, который будет прослушивать порт 8080 . Теперь, если вы используете EC2 или любую другую облачную виртуальную машину, вам не нужно ничего делать иначе, но если вы используете ngrok, то сначала запустите сценарий, а затем запустите ngrok, используя ./ngrok http 8080.. Скопируйте http: //*.ngrok. io, мы будем использовать его на следующем шаге.
  • Снова перейдите на страницу конфигурации вашего приложения, затем перейдите в Подписки на мероприятия и включите его. После того, как вы включите его, вы увидите, что он запрашивает URL-адрес запроса. Здесь нам нужно указать URL-адрес нашего флеш-приложения. Если вы используете экземпляр EC2, тогда URL-адрес будет примерно таким: http: //your.public.ipv4.address: 8080 / slacky / events (используйте IP-адрес, который вы используете для ssh это, например, общедоступный IPv4 адрес), и если вы используете ngrok, тогда URL будет примерно таким: http://fakeurl123s.ngrok.io. После того, как вы ввели URL-адрес, Slack отправит POST-запрос на URL-адрес для его проверки. Если все работает нормально, вы должны увидеть Подтверждено, как показано ниже. Помните, что конечная точка после номера порта или. ngrok.io должна быть такой же, как вы объявили в своем коде (@app.route(“/slacky/events”, methods=[“POST”])).

  • Прокрутите вниз до пункта «Подписка на события бота» и добавьте область действия «message: channels», которая дает нашему боту доступ для прослушивания общедоступных сообщений. каналы, если вы хотите использовать его для частного канала, добавьте 'message: groups'. Как только вы закончите, сохраните изменения и вернитесь в свой редактор, поскольку мы напишем еще немного кода.

  • С этого момента мы не будем использовать slack_sdk напрямую, вместо этого мы будем использовать slack_bolt. Теперь вы, должно быть, думаете, почему я написал основную часть с помощью slack-sdk? Что ж, уверяю вас, это не было пустой тратой времени, поскольку slack-bolt внутренне использует slack-sdk, поэтому изучение slack-sdk является совершенно необходимо понимать, как работает slack-bolt, а также, если вы хотите реализовать какое-то сложное решение, будет лучше, если вы будете напрямую использовать методы slack-sdk вместо этого. Я объясню это подробно позже. А пока напишем код. Добавьте следующие строки после signing_secret=os.environ.get(“SLACK_SIGNING_SECRET”)) и запустите приложение.
@bolt_app.message("hello slacky")
def greetings(payload: dict, say: Say):
    """ This will check all the message and pass only those which has 'hello slacky' in it """
    user = payload.get("user")
    say(f"Hi <@{user}>")
  • Результат должен быть похож на этот:

Объяснение

  • В Slack-Bolt есть множество декораторов, которые мы можем использовать. Если нам нужно прослушивать сообщения, нам нужно добавить слушателя message(). Итак, здесь мы добавляем прослушиватель сообщений, но мы будем действовать только для сообщений «hello slacky». Он отфильтрует все остальные сообщения. В определении функции я объявил переменную payload, которая представляет собой не что иное, как полезную нагрузку, которую нам отправляет Slack. Распечатайте payload, и вы увидите все подробности, которые Slack отправляет в наше приложение flask. Мы получаем user из payload dict, который дает нам идентификатор пользователя, разместившего сообщение. В нашем message() слушателе доступен say(), который можно использовать для отправки сообщений. Если вам нужно отправлять сообщения вне слушателя, вам нужно использовать client.chat_postMessage(), как мы использовали раньше.
  • В строке ниже мы создаем экземпляр SlackRequestHandler, который мы импортировали из slack_bolt.adapter.flask. Slack-Bolt имеет множество доступных адаптеров. Поскольку у нас есть приложение Flask, мы используем адаптер Flask от slack_bolt.
handler = SlackRequestHandler(bolt_app)
  • В этом блоке кода мы регистрируем конечную точку, где Slack будет публиковать свои запросы. handler запускает метод отправки приложения, то есть он будет выполнять метод отправки, доступный в slack_bolt.adapter.flask. Требуется только один аргумент типа Запрос.
@app.route("/slacky/events", methods=["POST"])
def slack_events():
    """ Declaring the route where slack will post a request """
    return handler.handle(request)

Ответ в ветке

Теперь мы будем отвечать на сообщения пользователей в ветке. Для этого вам необходимо добавить эти 4 области каналы: история, группы: история, im: history, mpim: history вашему боту. Добавьте этот блок кода перед оператором handler.

@bolt_app.message(re.compile("(hi|hello|hey) slacky"))
def reply_in_thread(payload: dict):
    """ This will reply in thread instead of creating a new thread """
    response = client.chat_postMessage(channel=payload.get('channel'),
                                     thread_ts=payload.get('ts'),
                                     text=f"Hi<@{payload['user']}>")

Объяснение

Здесь мы используем re.compile для проверки нескольких выражений. ts - это временная метка сообщения, нам нужно передать это, чтобы Slack-SDK знал, на какое сообщение нужно отправить ответ.

Слэш-команда

Прежде чем мы начнем писать код для команды косой черты, нам нужно добавить несколько вещей в пользовательский интерфейс Slack.

  • Перейдите на страницу конфигурации вашего бота.
  • Перейдите к "Slash Command".
  • Нажмите «Создать новую команду».
  • Команда будет именем команды, я назвал свою команду / help.
  • URL-адрес запроса будет таким же, как вы указали ранее.
  • Когда вы закончите, нажмите Сохранить.

Добавьте приведенный ниже блок кода перед операторомhandler.

@bolt_app.command("/help")
def help_command(say, ack):
    ack()
    text = {
        "blocks": [
            {
                "type": "section",
                "text": {
                    "type": "mrkdwn",
                    "text": "This is a slash command"
                }
            }
        ]
    }
    say(text=text)

Объяснение

«Command ()» - это слушатель, который нам нужно использовать для команд с косой чертой. Внутри command() нам нужно указать имя команды. Как только мы получили команду, нам нужно подтвердить ее, используя ack().. Рекомендуется использовать ack () перед запуском любого трудоемкого процесса, так как у нас будет всего 3 секунды, чтобы подтвердить его. Здесь я использовал текст в стиле блока, что является рекомендуемым способом ответа.

Заключение: Slacky Bot

Таким образом, полный код будет выглядеть примерно так:

Надеюсь будет полезно, еще раз встретимся с другой интересной темой.

Больше контента на plainenglish.io