TOPニュースを見れるLINEbotを作ってみた

#はじめに
社会人になり、ニュース見るようにしないといけないな、と思いつつも元々習慣づいていない私はたくさんあるニュースサイトからどれかを選んで面白そうな記事を探すということが面倒だと思っていました。
そこで、日常的に開くLINEで簡単に何個か最新のニュースを取れるようにしたいと思い、ワンタッチでニュースが取得できるLINEbotを作ってみました。


#完成イメージ
取得したいニュースのカテゴリーを選ぶと、カテゴリー名が送信され、当てはまるニュースが3つ返ってきます。
キーボードから一覧にないものを入力されると、「当てはまるニュースはありません」と返します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1989146/b7902d56-b9e7-a606-fb05-4b0e5be1babb.png)


#実装


##使用したもの
・Google App Script
・LINE bot
・NEWS API(https://newsapi.org/)


##LINEbotの設定
①まずは[LINE developer](https://developers.line.biz/ja/)のコンソールにログイン。
②Providersを作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1989146/65c26e56-004a-e565-2a3e-f20bb22c5b9b.png)
③Channelsタブで、Create a new channelでMessaging APIを選択し、画像内の必須項目を埋めます。
他の項目はデフォルト/未入力のままCreateを押して進めます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1989146/0a8abd10-5261-6975-6e18-540abfd05131.png)


##Google App Script
GAS上では、LINEで入力されたメッセージを取得し、それをもとにNEWS APIを叩きます。

###NEWS APIを叩く関数news(textInput)内
国とカテゴリーから絞り込みます。
カテゴリーはbusiness,entertainment,general,science,sports,technologyの中から入力されたものを用います。

```js
function news(textInput){

  baseurl = "https://newsapi.org/v2/top-headlines";
  app="?apiKey=APIキー";
  country = "&country=jp"
  category = "&category=" + textInput;
  pageSize = "&pageSize=3"
  
  fullurl = baseurl + app + country+ category + pageSize ;
  response = UrlFetchApp.fetch(fullurl).getContentText()
  json_response = JSON.parse(response)
  return json_response

}
```

###関数doPost(e)内
①LINE上で送られたメッセージを取得したり、返信したりするためのお作法

```js
// 環境変数を取り出す
  var prop = PropertiesService.getScriptProperties().getProperties();
  // WebHookで受信した応答用Token
  var replyToken = JSON.parse(e.postData.contents).events[0].replyToken;
  // ユーザーのメッセージを取得
  var userMessage = JSON.parse(e.postData.contents).events[0].message.text;
 
  // 応答メッセージ用のAPI URL
  var url = 'https://api.line.me/v2/bot/message/reply';
```
②NEWS APIからの取得結果を応答メッセージとしてLINE上で表示
LINE developerの[ドキュメント](https://developers.line.biz/ja/reference/messaging-api/#text-message)で、応答メッセージのお作法がわかります。

NEWS APIから、リクエストに当てはまるニュースがあれば3記事分のタイトルと概要、発行日、URLを取得して表示させます。
当てはまる記事がなかった場合は「当てはまるニュースはありません」と表示させます。

```js
//newsAPI呼び出す関数を呼び出す
  var news_res = news(userMessage);
  var available = news_res["totalResults"];

  //このURLへpostリクエスト
  if(available !== 0){
  UrlFetchApp.fetch(url, {
    'headers': {
      'Content-Type': 'application/json; charset=UTF-8',
      'Authorization': 'Bearer ' + prop.ACCESS_TOKEN,
    },
    'method': 'post',
    'payload': JSON.stringify({
      'replyToken': replyToken,
      'messages': [{
      'type': 'text',
      'text': "【タイトル】\n" + news_res["articles"][0]["title"]
            + "\n\n【概要】\n" + news_res["articles"][0]["description"]
            + "\n\n【発行日】\n" + news_res["articles"][0]["publishedAt"]
            + "\n\n【URL】\n" + news_res["articles"][0]["url"]
    },{
       'type': 'text',
       'text': "【タイトル】\n" + news_res["articles"][1]["title"]
             + "\n\n【概要】\n" + news_res["articles"][1]["description"]
             + "\n\n【発行日】\n" + news_res["articles"][1]["publishedAt"]
             + "\n\n【URL】\n" + news_res["articles"][1]["url"]          
      },{
       'type': 'text',
       'text': "【タイトル】\n" + news_res["articles"][2]["title"]
             + "\n\n【概要】\n" + news_res["articles"][2]["description"]
             + "\n\n【発行日】\n" + news_res["articles"][2]["publishedAt"]
             + "\n\n【URL】\n" + news_res["articles"][2]["url"]   
      
      }
                      ]
    }),
  });
  }else if(available == 0){ 
   UrlFetchApp.fetch(url, {
    'headers': {
      'Content-Type': 'application/json; charset=UTF-8',
      'Authorization': 'Bearer ' + prop.ACCESS_TOKEN,
    },
    'method': 'post',
    'payload': JSON.stringify({
      'replyToken': replyToken,
       'messages': [{
       'type': 'text',
       'text': "当てはまるニュースはありません$",
         'emojis': [{
           'index': 15,
           'productId': "5ac1bfd5040ab15980c9b435",
           'emojiId': "014"
         }]
       }]
    })
   });
  }
```
###アクセストークンの設定
①LINE developerに戻り、先程作成したTOPニュース検索の管理画面でMessaging APIタブを開きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1989146/8aa01d0a-e277-4270-369d-9ec1bc1acda5.png)
この画面の一番下にあるChannnel access tokenをコピーします。

