はじめに
現在ちょっとした副業(バイトのおまけ)みたいなものをやってて,通知がメールで来るんですけどgmailの通知がなんだか調子が良くなかったため,見過ごし対策のためにLINE botを作ってみたらなかなか面白かったので記事にしました.あと,もともとLINE botを使ってお家を便利にしようと思っていたのもあります.そっちの方は全然進んでないんですけどね...
事前準備
本ページではHerokuのサービスを使って公開しますが,後になって問題が発生したためお家のラズパイをサーバにした方も以下のリンクに記します.ラズパイサーバで公開編
※静的な処理のみであれば,本ページの方法で問題ないと思います.
- git
- Herokuアカウント
- LINE developersの登録
- python環境
Git
省略Herokuとは
アプリの構築,提供,監視に役立つクラウドプラットフォームです.今回はサーバ代わりに使います. https://jp.heroku.com/whatHeroku CLIをインストールしておきます.
https://devcenter.heroku.com/articles/heroku-cli
LINE developersの登録
以下から登録https://developers.line.biz/ja/services/messaging-api/
登録が済んだら,Basic settingsの下のところにある'Channel secret'とMessaging APIの下のところにある'Channel access token'の文字列をひかえる.(Channel access tokenはissueをクリックして生成)
Heroku関連
今回の最小構成だとこのようになります.
Procfile
プログラムの実行方法を定義// Procfile web: python main.py
main.py
プログラムのスクリプトファイルrequirements.txt
使用するライブラリを記述ローカル環境でpipで入れる代わりにここに記入
// requirements.txt flask==1.1.2 line-bot-sdk==1.6.0 gunicorn
Herokuに登録する
$ heroku login
アプリケーション登録
$ heroku create アプリケーション名エラーが出たら以下のコマンドを実行してからもう一度やる
$ heroku config --app アプリケーション名
環境変数の設定
$ heroku config:set YOUR_CHANNEL_ACCESS_TOKEN="【LineDevelopersのChannelの設定ページで表示されたAccessトークン】" --app 【アプリケーション名】 $ heroku config:set YOUR_CHANNEL_SECRET="【LineDevelopersのChannelの設定ページで表示されたSECRET】" --app 【アプリケーション名】きちんと設定できたか確認
$ heroku config --app 自分のアプリケーション名出力例
› Warning: heroku update available from 7.42.4 to 7.42.6. === linebot-nogami Config Vars YOUR_CHANNEL_ACCESS_TOKEN: *********** YOUR_CHANNEL_SECRET: ***********
LINE bot関連
Webhookの設定
Webhook URL : https://アプリケーション名.herokuapp.com/callbackとすればOK
※後ろの/callbackのところは適宜自分のプログラムに合わせて変更してください
あとは,初期設定されてる余計な返答の無効化などすると良いとおもいます.
デプロイする
プログラムや設定ファイルなどを置いてるディレクトリに移動し以下を実行.$ git init $ git add $ git commit -m "first commit" $ git push heroku masterこれで不具合がなければおしまい.
おうむ返しと注文管理しかしてないけどなかなか面白いです.

ログの確認
$ heroku logs --tail
最後にmain.pyのソースコード
from flask import Flask, request, abort
import os
from linebot import LineBotApi, WebhookHandler
from linebot.exceptions import InvalidSignatureError
from linebot.models import MessageEvent, TextMessage, TextSendMessage
import time
status = False
user_dict = {}
talk_mode = False
app = Flask(__name__)
#環境変数取得
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("/order_access")
def order_access():
message = '新しい注文が入りました'
push_list = []
for key in user_dict.keys():
if user_dict[key]:
push_list.append(key)
for id in push_list:
line_bot_api.push_message(id, TextSendMessage(text=message))
return "むかしむかし,あるところにおじいさんとおばあさんがいましたとさ。めでたしめでたし。"
@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)
try:
handler.handle(body, signature)
except InvalidSignatureError:
abort(400)
return 'OK'
@handler.add(MessageEvent, message=TextMessage)
def handle_message(event):
global status
global user_dict
global talk_mode
profile = line_bot_api.get_profile(event.source.user_id)
print(profile.user_id)
user_id = profile.user_id
user_name = profile.display_name
print(user_name)
if user_id not in user_dict:
user_dict[user_id] = False # 通知オフ
text = event.message.text
if text == 'on' or text == 'ON' or text == 'オン' or text == 'おん':
user_dict[user_id] = True
message = 'メッセージ取得がオンになりました'
# user_dict[user_id] = True
elif text == 'off' or text == 'OFF' or text == 'オフ' or text == 'おふ':
user_dict[user_id] = False
message = 'メッセージ取得がオフになりました'
elif text == 'リスト' or text == 'りすと' or text == 'list' or text == 'ヘルプ' or text == 'へるぷ' or text == 'help':
message = '「オン」:注文が入ると知らせてくれるよ!\n「オフ」:お知らせを止めるよ!\n「トーク」:おうむ返し(遊び)'
elif text == 'トーク' or text == 'とーく' or text =='talk':
talk_mode = not talk_mode
if talk_mode:
message = 'トークモード:ON'
else:
message = 'トークモード:OFF'
elif talk_mode:
message = text
else:
message = 'ちょっと何言ってるか,わからんちん。\n「ヘルプ」と入力すると使い方が分かるよ!'
line_bot_api.reply_message(event.reply_token, TextSendMessage(text=message))
if __name__ == "__main__":
# app.run()
port = int(os.getenv("PORT"))
app.run(host="0.0.0.0", port=port)