Python
Line
ngrok
linebot
LINEmessagingAPI

クラスLINEを楽しくするBotをつくる

はじめに

学生の皆さんはクラスのLINEグループに入ってますか?グループトークでの会話が弾めばクラスの雰囲気もよくなるはず。そこで今回はクラスLINEが楽しくなるようなBotをつくってみます。
(というのは建前で,KOSENハッカソンでLINEBotつくってるチームが楽しそうだったので自分もやってみる。)

開発環境

  • macos Mojava 10.14.2
  • Python 3.6.4

つくる

1.Botアカウントの作成

LINEdevelopersのサイトに自分のLINEアカウントでログインします。
「Messaging APIを始める」を選択します。
スクリーンショット 2019-01-03 21.47.08.png

「今すぐはじめよう」を選択します。
スクリーンショット 2019-01-03 21.52.15.png

プロバイダーを登録します。もうある人はそっちを使いましょう。
スクリーンショット 2019-01-07 14.41.49.png

Botの情報を入力していきます。
プランを「Developer Trial」にするところだけ注意してください。
業種はもちろん学生です。
スクリーンショット 2019-01-03 22.18.24.png

Botの設定を行います。
以下の設定にしているか確認してください。

  • Webhook送信: 利用する
  • Botのグループトーク参加: 利用する
  • 自動応答メッセージ: 利用しない
  • 友達追加時あいさつ: 利用する スクリーンショット 2019-01-07 14.42.16.png

最後にBotを友達追加しましょう。
「チャネル基本設定」の下までスクロールするとQRコードがあるのでLINEアプリなどから読み取りましょう。
IMG_1344.png
この時点では既読はついても返事はしてくれません。悲しいね。

2.サンプルの作成

まずは受け取ったテキストをおうむ返しするBotをつくります。

まずは環境構築
Flask・SDK of the LINE Messaging API for Python・ngrokをインストールします。

$ pip install flask 
$ pip install line-bot-sdk
$ brew install ngrok

line-bot-sdk-pythonREADME.rstへ行き,Usageのサンプルプログラムをコピーしてapp.pyとして保存します。
下記ではデバッグのためにメッセージを返す関数を追加しました。

app.py
from flask import Flask, request, abort

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

app = Flask(__name__)

line_bot_api = LineBotApi('YOUR_CHANNEL_ACCESS_TOKEN')
handler = WebhookHandler('YOUR_CHANNEL_SECRET')

#追加した部分
@app.route("/")
def hello_world():
    return "hello world!"

@app.route("/callback", methods=['POST'])
def callback():
    # get X-Line-Signature header value
    signature = request.headers['X-Line-Signature']

    # get request body as text
    body = request.get_data(as_text=True)
    app.logger.info("Request body: " + body)

    # handle webhook body
    try:
        handler.handle(body, signature)
    except InvalidSignatureError:
        abort(400)

    return 'OK'


@handler.add(MessageEvent, message=TextMessage)
def handle_message(event):
    line_bot_api.reply_message(
        event.reply_token,
        TextSendMessage(text=event.message.text))


if __name__ == "__main__":
    app.run()

Channel Secretとアクセストークンの確認

先ほどの「LINE developers」の画面でChannel SecretChannel Access Tokenを確認します。

  • Channel Secret確認

スクリーンショット 2019-01-07 16.31.32.png

  • アクセストークン発行

スクリーンショット 2019-01-07 16.31.57.png

app.pyのソースコードのYOUR_CHANNEL_ACCESS_TOKENYOUR_CHANNEL_SECRETの部分をそれぞれ確認した値に書き換えます。

3.Flaskの実行とngrokによる公開

Flaskの実行

app.pyのあるディレクトリに移動して以下のコマンドを実行します。

$ export FLASK_APP=app.py
$ export FLASK_DEBUG=1
$ flask run --host=0.0.0.0

http://localhost:5000 にアクセスし「hello world!」の画面が出れば成功です。

ngrokによる公開

一時的に外部へ公開するためにngrokを使います。
以下コマンドをFlaskを実行したのと同じ場所で実行してテストします。
今回は5000を指定しましょう。

$ ngrok http 5000

実行するとこのような画面が出てきます。

ngrok by @inconshreveable                                                           (Ctrl+C to quit)

