Статьи

Создайте свой собственный SlackBot с Node.js

Эта статья была рецензирована Дэном Принцем и Мэтью Уилкином . Спасибо всем рецензентам SitePoint за то, что сделали контент SitePoint как можно лучше!

У Slack есть определенная привлекательность и большой поклонник в сообществах разработчиков и не-разработчиков. Его приятный пользовательский интерфейс, концепция команд и каналов, позволяющих поддерживать коммуникацию отдельно и актуально, тонны интеграции для повышения производительности (Dropbox, Box, Google Calendar, Hangouts и т. Д.) И такие вещи, как giphy и напоминания , делают его забавным в использовании. Кроме того, их API-интерфейсы помогают разработчикам расширять функциональность и создавать индивидуальные возможности для своей команды.

Если вы думаете, что «ни в коем случае это не является уникальным для Slack, HipChat (или ваше любимое приложение) имеет все это!», Вы можете взглянуть на это: http://slackvshipchat.com/

Цель учебника

Цель этого руководства — помочь вам начать работу с простым приложением для узлов, которое превращает ваш канал Slack в пользовательский терминал командной строки. Мы будем использовать вспомогательный модуль с именем slack-terminalize ( disclaimer : я разработал его), который абстрагирует от начальной обработки сообщений. Он использует клиент Slack Real-Time API Node и готовит бота для прослушивания и ответа на ваши запросы.

Обратите внимание, что здесь мы не будем использовать команды Slash , но вместо этого мы будем интерпретировать обычные сообщения как команды. Так что, если вы хотите узнать о командах Slash, это может быть неуместное руководство.

Перед началом работы

Я предполагаю, что у вас есть практические знания JavaScript и NodeJS и что вы знакомы со Slack jargon: команды, каналы, боты и интеграции . Вам понадобится установленный узел и npm ; Вы можете следовать этому замечательному введению SitePoint в npm , чтобы настроить свою среду разработки.

Мотивация для разработки Slack-Terminalize

Хотя существует множество причудливых сценариев hubot, которые отвечают на запросы на естественном языке, многое можно достичь с помощью коротких команд и минимальных нажатий клавиш, как согласится любой поклонник Linux. Простые команды особенно полезны для мобильных устройств, помогая печатать меньше, делать больше. Если вы задумываетесь о системе командной строки, то в большинстве случаев оболочка выполняет тяжелую работу по извлечению, анализу, разбивке на токены и отправке команд (я знаю, что это чрезмерное упрощение).

Имея это в виду, я почувствовал необходимость в модуле, который мог бы сделать именно это. Оболочка для каналов Slack, если хотите. Благодаря подходу «процесс-диспетчеризация» и плагиноподобной архитектуре для добавления пользовательских команд, slack-Terminalize абстрагирует вещи, чтобы вы могли вместо этого сосредоточиться на определении поведения приложения.

Хватит говорить, давайте начнем

Во-первых, давайте создадим нового пользователя бота для вашей команды, который сможет принимать ваши заказы! Перейдите по https://<your-team-name>.slack.com/services/new/bot , выберите для него имя пользователя и нажмите Add Bot Integration .

Add Bot User

Скопируйте показанный вам токен API, поскольку это необходимо для того, чтобы ваш бот мог взаимодействовать с каналами. Настройте другие детали бота, его изображение профиля и настоящее имя, и нажмите « Сохранить интеграцию» .

Save Bot User

Теперь давайте клонируем пример приложения и установим зависимости:

 git clone https://github.com/ggauravr/slack-sample-cli.git cd slack-sample-cli npm install 

Краткое описание структуры проекта

Из списка зависимостей в package.json единственной требуемой зависимостью является slack-terminalize , но поскольку в примере приложения есть пример, демонстрирующий обработку асинхронных команд, модуль запроса используется для выполнения вызовов REST.

Project Structure

конфиг /

