GAS+linebotでgoogle spreadsheet勤怠管理

いろんな方がやっているかと思いますが、一応メモとして残しておきます。
大学のアルバイトでの勤怠管理用です。

## やりたいこと

- `出勤`、`退勤`を含むワードをlineに投下すると、その人のユーザー名、出勤時間帯とメッセージがgoogle spreadsheetに記録される。
- lineで`出勤よろしくお願いします！`、`お疲れ様でした！`などのリプライを返す。

（バイトでは不要だったのでスプレッドシートに退勤の記録を残さない方針で実装しました。多分追加するのは簡単だと思います。）

## 前提

- line accountを持っている
- google accountを持っている
- line developers登録済み

## まずやること

- google spreadsheetを作成
- シートの名前を `sheet1`にする。
- sheet idをメモっておく

以下のようなシートができていたら大丈夫です。

![Screen Shot 2021-04-24 at 19.17.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396623/3e7228ea-a4a5-1602-f37f-5ed8c823c16d.png)

## line の アクセストークン取得

developers consoleから取得します。自分のbotのチャンネルの `Messaging API`にあります。

![Screen Shot 2021-04-24 at 19.45.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396623/b147de6f-7c13-41dd-abed-10fd93eb25ce.png)


## GASのコード

スプレッドシートのメニューからGASのコードエディタを開けます。

![Screen Shot 2021-04-24 at 19.30.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396623/aa1e8e74-b463-091c-1259-601a97d102b1.png)


GASのスクリプトは以下のようになります。
`ACCESSTOKEN`, `id`はさきほどそれぞれ取得したものを使いましょう。

ちなみに、urlをgetするときに返される変数は`reponse`という変数名に格納しないとエラーになります。

```code.gs
var ACCESSTOKEN = "xxxxxx"
 
//spreadSheetの設定
var id = 'xxxxxx';//https://docs.google.com/spreadsheets/d/"この部分がidです"/edit#gid=1856578608
var spreadsheet = SpreadsheetApp.openById(id);
 
var URL = "https://api.line.me/v2/bot/message/reply"; // 応答メッセージ用のAPI URL
 

// ボットにメッセージ送信/フォロー/アンフォローした時の処理
function doPost(e) {
  var json = JSON.parse(e.postData.contents);  
  var reply_token= json.events[0].replyToken;  
  var user_id = json.events[0].source.userId;
  var user_message = json.events[0].message.text; //ここにメッセージが格納される

  // ユーザー名を取得する場合は、user_idから取得する必要がある。あと、ここはresponseという変数名に格納しないとエラーになる？
  var response = UrlFetchApp.fetch(
    'https://api.line.me/v2/bot/profile/' + user_id,
    {
      "headers": {
        "Authorization": "Bearer " + ACCESSTOKEN,
      }
    }
  );
  profile = JSON.parse(response);
  var username = profile.displayName

  var today = new Date();
  var month = today.getMonth() + 1;
  var date = today.getDate();
  var hour = today.getHours();
  var minute = today.getMinutes();
  var time = month + '月' + date + '日' +hour + ':' + minute;

  // 時間帯によってどの時限のシフトか分ける
  switch (true) {
    case hour <= 13:
      var period = "lunch";
      break
    case hour <= 14:
      var period = "3rd period";
      break
    case hour <= 16:
      var period = "4th period";
      break
    default:
      var period = "finished";
      break
  }

  if(user_message.includes('出勤')){//出勤という言葉を含む場合
    var sheet;
    sheet = spreadsheet.getSheetByName("sheet1");//sheet1に記入する
    sheet.appendRow([user_message, username, period]);//シートにメッセージを記入
    //返信
    if (period == "finished") {
      textMessage = "tutoring sessions are over for today!";
    } else {
      textMessage = username + 'さん、' + period + 'のシフトよろしくお願いします！';
    }
    pushMessage(textMessage, reply_token);
  }
  else if(user_message.includes('退勤')){//退勤という言葉を含む場合
    textMessage = username + 'さん、' + 'お疲れ様でした！';
    pushMessage(textMessage, reply_token);
  }
}

/*メッセージを送信*/
function pushMessage(textMessage, replyToken) {
  UrlFetchApp.fetch(URL, {
    "headers": {
      "Content-Type": "application/json; charset=UTF-8",
      "Authorization": "Bearer " + ACCESSTOKEN,
    },
    "method": "post",
    "payload": JSON.stringify({
      "replyToken": replyToken,
      "messages": [{
        "type": "text",
        "text": textMessage,
      }],
    }),
  });
}
```

## デプロイ

ウェブアプリとしてデプロイします。アクセスできるユーザーは `全員`としておきます。

![Screen Shot 2021-04-24 at 19.19.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396623/07a55a79-e7b6-f3c6-8f6a-c79c5d1abcf3.png)

これでデプロイされるので、URLをコピーして

![Screen Shot 2021-04-24 at 19.20.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396623/b6270ea4-ded7-ff4b-b2e5-b19dd15ac4eb.png)

webhookに貼り付けます。

![Screen Shot 2021-04-24 at 19.21.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396623/90e5bfb6-85b3-0086-8748-293256f097cf.png)


verify を押してsuccessだったら成功です。

![Screen Shot 2021-04-24 at 19.21.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396623/155f6050-06ae-3881-f7b2-9f15a67e2527.png)


## lineでの挙動

時間外に出勤しようとしたので、もう終わっていると言われてしまいました、、、

![IMG_4002.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396623/9860c4c1-7bf0-132a-0daa-5c13bb214ce4.jpeg)

退勤のときはうまくいきます。

![IMG_4003.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396623/395d2b49-52ff-0f0c-8704-78cffd8be720.jpeg)

ただ、出勤と退勤で連動できていないのが、ちょっとひっかかる。けどまあいいか。

## spreadsheet側の挙動

ここは直すのを忘れていました、finishedのまま記録されていますね。まあ挙動を確認できたので次回以降直すとします。

![Screen Shot 2021-04-24 at 19.28.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396623/4f241c7e-874f-b795-95d8-7aaacc8a6f46.png)

## まとめ

GASでLinebotを作って、spreadsheet側でも反映させることができました。
不具合やらミスやらでだいたい3時間ぐらいかかったと思います。

GASに触れることができたのは楽しかったですね！ただデバッグとかの簡単な方法を教えて欲しい、、、

## 参考

[GASを使ってLINEBOTを作ろう(1)．](http://ryoizu.com/blog/2019/01/16/gas%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%A6linebot%E3%82%92%E4%BD%9C%E3%82%8D%E3%81%86%EF%BC%8E/)

[Google Apps Script で LINE Bot を作成する](https://www.ois-yokohama.co.jp/oisblog2018/archives/6935)

[Messaging APIリファレンス #分析](https://developers.line.biz/ja/reference/messaging-api/#get-insight)

[Messaging APIリファレンス #応答メッセージ](https://developers.line.biz/ja/reference/messaging-api/#send-reply-message)

[Class UrlFetchApp](https://developers.google.com/apps-script/reference/url-fetch/url-fetch-app)