ひびのログ

日々ではないけどログを出力していくブログ

Slack bot をBotkitで作成してみる!

私は今プライベートでSlackを使っていて、botを育てている最中です。 だんだん機能が充実してきて、なかなか楽しくなってきました。 どのような機能があるのか、今後ご紹介したいと思っています。

今回はbotを動かすところまで解説したいと思います。



環境

OS:CentOS7
Node.js:9.2

Hello World

まずは、botに「hello」とリプライを送ったら「World」と言うようにしましょう。

Slackの設定(事前準備)

Appディレクトリを「Bots」で検索して「設定を追加」! ユーザー名を入力して「追加する」ボタンを押すと設定画面が出てきます。 そこにAPI トークンがあり、それを使用します。 それ以外はよしなに設定しておいてください。

サーバ側の設定

私は勉強用のVPSが遊んでいたので、それを使用しています。 Herokuとかでも運用できるみたいなので、完全無料がいい方はそちらを使用してください。

ちなみに外部からポートを開ける必要などはありません。

サーバにSSHしたら、Slack bot用のディレクトリを作成して、npm init -yを実行します。 いつものやつです。

するといつものようにpackage.jsonとかができるので、以下のようにBotkitをインストールします。

$ npm init -y
$ npm i -S botkit

botのソースは下記のとおりです。

const Botkit = require("botkit");

// bot controller 取得
const controller = Botkit.slackbot({
    debug: false,
});

// botの起動
controller.spawn({ token: slackToken }).startRTM((err, bot, payload) => {
    // エラーが出たら落とす
    if (err) {
        throw new Error(err);
    }
});

// 指定した単語が、指定の方法で投稿された場合に、コールバックを実行する
controller.hears(["hello"], ["direct_mention"], (bot, message) => {
    bot.reply(message, "World");
});

slackTokenには、先程取得したAPI トークンを記述してください。

そしてnodeコマンドで実行すれば、botが起動します。 Slackでbotに「Hello」とリプライを送ると、「World」と返ってきます。 「Hello」がどこかしらに含まれていれば反応があります。

f:id:tee-talog:20171218224454p:plain

(かなり黒いですね……)

もうちょっと賢くさせる

簡単なやつだけじゃなくてもっと難しいこともしたい! というあなたに。

正規表現

反応する単語を正規表現で指定することもできます。 ただし正規表現リテラルではなく、文字列で指定する必要があるようです。

// 最後にYOとついている投稿があったら反応する
controller.hears(["YO$"], ["ambient"], (bot, message) => {
    bot.reply(message, "YOYO!");
});

キャプチャもできます!

controller.hears(["ドーモ。(.*)です"], ["direct_mention", "direct_message"], (bot, message) => {
    bot.reply(message, `ドーモ。${message.match[1]}=サン。botです。`);
});

定時処理

Botkitだけではできないため、cronパッケージを使用します。

$ npm i -S cron

そして、bot.replyは使用できないため、bot.sayを使用します。 botを起動した際にcronへ登録します。

// botの起動
controller.spawn({ token: slackToken }).startRTM((err, bot, payload) => {
    // エラーが出たら落とす
    if (err) {
        throw new Error(err);
    }
    
    // cronに登録
    new CronJob({
        cronTime: "0 12 * * *",
        onTick: () => bot.say({
            text: "お昼休みは ウキウキ watching",
            channel: "general",
        }),
        start: true,
        timeZone: "Asia/Tokyo",
    });
});

ファイルアップロード時の処理

controller.hearsは、特定の単語のみに反応しますが、もっと広範囲に反応するcontroller.onを使用します。

// ファイルアップロードイベントにリスナ登録する
controller.on(["file_share"], (bot, message) => {
    bot.reply(message, "ファイルがアップロードされました。”);
});

ちなみに

controller.hearscontroller.onの特化したもの、
bot.replybot.sayの特化したものと捉えています。


その他詳しくは、Botkitの公式ドキュメントを参照してください。

https://github.com/howdyai/botkit/blob/master/docs/readme.mdgithub.com

messageオブジェクトをのぞいてみると面白いと思います。