Help us understand the problem. What is going on with this article?

LINE Bot を Python Flask を使って Now.sh (Zeit.co) 上で無料で簡単に動かす方法

More than 1 year has passed since last update.

LINE で自動で返信してくれる Bot が、今ナウい Now.sh (Zeit.co) 上に Python Flask を使って無料で簡単に作れます!

Now.sh とは?

  • PaaS:ソースコードをデプロイ(利用可能にすること)するだけで自前サーバーなしでプログラムが動かせる!
  • 小規模なら無料!クレジットカード不要
  • HTML/CSS/JavaScript を使った静的 Web ページ、Node.js、Go、PHP、Python(今回使う)、Rust、Bash、Markdown などに対応
  • https 対応(LINE Bot を作るには必須)
  • Heroku のようにスリープ後の復帰に時間がかからない(1秒以内)

Now.sh の無料での制限

  • 帯域幅 100 GB/月
  • ビルドとリクエスト 1000回/日
  • 最長実行時間 10秒
  • ログ 1000回/日
  • ストレージ 100GB
  • ファイルサイズ 100MB/ファイル
  • ビルド 32回/時、100回/日

個人/少人数利用ならまったく問題ないですね。

https://zeit.co/pricing, https://zeit.co/docs/v2/deployments/builds#limits)

完成イメージ

LINE Screenshot

流れ


LINE で Bot にメッセージが送られると LINE Messaging API から Now.sh 上のサーバーに POST リクエストが飛ぶので、サーバー上で処理をして、メッセージを LINE Messaging API にまた POST で返します。

  1. LINE Developers の登録
  2. Now.sh (Zeit.co) の登録
  3. ファイルの作成と Now.sh へのデプロイ

という順番でやっていきます。

1. LINE Developers の登録

  1. https://developers.line.biz/console/ にアクセスしてログイン
  2. プロパイダー作成
  3. チャネル作成:Messaging API を選択。プランは Developer Trial がおすすめ

この Developer Trial には特に有効期限はありませんが、友だちが50人までという制限があります。

登録方法について詳しくはこちらへ:https://developers.line.biz/ja/docs/messaging-api/getting-started/

登録が終わったら設定をします。

[チャネル基本設定]

メッセージ送受信設定
アクセストークン(ロングターム):「再発行」をクリック → 0時間に設定(=失効しない)
Webhook送信:利用する

LINE@機能の利用
自動応答メッセージ:利用しない
友達追加時あいさつ: 利用しない

設定が終わったらこのページは後でまた使うのでそのままにしておいてください。

2. Now.sh (Zeit.co) の登録

:information_source: ここではコマンドラインを使用しますが、GUI アプリもあります:https://zeit.co/download

まず brew または npm を使って now をインストールします。

Homebrew(Mac) を使用:

$ brew cask install now

npm を使用(インストール方法):

$ npm install -g now

インストールが終われば now を実行します。
メールアドレスの入力を求められるので入力すると、
Verify email
というメールが届くので VERIFY をクリックすると登録完了です。

3. Now.sh へのデプロイと設定

ファイルの作成

まずディレクトリを作ります。

$ mkdir line-bot
$ cd line-bot

必要なファイルは app.py now.json requirements.txt の3個です。
now.jsonエイリアス の部分は username-line-bot など自由に置き換えてください。

app.py
import os
from flask import Flask, request, abort, redirect
from linebot import LineBotApi, WebhookHandler
from linebot.exceptions import InvalidSignatureError, LineBotApiError
from linebot.models import MessageEvent, TextMessage, TextSendMessage

app = Flask(__name__)
line_bot_api = LineBotApi(os.environ['ACCESS_TOKEN'])
handler = WebhookHandler(os.environ['CHANNEL_SECRET'])


