名刺から情報を抽出するSlackBotを作る

# はじめに
今までやってきたことを組み合わせてSlackにコメント付きで名刺画像をアップロードすると、名刺情報をkintoneに登録するようにしてみましょう。APIを使うためにPythonを用いて作ることにします。

前回記事はこちら:

* [Vision APIとNatural Language APIを組み合わせて名刺から情報抽出する](http://qiita.com/Hironsan/items/166515acec35658986b2)

# これから作るアプリ
以下のように名刺画像をSlackにアップロードするとBotが情報を抽出してkintoneに登録してくれます。
<img width="450" alt="スクリーンショット 2016-11-08 15.59.53.png" src="https://qiita-image-store.s3.amazonaws.com/0/77079/4d561447-022d-f7a3-9fa9-123c957cbd8b.png">

[Slackとは？](https://www.youtube.com/watch?v=9RJZMSsH7-g)

# アプリ作成の流れ
Step 0：アプリ作成の準備をする
↓
Step 1：pykintoneを使ってkintoneにデータ登録をする
↓
Step 2：SlackBotを作る
↓
Step 3：Slackからkintoneへ名刺情報を登録する


# Step0(10min) アプリ作成の準備をする
アプリを作るために、必要なライブラリのインストール、SlackBotアカウントの作成、APIキーの設定を行います。

## 必要なライブラリをインストールする
アプリを作成するために必要なライブラリをインストールします。以下のコマンドを実行してインストールしてください。

```shell-session
$ pip install pykintone
$ pip install slackbot
```

## SlackBotアカウントを作成する
まずはSlack Botアカウントを作成しましょう。

<!--
[https://api.slack.com/bot-users](https://api.slack.com/bot-users)
-->
[https://my.slack.com/services/new/bot](https://my.slack.com/services/new/bot)

既にチームのSlackは開設済で、権限のあるユーザでログインしているものとします。その状態で、上記リンクを開くと、Botアカウントの作成画面が開きます。表示されているフォーム中にBotアカウントのユーザ名を入力して、「Add bot integration」を押してください。
<img width="450" alt="スクリーンショット 2016-08-21 22.10.05.png" src="https://qiita-image-store.s3.amazonaws.com/0/77079/3273c39b-618d-b712-2928-7905516fd9a0.png">


「Add bot integration」を押すと、新たにフォームが表示されます。その中の「API Token」は後で作成するBotで用いるのでメモしてください。
<img width="450" alt="スクリーンショット 2016-08-21 22.25.23.png" src="https://qiita-image-store.s3.amazonaws.com/0/77079/42c5aba5-0ced-6ee6-4b77-00bd3ecac688.png">


「Customize Icon」や「Customize Name」で作成したBotの名前やアイコン画像を変更できます。変更内容を「Save Integration」で保存します。
<img width="450" alt="スクリーンショット 2016-08-21 22.26.46.png" src="https://qiita-image-store.s3.amazonaws.com/0/77079/455e3859-7487-b7f3-a3bb-4257e099d203.png">


この後のテスト用にプライベートチャンネルを作成して作成したBotを登録しておきましょう。下記のように設定したら、「Create Channel」で内容を保存します。
<img width="450" alt="スクリーンショット 2016-08-21 22.30.18.png" src="https://qiita-image-store.s3.amazonaws.com/0/77079/a28c5a27-cb19-cc78-cc39-8e452e9ac920.png">

以上でSlackBotの設定は完了です。


## APIキーを設定する
### SlackのAPIキーを設定する
Slackで取得したAPIキーを設定ファイル(plugins/config/slack.yaml)に記述します。エディタでslack.yamlを開いて、tokenの値をあなたのSlackのAPIキーの値で上書きしましょう。xxxの部分を書き換えてください。

```yaml:slack.yaml
token: xxx
```

### kintoneのAPIキーを設定する
kintoneで取得したAPIキー、ドメイン名、アプリIDを設定ファイル(plugins/config/kintone.yaml)に記述します。エディタでkintone.yamlを開いて、domain、id、tokenの値をあなたのkintoneアプリのドメイン名、アプリID、APIキーの値で上書きしましょう。xxxの部分を書き換えてください。

```yaml:kintone.yaml
domain: xxx
apps:
    test:
        id: xxx
        token: xxx
```

# Step1(10min) pykintoneを使ってkintoneにデータ登録をする
ここではpykintoneを使ってkintoneに情報を登録するためのスクリプトの記述を行います。記述を行ったら、動作確認のためにスクリプトを実行します。ではまずはスクリプトの記述から行いましょう。

## スクリプトの記述
kintoneに情報を登録するために、スクリプトを記述します。スクリプトの場所は、plugins/apis/kintone.pyです。エディタでkintone.pyを開いて、内容を以下のように書き換えましょう。書き換え終わったら保存してください。その際の文字コードはUTF8でお願いします。

```py3
# -*- coding: utf-8 -*-
import pykintone
from pykintone import model
import pykintone.structure_field as sf


class BusinessCard(model.kintoneModel):

    def __init__(self, app, name, company, location, impression, submitter, image_path):
        super(BusinessCard, self).__init__()
        self.name = name
        self.company = company
        self.location = location
        self.impression = impression
        self.submitter = submitter
        self.image = [sf.File.upload(image_path, app)]


def create_card(comment, entities, file_path, submitter, conf_path):
    app = pykintone.load(conf_path).app()

    name, company, location = entities['PERSON'], entities['ORGANIZATION'], entities['LOCATION']
    card = BusinessCard(app, name, company, location, comment, submitter, file_path)
    result = app.create(card)

    if result.ok:
        return result
    else:
        print(result.error)
```

create_cardに名刺情報とAPIキーの設定ファイルを与えることで、名刺情報をkintoneに登録してくれます。では動作確認のために実行してみましょう。


## スクリプトの実行
先ほど書いたスクリプトを実行してみましょう。
まずplugins/testsフォルダに移動してください。その中にtest_kintone.pyがあるのを確認できるでしょうか。test_kintone.pyでは先ほど書いたスクリプトのcreate_cardを呼び出すように指定しています。つまり、正しく動作すれば名刺情報を与えた時にその情報がkintoneに登録されるはずです。

```shell-session
$ python test_kintone.py data/example.png
```

実行結果として以下のようにkintoneに名刺情報が登録されたでしょうか？
<img width="1044" alt="スクリーンショット 2016-11-08 15.19.12.png" src="https://qiita-image-store.s3.amazonaws.com/0/77079/eb5705d8-143e-9ca1-6677-a33a595888c9.png">



# Step2(10min) SlackBotを作る
ここではごくごく基礎的なSlackBotを動かすためのスクリプトの記述を行います。記述を行ったら、動作確認のためにスクリプトを実行します。ではまずはスクリプトの記述から行いましょう。

## スクリプトの記述
SlackBotを作るために、スクリプトを記述します。スクリプトの場所は、plugins/slack.pyです。エディタでslack.pyを開いて、以下の内容を**<font color="red">追記</font>**してください。追記し終わったら保存してください。その際の文字コードはUTF8でお願いします。

```py3
from slackbot.bot import respond_to

@respond_to('こんにちは')
@respond_to('今日は')
def hello(message):
    message.reply('こんにちは!')
```

“respond_to”にマッチするキーワードを指定することで、Botに対するメンションに反応するようになります。とにかく動かしてみましょう。


## スクリプトの実行
ではSlackBotを起動してみましょう。
トップレベルにあるbot.pyを起動して**<font color="red">@をつけて</font>**メッセージを送ってみましょう。

```shell-session
$ python bot.py
```

以下のように反応したでしょうか？
<img width="379" alt="スクリーンショット 2016-11-08 15.19.12.png" src="https://qiita-image-store.s3.amazonaws.com/0/77079/050c33a3-f351-5a31-2042-9c2cd01442d3.png">



# Step3(10min) Slackからkintoneへ名刺情報を登録する
さて、いよいよ今までの集大成です。Slackに名刺画像をアップロードすると、SlackBot経由でkintoneに情報を登録します。まずはVision API、Natural Language API、kintone APIを統合したSlackBotスクリプトの記述を行います。記述を行ったら、動作確認のためにスクリプトを実行します。ではまずはスクリプトの記述から行いましょう。

## スクリプトの記述
SlackBotからkintoneに名刺情報を登録するためのスクリプトを記述します。スクリプトの場所は、plugins/slack.pyです。エディタでslack.pyを開いて、以下の内容を**<font color="red">追記</font>**してください。追記し終わったら保存してください。その際の文字コードはUTF8でお願いします。

```py3
@listen_to('(.*)')
def anymessage(message, something):
    if 'file' in message.body:
        slack_token = loader(os.path.join(BASE_DIR, 'config/slack.yaml'))
        google_token = loader(os.path.join(BASE_DIR, 'config/google.yaml'))
        kintone_conf = os.path.join(BASE_DIR, 'config/kintone.yaml')

        url = message.body['file']['url_private_download']
        submitter = get_user_name(message.body['user'], slack_token['token'])
        img_path = download_image(url, slack_token['token'])

        entities = extract_entities_from_img(img_path, google_token['token'])

        comment = message.body['file']['initial_comment']['comment']
        create_card(comment, entities, img_path, submitter, kintone_conf)
        message.reply('名刺情報を登録しました。')
    else:
        message.reply('名刺情報の登録をできますよ。')
```

名刺画像がアップロードされた場合は、名刺画像から情報を抽出してkintoneへ登録するような処理を書いています。では動作確認のために実行してみましょう。


## スクリプトの実行
ではSlackBotを起動してみましょう。トップレベルにあるbot.pyを起動します。

```shell-session
$ python bot.py
```

名刺画像をアップロードしてコメントを書いてみましょう。
<img width="400" alt="スクリーンショット 2016-11-08 15.59.53.png" src="https://qiita-image-store.s3.amazonaws.com/0/77079/4d561447-022d-f7a3-9fa9-123c957cbd8b.png">



実行結果としてkintoneに情報が登録されたでしょうか？
<img width="400" alt="スクリーンショット 2016-11-08 16.01.46.png" src="https://qiita-image-store.s3.amazonaws.com/0/77079/f98b2741-6db0-ca9f-d303-2b343daac10f.png">



# おわりに
いかがだったでしょうか。
Vision API、Natural Language API、kintone、Slackを組み合わせて名刺管理アプリケーションを作って見ました。可能性を感じていただけたでしょうか？

今回は登録しかしませんでしたが、Botを使っているのでインタラクティブなアプリを作ることもできます。
これらのweb APIや他のweb API、もしくは、自作のweb APIを用意して、賢い処理をする仕組みを考えてみましょう！

おつかれさまでした。

# 記事まとめ
今回のハンズオンの内容は３つの記事にまとめています。

* [kintoneで名刺管理アプリを作ってみよう](http://qiita.com/Hironsan/items/be3497972fb3517cb2b2)
* [Vision APIとNatural Language APIを組み合わせて名刺から情報抽出する](http://qiita.com/Hironsan/items/166515acec35658986b2)
* [名刺から情報を抽出するSlackBotを作る](http://qiita.com/Hironsan/items/9bfba01c37e9fcd7b8af)


事前準備は以下の記事からお願いします。

* [kintone x 機械学習で実現する簡単名刺管理@kintone Café](http://qiita.com/Hironsan/items/a81eef912881b1051de5)