Статьи

Написание плагинов Hubot с CoffeeScript

Если вы прятались под скалой, Campfire — это приложение для чата в реальном времени, написанное нашими друзьями по адресу 37 Signals. Campfire имеет надежный API , который дает вам возможность использовать инструменты для улучшения командной среды.

Campfire широко используется компаниями с удаленными работниками и позволяет быстро сотрудничать между распределенными командами. Имейте в виду, что в некоторых случаях, например, на моей работе в Emma, ​​Inc. , удаленный может означать «в соседней комнате». В Эмме мы можем проверить состояние наших систем, быстро получить данные о клиентах и ​​многие другие полезные задачи, которые облегчают нашу работу. Многие из этих задач стали возможными благодаря реализации Hubot .


Плагины интересно писать и еще веселее использовать.

Hubot — это скриптовая среда, созданная людьми из Github; они описывают его как «настраиваемого, питаемого кегератором робота для жизнедеятельности». Hubot является открытым исходным кодом, написан на CoffeeScript для Node.js и легко развертывается на платформах, таких как Heroku. Хотя Hubot может работать в разных средах, я сосредоточусь на запуске Hubot в пределах чата Campfire.

В дополнение к выпуску исходного кода для Hubot , Github создал небольшое количество готовых скриптов, которые поставляются с исходным кодом Hubot. Эти сценарии позволяют Hubot легко импортировать изображения /img cute kittens :

image

Или вы можете импортировать видео /youtube breakdancing :

image

Github также создал хранилище плагинов Hubot, где пользователи могут отправлять новые плагины. На момент написания этой статьи в общедоступном репозитории насчитывалось 294 плагина, охватывающих все виды функциональных возможностей, начиная от полезных: проверка состояния службы AWS , взаимодействие с сервером Travis-CI или кодирование base64 ; для юмора: проигрывание римшота аудиоклипа ; до абсурда: добавить усы к фотографии . Вы даже можете проверить плагин генератора никнейма, который я написал!

Небо это предел с Hubot. Если что-то можно сделать из Node.js, то это можно автоматизировать с помощью Hubot. С небольшим знанием CoffeeScript вы можете написать следующий отличный плагин Hubot. Кстати, давайте быстро пройдем курс повышения квалификации по CoffeeScript, прежде чем писать наш первый плагин Hubot. Если вы уже знакомы с CoffeeScript, переходите к следующему разделу.


CofeeeScript описывает себя как «маленький язык, который компилируется в JavaScript» и «попытку раскрыть хорошие части JavaScript простым способом». Цель CoffeeScript состоит в том, чтобы убрать скуку шаблонов (все эти надоедливые фигурные скобки, точки с запятой и круглые скобки) из жизни разработчиков и превратить JavaScript в его чистую сущность. В результате ваш код становится легче читать, и его становится меньше для загрузки. Давайте посмотрим на несколько простых примеров и сравним полученный JavaScript, который вы компилируете CoffeeScript.

Ой, подождите, я сказал «компилировать»?

Я уверен, и как ты это делаешь? Я рад, что вы спросили … есть ряд инструментов, которые предлагают эту услугу. Мой личный фаворит — CodeKit , но обязательно ознакомьтесь с командной строкой Yeoman . Вы также можете напрямую скомпилировать CoffeeScript, если вы установили Node.js, и вы даже можете использовать инструмент преобразования в реальном времени, такой как JS2Coffee , который позволяет вам конвертировать туда и обратно между CoffeeScript и JavaScript.

Итак, как выглядит CoffeeScript? Давайте начнем со строки JavaScript:

var author = 'Ernest Cline';

Эквивалент CofeeScript:

author = 'Ernest Cline'

Это простой пример, но он начинает показывать, что CoffeeScript делает для вас … удаление многословия. Обратите внимание на отсутствие ключевого слова var и точки с запятой. Они вам никогда не понадобятся, когда вы пишете на CoffeScript. Как насчет ссылки на объект в JavaScript?

1
2
3
4
5
6
7
8
9
book = {
    title: ‘Ready Player One’,
    date: ’10/16/2011′,
    references: {
        games: [‘Street Fighter’, ‘Pac-Man’],
        music: [‘Oingo Boingo’, ‘Men Without Hats’],
        movies: [‘Back To The Future’, ‘The Last Starfighter’]
    }
}

Вот версия CoffeeScript:

1
2
3
4
5
6
7
book =
 title: «Ready Player One»
 date: «10/16/2011»
 references:
   games: [«Street Fighter», «Pac-Man»]
   music: [«Oingo Boingo», «Men Without Hats»]
   movies: [«Back To The Future», «The Last Starfighter»]

Ключевой момент, который следует помнить о CoffeeScript, заключается в том, что ваш код все еще там, но лишние разделители, терминаторы и ключевые слова пропали. CoffeeScript делает дополнительный шаг (или три) и принимает эти символы за вас.

Как насчет функций вы можете спросить? Они так же аккуратны, убирают скобки и ключевое слово return. Как и прежде, вот JavaScript:

01
02
03
04
05
06
07
08
09
10
function openGate(key) {
    var gates = {
        ‘Copper’: ‘You opened the Copper Gate’,
        ‘Jade’: ‘You opened the Jade Gate’,
        ‘Crystal’: ‘You opened the Crystal Gate’
    };
    return gates[key] ||
}
 
