slackのBotkitとkintoneを使って、クリスマスプレゼントを選んでみた

[kintone Advent Calendar 2016](http://qiita.com/advent-calendar/2016/kintone) の24日目の記事です。

今夜はクリスマスイヴということで、クリスマスプレゼントを何にするか悩んでいる人も多いのではないでしょうか？
私は、優柔不断なので全然選べません・・・orz

そんな悩める方におくるslack kintone 連携を考えてみました。

#理想形
理想形は、まず適当にピックアップしたいくつかの商品をkintoneにいれておきます。
slackで「プレゼントを決める」とつぶやくと、kintoneに入れておいたプレゼントからランダムで選んでとってきてくれるbot的なやつを作ろうと思います。
![risou.png](https://qiita-image-store.s3.amazonaws.com/0/83679/b9a08622-ba5a-5637-4656-64891d6787d7.png)

優柔不断なので、登録しておいたプレゼントをランダムに選んでくれると尚よいです。

#kintoneの準備
今回は以下のようなシンプルなアプリを作りました。
![プレゼントcapture.PNG](https://qiita-image-store.s3.amazonaws.com/0/83679/00d2534c-d7e6-888a-b92b-1e5b3467dbff.png)

| フィールド名       |       フィールドタイプ |    フィールドコード    | 　備考   |
|:-----------------:|:------------------:|:------------------:|:------------------:|
| 品名             |文字列(1行)             |item        |        |
| 値段             |数値                    |price       |        |     
| 詳細             |文字列(複数行)　　　　　 |details     |        |   
| ステータス       |ラジオボタン            |status       |   選択肢は「渡してない」「渡した」     |    
| リンク           |リンク              　 |item_link    |         |

試しにいくつかプレゼントを登録しておきます。
迷ったので、最近流行りの品々を。PPAP。
![capture1.PNG](https://qiita-image-store.s3.amazonaws.com/0/83679/ca5dccf8-e11c-0085-b821-16efe63c3b52.png)

また、後ほど使うので アプリの設定を変更 → 設定 → APIトークン よりAPIトークンを発行しておきます。[参考](https://help.cybozu.com/ja/k/user/api_token.html) 
アクセス権は、「レコード閲覧」「レコード追加」「レコード編集」を与えておきます。
![apiToken.PNG](https://qiita-image-store.s3.amazonaws.com/0/83679/98ba2b19-02e8-946e-1b77-0a142ba4772f.png)

#SlackのBotKitの準備
[こちら](http://dotnsf.blog.jp/archives/1054134334.html)の記事を参考に、サクサク準備を進めます。
[Bot creation page](https://my.slack.com/services/new/bot)にアクセスして、新しいbotを作成します。
名前は「kintone_bot」にしました。
![slack-bot.PNG](https://qiita-image-store.s3.amazonaws.com/0/83679/dda51245-5474-439a-0c45-68dbf55af808.png)

次に、npmをセットアップした環境でごにょごにょしていきます。
(nodeやらもろもろインストールしましたが、環境セットアップは割愛します。)

```
# mkdir /slack_work
# cd /slack_work
# git clone https://github.com/howdyai/botkit.git
# cd botkit/
# token='取得したトークン' node slack_bot.js
```

参考記事通り、kintone_botを招待して挨拶したらkintone_botが喋りましたっ！！
![slack-kin-bot.PNG](https://qiita-image-store.s3.amazonaws.com/0/83679/b1a82eb4-6836-cefd-5e93-53c17059efaa.png)

これでもちょっと満足してしまったのですが、さらに改造してkintoneのデータを使って喋らせてみたいと思います。

#SlackのBotKitをいじってみる
[BotkitでSlackのBotをサクッと作る方法](http://toach.click/slack-botkit/)を参考に、kintone連携 botを作ってみたいと思います。やりたいことは2つ。

- kintoneに登録したプレゼントをランダムで選んでサジェストしてくれる。
- 贈ったプレゼントは、プレゼント名を語りかけると「渡した」フラグ更新してくれる。

準備として、フラグ更新の際にプレゼント名を指定したいため、kintone側でフィールド名「品名」の値の重複を禁止にしておきます。

![cyoufuku-kinshi.PNG](https://qiita-image-store.s3.amazonaws.com/0/83679/30aa609c-e414-4c71-3faa-c548bb9778cc.png)

また、これによって「品名」もそれぞれユニークなものにしておきます。

![index.PNG](https://qiita-image-store.s3.amazonaws.com/0/83679/85d1c281-6008-f416-6544-d8ac52086d81.png)

slack_bot.jsを編集してkintoneと通信できるようにします。

```js
:slack_bot.js
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           ______     ______     ______   __  __     __     ______
          /\  == \   /\  __ \   /\__  _\ /\ \/ /    /\ \   /\__  _\
          \ \  __<   \ \ \/\ \  \/_/\ \/ \ \  _"-.  \ \ \  \/_/\ \/
           \ \_____\  \ \_____\    \ \_\  \ \_\ \_\  \ \_\    \ \_\
            \/_____/   \/_____/     \/_/   \/_/\/_/   \/_/     \/_/


This is a sample Slack bot built with Botkit.

This bot demonstrates many of the core features of Botkit:

* Connect to Slack using the real time API
* Receive messages based on "spoken" patterns
* Reply to messages
* Use the conversation system to ask questions
* Use the built in storage system to store and retrieve information
  for a user.

# RUN THE BOT:

  Get a Bot token from Slack:

    -> http://my.slack.com/services/new/bot

  Run your bot from the command line:

    token=<MY TOKEN> node slack_bot.js

# USE THE BOT:

  Find your bot inside Slack to send it a direct message.

  Say: "Hello"

  The bot will reply "Hello!"

  Say: "who are you?"

  The bot will tell you its name, where it is running, and for how long.

  Say: "Call me <nickname>"

  Tell the bot your nickname. Now you are friends.

  Say: "who am I?"

  The bot will tell you your nickname, if it knows one for you.

  Say: "shutdown"

  The bot will ask if you are sure, and then shut itself down.

  Make sure to invite your bot into other channels using /invite @<my bot>!

# EXTEND THE BOT:

  Botkit has many features for building cool and useful bots!

  Read all about it here:

    -> http://howdy.ai/botkit

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/


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

var Botkit = require('./lib/Botkit.js');
var os = require('os');
var request = require('request');
var DOMAIN = 'your domain';
var APP_ID = 'app number';
var API_TOKEN = 'your API token';
var BASE_URL = 'https://' + DOMAIN + '/k/v1/';
var headers = {'X-Cybozu-API-Token': API_TOKEN}
var controller = Botkit.slackbot({
    debug: true,
});
var bot = controller.spawn({
    token: process.env.token
}).startRTM();
var myIds = [];

controller.hears(['Choose a gift.'], 'direct_mention, mention', function(bot, message){
    var query = 'give_status in ("渡してない")'
    var body_get = {
      app: APP_ID,
      query: query
    }
    var options_get = {
      url: BASE_URL + 'records.json',
      method: 'GET',
      headers: headers,
      'Content-Type': 'application/json',
      json: body_get
    }
    request(options_get, function(error, response, body){
      var records = body.records;
      if(records.length > 0){
        myIds = [];
        for(var i = 0; i < records.length; i++){
          myIds.push(i);
        }
        var myIndex = myIds[Math.floor(Math.random() * myIds.length)];
        bot.reply(message, records[myIndex].my_item.value+'をプレゼントしましょう！ \n リンク:' + records[myIndex].item_link.value);
      }else{
        bot.reply(message, '今年のプレゼントはなくなりました。');
      }
    });
});

controller.hears(['I gave a present.'], 'direct_mention, mention', function(bot, message){
  bot.startConversation(message, function(err, convo){
    convo.ask('What is your item name ?', function(resp, convo){
      var item_name = resp.text;
      var body_update = {
        app: APP_ID,
        updateKey: {
          "field":"my_item",
          "value":item_name
        },
        record: {
          "give_status" : {
            "value" : "渡した"
          }
        }  
      }
      var option_put = {
        url: BASE_URL + 'record.json',
        method: 'PUT',
        headers: headers,
        'Content-Type': 'application/json',
        json: body_update
      }
      request(option_put, function(error, response, body){
        console.log(JSON.stringify(response));
        if(response.statusCode == 200){
          bot.reply(message, item_name + 'のステータスを「渡した」に変更しました！');
        }else{
          bot.reply(message, 'Error');
        }
        convo.stop();
      });
    });
  });
});

```

#プレゼントを早速選んでみる
では、早速プレゼントを選んでみます。
`token="your token" node slack_bot.js` 　
でbotを起動後、Choose a gift.と語りかけてみます。
![choose-gifts.PNG](https://qiita-image-store.s3.amazonaws.com/0/83679/f9631680-e6c2-eada-99df-26500e5ca87f.png)


おおっ。ランダムに選べてるのか怪しいのでもう一度・・・
![choose-pip.PNG](https://qiita-image-store.s3.amazonaws.com/0/83679/7cb1996a-d201-97d8-cf8f-dc503214506e.png)

今度はペンが選ばれましたね。
このペンは早速プレゼントしてしまいましたので、渡したフラグを付けてみます。
I gave a present.と語りかけ会話を楽しみます。
![flag-change.PNG](https://qiita-image-store.s3.amazonaws.com/0/83679/0a77283e-0793-00bf-22de-c5f681b098fa.png)

フラグが変わったっぽいのでkintoneをみてみます。
![kintone.PNG](https://qiita-image-store.s3.amazonaws.com/0/83679/94b2a74a-98b8-643e-f719-b8ba7f54b56a.png)

無事にフラグの変更ができました。
PPAP♪

#所感
なかなか楽しくkintone連携できました。
今度は、[Amazon Lex](https://aws.amazon.com/jp/lex/)連携なんかもやってみたいなぁと思います。