no-image

Python初心者がたったの3日間でチャットボットを作った【1日目】

社会人になって初めての連休(3連休)を利用してチャットボットを一本作ろうという今回の企画。
名付けて、『ゼロから3日でLINEbot開発チャレンジ』
今日は初日。
ちょっとしたbotアプリをデプロイするところまでは進めることができたので、本日学んだことをまとめる。

参考にした教材はこちら。
書籍の中で使われている言語はPHPだが、チャットボットの基礎的な仕組みについて丁寧に解説してあり、Pythonでの開発にも応用が非常に簡単であった。
チャットボットのつくり方について体系的にまとめられたリソースは非常に少ないので助かる。

おもしろまじめなチャットボットをつくろう

追記(2018/11/15)

この記事を書いたのが大体3ヶ月くらい前なのですが、いつの間にか「Python チャットボット」といったキーワードで一位になりました。
毎日誰かがこの記事を読んでくださり、とても嬉しく思っております。

しかし、僕がこの記事を書いたのは、LINEBotに初めて触れた時なので、十分に読んでくださる方の役に立つ記事であるかは疑問があります。

そこで、この記事を読んでくださった方で、もしもチャットボットの勉強でつまづいている点、解決できない問題などありましたら、ぜひ遠慮なくコメントをいただければと思っています。
微力ながら力になれることがあるかもしれません。

本記事の構成

この記事の構成は以下の通り。

  1. botの仕組み
  2. JSONファイルから必要な情報を取得する
  3. リプライトークンとは
  4. Pythonの正規表現を使う
  5. 現時点での完成品

botの仕組み

今日はまず、botの仕組みを勉強するところから始めた。
LINEbotにおける、基本的な仕組みは以下の4点である。

・Botをチャットサーバーと連携する
・HTTPプロトコルを用いて、Botとサーバーでデータの受け渡しを行う
・Botからのリクエストをもとに、サーバーで処理を行う
・サーバーから返ってきたリクエストに応じてBotが処理を行う

まず、Botのサーバーとの連携について。
今回はチャットサーバーとしてHeroku、サーバー内で処理を行う言語としてPythonを使用する。
Botとサーバーとの連携については、Python初心者がたったの3日間でチャットボットを作った【0日目】ですでに完了しているので割愛。

次にHTTPプロトコルを用いた情報の受け渡し。
こちらも、webhook設定の際に鍵とトークンを渡してあるので、特に意識せずとも実現されている。

さて、次が本日のメインの学習項目。
サーバー内での処理である。
行うべき処理はもちろん実装したい機能によって変わる。
今回実装した処理は、
・JSONで受け取ったデータから、テキストのみをログファイルに記録していく処理
・JSONのデータからリプライトークンを取り出す処理
・数字列が与えられたときと与えられなかったときで表示されるリプライを変える処理
である。

JSONから必要な情報を取得する

そもそもJSONとは何か。
JSONはJavaScript Object Notationの略である。
現在よく用いられるデータ交換用の形式であり、辞書型の配列のように、名前と値のペアで記述されている。
LINEbotから受け取るデータは、このJSON形式で渡される。

まずは、JSONから送信されたテキストのみを取り出してログファイルにテキスト形式で記録する関数。

  def listen(body_content):
      with open('log.txt', 'a') as f:
          f.write(str(body_content["events"][0]['message']['text']))
          f.write("\n")

テキストは、eventsに対応する配列の、一つ目の要素の、messageに対応する辞書の、textに対応する値として渡される。
少しややこしいが、データの構成さえ理解してしまえばどうということはない。
ちなみに、引数のbody_contentは、JSON形式のデータをpythonで扱えるように変換してある。

変換の方法はとても簡単。
以下のコードでOK。

  import json
  body_content = json.loads(JSON形式のデータ)

次に、JSONデータからリプライトークンを取り出す関数。

  def get_reply_token(body_content):
      reply_token = body_content["events"][0]['replyToken']
      return reply_token

リプライトークンは、eventsに対応する配列の一つ目の要素の、replyTokenに対応する値として渡されている。

最後に、リプライトークンを使ってLINEbotに任意のテキストを表示させる関数。

  def error_reply(reply_token):
      line_bot_api.reply_message(
          reply_token,
          TextSendMessage(text="任意の文字列"))

line_bot_api.reply_messageメソッドの、一つ目の引数にリプライトークン、二つ目の引数にTextsendMessageを与える。
これで完成。

リプライトークンとは

さて、さらっと出てきたリプライトークンについて。
リプライトークンとは、簡単に言えば、Botに発言を許可するチケットのようなものである。
このリプライトークン一つにつき、一つ発言することが許される。

Pythonの正規表現を使う

正規表現とはそもそも何なのか。
こちらの記事が参考になる。

正規表現とは?

詳細は割愛するが、ざっくり言うと、『使えば文字列の検索や置換などがとても楽になる記法』のようだ。
今回は、正規表現を用いて、入力された数字の取得を行った。

  import re

  def find_number(body_content):
      body_content = str(body_content["events"][0]['message']['text'])
      match = re.search("^\d*", body_content)
      number = match.group(0)

      return number

正規表現については正直まだ理解が浅いのだが、簡単に解説。
まず、re.search()というメソッドで、指定した文字列が検索元の文字列に含まれるかどうかの判定を行っているようだ。
このメソッドは、一つ目の引数に正規表現で表した文字列、二つ目の引数に検索元の文字列を入れる。
このあと、groupというメソッドで正規表現とマッチした文字列を丸々取得している。

とりあえず動かすことを優先したため、理解は浅い。
正規表現についてはまたそのうち別の記事でまとめようと思う。

現時点での完成品

とりあえず初日時点での完成品はこんな感じ。

予備知識ゼロだったので、もっと苦戦するかと思ったが、FlaskとPythonの基礎知識があったので学習は進めやすかった。
明日明後日の二日間では、もう少し返答パターンと機能を増やして、無駄遣い防止のためのサービスとして人に使ってもらえるレベルにすることを目指す。

参考

・BOOK
おもしろまじめなチャットボットをつくろう
逆引きPython標準ライブラリ 目的別の基本レシピ180 ! (impress top gear)

・WEB
正規表現とは?
Messaging APIリファレンス
LINE Messaging APIとPythonを使ってChatbotを作ってみた
Pythonの正規表現の基本的な使い方

次の記事:Python初心者がたったの3日間でチャットボットを作った【2日目】

前回の記事:Python初心者がたったの3日間でチャットボットを作った【0日目】