openGate(‘Jade’)

И вот то же самое в CoffeeScript:

1
2
3
4
5
6
7
8
openGate = (key) ->
  gates =
    Copper: «You opened the Copper Gate»
    Jade: «You opened the Jade Gate»
    Crystal: «You opened the Crystal Gate»
 
  gates[key] |
openGate «Jade»

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


Нам нужно будет установить несколько элементов, прежде чем мы сможем начать работу над нашим плагином. Нам понадобятся Node.js, NPM и Hubot — вместе с их различными зависимостями.

Небо это предел с Hubot.

Давайте сначала установим Node.js. Откройте окно терминала и введите, which node . Если вы вернетесь к пути файловой системы, вы можете пропустить этот раздел. Если вы видите, что node not found или что-то подобное, вам нужно будет установить его. Перейдите на сайт Node.js и загрузите (и установите) соответствующий двоичный файл для вашей операционной системы. Если вы недавно не установили Node, возможно, стоит попробовать установить самую последнюю версию. Новые версии Node поставляются с NPM (или Node Package Manager), который мы будем использовать для установки нашего программного обеспечения.

Далее нам нужно установить Hubot. Введите npm install hubot -g в окно терминала и позвольте NPM выполнять свою работу. Я предпочитаю устанавливать подобные плагины глобально, поэтому флаг -g.

После завершения установки мы перейдем в каталог установки hubot и запустим его в первый раз. Этот каталог может отличаться в зависимости от вашей конкретной машины, но он находится в /usr/local/lib/node_modules/hubot на моей машине. Запустите Hubot с помощью следующей команды . bin/hubot . bin/hubot Затем проверьте это с помощью команды hubot ping . Hubot должен немедленно ответить PONG . Давайте кратко рассмотрим этот плагин, прежде чем писать наш собственный. Три строчки кода — это сущность практически любого другого плагина Hubot. Вот оно во всей красе:

1
2
3
module.exports = (robot) ->
   robot.respond /ping$/i, (msg) ->
       msg.send «ping»

При первом запуске Hubot он запускается через каждый плагин в каталоге scripts. Каждый плагин написан с использованием общего module.exports Node module.exports , который позволяет плагину идентифицировать себя для Hubot, а также предоставляет Hubot доступ к внутренней работе плагина. Также в плагине есть один или несколько respond вызовов функций. Каждый из этих вызовов связан с прослушивателем событий, который ожидает услышать определенное ключевое слово или шаблон. Наконец, этот плагин отправляет обратно значение, используя msg.send , возвращая любое произвольное сообщение, которое вы предпочитаете.

Кстати, если вам любопытно (как и мне) увидеть, что содержат аргументы робота или msg, просто добавьте оператор console.log любом месте кода. Например, добавление console.log(robot) сразу после операторов module.exports отображает следующую информацию:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
{
      name: ‘Hubot’,
      commands: [],
      version: ‘2.3.4’,
      server: {}
      documentation: {},
      listeners:
      [
            {
                  robot: [Circular],
                  regex: /^Hubot[:,]?\s*(?:PING$)/i,
                  callback: [Function],
                  matcher: [Function]
            }
      ],
      [more stuff]
}

Теперь вы готовы начать работу над нашим первым плагином Hubot.


Хорошо, хватит уже. Я знаю, что вы готовы написать свой собственный плагин, поэтому давайте сделаем быстрый наш собственный. Создайте новый файл в каталоге scr/scripts вашей установки Hubot. Назовите его deepthoughts.coffee , откройте его в выбранном вами редакторе и введите следующие строки:

01
02
03
04
05
06
07
08
09
10
# Configures the plugin
module.exports = (robot) ->
    # waits for the string «hubot deep» to occur
    robot.respond /deep/i, (msg) ->
        # Configures the url of a remote server
        msg.http(‘http://andymatthews.net/code/deepthoughts/get.cfm’)
            # and makes an http get call
            .get() (error, response, body) ->
                # passes back the complete reponse
                msg.send body

Вы уже знакомы с первыми двумя строками, поэтому мы не будем их рассматривать. Третья строка начинает настройку HTTP-запроса; в этом случае это GET, который не отправляет параметры на удаленный сайт. Четвертая строка выполняет HTTP-запрос и устанавливает функцию обратного вызова, которая получает любые ошибки, необработанный ответ и тело возвращаемой страницы. В этом случае тело загруженной страницы даже не имеет HTML … это просто строка. Это позволяет нам возвращать его непосредственно пользователю посредством msg.send . Сохраните этот файл, перезапустите Hubot с помощью hubot die и bin/hubot , а затем bin/hubot случайную глубокую мысль с hubot deep . Надеюсь, это что-то глубокое, глубоко провоцирующее, а не о продавце батутов или золотом скунсе.

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

01
02
03
04
05
06
07
08
09
10
QS = require ‘querystring’
 
module.exports = (robot) ->
    robot.respond /post (.+)/i, (msg) ->
        url = ‘http://httpbin.org/post’
        data = QS.stringify({‘hubot-post’: msg.match[1]})
 
        msg.http(url)
            .post(data) (err, res, body) ->
                msg.send body
  • Обратите внимание, что импорт происходит сверху.
  • Что слушает метод ответа?
  • Что такое msg.match ?
  • Видите, что плагин также может делать запросы?

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

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