愛媛県今治市弁のチャットボットを作ってみた 

# はじめに
[docomo Developer support](https://dev.smt.docomo.ne.jp/) では，さまざまな開発者向けAPIが公開されています．その中の [自然対話API](https://dev.smt.docomo.ne.jp/?p=docs.api.page&api_name=natural_dialogue&p_name=api_6#tag01) を使用すると，誰でも対話型サービス（無償提供サービスに限定）を自然言語処理技術の知識なしに開発することができます．
自然対話APIは，下記の5つのAPIから構成されています．

- 意図解釈API
- FAQチャットAPI
- 雑談対話API
- 知識検索API
- キャラクタ変換API

今回は，自然対話APIのうち，雑談対話APIとキャラクタ変換APIを使って，Python3で動く，愛媛県今治市弁を話すチャットボットを作ってみたいと思います．
雑談対話APIからのレスポンスのシステム発話を，をキャラクタ変換APIにリクエストとして送ることで，キャラクタ風の発話に変換します．


# 準備
docomo Developer support のアカウントをお持ちでない方は，新規登録が必要です．
docomo Developer support にログインし，自然対話API > 雑談対話API・キャラクタ変換APIのAPIの利用申請を行います．
アプリケーション登録の画面で必要事項を入力後，API機能選択の画面で，雑談対話APIとキャラクタ変換APIの利用にチェックを入れます．

<img src="https://qiita-image-store.s3.amazonaws.com/0/320459/c89007b6-8530-ac47-377d-b7dee4728430.png" width="100%">


API利用申請が完了すると，マイページ > API利用申請・管理からAPI keyが確認できます．

<img src="https://qiita-image-store.s3.amazonaws.com/0/320459/ba15b319-da51-c6cd-50cd-91f17f32990b.png" width="100%">


# チャットボットの作成

pythonから雑談対話APIとキャラクタ変換APIを呼び出し，コマンドライン上で動作するチャットボットを構築します．

## 雑談対話APIのユーザ登録
雑談対話APIを利用するために，ユーザー情報を登録してappIdを取得する必要があります．
appIdは，ユーザ毎の会話のステータスを管理するのに用いられています．
複数のユーザで同じappIdを使用してしまうと，別のユーザの対話の状態が引き継がれてしまうため，ユーザ毎にappId取得するようにしてください．
ユーザ登録のエンドポイント（`https://api.apigw.smt.docomo.ne.jp/naturalChatting/v1/registration`）に対してリクエストを送ると，レスポンスとしてappIdを取得できます．
下記はユーザ登録を行うpython3のサンプルプログラムです．

```Python
chatting_KEY = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
url = "https://api.apigw.smt.docomo.ne.jp/naturalChatting/v1/registration?APIKEY="+chatting_KEY
header = {"Content-type": "application/json;charset=UTF-8"}
request = {
    "botId": "Chatting",
    "appKind": "Smart Phone"
}
response = requests.post(url, data=json.dumps(request), headers=header)
chatting_appId = response.json()["appId"]
```


## 雑談対話API
雑談対話APIのエンドポイント（`https://api.apigw.smt.docomo.ne.jp/naturalChatting/v1/dialogue`）に対してリクエストを送ると，レスポンスとしてシステム発話を取得できます．
下記は雑談対話を行うpython3のサンプルプログラムです．

```Python
chatting_KEY = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
url = "https://api.apigw.smt.docomo.ne.jp/naturalChatting/v1/dialogue?APIKEY="+chatting_KEY
header = {"Content-type": "application/json;charset=UTF-8"}
request = {
    "language": "ja-JP",
    "botId": "Chatting",
    "appId": chatting_appId,
    "voiceText": user_utt,
    "clientData":{
    "option":{
      "mode":"dialog"
      }
    },
    "appRecvTime": "", 
    "appSendTime": ""
}
response = requests.post(url, data=json.dumps(request), headers=header)
system_utt = response.json()["systemText"]["expression"]
```

modeを"srtr"にすると，しりとりを行うことができます．
しりとりを継続する場合は，レスポンスのmode（srtr）をリクエストボディのmodeに指定します．
レスポンスのmodeは，Base64 URLエンコーディングされていますので，デコードした値を指定してください．

## キャラクタ変換APIのユーザ登録
キャラクタ変換APIを利用するために，ユーザー情報を登録してappIdを取得する必要があります．
ユーザ登録のエンドポイント（`https://api.apigw.smt.docomo.ne.jp/naturalCharaConv/v1/registration`）に対してリクエストを送ると，レスポンスとしてappIdを取得できます．
下記はユーザ登録を行うpython3のサンプルプログラムです．

```Python
chara_KEY = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
url = "https://api.apigw.smt.docomo.ne.jp/naturalCharaConv/v1/registration?APIKEY="+chara_KEY
header = {"Content-type": "application/json;charset=UTF-8"}
request = {
    "botId": "CharaConv",
    "appKind": "Smart Phone"
}
response = requests.post(url, data=json.dumps(request), headers=header)
chara_appId = response.json()["appId"]
```


## キャラクタ変換API
キャラクタ変換APIのエンドポイント（`https://api.apigw.smt.docomo.ne.jp/naturalCharaConv/v1/dialogue`）に対してリクエストを送ると，レスポンスとして方言・指定キャラクタ風の話し方に変換されたテキストを取得できます．
下記の13種類のキャラクタが指定でき（なぜか愛媛弁が多い気がしますね），clientData > option > t の値にキャラクタIDを設定します．

- ehime1：愛媛県今治市弁
- ehime2：愛媛県四国中央市弁
- ehime3：愛媛県松山市弁
- kansai：関西弁
- hakata：博多弁
- fukushima：福島弁
- mie：三重弁
- maiko：舞妓風
- ojo：お嬢様風
- bushi：武士風
- gyaru：ギャル風
- burikko：ぶりっ子風
- akachan：赤ちゃん風

今回は愛媛県今治市弁に変換するので， t の値に "ehime1" を設定します．
下記はキャラクタ変換を行うpython3のサンプルプログラムです．

```Python
chara_KEY = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
url = "https://api.apigw.smt.docomo.ne.jp/naturalCharaConv/v1/dialogue?APIKEY="+chara_KEY
header = {"Content-type": "application/json;charset=UTF-8"}
request = {
    "language": "ja-JP",
    "botId": "CharaConv",
    "appId": chara_appId,
    "voiceText": system_utt,
    "clientData":{
        "option":{
            "t":"ehime1"
        }
    },
    "appRecvTime": "", 
    "appSendTime": ""
}
response = requests.post(url, data=json.dumps(request), headers=header)
converted_system_utt = response.json()["systemText"]["expression"]
```

## ボットと対話してみよう

これまでのサンプルプログラムをまとめて，コマンドライン上で動作するチャットボットを構築します．

```Python
# -*- coding: utf-8 -*-

import requests
import json

# APIkey
chatting_KEY = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
chara_KEY = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"


# 雑談APIユーザ登録
def registration_chatting():
    url = "https://api.apigw.smt.docomo.ne.jp/naturalChatting/v1/registration?APIKEY="+chatting_KEY
    header = {"Content-type": "application/json;charset=UTF-8"}
    request = {
        "botId": "Chatting",
        "appKind": "Smart Phone"
    }
    response = requests.post(url, data=json.dumps(request), headers=header)
    chatting_appId = response.json()["appId"]
    return chatting_appId


# 雑談対話APIに接続
def chatting(chatting_appId, user_utt):
    url = "https://api.apigw.smt.docomo.ne.jp/naturalChatting/v1/dialogue?APIKEY="+chatting_KEY
    header = {"Content-type": "application/json;charset=UTF-8"}
    request = {
        "language": "ja-JP",
        "botId": "Chatting",
        "appId": chatting_appId,
        "voiceText": user_utt,
        "clientData":{
        "option":{
          "mode":"dialog"
          }
        },
        "appRecvTime": "", 
        "appSendTime": ""
    }
    response = requests.post(url, data=json.dumps(request), headers=header)
    system_utt = response.json()["systemText"]["expression"]
    return system_utt


# キャラクタ変換APIユーザ登録
def registration_characonv():
    url = "https://api.apigw.smt.docomo.ne.jp/naturalCharaConv/v1/registration?APIKEY="+chara_KEY
    header = {"Content-type": "application/json;charset=UTF-8"}
    request = {
        "botId": "CharaConv",
        "appKind": "Smart Phone"
    }
    response = requests.post(url, data=json.dumps(request), headers=header)
    chara_appId = response.json()["appId"]
    return chara_appId


# キャラクタ変換APIに接続
def characonv(chara_appId, system_utt):
    url = "https://api.apigw.smt.docomo.ne.jp/naturalCharaConv/v1/dialogue?APIKEY="+chara_KEY
    header = {"Content-type": "application/json;charset=UTF-8"}
    request = {
        "language": "ja-JP",
        "botId": "CharaConv",
        "appId": chara_appId,
        "voiceText": system_utt,
        "clientData":{
            "option":{
                "t":"ehime1"
            }
        },
        "appRecvTime": "", 
        "appSendTime": ""
    }
    response = requests.post(url, data=json.dumps(request), headers=header)
    converted_system_utt = response.json()["systemText"]["expression"]
    return converted_system_utt


if __name__ == "__main__":
    chatting_appId = registration_chatting()
    chara_appId = registration_characonv()
    
    while True:
        user_utt = input("User> ")
        if user_utt == "exit":
            break
        else:
            system_utt = chatting(chatting_appId, user_utt)
            converted_system_utt = characonv(chara_appId, system_utt)
            print("System> %s" % converted_system_utt)
```

コマンドラインで実行すると，下記のような感じで対話でき，exitを入力すると対話が終了します．
※雑談対話APIではレスポンスまで10秒程度かかりますので，ユーザ発話入力後，応答があるまでしばらくお待ちください．

<img src="https://qiita-image-store.s3.amazonaws.com/0/320459/c18def01-0b2b-9c7c-2bab-207270bd770d.png" width="100%">


愛媛県今治市弁のボット，なかなか可愛くないでしょうか？
愛媛弁以外にも様々なキャラクタが設定できるので，ぜひいろいろ試してお気に入りを見つけてください．



# おわりに
自然対話APIのうち，雑談対話APIとキャラクタ変換APIを使って，Python3で動く，愛媛県今治市弁を話すチャットボットを作ってみました．
APIにリクエストを送るだけなので，お手軽にチャットボットが作成できます．
SlackやTelegramなどと連携すれば，よりチャット感が出るかと思います．
docomo Developer support の自然対話APIでは，他にも様々な機能のAPIを公開しておりますので，いろいろ組み合わせて，ぜひお好みのチャットボットを構築してみてください．

また，2018年10月1日より，商用雑談対話サービス「[katarai](https://www.katar.ai/)」がリリースされています．カスタマイズにも対応しておりますので，ご興味ある方はぜひ見てみてください．