DjangoでLINEBotを作成する

January 08, 2020

Django で LINEBot を使うという内容の記事がパッと調べた感じ少なかったり、あっても古かったりしたのでまとめました。

とりあえず LINEBot 入門として送られてきた文章をそのまま返信するおうむ返し Bot を作成します。

こちらの記事では SDK を利用していますが、Python 初心者の僕はPython で HTTP リクエストすら投げれないので修行のために自力でやりたいと思います。

自分は Django 歴 1 週間弱の Django 初心者です。 また、普段よく使う言語が関数型の Elixir なので実装がオブジェクト指向っぽくない可能性があります。

何か間違っている部分や改善したほうがいいところ、アドバイスがあったら是非コメントをください。

LINE Developer への登録/チャネルの登録

↓ ここから登録 https://developers.line.biz/ja/

プロジェクト作成

適当にプロジェクトを作成します。

$ django-admin startproject qiita_linebot
$ cd qiita_linebot/
$ python manage.py startapp qiita_linebot_ai

urls.py を作成

from django.urls import path

from . import views

urlpatterns = [
    path('', views.index, name='callback'),
]

qiita_linebot/urls.pyに反映させます。

from django.contrib import admin
from django.urls import include, path

urlpatterns = [
    path('qiita_linebot_ai/', include('qiita_linebot_ai.urls')),  #add
    path('admin/', admin.site.urls),
]

LineMessage クラスの作成

普段 Elixir ばかりを使っているのでオブジェクト指向的な考えは苦手なのですが、こういう時はカプセル化(?)した方がいいと思うので、LineMessageクラスを作成し、中で、reply メソッドを作成します。

from django.http import HttpResponse
from django.views.decorators.csrf import csrf_exempt

import urllib.request
import json


REPLY_ENDPOINT_URL = "https://api.line.me/v2/bot/message/reply"

ACCESSTOKEN = '自分のアクセストークン'   #MessagingAPI設定|>チャネルアクセストークンからアクセストークンを取得
HEADER = {
    'Content-Type': 'application/json',
    'Authorization': 'Bearer ' + ACCESSTOKEN
}

class LineMessage():
    def __init__(self, messages):
        self.messages = messages

    def reply(self, reply_token):
        body = {
            'replyToken': reply_token,
            'messages': self.messages
        }
        print(body)
        req = urllib.request.Request(REPLY_ENDPOINT_URL, json.dumps(body).encode(), HEADER)
        try:
            with urllib.request.urlopen(req) as res:
                body = res.read()
        except urllib.error.HTTPError as err:
            print(err)
        except urllib.error.URLError as err:
            print(err.reason)

ここでメソッド reply に渡されている message は以下のような形式を想定しています。

{
 type: "text",
 text: "hogehoge" # 今回は受信したメッセージをそのまま返す
}

これをみて 「送るメッセージ(上なら”hogehoge”)だけを引数でとればいいじゃん」 と思う方もいるかもしれませんが、LINE Messaging API は複数のメッセージの同時送信にも対応しています。 また、typeに関しても text 以外に存在します。

クラスをさらに分けるということも考えたのですが、今回はとりあえずこのような形で実装します。

message_creater を作成

def create_single_text_message(message):
    test_message = [
                {
                    'type': 'text',
                    'text': message
                }
            ]
    return test_message

LineMessage.replyで用いる引数の message 用のモジュール message_creater を作成します。

view を編集

from django.shortcuts import render
from django.http import HttpResponse
import json
from django.views.decorators.csrf import csrf_exempt

from utils import message_creater
from qiita_linebot_ai.line_message import LineMessage

@csrf_exempt
def index(request):
    if request.method == 'POST':
        request = json.loads(request.body.decode('utf-8'))
        events = request['events']
        for event in events:
            message = event['message']
            reply_token = event['replyToken']
            line_message = LineMessage(message_creater.create_single_text_message(message['text']))
            line_message.reply(reply_token)
        return HttpResponse("ok")

これで実装は終了です。

ngrok を用いてテストする

ngrok の設定

実際に試してみます。 WebhookURL に localhost は指定できないので ngrok を使います。

以下の記事を参考に ngrok をインストールしてください。 ngrok が便利すぎる

インストールできたら

$ ngrok http 8000

とすると

スクリーンショット 2020-01-08 16.23.00.png

このように起動できます。 これより後に出てくる ngrok の URL は適宜自分のものと置き換えてください

WebhookURL の設定

MessagingAPI 設定|>Webhook 設定|>WebhookURL から https://ecdb2a20.ngrok.io/qiita_linebot_ai/を入力します。

ALLOWED_HOSTS の編集

ALLOWED_HOSTS に以下のように ngrok を追加します。

ALLOWED_HOSTS = ["ecdb2a20.ngrok.io"]

テスト

これで準備は整いました!

サーバーを起動して以下のようにおうむ返しされれば成功です!

スクリーンショット 2020-01-08 16.30.28.png

このエントリーをはてなブックマークに追加