Message Buttonとは
最近になってSlack APIに追加された新機能 普段使ってるタイムライン上でボタン出せるよ!って話
ニュースになって(一部の界隈では)結構話題になった
その割に「実際に試してみた」的な記事は殆ど見かけない。あのQiitaですら音沙汰ない(平成28年7月2日現在)
何故か、理由は簡単で APIはシンプルなくせに実装がくっそ煩わしいから である
けどどうしてもボタンを作ってみたくなったので試しにやってみた
用意するもの
- Slack
- 1 Integration消費するっぽい かなC
- SSL通信できるサーバー
- 証明書はLet's Encryptでも可能
- 上記サーバーに接続するためのドメイン1つ
構成
数値はポート番号を表す。
[ いんたーねっと ]-----[ ルーター ]--443--[ nginx ]--3000--[botkit]
証明書の準備
繰り返すがLet's Encryptでもできた 要はHTTPSなら何でもいいっぽい(オレオレ証明書は未確認)
Slackの設定
これが結構ややこしい
https://api.slack.com/apps/newにアクセスしてアプリを作る 作成時は適当でもおk
次にココからさっき作ったアプリの設定画面に行き各種設定を行う
- App Credentialsより
- Redirect URIを
https://YOUR_HOST/oauth
にする - Client IDとClient Secretは後で使うので控えておく
- Redirect URIを
- Bot Userより
- 適当な名前を設定しておく
- Interactive Messagesより
- Request URLを
https://YOUR_HOST/slack/receive
にする
- Request URLを
nginxのインストール
省略 リバースプロキシ役なので適当に443でlistenしてhttp://localhost:3000に投げればおk
Botの作成
npm init
して npm install -S botkit
は予めやっておく bot.jsとして以下を作成
var Botkit = require('botkit'); /*********************************** * Setup ***********************************/ if (!process.env.clientId || !process.env.clientSecret || !process.env.port) { console.log('Error: Specify clientId clientSecret and port in environment'); process.exit(1); } var controller = Botkit.slackbot({ json_file_store: './bot_db/' }).configureSlackApp( { clientId: process.env.clientId, clientSecret: process.env.clientSecret, scopes: ['bot'] } ); controller.on('create_bot',function(bot,config) { if (_bots[bot.config.token]) { // already online! do nothing. } else { bot.startRTM(function(err) { if (!err) { trackBot(bot); } bot.startPrivateConversation({user: config.createdBy},function(err,convo) { if (err) { console.log(err); } else { convo.say('I am a bot that has just joined your team'); convo.say('You must now /invite me to a channel so that I can be of use!'); } }); }); } }); // Handle events related to the websocket connection to Slack controller.on('rtm_open',function(bot) { console.log('** The RTM api just connected!'); }); controller.on('rtm_close',function(bot) { console.log('** The RTM api just closed'); // you may want to attempt to re-open }); controller.setupWebserver(process.env.port,function(err,webserver) { controller.createWebhookEndpoints(controller.webserver); controller.createOauthEndpoints(controller.webserver,function(err,req,res) { if (err) { res.status(500).send('ERROR: ' + err); } else { res.send('Success!'); } }); }); var _bots = {}; function trackBot(bot) { _bots[bot.config.token] = bot; } controller.storage.teams.all(function(err,teams) { if (err) { throw new Error(err); } // connect all teams with bots up to slack! for (var t in teams) { if (teams[t].bot) { controller.spawn(teams[t]).startRTM(function(err, bot) { if (err) { console.log('Error connecting bot to Slack:',err); } else { trackBot(bot); } }); } } }); /************************** * Reply **************************/ controller.hears('hi', ['direct_message','direct_mention','mention'],function(bot,message) { var reply = { "text": "朝にする挨拶は?", "attachments": [{ "text": "どれか1つ選んでね", "fallback": "failed...", "callback_id": "my_quiz", "color": "#3AA3E3", "actions": [ { "type": "button", "name": "atari", "text": "おはよう" }, { "type": "button", "name": "hazure", "text": "こんにちは" }, { "type": "button", "name": "hazure", "text": "こんばんわ" } ] }] }; bot.reply(message, reply); }); controller.on('interactive_message_callback', function(bot, message) { var users_answer = message.actions[0].name; if (users_answer == "atari") { bot.replyInteractive(message, "正解!"); }else { bot.replyInteractive(message, "はずれ。。。。"); } });
コードは以下を参考にした
- henteko/slack_message_button_test
- botkit/slackbutton_bot_interactivemsg.js at master · howdyai/botkit(公式サンプル)
実行!
clientId=CLIENT_ID clientSecret=CLIENT_SECRET port=3000 node bot.js