Session Status                online
Session Expires               7 hours, 59 minutes
Version                       2.2.8
Region                        United States (us)
Web Interface                 http://127.0.0.1:4040
Forwarding                    http://c7602dfa.ngrok.io -> localhost:5000
Forwarding                    https://c7602dfa.ngrok.io -> localhost:5000

Connections                   ttl     opn     rt1     rt5     p50     p90
                              0       0       0.00    0.00    0.00    0.00

https://で始まるアドレスをコピーします。
この場合はhttps://c7602dfa.ngrok.ioです。

Webhook URLの更新

先ほど取得したURLを登録します。
今回はhttps://c7602dfa.ngrok.io/callbackWebhook URLになります。
LINE developers画面のWebhook URLを更新しましょう。
スクリーンショット 2019-01-09 22.14.56.png

更新ボタンを押して,もう一度Botに話しかけてみます。
IMG_1366.png
おうむ返ししてくれました!

4.楽しくする

このままだと特に楽しくもないのでクラスラインで使えそうな機能を追加しましょう。
今回は時間割を教えてくれるBotをつくります。

先ほどのapp.pyを書き換えます。

app.py
from flask import Flask, request, abort

from linebot import (
    LineBotApi, WebhookHandler
)
from linebot.exceptions import (
    InvalidSignatureError
)
from linebot.models import (
    MessageEvent, TextMessage, TextSendMessage, QuickReplyButton, MessageAction, QuickReply,
)

app = Flask(__name__)

line_bot_api = LineBotApi('YOUR_CHANNEL_ACCESS_TOKEN')
handler = WebhookHandler('YOUR_CHANNEL_SECRET')

lesson = {
    '月曜日の時間割':'月曜日は\n1:こくご\n2:たいいく\n3:さんすう\nです。',
    '火曜日の時間割':'火曜日は\n1~2:りかじっけん\n3:こくご\nです。',
    '水曜日の時間割':'水曜日は\n1:さんすう\n2:おんがく\n3:せいかつ\nです。',
    '木曜日の時間割':'木曜日は\n1:たいいく\n2:かていか\n3:りか\nです。',
    '金曜日の時間割':'金曜日は\n1:さんすう\n2:こくご\n3:がっかつ\nです。'
}

@app.route("/")
def hello_world():
    return "hello world!"

@app.route("/callback", methods=['POST'])
def callback():
    # get X-Line-Signature header value
    signature = request.headers['X-Line-Signature']

    # get request body as text
    body = request.get_data(as_text=True)
    app.logger.info("Request body: " + body)

    # handle webhook body
    try:
        handler.handle(body, signature)
    except InvalidSignatureError:
        abort(400)

    return 'OK'


@handler.add(MessageEvent, message=TextMessage)
def handle_message(event):
    if event.message.text =='時間割を教えて':
        day_list = ["月", "火", "水", "木", "金"]
        items = [QuickReplyButton(action=MessageAction(label=f"{day}", text=f"{day}曜日の時間割")) for day in day_list]
        messages = TextSendMessage(text="何曜日の時間割ですか?",quick_reply=QuickReply(items=items))
        line_bot_api.reply_message(event.reply_token, messages=messages)
    elif event.message.text in lesson:
        line_bot_api.reply_message(
            event.reply_token,
            TextMessage(text=lesson[event.message.text])
        )

    '''
    line_bot_api.reply_message(
        event.reply_token,
        TextSendMessage(text=event.message.text))
    '''

if __name__ == "__main__":
    app.run()

時間割を教えて」というメッセージに対して,クイックリプライの機能で曜日を決めてもらい,その曜日ごとの時間割を返します。
IMG_1368.png
金曜日を選択
IMG_1369.png
時間割を聞いたときに全員に既読無視されるようなことが無くなるといいな😊

終わりに

とりあえず,クラスラインに入れて使ってもらうところまではできたのでよかったです。
LINEBotのいいところは身近の人たちに使ってもらえて直接意見を聞けるところだと思います。
これからもっとクラスラインを盛り上げるBotにできたらいいな。

参考

Messaging API - LINE Developers
1時間でLINE BOTを作るハンズオン (資料+レポート) in Node学園祭2017 #nodefest
FlaskでLINE botを実装し,herokuにdeployするまで