keep learning blog(キープラーニングブログ)

自分が興味を持ったことを備忘録として残すブログです。

28.PythonでLINE botを作ろう

――あなたにできること、あるいはできると夢見ていることがあれば、今すぐ始めなさい。向こう見ずは天才であり、力であり、魔法です。――

ヴォルフガング・フォン・ゲーテ

 

 

PythonでLINE botを作ろう

日本はGWですね。今年は小池知事の仰るようにSTAY HOME WEEKなのでSHWと略すべきでしょうか。私はなんだか時間感覚がないまま毎日論文をぼんやりした頭で読んでいます。

とはいえ、さすがに論文を読むだけの日々にちょっと飽きたので、何かプログラムが書きたいなあ、できれば何か実用性のあるものがいいなあと思い立ちました。そこで、初心者でも気軽に作れそうで、かつできたら楽しそうなBotを作ることにしました。

Botとは、身近な例で言うとSiriのような、こちらの入力(声やメッセージ)に反応して何かのリアクションを返してくれるプログラムのことです。Siriはアップル社の開発したAIアシスタントで、iPhoneMacに標準搭載されていますね。

他方、日本最大手のメッセンジャーアプリLINE®では、企業が自社製品の宣伝をしたり政府機関が広報を行ったりするための媒体として、LINEチャネルと呼ばれるサービスを提供しています。

LINEチャネルにはMessaging APIという機能が搭載されています。ネット上のサーバーに置いたプログラム*1と連携させることで、こちらのメッセージに返信をくれたり、今日の天気を教えてくれたりするアシスタント機能を付加することができます。

このMessaging API機能を利用したLINEチャネルのことを、以下「LINE bot」と呼びます。この記事では、私のようなプログラミング初心者向けに、丁寧に順を追ってLINE botの作り方をご説明します。

f:id:yuki0718:20200501024329j:plain

 

環境

・Windows10 Home 64bit

Python 3.7.3 (Anaconda distributionで環境構築)

AnacondaによるPythonの環境構築については、以下の過去記事をご参照ください。

keep-learning.hatenablog.jp

 

手順1:LINE developersアカウントの作成

まずは自分のLINEチャネルを開設する必要があります。LINEのアカウントをお持ちの方は、以下のウェブサイトからログイン→アカウントを作成→LINEアカウントで登録、の順に進んでLINE Business IDを作ってください。

developers.line.biz

アカウント登録が済んだら、以下のコンソール画面が表示されます。下部にスクロールしてLINEチャネルの新規プロバイダーを作成しましょう。この名前はこれから作成するLINE botの提供元として表示される情報です。

f:id:yuki0718:20200430230651p:plain

自分のプロバイダーを作成したら、以下の画面が表示されます。ここでは中央の「Messaging API」をクリックして、新規チャネルを作成します。

f:id:yuki0718:20200430231606p:plain

チャネル名はLINE botの名前になるので個人情報等を入れないように注意しましょう。その他の項目は、私の場合は大業種「個人」、小業種「架空」に設定しました。プライバシーポリシーURLとサービス利用規約URLは空欄でOKです。

f:id:yuki0718:20200430232320p:plain

testという名前のチャネルを作ってみました。とりあえずチャネル作成はこれで完了です。後でまた使うのでブラウザの×は押さずに開いたままにしておいてください。

 

手順2:Herokuアカウントの作成

これから作るLINE botの応答は、Pythonのプログラムで指定します。残念ながら、LINE自体はプログラムの置き場所(サーバー)を提供してくれないため、プログラムをネットからアクセス可能などこか別の場所*2に置いておく必要があります。

無料で、かつ気軽にPythonが動かせるサーバーとなると国内にはあまり選択肢がないので、ここでは米国の企業が提供するHerokuというリモートサーバーを利用します。まずは以下のウェブサイトでアカウントを作ります。

signup.heroku.com

登録はすべて英語表記です。Name(名前)とEmail address(メールアドレス)を入力し、Role(役割)は趣味なのでhobbyist、Country(国)はJapan、Primary development language(開発言語)はPythonとします。Company nameは空欄で構いません。

アカウント作成ボタンをクリックするとページが遷移し、しばらくしてHerokuから登録時のメールアドレスに「Thanks for signing up with Heroku! You must follow this link to activate your account:」というメッセージが届きます。この後に続くURLにアクセスすると以下のパスワード設定ページに遷移します。

