Slack: Build a chat bot with Hubot in JavaScript

Slack: Build a chat bot with Hubot in JavaScript

Hubot is an scriptable chat bot framework created by GitHub. The newer version supports JavaScript (ES6+), no more CoffeeScript!

ref:
https://hubot.github.com/
https://slack.dev/hubot-slack/

Installation

$ npm install -g yo generator-hubot

$ mkdir codetengu-bot
$ cd codetengu-bot
$ yo hubot --adapter=slack

You could find all available adapters here:
https://hubot.github.com/docs/adapters/

Slack Token

The next thing you need is a Slack Bot Token (API Token) which looks like xoxb-xxx for your chat bot app. You could create a Hubot app in your Slack workspace to request a token, for instance https://vintachen.slack.com/apps/A0F7XDU93-hubot.

Otherwise, you could also create an universal Slack app, install it to your workspace. In your app settings, under "Install App" section, you are able to find OAuth Tokens for your chat bot. See https://api.slack.com/apps.

ref:
https://api.slack.com/bot-users

Development

$ HUBOT_SLACK_TOKEN=YOUR_SLACK_BOT_TOKEN \
./bin/hubot --adapter slack

I fork a script named hubot-reload-scripts to help you reload your scripts when developing them.
https://github.com/vinta/hubot-reload-scripts

Hear And Respond Messages

Writing your own script
https://hubot.github.com/docs/scripting/

// scripts/your_script.js
// Description
//   Do your shit
//
// Author:
//   Vinta Chen
//
// Commands:
//   * `restart <service>`* - Restart the service
//
const _ = require('lodash');

module.exports = (robot) => {
  robot.hear(/restart ([a-z0-9_\-]+)/i, (res) => {
    robot.logger.debug(`Received message: ${res.message.rawText}`);
    const [ serviceName ] = res.match.slice(1);
    res.send(`Restarting ${serviceName}`);
    doYourShit();
  });
};

Call Slack APIs

robot.slack.channels.info({'channel': res.message.rawMessage.channel})
  .then(apiRes => {
    const purpose = apiRes.channel.purpose.value;
    const topic = apiRes.channel.topic.value;
    res.send(`purpose: ${purpose}`);
    res.send(`topic: ${topic`);
  })
  .catch(apiErr => {
    robot.logger.error('apiErr', apiErr);
  });

ref:
https://slack.dev/hubot-slack/basic_usage#using-the-slack-web-api
https://api.slack.com/methods

Parse datetime in Python and JavaScript

Parse datetime in Python and JavaScript

Python

I recommend dateutil.

ref:
https://dateutil.readthedocs.org/en/latest/

import datetime
from dateutil import parser as dateutil_parser

>>> dateutil_parser.parse('2014-12-24T16:15:16')
datetime.datetime(2014, 12, 24, 16, 15, 16)

>>> datetime_obj = datetime.datetime.strptime('2014-12-24T16:15:16', '%Y-%m-%dT%H:%M:%S')
datetime.datetime(2014, 12, 24, 16, 15, 16)

>>> datetime_obj = datetime.datetime.strptime('201408282300', '%Y%m%d%H%M')
datetime.datetime(2014, 8, 28, 23, 0)

>>> datetime_obj.strftime('%Y-%m-%d %H:%M')

strftime >> datetime -> str
strptime >> str --> datetime

ref:
https://docs.python.org/2/library/datetime.html#strftime-and-strptime-behavior

Django Template

class DriverInfoForm(forms.ModelForm):
    service_time_start = forms.TimeField(
        widget=forms.TimeInput(format='%H:%M'),
        input_formats=['%H:%M', ]
    )

@register.filter
def str_to_time(time_str, output_format):
    """
    把字串轉成 datetime obj
    再依據 output_format 輸出

    {{ news.modified_at|str_to_time:"%Y/%m/%d %H:%M" }}
    """

    from dateutil import parser

    datetime_obj = parser.parse(time_str, fuzzy=True)

    return datetime_obj.strftime(output_format)
日期:{{ withdraw.presented_at|date:"%Y 年 %n 月" }}
聯絡時間:{{ driver.service_time_start|date:"H:i" }} - {{ driver.service_time_end|date:"H:i" }}

要注意的是,Django 似乎不能 parse AM / PM,所以儘量用 24 小時制。

ref:
https://docs.djangoproject.com/en/dev/ref/templates/builtins/#date

JavaScript

I recommend moment.js.

ref:
https://momentjs.com/

var today = new Date().toISOString().slice(0, 10);
// 2016-05-11

var t1 = new Date('2016-05-02T03:00:00.000+01:00');
// Mon May 02 2016 10:00:00 GMT+0800 (CST)

var t1_timestamp_ms = t1.getTime();
// 要注意的是 JavaScript 的 getTime() 的單位是 ms
// 1462154400000

var t1_timestamp = t1.getTime() / 1000;
// 1462154400

var t2 = new Date(1485596172 * 1000);
// Sat Jan 28 2017 17:36:12 GMT+0800 (CST)

var t3 = moment('201408292300', 'YYYYMMDDHHmm');

var t3 = moment('2018-02-02')
var timestamp = time.unix()
// 單位是 second
// 1518192000

ref:
https://stackoverflow.com/questions/3552461/how-to-format-a-javascript-date

nvm: Node.js Version Manager

nvm: Node.js Version Manager

A simple Node.js version manager.

Install nvm

$ curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.34.0/install.sh | bash

ref:
https://github.com/nvm-sh/nvm

Install Node.js

You could also simply run brew install node if you don't really care about what version you installed.

# list available Node.js versions
$ nvm ls-remote

# install the latest LTS version
$ nvm install --lts

$ nvm install 12.13.0 && \
  nvm use 12.13.0 && \
  nvm alias default 12.13.0

# list installed Node.js versions
$ nvm ls

ref:
https://nodejs.org/en/

Install Node.js Packages

# install the package globally
$ npm install -g pangu

# install the package in the current folder
# which generate `package.json` in the same folder
$ npm init
$ npm install pangu