@app.route('/', methods=['POST'])
def callback():
    try:
        signature = request.headers['X-Line-Signature']
    except KeyError:  # POSTリクエストのヘッダーに署名がないとき
        print('No signature in header:' + request.remote_addr)
        abort(400)

    body = request.get_data(as_text=True)
    print('Request body: ' + body)

    try:
        handler.handle(body, signature)
    except LineBotApiError as e:  # 何らかのエラー
        print("LINE Messaging API Error: %s\n" % e.message)
        for m in e.error.details:
            print("  %s: %s" % (m.property, m.message))
        print("\n")
    except InvalidSignatureError:  # POST リクエストの署名が無効のとき(LINE API からでないとき)
        print('Signature was in header, but invalid:' + request.remote_addr)
        abort(400)

    return 'OK'


@handler.add(MessageEvent, message=TextMessage)  # テキストメッセージを受け取ったときの処理
def handle_message(event):

    received = event.message.text
    send_message = received + '!'

    line_bot_api.reply_message(
        event.reply_token,
        TextSendMessage(text=send_message)
    )
now.json
{
  "version": 2,
  "builds": [
    { "src": "app.py", "use": "@sisp/python-wsgi", "config": { "maxLambdaSize": "15mb" } }
  ],
  "env": {
    "ACCESS_TOKEN": "@access-token",
    "CHANNEL_SECRET": "@channel-secret"
  },
  "routes": [
    { "src": "/.*", "dest": "/"}
  ],
  "regions": ["hnd1"],
  "alias": ["エイリアス.now.sh"]
}

requirements.txt
flask
line-bot-sdk

環境変数の設定

続いて、環境変数を設定します。
先ほど開いた https://developers.line.biz/console/channel/ にアクセスします。

以下の2つの情報を使います。

基本情報
Channel Secret

メッセージ送受信設定
アクセストークン(ロングターム)

そして以下のコマンドを実行します。YOUR_CHANNEL_SECRET_HERE, YOUR_ACCESS_TOKEN_HERE は上の Channel Secret とアクセストークンに置き換えてください。

$ now secret add channel-secret YOUR_CHANNEL_SECRET_HERE
$ now secret add access-token YOUR_ACCESS_TOKEN_HERE

そして、同じく メッセージ送受信設定 から

Webhook URL:先程 now.json で指定した エイリアス.now.sh を入力

「接続確認」を押すとエラーになりますが、認証が通っていないだけなので問題ありません。

デプロイ

準備が終わりました。ファイルを Now.sh にアップロードしてデプロイ(利用可能にすること)します。

$ now

と3文字打つだけです!簡単!

完成です! :tada::tada::tada:
実際に Bot にメッセージを送ってみてください。


更新したいときはまた

$ now

と打つだけで更新されます。(1分ほど時間がかかります)

おまけ:ローカルでの開発

ファイルに変更を加えた後いちいち Now.sh にデプロイするのは時間がかかるので開発用にローカルサーバーを作ります。

今度はこうなります。

ngrok というのは、ローカルサーバーにインターネットからアクセスできるように URL を与えてくれるものです。ポート開放などの手間がなくなります。コマンド1発で数秒で URL が生成されます。

Python, Flask のインストール

$ brew install python

最初から python が入っている場合はコマンド名 python,pip がそれぞれ python3pip3 になります。
面倒なのでエイリアス設定してしまいます。

~/.bashrcなど
alias py='python3'
alias pip='pip3'

そして flask のインストール。

$ pip3 install flask

ngrok のインストール

$ brew cask install ngrok

ローカルサーバー起動

$ flask run --reload

この --reload オプションはファイルが変更されるごとに自動でリロードしてくれるオプションです。

* Running on http://127.0.0.1:5000/

などと表示されるので : 以降のポート番号の部分を覚えておきます。

ターミナルで新しいタブまたはウインドウを開いて以下の 5000 の部分を先程のポート番号に変更します(デフォルトでは 5000 なので変えなくて良い)。

$ ngrok http 5000

http://localhost:4040 にアクセスすると POST の内容とかが見れます。便利!

あとがき

マルコフ連鎖と組み合わせると自動生成したメッセージを返せるので面白いですね。
https://qiita.com/shge/items/fbfce6b54d2e0cc1b382

参考

https://qiita.com/nkjm/items/38808bbc97d6927837cd
https://qiita.com/vimyum/items/2226daa74444575811b5
https://qiita.com/tetrapod117/items/a7079b9cc2d2c9ac4f14

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away