Все файлы JSON, которые могут вам понадобиться для вашего приложения, можно найти здесь. И я говорю «можно», потому что он достаточно гибкий, и вы можете изменить его для работы с другим каталогом через параметры конфигурации (подробнее об этом позже). Это только один из многих способов структурирования вашего приложения, но если вы новичок в интеграции Slack, я предлагаю вам придерживаться этого.

commands.json

Это то, что делает добавление пользовательских команд простым куском. Каждая команда представлена ​​парой ключ-значение: ключом является имя команды (я назову его основным именем ), а значением является объект с пользовательскими парами ключ-значение, которые вы хотите использовать для команды ,

Здесь я использую следующие настраиваемые поля для каждой команды:

  • alias — это псевдонимы (назовем их вторичными именами ) для команды, которые также можно использовать в слабом канале для вызова команды. Лучше всего, чтобы наименьшее имя было основным, а более значимые, более длинные имена — псевдонимами.

  • description — краткое читаемое описание того, что делает команда

  • help — сообщение помощи, чтобы сделать что-то вроде man <command-name> или help <command-name>

  • exclude — флаг, указывающий, должна ли эта команда отображаться в списке доступных пользователю команд. Некоторые команды могут быть только для целей разработки и / или помощников, которые не должны быть представлены пользователю (например, команда ошибки выше).

  • endpoint — конечная endpoint REST, с которой должна взаимодействовать команда, в случае, если выполнение каких-либо задач зависит от каких-либо внешних служб

Из вышеперечисленного alias является единственным ключом, который ищется для сопоставления пользовательских команд с его основным именем. Остальные являются необязательными, и вы можете использовать любые поля внутри объекта команды, как считаете нужным.

команды /

Это место, где происходит волшебство, место, где вы определяете поведение команды. У каждой команды, указанной в config / commands.json, должна быть соответствующая реализация, а имя файла соответствует ключу (первичному имени), используемому в этом JSON. Именно так диспетчер вызывает правильный обработчик. Да, я немного согласен, но, тем не менее, полезен и настраиваем.

 { "help": { "alias": [ "halp" ], "endpoint": "#", "help": "help [command](optional)", "description": "To get help on all supported commands, or a specified command" }, "gem": { "alias": [], "endpoint": "https://rubygems.org/api/v1/gems/{gem}.json", "help": "gem [gem-name]", "description": "Fetches details of the specified Ruby gem" }, "error": { "exclude": true } } 

Еще раз обратите внимание, что имена ключей в этом файле совпадают с именами файлов в каталоге commands/ .

Код прохождение

