Slack быстро становится новым отраслевым стандартом для общения команд. На самом деле, это настолько популярно, что, когда я набрал слабину в Google, как я и ожидал, первым результатом было определение слова из словаря. За этим немедленно последовал сайт Слэка!
Это почти неслыханно для большинства распространенных слов в словаре английского языка. Обычно определение Google сопровождается несколькими ссылками на главные словарные сайты.
Что такое Slack?
По своей сути Slack — это система обмена сообщениями. Он позволяет отправлять прямые сообщения членам команды и создавать каналы (частные или общедоступные), которые обеспечивают удобное общение в режиме реального времени и совместную работу. Для получения дополнительной информации о Slack, вы можете просмотреть его возможности .
В этот момент вы можете задаться вопросом, откуда приходит Node.js. Как я уже говорил, Slack — это система обмена сообщениями; однако, это может быть бесконечно расширено и настроено. Slack предоставляет невероятно гибкую систему для настройки интеграции вашей команды, в том числе:
- создание пользовательских приветственных сообщений
- создание пользовательских смайликов
- установка сторонних приложений
- создание собственных приложений
- создание пользовательских Slack Bots
В этой статье я собираюсь продемонстрировать, как создать Slack Bot с Node.js, который можно добавить в конфигурацию Slack вашей команды.
Slack Bots Defined
Работа Slack Bot состоит в том, чтобы получать события, отправленные из Slack, и обрабатывать их. Существует множество событий, которые будут отправлены вашему боту, и именно здесь Node.js придет. Мы должны решить не только, какие события обрабатывать, но и как обрабатывать каждое отдельное событие.
Например, некоторые общие события, которые бот будет обрабатывать:
member_joined_channel
-
member_left_channel
-
message
В этой статье я создам приложение Node.js и Slack Bot, которые можно добавить в ваш командный проект для выполнения определенных действий в зависимости от полученных событий.
Для начала мне нужно создать бота на Slack. Можно создать два типа ботов:
- кастомный бот
- создание приложения и добавление пользователя бота
В этой статье будет создан пользовательский бот, потому что пользователь бот-приложения будет более уместным, если вы планируете написать и опубликовать приложение на Slack. Учитывая, что я хочу, чтобы этот бот был приватным для моей команды, подойдет специальный бот.
Создание собственного слабого бота
Пользовательский бот может быть создан здесь: https://my.slack.com/apps/A0F7YS25R-bots . Если вы уже вошли в свою учетную запись Slack, слева нажмите кнопку Add Configuration ; в противном случае, войдите в свою учетную запись Slack, прежде чем продолжить. Если у вас нет учетной записи Slack, вы можете зарегистрироваться бесплатно .
Это перенесет вас на новую страницу, где вам потребуется указать имя пользователя для вашего бота. Введите свое имя пользователя сейчас, убедившись, что вы следуете указаниям Slack. После того, как вы выбрали удивительное имя бота, нажмите Добавить конфигурацию бота .
После того, как вы успешно создали своего бота, Slack перенаправляет вас на страницу, которая позволяет для дальнейшей настройки вашего бота. Я оставлю эту часть вашему творческому я. Единственное, что нужно на этой странице — это xoxb-
API, который начинается с xoxb-
. Я либо скопировал бы этот токен в безопасное место для последующего использования, либо просто оставил бы эту страницу открытой, пока нам не понадобится токен для приложения Node.js.
Конфигурации
Прежде чем перейти к коду, требуются еще две конфигурации Slack:
- Создайте или выберите существующий канал, с которым ваш бот будет взаимодействовать. Пока я тестирую своего нового бота, я решил создать новый канал. Обязательно запомните название канала, так как оно вскоре понадобится вашему приложению.
- Добавьте / пригласите своего бота на канал, чтобы он мог взаимодействовать с ним.
Теперь, когда я настроил свой Slack Bot, пришло время перейти к приложению Node.js. Если у вас уже установлен Node.js, вы можете перейти к следующему шагу. Если у вас не установлен Node.js, я предлагаю вам начать со страницы загрузки Node.js. и выбрать установщик для вашей системы.
Для моего Slack Bot я собираюсь создать новое приложение Node.js, выполнив процесс npm init
. В командной строке, в которой вы хотите установить приложение, вы можете запустить следующие команды:
1
2
3
|
mkdir slackbot
cd slackbot
npm init
|
Если вы не знакомы с npm init
, запускается утилита, которая поможет вам настроить ваш новый проект. Первое, что он спрашивает, это имя. По умолчанию это был slackbot
, с которым мне удобно. Если вы хотите изменить имя своего приложения, сейчас есть шанс; в противном случае нажмите Enter, чтобы перейти к следующему шагу настройки. Следующие опции — версия и описание. Я оставил оба значения по умолчанию и просто продолжил, нажав Enter для обеих этих опций.
Точки входа
Следующая вещь, о которой просят, это точка входа . По умолчанию это index.js
; однако многим нравится использовать app.js
Я не хочу вступать в эту дискуссию, и, поскольку мое приложение не потребует интенсивной структуры проекта, я оставлю index.js
по умолчанию в качестве index.js
.
После того, как вы оправились от дебатов, которые, вероятно, столь же сильны, как табуляции и пробелов , конфигурация продолжается, задавая еще несколько вопросов:
- тестовая команда
- Git репозиторий
- ключевые слова
- автор
- лицензия
Для целей этой статьи я оставил все параметры по умолчанию. Наконец, после настройки всех параметров перед созданием файла отображается подтверждение файла package.json
. Нажмите Enter, чтобы завершить настройку.
Введите SDK
Чтобы упростить взаимодействие со Slack, я также собираюсь установить пакет Slack Developer Kit следующим образом:
1
|
npm install @slack/client —save
|
Вы наконец готовы к некоторому коду? Я уверен, что я. Для начала я собираюсь использовать пример кода с веб-сайта Slack Developer Kit, который публикует сообщение Slack с помощью API-интерфейса обмена сообщениями в реальном времени (RTM) с несколькими изменениями.
Учитывая, что я выбрал точку входа index.js
, пришло время создать этот файл. Пример с сайта Slack Developer Kit содержит примерно 20 строк кода. Я собираюсь разбить его на несколько строк за раз, только чтобы дать объяснение того, что делают эти строки. Но учтите, что все эти строки должны содержаться в вашем файле index.js
.
Код начинается с включения двух модулей из Slack Developer Kit:
1
2
|
var RtmClient = require(‘@slack/client’).RtmClient;
var CLIENT_EVENTS = require(‘@slack/client’).CLIENT_EVENTS;
|
Созданный RtmClient
станет нашим бот-объектом, который ссылается на RTM API. CLIENT_EVENTS
— это события, которые бот будет прослушивать.
Как только эти модули включены, пришло время создать экземпляр и запустить бот:
1
2
|
var rtm = new RtmClient(‘xoxb-*************************************’);
rtm.start();
|
Обязательно замените описанный выше токен API на ваш токен, полученный при создании Slack Bot.
Вызов функции start
на моем RtmClient
инициализирует сессию бота. Это попытается аутентифицировать моего бота. Когда мой бот успешно подключится к Slack, будут отправлены события, позволяющие продолжить работу моего приложения. Эти события будут показаны на мгновение.
При создании экземпляра клиента создается переменная channel
для мгновенного заполнения внутри одного из событий CLIENT_EVENTS
.
1
|
let channel;
|
Переменная channel
будет использоваться для выполнения определенных действий, таких как отправка сообщения на канал, к которому подключен бот.
Когда сеанс RTM запущен ( rtm.start();
) и ему присвоен действительный RTM.AUTHENTICATED
API для бота, будет отправлено сообщение RTM.AUTHENTICATED
. Следующие несколько строк прослушивают это событие:
1
2
3
4
5
6
|
rtm.on(CLIENT_EVENTS.RTM.AUTHENTICATED, (rtmStartData) => {
for (const c of rtmStartData.channels) {
if (c.is_member && c.name ===’jamiestestchannel’) { channel = c.id }
}
console.log(`Logged in as ${rtmStartData.self.name} of team ${rtmStartData.team.name}`);
});
|
Когда событие RTM.AUTHENTICATED
получено, предыдущий код выполняет цикл for
через список каналов команды Slack. В моем случае я специально ищу jamiestestchannel и проверяю , является ли мой бот участником этого канала. Когда это условие выполняется, идентификатор канала сохраняется в переменной channel
.
Отладка
Чтобы помочь в отладке, в консоль записывается сообщение, в котором отображается сообщение о том, что бот успешно прошел аутентификацию, отображая его имя ( ${rtmStartData.self.name}
) и имя команды ( ${rtmStartData.team.name}
). принадлежит.
После проверки подлинности бота запускается другое событие ( RTM.RTM_CONNECTION_OPENED
), которое указывает, что бот полностью подключен и может начать взаимодействовать со Slack. Следующие строки кода создают прослушиватель событий; При успехе привет! сообщение отправляется на канал (в моем случае jamiestestchannel ).
1
2
3
|
rtm.on(CLIENT_EVENTS.RTM.RTM_CONNECTION_OPENED, function () {
rtm.sendMessage(«Hello!», channel);
});
|
Теперь я могу запустить приложение Node и посмотреть, как мой бот автоматически отправляет новое сообщение на мой канал:
1
|
node index.js
|
Результаты выполнения этой команды (в случае успеха) имеют два аспекта:
- Я получаю сообщение об отладке, указывающее, что мой бот успешно вошел в систему. Это происходит из-за
RTM.AUTHENTICATED
чтоRTM.AUTHENTICATED
сработал после запуска клиента RTM. - Я получаю Привет! сообщение в моем канале Slack. Это произошло, когда сообщение о событии
RTM.RTM_CONNECTION_OPENED
было получено и обработано приложением.
Прежде чем приступить к дальнейшей работе над моим приложением, сейчас самое время вспомнить, что я сделал, чтобы продвинуться так далеко:
- Создан кастом Slack Bot.
- Создал собственный канал Slack и пригласил на него моего бота.
- Создано новое приложение Node.js под названием slackbot .
- Установил пакет Slack Developer Kit для моего приложения.
- Создал мой файл
index.js
который создаетRtmClient
используя мойRtmClient
API из моего собственного бота. - Создал прослушиватель событий для
RTM.AUTHENTICATED
который находит канал Slack, членом которого является мой бот. - Создан
RTM.RTM_CONNECTION_OPENED
событий дляRTM.RTM_CONNECTION_OPENED
который отправляет Hello! сообщение на мой Slack Channel. - Вызывается метод RTM Start Session, чтобы начать процесс аутентификации, который обрабатывается моими прослушивателями событий.
Сборка бота
Теперь пришло время для настоящего веселья, чтобы начать. Slack предлагает (я не считал) как минимум 50 различных событий , которые мой бот может прослушать и опционально обработать. Как видно из списка Slack Events, некоторые события настраиваются для API RTM (который мы используем), в то время как другие события настраиваются для API событий . На момент написания этой статьи, насколько я понимаю, SDK Node.js поддерживает только RTM.
Чтобы закончить мой бот, я обработаю событие message
; Конечно, это, вероятно, одно из самых сложных событий, поскольку оно поддерживает большое количество подтипов, которые я расскажу чуть позже.
Вот пример того, как выглядит самое основное событие message
из Slack:
1
2
3
4
5
6
7
|
{
«type»: «message»,
«channel»: «C2147483705»,
«user»: «U2147483697»,
«text»: «Hello world»,
«ts»: «1355517523.000005»
}
|
В этом базовом объекте три самые важные вещи, которые меня волнуют:
-
channel
Я хочу убедиться, что это сообщение принадлежит каналу, частью которого является мой бот. -
user
. Это позволит мне напрямую взаимодействовать с пользователем или выполнять конкретные действия в зависимости от того, кем он является. -
text
. Это, наверное, самая важная часть, так как она содержит содержание сообщения. Мой бот захочет отвечать только на определенные типы сообщений.
Некоторые сообщения являются более сложными. Они могут содержать множество под-свойств, таких как:
-
edited
: дочерний объект, который описывает, какой пользователь отредактировал сообщение и когда это произошло. -
subtype
: строка, которая определяет один из множества различных типов, таких как channel_join, channel_leave и т. д. -
is_starred
: логическое значение, указывающее, было ли это сообщениеis_starred
. -
pinned_to
: массив каналов, где это сообщение было закреплено. -
reactions
: Массив объектов реакции, которые определяют, какой была реакция (например, лицевая сторона лица), сколько раз она произошла, и массив пользователей, которые отреагировали таким образом на сообщение.
Я собираюсь расширить свой ранее созданный index.js
для прослушивания message
. Чтобы уменьшить избыточность кода, следующие примеры будут содержать только часть кода, связанную с улучшениями событий message
.
Первое, что нужно сделать, это включить новый модуль для RTM_EVENTS
который я буду слушать. Я поместил это ниже, мои два предыдущих модуля включают в себя:
1
|
var RTM_EVENTS = require(‘@slack/client’).RTM_EVENTS;
|
Код для обработки события message
я буду размещать внизу моего файла. Чтобы проверить, что событие message
работает правильно, я создал новый прослушиватель событий, который регистрирует объект message
на консоли следующим образом:
1
2
3
|
rtm.on(RTM_EVENTS.MESSAGE, function(message) {
console.log(message);
});
|
Теперь я могу перезапустить свое приложение Node ( node index.js
). Когда я набираю сообщение в моем канале, на моей консоли регистрируется следующее:
1
2
3
4
5
6
7
8
9
|
{
type: ‘message’,
channel: ‘C6TBHCSA3’,
user: ‘U17JRET09’,
text: ‘hi’,
ts: ‘1503519368.000364’,
source_team: ‘T15TBNKNW’,
team: ‘T15TBNKNW’
}
|
Все идет нормально. Мой бот успешно получает сообщения. Следующий шаг, который необходимо сделать, — убедиться, что сообщение принадлежит каналу, на котором находится мой бот:
1
2
3
4
|
rtm.on(RTM_EVENTS.MESSAGE, function(message) {
if (message.channel === channel)
console.log(message);
});
|
Теперь, когда я запускаю свое приложение, я вижу свое сообщение отладки, только если событие message
было для channel
, частью которого является мой бот.
Теперь я собираюсь расширить приложение, чтобы отправлять пользовательское сообщение на канал, демонстрируя, как пользователь может быть помечен в сообщении:
1
2
3
4
|
rtm.on(RTM_EVENTS.MESSAGE, function(message) {
if (message.channel === channel)
rtm.sendMessage(«Stop, everybody listen, <@» + message.user + «> has something important to say!», message.channel);
});
|
Теперь, когда кто-то печатает сообщение на канале, мой бот отправляет свое собственное сообщение, которое выглядит примерно так: «Стоп, все слушают, у @endyourif есть что-то важное!»
Хорошо, не очень полезно. Вместо этого я собираюсь завершить работу своего бота, расширив прослушиватель событий message
для ответа на конкретные команды. Это будет достигнуто путем выполнения следующих действий:
- Разбейте
text
частьmessage
на массив на основе пробела. - Проверьте, соответствует ли первый индекс имени пользователя моего бота.
- Если это произойдет, я посмотрю на второй индекс (если он существует) и буду рассматривать его как команду, которую должен выполнить мой бот.
Чтобы было легче определить, упоминался ли мой бот, мне нужно создать новую переменную, в которой будет храниться идентификатор пользователя моего бота. Ниже приведен обновленный раздел кода, в котором я ранее установил переменную channel
. Теперь он также хранит идентификатор пользователя моего бота в переменной с именем bot
.
01
02
03
04
05
06
07
08
09
10
11
|
let channel;
let bot;
rtm.on(CLIENT_EVENTS.RTM.AUTHENTICATED, (rtmStartData) => {
for (const c of rtmStartData.channels) {
if (c.is_member && c.name ===’jamiestestchannel’) { channel = c.id }
}
console.log(`Logged in as ${rtmStartData.self.name} of team ${rtmStartData.team.name}`);
bot = ‘<@’ + rtmStartData.self.id + ‘>’;
});
|
Установив переменную bot
, я завершил работу над ботом, добавив в него ранее созданный обработчик message
:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
rtm.on(RTM_EVENTS.MESSAGE, function(message) {
if (message.channel === channel) {
if (message.text !== null) {
var pieces = message.text.split(‘ ‘);
if (pieces.length > 1) {
if (pieces[0] === bot) {
var response = ‘<@’ + message.user + ‘>’;
switch (pieces[1].toLowerCase()) {
case «jump»:
response += ‘»Kris Kross will make you jump jump»‘;
break;
case «help»:
response += ‘, currently I support the following commands: jump’;
break;
default:
response += ‘, sorry I do not understand the command «‘ + pieces[1] + ‘».
break;
}
rtm.sendMessage(response, message.channel);
}
}
}
}
});
|
Следующий код разбивает text
свойство объекта message
на массив на основе пробела. Затем я гарантирую, что у меня есть как минимум два элемента в массиве, в идеале мой бот и команда для выполнения.
Когда первый элемент в массиве соответствует моему боту, я выполняю инструкцию switch
для второго элемента в массиве: команду. В настоящее время поддерживаются команды перехода и справки . Когда на канал отправляется сообщение, которое выглядит как «@jamiestest jump», мой бот ответит специальным сообщением исходному пользователю.
Если команда не распознана, она попадет в мой оператор case по умолчанию для моего switch
и ответит общей командой, которая будет выглядеть следующим образом: «@endyourif, извините, я не понимаю команду» hi «. Список поддерживаемых команды, введите: @jamiestest help «.
Вывод
На данный момент мой бот завершен! Если вы заинтересованы в дальнейшем улучшении своего бота, вот список идей:
- Обработайте присоединение нового члена команды, прослушав событие
team_join
. Когда присоединяется новый член команды, было бы неплохо отправить им разнообразную информацию и / или документацию, приветствующую их в вашей команде. - Расширьте список поддерживаемых команд, которые я начал.
- Сделайте команды интерактивными с помощью поиска в базе данных, Google, YouTube и т. Д.
- Создайте пользователя бота в приложении и создайте свои собственные команды слеша .