f:id:yuki0718:20200430234910p:plain

パスワードは記号、アルファベット、数字の3種類を少なくとも含まないといけないようです。この手の制限は面倒ですがセキュリティは重要です。無事にパスワード設定が終わり、「Welcome to Heroku」というページに遷移したら登録完了です。

 

手順3:Heroku toolbeltとGitのインストール

Herokuのサーバーに置かれるファイルはネット上に公開されます。つまり、サーバーにファイルを転送(Upload)するための作業が必要になるので、そのためのアップロードツールを導入します。

以下のウェブサイトからHeroku toolbeltというソフトウェアをインストールします。Windowsの64bit installerがページ中腹の右側にあります。

devcenter.heroku.com

Heroku toolbeltをインストールしたら、Anaconda Prompt(コマンドプロンプト)を立ち上げ、以下のように「heroku login」と入力してEnterキーを押下しましょう。

(base) C:\Users\username> heroku login

すると、プロンプト上に「Enter your Heroku credentials(資格情報を入力しなさい)」と表示されるので、Heroku登録時のメールアドレスとパスワードを入力してEnterキーを押下します。これで自分のPCとサーバーが接続可能になりました。

さて、毎回すべてのファイルを一からアップロードするのは無駄なので、前回と比べて変更した部分だけを抽出してアップロードするツールがあると便利です。ここではGitをインストールします*3。導入には以下のページが参考になります。

qiita.com

Anaconda Prompt(コマンドプロンプト)で「git --version」と入力してEnterキーを押下しましょう。エラーが出なければGitの導入成功です。

(base) C:\Users\username> git --version

 

手順4:LINE bot用プログラムファイルの作成

今回は非常にシンプルな応答として、特定の辞書ファイルの中からランダムにメッセージを選択して返してくれるLINE botを作りたいと思います。偉人の名言などを辞書として作ったら、一日一回いい言葉が聞けて楽しそうです。

まずは自分のPCの中に作業用フォルダを作りましょう。フォルダ名は日本語だとトラブルの元なので英語表記をおすすめします。私はマイドキュメントの中に「line_bot」という名前のフォルダを作ってその中にファイルを格納しました。

ここからはちょっと長いので、LINE botの動作に必要なそれぞれのファイルごとに項目立てしてご説明します。

「runtime.txt」「requirements.txt」

LINE botのプログラムに必要なライブラリは、「Flask」と「line-bot-sdk」の2つです。ご存知のとおり自分のPCにライブラリをインストールするときはAnaconda Prompt上に「conda install Flask」や「pip install line-bot-sdk」と打ち込めば済むのでした。

しかしながら、今回は自分のPC上ではなくHerokuのサーバー上でPythonを動作させます。そのため、Pythonのバージョンや、サーバー上にどういったライブラリが必要かをサーバー側に教えてあげる必要があります。

Herokuでは、「runtime.txt」というファイルをアップロードしておくと、自動的にそのバージョンのPythonをサーバーに導入してくれます。今回の場合、「runtime.txt」の内容は以下のようにして作業用フォルダ内に保存してください。

python-3.7.3

さらに、「requirements.txt」というファイルをアップロードしておくと、自動的にそのPythonライブラリをサーバーに導入してくれます。今回の場合、「requirements.txt」の内容は以下のようにして作業用フォルダ内に保存してください。

Flask==1.1.2
line-bot-sdk==1.16.0

1.1.2や1.16.0といった数字はライブラリのバージョン番号です。私の場合は、自分のPCでライブラリの動作確認をしてからサーバーに上げたので、自分のPCに入っているバージョンをAnaconda Prompt上の「conda list」コマンドで確認しました。

「main.py」

続いて、LINE botの頭脳となるプログラム部分はPythonファイルで作成します。以下の内容をコピペして「main.py」という名前で作業用フォルダ内に保存してください。以後このファイルをアレンジすればLINE botに色々な機能を付加できます。

#!/usr/bin/env python
# coding: utf-8

from flask import Flask,request,abort
from linebot import LineBotApi,WebhookHandler
from linebot.exceptions import InvalidSignatureError
from linebot.models import MessageEvent,TextMessage,TextSendMessage
import os
import random

app=Flask(__name__)
#Environment keys
YOUR_CHANNEL_ACCESS_TOKEN = os.environ["YOUR_CHANNEL_ACCESS_TOKEN"]
YOUR_CHANNEL_SECRET = os.environ["YOUR_CHANNEL_SECRET"]
line_bot_api=LineBotApi(YOUR_CHANNEL_ACCESS_TOKEN)
handler=WebhookHandler(YOUR_CHANNEL_SECRET)