②GAS画面上の左上の「ファイル」から「プロジェクトのプロパティー」を選択し、スクリプトのプロパティタブを開きます。
プロパティに「ACCESS_TOKEN」
値にコピーしたアクセストークンを貼り付け保存します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1989146/30f66e74-f0b6-0db0-a90c-0a97ee7c7250.png)
保存したら、GASのファイルをアプリケーションとして公開し、URLをコピーしておきます。


##LINEbotにGASを連携させる
①TOPニュース検索の管理画面でMessaging APIを開き、Webhook settingsでWebhook URLにGASファイルを公開した時のURLを貼り付け、「Verify」を押します。
「Success」が表示されればOK！
Use WebhookはONにします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1989146/8409d663-8db9-b7ca-df0d-07a14bfe3eae.png)

②Webhookの下にあるauto-reply messagesを編集し、詳細設定で「応答メッセージ」をオフ、
Webhookをオンにします。
(今回は自動応答メッセージを利用しないため。)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1989146/c77f8373-e4e5-a1c2-4e51-c9d67cb7645f.png)



##リッチメニューを作る
想定外のメッセージが送られるのをなるべく防ぐために、カテゴリー別のボタンをクリックするだけで結果が取得できるようにします。
リッチメニューの設定は[ここから](https://manager.line.biz/)行います。


①リッチメニューをつけたいチャンネルを選択し、左側のトークルーム管理からリッチメニューを開きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1989146/118f7bc4-5d9d-2770-fedb-91046e74e0aa.png)
②右上の「作成」を押し、表示設定でタイトルと表示期間を入力します。
③「コンテンツ設定」でテンプレートを選択し、ボタンの数などを選びます。
④「アクション」でボタンを押すとどんなアクションを起こすかを選びます。
今回は「テキスト」を選択し、設定したテキストが自動で送られるようにします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1989146/780d8f47-1763-d758-e600-7437cc52eda7.png)
⑤「画像を作成」から、デザインを整えます。
こんな感じ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1989146/573836a0-bbaa-2bd3-7783-f62b7aa52b99.png)


#最後に
飲食店などでよく見かけるLINEアカウントがどのように作られているかがわかり、自分が欲しいと思った機能をLINEbotで作ることが出来たのが面白かったです。
LINEbotを使えばフロント側はLINEから機能がたくさん提供されているので、リッチメニューなど使いたいものを選ぶだけで実装できるため、アプリ初心者でも手を出しやすくとても便利でした。