Замените значение для SLACK_TOKEN в index.js на значение для вашего бота. CONFIG_DIR и COMMAND_DIR должны указать COMMAND_DIR slack-terminalize где искать конфигурации и реализации команд соответственно.

 var slackTerminal = require('slack-terminalize'); slackTerminal.init('xoxb-your-token-here', { // slack client options here }, { CONFIG_DIR: __dirname + '/config', COMMAND_DIR: __dirname + '/commands' }); 

Затем запустите приложение с помощью следующей команды:

 node . 

Войдите в свою команду Slack через Интернет или приложение. Бот добавляется в #general канал по умолчанию, но вы можете пригласить бота на любой из каналов, даже приватный, с помощью команды Slash: /invite @<your-bot-name> . Как только вы введете /invite @ , Slack автоматически предложит вам имена пользователей. Если вы не видите своего бота в списке, вернитесь и проверьте, правильно ли вы интегрировали бота.

Invite Bot

Введите help или halp (псевдоним, помните?) В канале и «вуаля!», Бот должен ответить на ваш запрос. Продолжайте и commands/help.js с commands/help.js чтобы изменить то, что вы видите в ответе. Как видно из реализации, эта команда просто загружает подробные данные config/commands.json файла config/commands.json для ответа, поэтому она является синхронной. Иногда вам может потребоваться выполнить асинхронные задачи, такие как запрос к базе данных или вызов конечной точки REST, чтобы получить ответ. Давайте посмотрим, как это сделать.

Как я упоминал ранее, я использую модуль request для выполнения вызовов REST, а следующий фрагмент кода (команда gem) ищет имя гема, которое пользователь вводит в Slack. commands/gem.js и вы увидите, что он запоминает канал, на котором было размещено сообщение (с помощью замыкания ), и отправляет ответ в тот же канал!

 var request = require('request'), util = require('../util'); module.exports = function (param) { var channel = param.channel, endpoint = param.commandConfig.endpoint.replace('{gem}', param.args[0]); request(endpoint, function (err, response, body) { var info = []; if (!err && response.statusCode === 200) { body = JSON.parse(body); info.push('Gem: ' + body.name + ' - ' + body.info); info.push('Authors: ' + body.authors); info.push('Project URI: ' + body.project_uri); } else { info = ['No such gem found!']; } util.postMessage(channel, info.join('\n\n')); }); }; 

Попробуйте набрать gem ab в своем канале Slack, и вы должны увидеть что-то вроде этого:

Gem Response

Снова, попробуйте поиграться с форматированием ответа в commands/gem.js чтобы commands/gem.js его. Теперь у нас есть бот, который прослушивает приглашенные каналы и отвечает на наши запросы. Давайте посмотрим, как мы можем добавить пользовательские команды.

Добавление пользовательских реализаций команд

Добавьте вашу новую команду в config/commands.json . Как упоминалось ранее, ключ будет основным именем команды. Псевдонимы для команды представляют собой массив значений в псевдониме , как показано ниже.

 { "your-new-command": { "alias": [ "command-alias", "another-alias", "yet-another-alias" ], "help": "A short help message for the awesome new command", "description": "Brief description of what the command does" } } 

В настоящее время имена команд с пробелом в них не поддерживаются. Создайте файл с тем же именем, что и основное имя вашей команды выше (в данном случае your-command-name.js ), в каталоге commands/ . Присвойте module.exports функции реализации команды, как показано ниже.

 var util = require('../util'); module.exports = function (param) { // param object contains the following keys: // 1. command - the primary command name // 2. args - an array of strings, which is user's message posted in the channel, separated by space // 3. user - Slack client user id // 4. channel - Slack client channel id // 5. commandConfig - the json object for this command from config/commands.json // implement your logic here.. // .. // send back the response // more on this method here: https://api.slack.com/methods/chat.postMessage util.postMessage(param.channel, '<your-message-to-be-posted-back-in-the-channel>'); }; 

Обратитесь к документации по node-slack-client, чтобы узнать больше об объектах User и Channel .

Запрограммируйте новую команду, перезапустите приложение и все! Ваша новая команда должна работать. Введите команду и посмотрите, получите ли вы ожидаемый ответ.

Настройка поведения с помощью конфигураций

Модуль slack-terminalize принимает два параметра: объект параметров и объект конфигурации.

 var slackTerminal = require('slack-terminalize'); slackTerminal.init({ autoReconnect: true // or false, indicates if it should re-connect after error response from Slack // other supported options can be seen here: https://github.com/slackhq/node-slack-client/blob/master/lib/clients/rtm/client.js }, { CONFIG_DIR: __dirname + '/config', COMMAND_DIR: __dirname + '/commands', ERROR_COMMAND: "error" // The filename it looks for in COMMAND_DIR, in case the user entered command is invalid }) 

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

Что дальше?

  • Определите для своей команды классные команды: развлекайтесь и повышайте производительность.
  • Форк проекта Slack-Terminalize и его пример приложения . Поиграйте, внесите свой вклад и помогите улучшить его. Если вы обнаружите какие-либо ошибки, создайте проблему в репо!
  • Ниже прокомментируйте, как вы используете Slack для повышения производительности, или если у вас есть какие-либо предложения о том, как это можно улучшить. У меня есть все уши, чтобы изучить творческие возможности, которыми наделены разработчики Slack API.

Ссылки и ресурсы