未読になって忘れない!超簡単LINE botでTODOをメモ【Python】

# 対象者
- Torelloに書くほどじゃない些細なTODOがある
    - 帰りに牛乳を買う
    - 明日までに振り込む
    - 〇〇に電話する
    - etc...
- 些細なTODOを忘れやすい
- LINEは日常的に見る

# 完成イメージ
botに対してTODOを発言
<img width="494" alt="スクリーンショット 2019-04-22 19.12.06.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/187535/44e00659-1172-f0b4-a2cf-c193780fff70.png">

talkを抜ける
設定秒数後におうむ返しがくる(それが未読になる)
<img width="281" alt="スクリーンショット 2019-04-22 19.12.26.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/187535/9e3d784b-680e-d1ec-ba35-13c5914f7e51.png">

それだけ

<img width="300" alt="スクリーンショット 2019-04-22 22.11.51.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/187535/4aba8c1c-3e2b-73cd-5530-79fec66cb9ea.png">

**目立って忘れにくい！**
**気になって早く終わらせたくなる！**


# 作りかた

## LINEのチャネル作成
- [LINE Developer コンソール](https://developers.line.biz/ja/)にアクセス
- 詳細は[この記事](https://qiita.com/nkjm/items/38808bbc97d6927837cd)を参考にしてください

できたらこんな感じ
個人情報っぽいのは黒で隠しました
![スクリーンショット 2019-04-22 19.31.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/187535/d5c75c83-0218-9701-f6a1-b0bd6def5dd4.png)

## pythonコード
先ほど作成したチャネルのチャネルシークレットとアクセストークンを使います。
![スクリーンショット 2019-04-22 19.36.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/187535/85dddd77-d504-b94d-de24-4c9348a59cb1.png)
![スクリーンショット 2019-04-22 19.39.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/187535/f04bdc20-8a2d-5d55-1a97-46c556556f6c.png)

コードを書く前に下記をインストールしてください

```
$ pip install line-bot-sdk
```


コードは以下のようになっています。
簡単なおうむ返しのアプリになっています。
[参考コード](https://github.com/line/line-bot-sdk-python)

```python:main.py
from flask import Flask, request, abort

from linebot import LineBotApi, WebhookHandler
from linebot.exceptions import InvalidSignatureError
from linebot.models import MessageEvent, TextMessage, TextSendMessage
import os
import time

app = Flask(__name__)

# change your value
YOUR_CHANNEL_ACCESS_TOKEN = "YOUR_CHANNEL_ACCESS_TOKEN"
YOUR_CHANNEL_SECRET = "YOUR_CHANNEL_SECRET"

line_bot_api = LineBotApi(YOUR_CHANNEL_ACCESS_TOKEN, timeout=30)
handler = WebhookHandler(YOUR_CHANNEL_SECRET)

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

    # get body of request
    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)
    # it is ok if finish handle
    return 'OK'

## get line message and repeat message ##
@handler.add(MessageEvent, message=TextMessage)
def handle_message(event):
    time.sleep(10)  # add
    line_bot_api.reply_message(
        event.reply_token,
        TextSendMessage(text=event.message.text)) # repeat message

# ポート番号の設定
if __name__ == "__main__":
#    app.run()
    port = int(os.getenv("PORT", 5000))
    app.run(host="0.0.0.0", port=port)
```

注目するのは

```python
line_bot_api = LineBotApi(YOUR_CHANNEL_ACCESS_TOKEN, timeout=30)
# ...
def handle_message(event):
    time.sleep(10)  # add
    line_bot_api.reply_message(
        event.reply_token,
        TextSendMessage(text=event.message.text)) # repeat message
```
インスタンス生成時にtimeoutの値を生成し、`time.sleep()`することで時間差を作っています。
ここで、メッセージを受け取ってから10秒後に返事をするようにしています。
ここの値を変えることで返事をしてくる時間を変えられます。
**時間を長くして何件も未読のメッセージをためることもできます。**

## Herokuにデプロイ
アカウントを作成:https://jp.heroku.com
[アカウント作成参考記事](https://qiita.com/Arashi/items/b2f2e01259238235e187)

アカウントを作ったら

```
heroku create アプリ名
```

main.pyと同じ階層に`runtime.txt`と`Procfile`と`requirements.txt`を作成します。

```
line-bot
  ┣ main.py
  ┣ runtime.txt
  ┣ Procfile
  └ requirements.txt
```

```runtime.txt(Pythonのバージョン記憶)
python-3.6.6
```

```Procfile(プログラムの実行方法定義)
web: python main.py
```

```requirements.txt(インストールライブラリ)
Flask==0.12.2
line-bot-sdk==1.5.0
```

デプロイをします

```
$ cd line-bot
$ git init
$ git add
$ git commit -m "first commit"
$ git push heroku master
```

## webhookの設定
[LINE Developers](https://developers.line.biz/ja/)に戻って、Webhook URLを変更

![スクリーンショット 2019-04-22 22.05.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/187535/21ab28b3-0879-739f-cccd-5f40bea0a75c.png)

# 完成！(繰り返し)
botに対してTODOを発言
<img width="494" alt="スクリーンショット 2019-04-22 19.12.06.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/187535/44e00659-1172-f0b4-a2cf-c193780fff70.png">

talkを抜ける
設定秒数後におうむ返しがくる(それが未読になる)
<img width="281" alt="スクリーンショット 2019-04-22 19.12.26.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/187535/9e3d784b-680e-d1ec-ba35-13c5914f7e51.png">

それだけ

<img width="300" alt="スクリーンショット 2019-04-22 22.11.51.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/187535/4aba8c1c-3e2b-73cd-5530-79fec66cb9ea.png">

**目立って忘れにくい！**
**気になって早く終わらせたくなる！**

# まとめ
今回は発話してからの時間差を使って未読を意図的に作りました。
トリガーを決めてその言葉を発した数秒後におうむ返しさせたりすると、もっと気楽に何件もの未読をためれるかもしれません。