@app.route("/callback",methods=["POST"])
def callback():
    signature=request.headers["X-Line-Signature"]
    
    body=request.get_data(as_text=True)
    app.logger.info("Request body"+body)
    
    try:
        handler.handle(body,signature)
    except InvalidSignatureError:
        abort(400)
    return "OK"

@handler.add(MessageEvent,message=TextMessage)
def handle_message(event):
    
    #Get the message from counterpart
    message = event.message.text
    
    #Define trigger messsages
    triggers = [u"へいぼっと", u"ヘイボット"]
    
    #If the message was included in the triggers
    if message in triggers:
        #Read the dictionary file
        with open("./dictionary.csv", "r") as f:
            dic = f.read().rstrip()
        
        #Select a word randomly
        words = dic.split("\n")
        res = random.choice(words)
        
        #Respond
        line_bot_api.reply_message(event.reply_token, TextSendMessage(text=res))

if __name__=="__main__":
    port=int(os.getenv("PORT",5000))
    app.run(host="0.0.0.0",port=port)
「Procfile」

さて、あともう一息です。LINEからサーバーを呼び出したときの動作を決める必要があります。Herokuでは、「Procfile」(拡張子なし!)というファイルをアップロードしておくと、初期起動ファイルを指定できます。今回の場合、「Procfile」の内容は以下のようにして作業用フォルダ内に保存してください。

web: python main.py

今回はPythonの頭脳部分のファイルを「main.py」という名前にしたのでこうなっています。もちろんどんな名前でも両者が対応していれば問題ありません。

「dictionary.csv

最後に、このファイルはプログラムでも何でもなく単なるコンテンツです。例えば、偉人の名言botを作りたい場合は、Microsoft excelの新規ファイルなどを開いて、A列の各行に言わせたい名言を一つずつ入力します。

あとは、これをExcelの「名前を付けて保存」→「CSV UTF-8 (コンマ区切り) (*.csv)」でcsvファイルに変換します。当然ながら、直接エディタでcsvファイルを作ってもOKです。

「dictionary.csv」という名前で作業用フォルダ内に保存しておきましょう。これでmain.pyがこの辞書を参照できます。

 

手順5:アプリケーションの作成とWebhook URLの設定

サーバーの準備とLINE連携

手順3でHeroku toolbeltとGitが使えるようになっていれば、後は簡単です。まずはサーバー上にファイルが保存される場所を確保します。Anaconda Prompt(コマンドプロンプト)上で「heroku create アプリケーション名」と打ち込んでEnterキーを押下します。

(base) C:\Users\username> heroku create アプリケーション名

この「アプリケーション名」はサーバーの呼び出しURLに使われるので分かりやすい名前にしましょう。すなわち、「https://アプリケーション名.herokuapp.com/callback」がサーバーの呼び出しURLになります。

このURLは、Webhookという仕組みでサーバーとLINEとを連携するために使います。手順1で作成したLINE developersのチャネルから「Messaging API設定」タブを選択し、Webhook設定の項目に呼び出しURLを入力して、WebhookをONにしましょう。

f:id:yuki0718:20200503173056p:plain

また、同じ「Messaging API設定」の項目の中にいくつかある「編集」ボタンからLINE official account managerページに遷移し、「Messaging API」のタブを選択すると、Webhook URLという項目があります。ここにも呼び出しURLを入力して保存します。

f:id:yuki0718:20200501033527p:plain

最後に、LINE messaging API側とHerokuサーバー側の連携には、もう一工程必要です。LINE developersとLINE official account managerから取得できる自分のチャネルのキーをサーバーの環境変数に設定します。

環境変数というと何だか難しく聞こえるかもしれませんが、Anaconda Prompt(コマンドプロンプト)から以下のコマンドを打ち込んでEnterキーを押下するだけです。

(base) C:\Users\username> heroku config:set YOUR_CHANNEL_ACCESS_TOKEN="<1>" --app "さっき決めたアプリケーション名"
(base) C:\Users\username> heroku config:set YOUR_CHANNEL_SECRET="<2>" --app "さっき決めたアプリケーション名"

ここで、<1>と<2>と書かれている部分には、LINE developersアカウントで発行できるトークンの情報を入力します。「Messaging API設定」というタブを選択すると、ページ下部にチャネルアクセストークの発行ボタンがあるはずです。

