モーニング娘。の最新ニュースを知りたかったのでLINE Botに通知させました

# 背景
モー娘。ファン歴は3ヶ月くらい。Rock'in Japan 2019に参加し、大勝利を目撃。
ついったーもいんすたもやってない情報弱者なので、モー娘。情報をお知らせしてくれるボット作ってみました。

# 環境
- Macbook Air
- macOS Mojave v.10.14.6
- Google Chrome
- GAS(GoogleAppsScript)

#### 必要なもの
- Googleアカウント
- LINE developersアカウント
- モーニング娘。への愛

#### 必要ないもの
- サーバー
- 経験

# 流れ
1. Googleアカウントの準備（もってるよね？）
2. Line Developersアカウントの準備
3. Google スプレッドシートにモーニング娘。のニュースをスクレイピング
4. LINE Botで通知するようにGASでコーディング
5. アプリケーションを公開してトリガーを設定

# Line Developersアカウントの準備
すでにいろん方がわかりやすく説明してくださっているので、割愛。
この辺が参考になると思います。
> [LINEのBot開発 超入門（前編） ゼロから応答ができるまで](https://qiita.com/nkjm/items/38808bbc97d6927837cd)

# Google スプレッドシートにモーニング娘。のニュースをスクレイピング
#### RSSフィードを取得
まずは取得したいニュースのURLを調べます。
今回は、Googl newsから取得します。
[Google news] https://news.google.com/?hl=ja&gl=JP&ceid=JP:ja
上記URLを叩くとGoogle newsのページにアクセスするので、検索窓で取得したいニュースを検索します。

例えば「モーニング娘。」で検索すると、
<img width="1440" alt="Google_news.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/360809/ffd3d7a5-e4a8-a437-0084-5db64a9b3065.png">

こんな感じでモー娘。のニュースがずらーっとでてきます。

ここでURL欄に注目！
`https://news.google.com/rss/search?q=モーニング娘。&hl=ja&gl=JP&ceid=JP:ja`
こんな風に書いてますね。
これがスクレイピングする際に使用するURLになるので、控えておきましょう。

#### Googleスプレッドシートにスクレイピング
サーバレスでLine Botを利用するためにGASを使うので、Google newsで調べた結果はGASと相性のいいGoogleスプレッドシートに記録していきます。


まずは新規でGoogleスプレッドシートを作成してください。
テンプレートが色々と選べると思いますが、無地の「空白」ってやつで大丈夫です。

新規作成したスプレッドシートを使ってスクレイピングしていきます。
まずはA1セルに上で調べたURLを記述します。
<img width="1379" alt="スプレッドシート1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/360809/71b3f6b2-1acf-51e4-0f52-f77260bf7714.png">

フィードのインポートにはスプレッドシートの関数`IMPORTFEED`を利用します。
書き方はこんな感じ。
`IMPORTFEED(フィードURL, クエリ, 見出し, アイテム数)`　
関数の引数にはそれぞれ、

- フィードURL：RSSフィードURLを入力する。A1セルに入力したURLを指定。
- クエリ：フィードに公開されている記事を取得したいので、itemを指定。
- 見出し：見出しの表示/非表示を設定。ここでは見出しを表示するためtrueを指定。
- アイテム数：取得する記事の数を指定。ここでは5件取得する。

A2セルに`IMPORTFEED`関数を記述します。
<img width="1379" alt="スプレッドシート2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/360809/9a7be223-5c49-925d-2e36-42c0aa3e5962.png">

このように`IMPORTFEED`関数を使用することで、スクレイピングできるはずなのですが、、、
このままだとうまくいきません

どうやらURL末尾にトレイリングスラッシュ（/）をつけるかパラメータをつける必要があるようです。

最終的な目標はモー娘。の **最新** ニュースをBotに通知させることなので、URL末尾に日付のパラメータをつけてみることにします。
方法はこんな感じ。
1. C1セルに`=TODAY()`を記入して現在日時を取得する。
2. B1セルに`=A1&"%d="&C1`と記入。URL末尾に日付がくっつく。
3. `IMPORTFEED`関数の第一引数、フィードURLにB1セルを指定する

こんな感じで最新のニュース5件がスクレイピングされるはずです。
<img width="1383" alt="スプレッドシート3.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/360809/0f27fb46-d8fd-d81d-db78-32a6d8ccd09e.png">

# LINE Botで通知するようにGASでコーディング
モー娘。の最新ニュースを取得できるようになったので、これをLINE Botに通知するよう実装しましょう。

先ほど作成したスプレッドシートに紐づいたGAS上にコーディングしていきます。
ますは、スプレッドシート上で「ツール」タブをクリック→「スクリプトエディタ」をクリック
<img width="1368" alt="スプレッドシート4.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/360809/5b76f08d-e897-d0ac-c8bc-89c31176345d.png">

スクリプトエディタが開かれるとfunction myFunction(){}があるので、削除します。
左上の「無題のプロジェクト」をクリックすると、プロジェクト名を編集できるので任意のプロジェクト名に修正しておきましょう。
処理は以下の流れで実装します。
1. ニュースフィードを取得
2. 前回の取得以降に配信されたニュースかチェック
3. 最新のニュースフィードのみ配列に追加
4. 配列をLINE Botにpush

処理はmain関数の中に記述しました。

```javascript:main.js
var CURRENT_TIME = new Date();

function main() {　
  // 紐づいているスプレッドシートの情報を取得
  var sheets = SpreadsheetApp.getActiveSpreadsheet().getSheets();

  // 1.ニュースフィードを取得
  var feedsObj = getFeeds(sheets[0]);

  // ニュースフィード毎に最新か確認し、配列に格納
  var newFeeds = [];
  for (var i in feedsObj["feeds"]) {
    // 2.前回の取得以降に配信されたニュースかチェック
    if (
      new Date(feedsObj["feeds"][i][2]).getTime() >
      new Date(feedsObj["lastCheckTime"]).getTime()
    ) {
      // 3.最新のニュースフィードのみ配列に追加
      newFeeds.push(feedsObj["feeds"][i]);
    }
  }

  // Botで通知するメッセージの作成
  for (var i in newFeeds) {
    var message = [
      {
        type: "text",
        text: newFeeds[i][0] + "\r\n" + newFeeds[i][1]
      }
    ];
    Logger.log("メッセージ：" + message[0].text); // デバッグ用

    // 4. 配列をLINE Botにpush
    pushTemplate(message);
  }
}
```


1.ニュースフィードを取得する
の中身はgetFeeds関数の中に記述しています。

```javascript:main.js
function getFeeds(sheet) {
  // １週間前の日時を取得
  var pastDate = new Date();
  pastDate.setDate(pastDate.getDate() - 7);

  // 最終更新日を取得。更新日のセルが未入力だった場合は１週間前の日時を入れる
  var lastCheckTime = sheet.getRange("C1").getValue() || pastDate;
  Logger.log("lastCheckTime：" + lastCheckTime); // デバッグ用

  // 更新日のセルに現在日時を設定（C1セルが更新されるとスクレイピングを始めるので3秒待つ）
  sheet.getRange("C1").setValue(CURRENT_TIME);
  Utilities.sleep(3000);

  // スクレイピングしたフィードを取得
  var lastRow = sheet.getLastRow();
  var feeds = sheet.getRange(3, 1, lastRow - 2, 3).getValues();

  return { feeds: feeds, lastCheckTime: lastCheckTime };
}
```

4.配列をLINE Botにpush
はpushTemplate()関数に記述してあります。
こちらの記事を参考にさせていただきました。
> [Google Apps ScriptでPushメッセージのLINE Botを作る。 \- Qiita](https://qiita.com/tetrapod117/items/0e3a9caf846ea11b688a)

```javascript:main.js
// スクリプトプロパティの操作のための変数
var PROP = PropertiesService.getScriptProperties();
// LINE developersのメッセージ送受信設定に記載のアクセストークン
var ACCESS_TOKEN = PROP.getProperty("ACCESS_TOKEN");
// 必要なURL情報の定義
var URL_PUSH = "https://api.line.me/v2/bot/message/push";
// ヘッダーを定義
var HEADERS = {
  "Content-Type": "application/json",
  Authorization: "Bearer " + ACCESS_TOKEN
};

function pushTemplate(message) {
  var props = PROP.getProperties();
  for (var prop in props) {
    if (prop !== "ACCESS_TOKEN") {
      var postData = {
        to: props[prop],
        messages: message
      };

      var options = {
        method: "post",
        headers: HEADERS,
        payload: JSON.stringify(postData)
      };
      var response = UrlFetchApp.fetch(URL_PUSH, options);
    }
  }
}
```
なお、ユーザーIDやアクセストークンは、GASのスクリプトプロパティに保存しました。
<img width="845" alt="スクリプトプロパティ.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/360809/bbc694e0-ea3a-c62b-57f5-da721e8fdef6.png">
スクリプトプロパティの書き方はこちらが参考になります。
> [GoogleAppsScript　スクリプトのプロパティの超簡単な使い方 \- Qiita](https://qiita.com/0Delta/items/7d8303eebbff4062069e)

以上でコーディングは完了です！
作成したアプリケーションをwebで公開することで、Line Botとして利用できるようになります。


# アプリケーションを公開してトリガーを設定
作成したコードをwebアプリケーションとして公開することで、webアプリケーションのURLを取得することができます。
このURLをLINE DevelopersのBotの設定画面のWebhookURLに設定することで、Line BotとGASアプリケーションを紐づけることができます。
詳細な手順は下記を参考にしてください。
> [Google Apps Scriptでオウム返しLINE Botを作る。](https://qiita.com/tetrapod117/items/e7b48485c98f6b88f311#webhook-url%E3%81%AE%E8%A8%AD%E5%AE%9A)

以上で、アプリケーションは完成ですので、一度テストしてみましょう。
1. GASコード上部の「関数を選択」と書いてある部分をクリック
2. プルダウンが現れるので、main関数を指定
3. プルダウンの左側の▶︎ボタンを押して、関数を実行。・
処理が正常終了すれば。LINE Botからスクレイピングしたモー娘。のビュースが届くはずです。
<img width="1431" alt="スプレッドシート5.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/360809/a4bbdec2-0050-bc54-ac2d-82e5d035edd1.png">

最後にアプリケーション実行のタイミングを指定しましょう。
GASコードのメニューバーの「編集」→「現在のプロジェクトのトリガー」」をクリックすると、プロジェクトのトリガーを管理する画面が開きます。
<img width="1440" alt="スプレッドシート6.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/360809/027622dc-03ab-3596-6293-14bd3590fd22.png">

トリガーとは作成したGASアプリケーションを実行するきっかけを意味するものです。
画面右下に「+トリガーを追加」というボタンがあるので、クリックしてください。
自分は以下のようにトリガーを設定しています。ご参考までにどうぞ。

-  実行する関数を選択：「main」
- 実行するデプロイを選択：「Head」
- イベントのソースを選択：「時間主導型」
- 時間ベースのトリガーのタイプを選択：「日付ベースのタイマー」
- 時刻を選択：「午前7時〜8時」  

上記のように設定していると、毎朝７時から８時の通勤時間に最新のモー娘。ニュースを通知してくれます。

作業は以上です。お疲れ様でした！

# 参考
本文でも触れていますが、下記のサイトを参考にさせていただきました。ありがとうございました！

- [LINEのBot開発 超入門（前編） ゼロから応答ができるまで](https://qiita.com/nkjm/items/38808bbc97d6927837cd)
- [Google Apps ScriptでPushメッセージのLINE Botを作る。 \- Qiita](https://qiita.com/tetrapod117/items/0e3a9caf846ea11b688a)
- [GoogleAppsScript　スクリプトのプロパティの超簡単な使い方 \- Qiita](https://qiita.com/0Delta/items/7d8303eebbff4062069e)
- [Google Apps Scriptでオウム返しLINE Botを作る。](https://qiita.com/tetrapod117/items/e7b48485c98f6b88f311#webhook-url%E3%81%AE%E8%A8%AD%E5%AE%9A)