読者です 読者をやめる 読者になる 読者になる

ほげほげ(仮)

仮死状態

BotkitでSlackのSlash Commandを実装

f:id:STAR_ZERO:20160206234803g:plain:w300

最近、Botkitを色々いじっててSlash Commandについて調べたのでメモです。

今回のは1チームで使う感じの実装なので特にOAuthとかは使わないです。

標準のSlash CommandについてはHelpを参照してください。
Using slash commands – Slack Help Center

必要なもの

  • node.js
  • 公開サーバー

Slack設定

BotとSlash Commandで必要なSlack設定を行います。

bot作成

https://my.slack.com/services/new/bot にアクセスしてbotを作成します。

作成後にAPI Tokenが発行されるので、あとで使うので控えておきます。

Slash Command作成

https://my.slack.com/services/new/slash-commands にアクセスしてSlash Commandsを作成します。

サンプルでは/helloで作成しています。

URLにはhttp://[HOST_NAME]/slack/receiveのように記述します。HOST_NAMEの箇所は自分の環境に置き換えてください。

Botkitは内部でexpressを使ってWebアプリを起動してslack/receiveのパスでSlash Commandを受け取ります。

設定画面でAutocomplete help textを設定しておくとSlackで入力補完ができるようになるので、やっておくといいでしょう。

セットアップ

$ mkdir slashcommand-sample
$ cd slashcommand-sample
$ npm init

... いろいろ入力 ...

$ npm install --save botkit

コード

サンプルとして単純なSlash Commandを作ります。ファイル名はindex.jsで保存しています。

var Botkit = require('botkit');

if (!process.env.token) {
  console.log('Error: Specify token in environment');
  process.exit(1);
}

var controller = Botkit.slackbot({
  debug: false,
});

var bot = controller.spawn({
  token: process.env.token
}).startRTM();

// https://github.com/howdyai/botkit/issues/108
// SlashCommand受付時にteam idが保存されていないとエラーになるため、その対応。
bot.api.team.info({}, function(err, res) {
  controller.storage.teams.save({
    id: res.team.id
  }, function(err) {
  });
});

// Webサーバー起動(express)
controller.setupWebserver(process.env.port, function(err, webserver) {
  // end pointのパス作成(/slack/receive)
  controller.createWebhookEndpoints(controller.webserver);
});

controller.on('slash_command', function(bot, message) {
  // Slash Commandを受け取った時の処理
  if ('/hello' === message.command) {
    // 公開リプライ
    bot.replyPublic(message, 'Hello!');
  }
});

Slash Commandしか使わないの場合でもbotの設定が必要になりますので注意してください。理由はBotkit内部でteam idがあるかをチェックしてる箇所があるため、事前にbotオブジェクト経由でteam idを保存する必要があるからです。

デプロイ

どっか公開されてるサーバーへデプロイしてください。

ぼくが試した環境はVPSですが、Herokuでも設定をすればたぶん動きます。

起動

$ token=xxxxxxxxxxx port=3000 node index.js

tokenはbotを作成して生成されたAPI Tokenを指定します。portはWebを受け付けるport番号指定します。

もしくは環境変数に事前に設定しておきます。

色々な返信

Slash Commandの返信の方法です。

公開リプライ

他のメンバーが見れます

bot.replyPublic(message, 'Hello!');

非公開リプライ

Slash Commandを実行した本人のみが見れます。

bot.replyPrivate(message, 'Hello!');

Attachments

詳しくは公式ドキュメントを見て欲しいのですが、リッチフォーマットのものを返信できます。

message.text = 'Hello!';
message.attachments = [{
  text: 'Attachement text',
  image_url: 'https://octodex.github.com/images/original.png'
}];
bot.replyPublic(message, message);

この例だと次のような感じで表示されます。

f:id:STAR_ZERO:20160206234847p:plain:w300

注意事項

Slash Commandは基本的にHTTPのJSONレスポンスを返すことで返信しているので、例えば同時に2件リプライするようなことはできません。

bot.replyPublic(message, '11111');
// 2件目はエラーになる (Error: Can't set headers after they are sent.)
bot.replyPublic(message, '22222');

サンプル

今回のサンプルはGitHubにあげてあります。

STAR-ZERO/slashcommand-sample

参考