【LINE Notify API,AWS】バズってるツイートをグループLINEに定期送信

##今回作るもの
友達とのグループLINEに対して、
定刻になるとバズってるツイートを送信する仕組みをつくります。


##LINE Notify API

>LINE Notifyと連携を行うことで、LINEユーザーが簡単にサービスの通知を受信できるようになります。

【引用元】：[LINE Notify](https://notify-bot.line.me/ja/)

らしいです。

実際に使うとこんな感じで`LINE Notify`というアカウントからメッセージが届きます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244071/d1d9e121-8e8a-db95-1cd3-65c688f9cce6.png)


##LINE Notifyの下準備

下記リンクの手順通り、`LINE Notify`が使える状態にします。
[[超簡単]LINE notify を使ってみる](https://qiita.com/iitenkida7/items/576a8226ba6584864d95#%E6%89%8B%E9%A0%86)


##バズってるツイートの取得

バズってるツイートも`Twitter API`使って頑張ろうか迷いましたが、
辛そうだったので既存のランキングサイトからスクレイピングしてくることにしました。

Twitter人気ランキングサイト →【[TwTimez](http://www.twtimez.net/index.html)】


##コード(Python)

```Python
import requests
from bs4 import BeautifulSoup

#一番勢いのあるツイートを取得
def bazz_get():
    # アクセスするURL
    url = "http://www.twtimez.net/index.html"

    # URLにアクセスする
    html = requests.get(url)

    # htmlをBeautifulSoupで扱う
    soup = BeautifulSoup(html.text, "html.parser")

    try:
        for detalis in soup.find(class_="details details2"):
            print(detalis.get("href"))
            return str(detalis.get("href"))
    except:
        return "なんかしらのエラー"

#Lineにメッセージを送る
def send_line(Bazz):

    notify_url = "https://notify-api.line.me/api/notify"
    token = "アクセストークン"
    headers = {"Authorization": "Bearer " + token}

    message = "\r\n" + Bazz
    payload = {"message":  message}

    requests.post(notify_url, headers=headers, params=payload)


if __name__ == "__main__":
    send_line(bazz_get())
```
##スクレイピング
何気にちゃんとやる？の初めてです。
`BeautifulSoup`ってのを使えばちょちょいのちょいでした。

下記の箇所でhtmlの中から欲しい情報を持つクラスやタグを引っ張ってきてます。

```Python
    for detalis in soup.find(class_="details details2"):
        print(detalis.get("href"))
        return str(detalis.get("href"))
```

欲しい情報を持つクラスやタグはGIFでやっているような手順で突き止めます。
`F12 Key`を押せばページのhtmlを見れます。

![F12.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244071/ca4b741b-0d90-7ca9-ea4e-00813804c149.gif)


ここまで問題なければ、実行後にLINEへメッセージが送られます。

##AWS
AWSのサービスを利用して定刻になるとメッセージを自動で送る仕組みを作ります。

多分無料です。後で請求書来たら勉強料を支払って速攻で止めます。


###AWS Lambda

[AWS Lambda解説動画](https://youtu.be/Hr6ZIvXSZpw)

>サーバーについて検討することなくコードを実行できます。お支払いいただくのは、実際に使用したコンピューティング時間に対する料金のみです。

らしいです。ここに今回書いたコードをぶち込みます。

###Amazon CloudWatch

[Amazon CloudWatchの解説動画](https://youtu.be/M7HAI4S0yz4)

>AWS とオンプレミスにおける AWS のリソースとアプリケーションのオブザーバビリティ

らしいです。なるほどわからん。
要するに自分で作った何かしらを簡単に監視していろいろできますってことだと思います。
設定した時刻にLambda上で作成した関数を定期的に実行可能です。

##実際の手順

`Lambda`のコンソールにサインインして`関数の作成`を選択し、
適当に名前をつけて次に進みます。

![AWSAddTrigger.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244071/e52e4085-9657-ac23-82a3-e944783977ee.png)

~~Zipでフォルダ毎アップすることもできるみたいですが、
そこまで大したものを作ってないので、関数に先程のコードをコピペして貼り付けます。~~

モジュールを利用しているのでダメでした。
さらに言うと、コードを追加、もしくは修正する必要があります。

また、`コードをインラインで編集`ではなく、`.zipファイルでアップロード`します。

###AWS用に変更したコード

```python

import requests
from bs4 import BeautifulSoup


def bazz_get():
    # アクセスするURL
    url = "http://www.twtimez.net/index.html"

    # URLにアクセスする
    html = requests.get(url)

    # htmlをBeautifulSoupで扱う
    soup = BeautifulSoup(html.text, "html.parser")

    try:
        for detalis in soup.find(class_="details details2"):
            print(detalis.get("href"))
            return str(detalis.get("href"))
    except:
        return "なんかしらのエラー"


def send_line(Bazz):

    notify_url = "https://notify-api.line.me/api/notify"
    token = "アクセストークン"
    headers = {"Authorization": "Bearer " + token}

    message = "\r\n" + Bazz
    payload = {"message":  message}

    requests.post(notify_url, headers=headers, params=payload)


def bot(event, lambda_context):
    send_line(bazz_get())

```
下記がLambdaで実際に呼び出される関数です。
実行だけを担うScriptを別途用意しても良かったのですが、
問題なく動いてくれて、今後拡張する予定もないので下記のようにしました。
Lambdaで呼び出すためには引数が必要です。

```python

def bot(event, lambda_context):
    send_line(bazz_get())
```

アップロード先のハンドラにPython Script名と呼び出したいメソッド名を`.`で繋いで書いておきます。

![BuzzNotify.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244071/02df6ad2-87ed-7ca1-29e3-cbac8801fcd5.png)



###モジュール入りのZipファイルをLambdaにアップロード

まずは、モジュールを任意のディレクトリに保存します。

まずは保存したいディレクトリまで移動します。

```:コマンドプロンプトで実行
cd 任意のディレクトリ
```

あとは、カレントディレクトリにPython Script内で使用したモジュールを保存します。

```:コマンドプロンプトで実行
pip install beautifulsoup4 -t .
pip install requests -t .
```

次はZip圧縮です。
アップロードしたいPython Scriptとモジュールを圧縮します。
全てを格納したフォルダに対してZip圧縮行うと一階層分余計なフォルダができてしまうので
GIF画像のように全選択して圧縮します。

![Zip.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244071/1932fd4c-c710-c7c5-c3b9-39089347d67a.gif)


##CloudWatch Events

次は`トリガーを追加`を選択してCloudWatchと連携します。
(CloudWatchのコンソールにサインインして別途設定を行うアプローチでも可能です。)

![AWRTrigger.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244071/c4ab1b1e-097a-3610-23a9-59b1c564a9fe.png)

##スケジュールの設定
スケジュールの設定方法(いつコードを実行するか)は下記リンクが参考になります。
[Schedule Expressions for Rules](https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/events/ScheduledEvents.html)

CloudWatchにコンソールからサインインして
`ルールの新規作成`をした場合は下記画像のように
どのタイミングで実行するか表示されるのでわかりやすいです。

![CloudWatch.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244071/583b7894-6240-2c4a-5ebc-7c624aabd011.png)

##UTC(GMT)とJST
先程の画像を見ればわかりますが、GMTという文字が実行時間の後ろに書かれています。

日本の時間と9時間差があるそうなので、その時差を考慮した時間で設定しないとダメなようです。

【参考リンク】:[【AWS】CloudWatch cron 式 または rate 式の書式について解説](https://go-journey.club/archives/13302#UTCJST)


##グループLINE内のみんなの感想
全員フルシカトでした。なんで？

---
2019/12/07　追記

実際にRT数、ファボ数が多いツイートってキャンペーン系ばっかりなんですね。。。
毎日ローソンのRTキャンペーンがグループラインに流れてくるので怒られました。

![BazzLine.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244071/557a8e5d-13ae-9776-c214-87e6f37c472d.png)


##参考リンク
[朝イチで知りたいことをLINEで教えてくれるプログラム(Python)](https://qiita.com/KMim/items/7e5727ab4fc3b962b8fe)
[【Python】BeautifulSoupの使い方・基本メソッド一覧｜スクレイピング](https://lets-hack.tech/programming/languages/python/beautifulsoup/#keni-toc37)
[AWS LambdaをPythonで使ってみた　ライブラリの読み込みや環境変数の注意点について解説
](https://tech.bita.jp/article/38)