pythonでLINE BOTを作る

作成の記事自体は色々見つかるんだけど、LINE側のWebhockの値が異なっていたりしたので自分メモ
まずはリファレンスをちゃんと読もう!(自戒)

LINE Developers

https://developers.line.biz/ja/ から

BOTユーザーは別に作るので、ここへの登録は個人のLINEアカウントで問題ない

ログイン後、新規プロバイダーを作成する

次にチャンネルを作成する
今回は普通(?)のチャットボットを作るので、Massaging APIを選択する

必要な情報を入力してチャンネルを作成する

作成後に、アプリを作る上で必要な情報は
1. Channel Secret
2. アクセストークン (ロングターム)
の2つ

Webhook送信を有効にし、Webhookを受け入れるURLを入力する(httpsのみ)

botサーバー

nginx + flaskで作りました

OSの環境変数(.bash_profileなど)にLINE_CHANNEL_SECRETとLINE_CHANNEL_ACCESS_TOKENを設定します。
書いた後は反映を忘れずに!

export LINE_CHANNEL_SECRET=xxxxxxxxxx
export LINE_CHANNEL_ACCESS_TOKEN=xxxxxxxxxxxxxxxxxx

nginxのconfigにlocationを追加する

    location ~ /何かしら {
        proxy_pass http://localhost:8000;
    }

flask アプリケーションを作る

#!/usr/bin/env python3.7
import os,json
from flask import Flask, request, make_response
import base64
import hashlib
import hmac

from linebot import (
    LineBotApi, WebhookParser
)
from linebot.exceptions import (
    InvalidSignatureError
)
from linebot.models import (
    MessageEvent, TextMessage, TextSendMessage
)

channel_secret = os.getenv('LINE_CHANNEL_SECRET', None)
channel_access_token = os.getenv('LINE_CHANNEL_ACCESS_TOKEN', None)

if channel_secret is None:
    print('Specify LINE_CHANNEL_SECRET as environment variable.')
    sys.exit(1)
if channel_access_token is None:
    print('Specify LINE_CHANNEL_ACCESS_TOKEN as environment variable.')
    sys.exit(1)

line_bot_api = LineBotApi(channel_access_token)

# Flask
app = Flask(__name__)
@app.route('/line-bot/api',methods=['post'])

def application():
    environ = request.headers
    data = json.loads(request.data)

    # シグネチャ検証(とりあえずマスク)
#    signature = environ['X_LINE_SIGNATURE']
#    hash = hmac.new(channel_secret.encode('utf-8'),
#        data.encode('utf-8'), hashlib.sha256).digest()
#    signature_from_data = base64.b64encode(hash)
#
#    print(signature)
#    print(signature_from_data)
#
    # get request body as text
    content_length = int(environ['CONTENT_LENGTH'])

    # 画像かスタンプを送られた場合
    if 'text' not in data["events"][0]["message"]:
       body = '画像、スタンプは送らないで!'

    # 教えて or おしえてと言われたら自分で探せと返す
    elif 'おしえ' in data["events"][0]["message"]["text"] or '教え' in data["events"][0]["message"]["text"]:
       body = 'オッケーグーグル!\nhttps://www.google.com/'

    # 感謝の言葉を言われたら嬉しいよね
    elif 'ありがとう' in data["events"][0]["message"]["text"]:
       body = 'お役に立てて何よりです'

    # それ以外は、とりあえずオウム返し
    else:
       body = data["events"][0]["message"]["text"]

    for i in data["events"]:
        print(i)
        line_bot_api.reply_message(
            i["replyToken"],
            TextSendMessage(text=body)
        )

    return make_response('ok'), 200

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=8000)

作成後、flaskアプリケーションを起動する

スマホでLINEを起動し、LINEDeveloperのチャンネルに表示されているQRコードを読み込んで友達追加する
(確認していたら、娘からスマホを取り上げられて遊ばれた…)