f:id:yuki0718:20200501005933p:plain

発行をクリックすれば「=」で終わるなが~いトークンが発行されるので、これを上のコマンドの<1>部分に当てはめましょう。

<2>については、上述したLINE official account managerページ(Webhook URLを入力した画面)にChannel secretという項目があります。これを上のコマンドの<2>部分に当てはめましょう。

コマンドをまともに打ち込むのはきついので、メモ帳などに書いてからコピーし、Anaconda Prompt(コマンドプロンプト)上で右クリックしてペーストすると楽です。

ファイルのアップロード

後は、手順4で作業用フォルダ内に作っておいたファイルたちを、Herokuサーバーにアップロードする作業です。これは非常に簡単で、Anaconda Prompt(コマンドプロンプト)上に以下のようなコマンドを順次入力していけば、自動的に終了します。

まずは次のコマンドで作業用フォルダに移動します。

(base) C:\Users\username> cd 自分のPCの作業用フォルダのパス

次のコマンドで、転送先のサーバー(リモートリポジトリ)を指定します。

(base) C:\Users\username> heroku git:remote -a さっき決めたアプリケーション名

次のコマンドで、作業用フォルダ内のすべてのファイル(.)を.gitによるバージョン管理対象に追加します。

(base) C:\Users\username> git add .

次のコマンドで、管理対象ファイルを.gitフォルダ(ローカルリポジトリ)に登録します*4

(base) C:\Users\username> git commit -m "Add files."

次のコマンドで、自分のPC(ローカル)からサーバー(リモート)への転送を実行します。「master」は管理者を表すブランチです。複数人で開発するときはここに自分のブランチ名を指定します。

(base) C:\Users\username> git push heroku master

2回目以降の更新は、PCの再起動などで接続が切れていたら改めて「heroku login」でログインしてから行ってください。デバッグするのは少し大変ですが*5、アップ自体はAnaconda Prompt(コマンドプロンプト)で完結しているので簡単ですね。

 

手順6:自分のLINE botとお友達になる

LINE botには普通のLINEアカウントと同じくLINE IDが割り振られています。LINE official account managerの「アカウント設定」というタブを選択すると、「ボットのベーシックID」として@から始まるIDがあります。これで友達になれます。

他にも、この「アカウント設定」のページからLINE botのアイコンや背景画像を変えたり、グループLINEへの参加可否を決めたりできます。一般公開などはLINE botの発信内容が第三者著作権に触れないかどうか留意しつつ、設定しましょう。

友達になったら「へいぼっと」又は「ヘイボット」と話しかけて応答が返ってくることを確認します*6。その辺のキーワードはmain.pyのtriggersという変数で指定しているので、適当に変えてください。

 

以上、今回はLINE botの作り方という、研究にもデンマークにも全然関係ない記事でした。でも、たまにはこういう息抜きみたいなプログラミングもいいですよね。友達に共有して遊んだりできるので(というかしました)、とてもおもしろいです。

次回は、今度こそ寄り道せずに、真面目に時系列クラスタリングアルゴリズムK-shapeについてご紹介し、これを音源分離に応用してみたいと思います。

稚文をお読みいただきありがとうございました。

*1:これをAIとは呼びたくありません。あまりにも単純な応答プログラムなので。

*2:このように、インターネット上にURLをもって公開されたプログラムのことを、ウェブ・アプリケーション・インターフェース(API)と呼びます。Python等のプログラムは、自分のPC上でプログラムを動作させるだけでなく、APIにして自由に呼び出せるようにすればどこでも同じ機能を利用可能になって便利です。

*3:プログラム初心者の方でも、Githubという名前なら聞いたことがあるのではないでしょうか。Gitを使えば、PCの特定フォルダに格納されているファイルの更新状況を自動で追ってくれるので、自分のPC内でバージョン管理ができてとても便利です。

*4:commitするときの「-m」オプションは、「更新内容を"Add files."という簡易なコメントで投稿します」という意味です。vimで詳細に更新内容を書きたい場合は「-a」オプションを指定します。

*5:LINE botに既読スルーされたときの深い悲しみは、開発したことのある人にしか分かりませんきっと。

*6:どうやら、LINE messaging APIはちょっと反応が遅いときがあるようなので、アップロードが完了してから少し時間をおいたり、何度か話しかけましょう。