docomo自然対話APIを使ってみる

# はじめに
[前回](https://qiita.com/yukky-k/items/0d18ec22420e8b35d0ac)の投稿から4ヶ月も経ってしまったことに驚いていますが、また何か作りたい衝動が出てきた＆勉強を兼ねて、前回もお世話になったdocomoさんのAPIを使って自然対話に挑戦してみました。チャットボットですね。

# 参考サイト
[Python3でdocomoの自然対話：雑談apiを動かす](https://qiita.com/aoyahashizume/items/a3d798bbb5c8d639abaa)
[docomo Developer support 自然対話](https://dev.smt.docomo.ne.jp/?p=docs.api.page&api_name=natural_dialogue&p_name=api_usage_scenario)

# 作る前に
APIの利用申請は割愛。方法は下記サイトとかに書いてあります。
https://codezine.jp/article/detail/8299

[docomo Developer supportの自然対話の機能別リファレンス](https://dev.smt.docomo.ne.jp/?p=docs.api.page&api_name=natural_dialogue&p_name=api_4#tag01)を見ると、どんなパラメータを送れば良いか。どんなレスポンスが返ってくるかが載っているので、まずは予習してみる。
![図1.png](https://qiita-image-store.s3.amazonaws.com/0/242725/851aebdf-74bd-1cdf-ad56-8f422562500d.png)
![図2.png](https://qiita-image-store.s3.amazonaws.com/0/242725/fe6647ff-88ee-6d86-66a1-693c72b43a21.png)
![図3.png](https://qiita-image-store.s3.amazonaws.com/0/242725/649d2c42-14d0-435f-7fe7-156c87ab2104.png)

どうやら、JSON形式でボディ部に`language` `botId` `appId` `voiceText` `appRecvTime` `appSendTime`の情報を入れればレスポンスが返ってきて、`systemText`内の`expression`または`utterance`を取り出せば良さそうとのこと。
そして`appId`は別途取得する必要があるということのようです。

# appIdを取得する
pythonで下記のコードを作って取得しました。
`botId`は"Chatting"指定
`appKind`はサービスごとに定義する任意の値だそうです。

~~~python:get_appid.py
#!/usr/bin/env python
# coding: utf-8

import requests
import json

send_data = {
    "botId": "Chatting",
    "appKind": "Chatbot"
}
headers = {'Context-type': 'application/json'}

APIKEY = '[APIキー]'
url = 'https://api.apigw.smt.docomo.ne.jp/naturalChatting/v1/registration?APIKEY={}'.format(APIKEY)

r = requests.post(url, data=json.dumps(send_data), headers=headers)
print(r.status_code) # レスポンスステータスを確認。200なら正常。
return_data = r.json()
print(return_data) # appIdを出力。
~~~
これを実行すると画面にappIdが出力されるので、それを使います。

~~~
200　←200なら正常にレスポンスが返ってきている
{'appId': 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'}　←これがappId
~~~

# 雑談APIを使う
以上で準備ができたので、実際に雑談APIを使うコードを作りました。
リクエストを送るJSONデータに`appRecvTime`を入れ忘れたのですが動いたので結果オーライ（笑）

~~~python:docomo_talk_api.py
#!/usr/bin/env python
# coding: utf-8

import requests
import json
from datetime import datetime

# APIキー
APIKEY = "[APIキー]"

# リクエストボディ(JSON形式)
send_data = {
    "language": "ja-JP",
    "botId": "Chatting",
    "appId": "[appId]",
    "voiceText": "",
    "appSendTime": ""
    }

# リクエストヘッダ
headers = {'Context-type': 'application/json'}

# リクエストURL
url = "https://api.apigw.smt.docomo.ne.jp/naturalChatting/v1/dialogue?APIKEY={}".format(APIKEY)

#ループ処理
while True:
    # メッセージを入力
    send_text = input()
    # endと入力すると終了
    if send_text == "end":
        print("おしゃべりを終了します。")
        break

    send_data['voiceText'] = send_text
    # 送信時間を取得
    send_time = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
    send_data['appSendTime'] = send_time

    # メッセージを送信
    r = requests.post(url, data=json.dumps(send_data), headers=headers)
    # レスポンスデータから返答内容を取得
    return_data = r.json()
    return_message = return_data['systemText']['expression']
    print(return_message)
~~~
実行するとこんな感じになります。ちょっと分かりにくいですが、奇数行目が自分が送ったメッセージで偶数行目がAPIからの返答です。

~~~
こんばんは
ばわー
元気ですね
げんき
名前を教えて
私の名前はゼロです。
end
おしゃべりを終了します。
~~~
名前はゼロらしいです。

ちなみに、リクエストボディにはもっと色々付けられるので、例えば

~~~python
send_data = {
    "language": "ja-JP",
    "botId": "Chatting",
    "appId": "[appId]",
    "voiceText": "",
    "clientData": {
        "option": {
            "nickname": "[名前]",
            "nicknameY": "[呼び方(カタカナ)]",
            "sex": "[性別]",
            "birthdateY": "[誕生年]",
            "birthdateM": "[誕生月]",
            "birthdateD": "[誕生日]",
            "bloodtype": "[血液型]",
            "constellations": "[星座]",
            "place": "[住んでる地域]",
            "mode": "dialog"
            "t": ""
        },
    },
    "appSendTime": ""
    }
~~~
みたいに情報を入れると名前を呼んでくれたりします。

~~~
なにもしてないよ
そうだったんですか・・・　そういえば、[名前]さん、今のアニメお勧めあります？
~~~

誕生日とか星座もなにかのタイミングで言ってくれるのかな？
住んでる地域は場所リストに記載された地域しか駄目らしい。県名だったり市の名前だったり統一感がない。。。
bot君の名前とかは変えられないのは残念。
ただ、`t`タグを"kansai"とすると返事が関西弁に、"akachan"にすると赤ちゃん言葉（○○でちゅ）に変わりました。
やっぱり、こういうのを作るのは楽しいですね。