【GAS×LINEMessagingAPI】LINEで今日、明日の予定と天気を送ってもらうチャットボットを作ってみた！

#はじめに
私は留学をきっかけにプログラミングを学び始めた理系大学生です。
inteeというキャリア支援サービスが提供しているリアルカレッジというプログラミング教室のゴールとして学んだことを使って、ポートフォリオを作成したので簡単に紹介します。
プログラミング初心者なので、コメントでアドバイスなどありましたら、とても嬉しいです！！
#作った理由
リアルカレッジの最終目標としてポートフォリオ作成をするということになったのですが、自分が作りたいものが思いつかず、知り合いに作って欲しいものを聞いたところ予定と天気が知れるようんものがあったら嬉しいと言われたのでそれを作りました。
#GASとは
今回実際に参考にしたものを紹介します。
[こちら](https://udemy.benesse.co.jp/development/intro-gas.html)です。
#LINEMessagingAPIとは
MessagingAPIを使用するにあたって参考になるものを紹介します。
[こちら](https://qiita.com/nkjm/items/38808bbc97d6927837cd)です。
#今回使ったAPI
+ [GoogleCalendarAPI](https://google-apps-script.net/instructions/?p=249)
+ [Livedoor天気API](http://weather.livedoor.com/weather_hacks/webservice)
+ [Yahoo!気象情報API](https://developer.yahoo.co.jp/webapi/map/openlocalplatform/v1/weather.html)

#手順
1. 予定を全てログに出力できるようにする。
2. 今日と明日の場合分け。
3. 天気に関しても同様に書いていく。
4. LINEで動くようにする。
5. リッチメニュー作成。

#コード
###メイン処理
```Javascript
// LINE developersのアクセストークン
var ACCESS_TOKEN = '';

function doPost(e) {
  // 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';
  
  var text = main(userMessage);

  UrlFetchApp.fetch(url, {
    'headers': {
      'Content-Type': 'application/json; charset=UTF-8',
      'Authorization': 'Bearer ' + ACCESS_TOKEN,
    },
    'method': 'post',
    'payload': JSON.stringify({
      'replyToken': replyToken,
      'messages': [{
        'type': 'text',
        'text': text,
      }],
    }),
    });
  return ContentService.createTextOutput(JSON.stringify({'content': 'post ok'})).setMimeType(ContentService.MimeType.JSON);
}
```

###カレンダーの内容所得
```Javascript
function main(userMessage) {
  var message = userMessage;
  
  //予定を返信する
  if(message === '今日の予定' || message === '明日の予定'){
    // Google カレンダーと連携
    var calendars = CalendarApp.getAllCalendars();
    
    // 今日の日付
    var date = new Date();
    if(message === '今日の予定'){
        var text = Utilities.formatDate(date, 'JST', 'yyyy/MM/dd') + "\n";
    }else{
        date.setDate(date.getDate() + 1);
        var text = Utilities.formatDate(date, 'JST', 'yyyy/MM/dd') + "\n";
    }
    
    for(i in calendars) {
      var calendar = calendars[i];
      
      // 今日の予定を取得 
      var events = calendar.getEventsForDay(date);
  
      // それぞれの予定に対して処理をします。
      for(j in events) {
        // 予定取得
        var event = events[j];
        
        // 予定のタイトル取得
        var title = event.getTitle();
        
        // toTime()は後述しています。
        //始まりの時間取得
        var start = toTime(event.getStartTime());
        
        // おわりの時間取得
        var end = toTime(event.getEndTime());
        
        // 合体
        text += start + ' - ' + end + " " + title + '\n';
      }
    }
    //予定がない場合の処理
    if(text === Utilities.formatDate(date, 'JST', 'yyyy/MM/dd') + "\n"){
      text += '予定はありません'; 
    }
    return text;
```
```Javascript
//時間のフォーマット
function toTime(str){
    return Utilities.formatDate(str, 'JST', 'HH:mm');
}
```

###天気情報取得
```Javascript
    //天気を返す
  }else if(message === '今日の天気' || message === '明日の天気'){
     //city=の部分は取得したい場所のid
    var response = UrlFetchApp.fetch("http://weather.livedoor.com/forecast/webservice/json/v1?city="); 
    var json = JSON.parse(response.getContentText());
    //yahooで取得したid
    var appId = "";
    //取得したい雨の情報の緯度経度
    var place = ",";
    //YOLPのURL
    var url_yahoo = "https://map.yahooapis.jp/weather/V1/place?coordinates=" + place + "&output=json&appid=" + appId;
    //場所の名前取得
    var text = json["location"]["prefecture"] + " " + json["location"]["city"] + "\n";
    //今日の天気取得
    if(message === '今日の天気'){
    //最高気温・最低気温
      var temp_max = json['forecasts'][0]['temperature']['max'];
      var temp_min = json['forecasts'][0]['temperature']['min'];
      text += json['forecasts'][0]['date'] + 'の天気は' + '\n';
      //天気を表示
      text += "天候： " + json["forecasts"][0]["telop"] + "\n";
      //最高気温・最低気温の処理
      if(temp_max === null){
        text += '最高気温のデータがありません' + '\n';
      }else{
        text += "最高気温： " + json["forecasts"][0]["temperature"]['max']['celsius'] + "度" + "\n";
      }
      if(temp_min === null){
        text += '最低気温のデータがありません' + '\n';
      }else{
        text += "最低気温： " + json["forecasts"][0]["temperature"]['min']['celsius'] + "度" + "\n";
      }
      var response_rain = UrlFetchApp.fetch(url_yahoo);
      var json_rain = JSON.parse(response_rain.getContentText());
      var scr = '';
      //YOLPで１時間後まで雨量取得
      for(var i=1; i<7; i++){
        if(json_rain['Feature'][0]['Property']['WeatherList']['Weather'][i]['Rainfall'] > 0.00){
          var time = json_rain['Feature'][0]['Property']['WeatherList']['Weather'][i]['Date'];
          var rainfall_time = time.split('');
          scr += rainfall_time[8] + rainfall_time[9] + '時' + rainfall_time[10] + rainfall_time[11] + '分に' + json_rain['Feature'][0]['Property']['WeatherList']['Weather'][i]['Rainfall'] + 'mm/h' + 'の雨が降ります。' + '\n';
        }
      }
      if(scr.length > 0){
        text += scr;
      }else{
        text += '１時間以内に雨は降りません。' + '\n';
      }
      text += json['pinpointLocations'][6]['link'];
      
      //明日の天気の処理
    }else{
      var temp_max = json['forecasts'][1]['temperature']['max'];
      var temp_min = json['forecasts'][1]['temperature']['min'];
      text += json['forecasts'][1]['date'] + 'の天気は' + '\n';
      text += "天候： " + json["forecasts"][1]["telop"] + "\n";
      if(temp_max === null){
        text += '最高気温のデータがありません' + '\n';
      }else{
        text += "最高気温： " + json["forecasts"][1]["temperature"]['max']['celsius'] + "度" + "\n";
      }
      if(temp_min === null){
        text += '最低気温のデータがありません' + '\n';
      }else{
        text += "最低気温： " + json["forecasts"][1]["temperature"]['min']['celsius'] + "度" + "\n";
      }
      text += json['pinpointLocations'][6]['link'];
    }
    return text;
    
    //取得したい言葉が送られなかった時の処理
  }else{
    var text = 'リッチメニューから選んでください。';
    return text;
  }
}
```
#完成したもの
<img width="400" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/676653/7a452587-eb22-b8d7-0585-d7f09c45f79e.png">
#まとめ
今回初めてLINEのチャットボットを作ってみて自分でもこんなものが作れるんだという自信になりました。
また、実際に自分で使ってみて便利なので、他にも便利になるようなものを作ってみようと思いました。具体的には、位置情報を取得して天気情報が送信されるようなものを考えています。
位置情報取得に関して良いAPIを知っている方がいましたら、コメントで教えていただきたいです。
#参考サイト
+ [GASを使ってGoogleカレンダーの予定をLineに送る](https://qiita.com/jacky_dev/items/214eba7446c716466427)
+ [LINEBotのMessageAPIでのリッチメニューの作り方](https://qiita.com/hirokisoccer/items/0d3695a120efb7512f1f)
+ [【GAS修行①】毎朝天気を教えてくれるLINE BOTをLINE Notifyで作成](https://qiita.com/t_o_d/items/a29b4ba6eacad77b3690)