GASを用いLINE Messaging APIのフォローイベントでuserIdをスプレッドシートに転記する

## はじめに
　LINE Messaging APIのPush APIを用いてメッセージを送信したい場合、userIdを用いて送信するため、友達追加時にuserIdを取得しスプレッドシートに保存しておかなければなりません。
　この記事では、友達追加時にuserIdをスプレッドシートへの転記し、もしIDが重複した場合自動で削除するまでの流れを解説していきます。

## 前提
LINE Messaging APIとGASの紐付けは既に済んでいるものとして進めていきます。

## 目次
・完成図
・コード全体のサンプル
・解説

## 完成図
個人情報保護のため画像の一部を加工しています
<img width="866" alt="スクリーンショット 2019-11-13 19.25.26.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/532677/5c6cc1f0-5147-c3f8-8f25-4302367cf883.png">

## コード全体
コード全体はこんな構図になってます

```javascript:コード.gs
// LINE Developersに書いてあるChannel Access Token
const access_token = "ここにトークンを入力";


function doPost(e){
//ポストで送られてきたJSONをパース
  const event = JSON.parse(e.postData.contents).events[0];
  const user_id = event.source.userId;
  const eventType = event.type;
  const nickname = getUserProfile(user_id);

// botが友達追加された場合に起きる処理
  if(eventType == "follow") {
    const data = SpreadsheetApp.openById("スプレッドシートのIDを入力").getSheetByName('シートの名前');
    const last_row = data.getLastRow();
    for(let i = last_row; i >= 1; i--) {
      if(data.getRange(i,1).getValue() != '') {
        const j = i + 1;
        data.getRange(j,1).setValue(nickname);
        data.getRange(j,2).setValue(user_id);
        data.getDataRange().removeDuplicates([2]);
        break;
      }
    }
  }
}

// profileを取得してくる関数（コピペでOK）
function getUserProfile(user_id){ 
  const url = 'https://api.line.me/v2/bot/profile/' + user_id;
  const userProfile = UrlFetchApp.fetch(url,{
    'headers': {
      'Authorization' :  'Bearer ' + access_token,
    },
  })
  return JSON.parse(userProfile).displayName;
}
```

## 解説

### 1.各情報の取得

```javascript
  const user_id = event.source.userId;
  const eventType = event.type;
  const nickname = getUserProfile(user_id);
```
　ユーザーIDとイベントタイプの取得は[公式リファレンス](https://developers.line.biz/ja/reference/messaging-api/#follow-event)を参照しました。その後、LINEの表示名を取得するために**getUserProfile関数**を呼び起こします。

### 2.友達追加された場合に起きる処理

```javascript

  if(eventType == "follow") {
    const data = SpreadsheetApp.openById("スプレッドシートのIDを入力").getSheetByName('シートの名前');
    const last_row = data.getLastRow();
    for(let i = last_row; i >= 1; i--) {
      if(data.getRange(i,1).getValue() != '') {
        const j = i + 1;
        data.getRange(j,1).setValue(nickname);
        data.getRange(j,2).setValue(user_id);
        data.getDataRange().removeDuplicates([2]);
        break;
      }
    }
  }
```
まずスプレッドシートを指定します。スプレッドシートのIDは↓の画像でいうと
`1WFnaEsqsOZ46hfx46_gOe-Rp4rf7BEIA_UxC6bDlQ3E`
の部分です。各自IDをコピペしてください。
<img width="700" alt="スクリーンショット 2019-11-15 1.15.29.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/532677/472e732a-3c1d-9d67-be73-0de69a101205.png">


シートの名前は↓の`birthday`とか`user_id`の部分です。
<img width="428" alt="スクリーンショット 2019-11-15 1.12.29.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/532677/abc83689-4fb9-2f58-00fe-ed49b821e715.png">



```javascript
const last_row = data.getLastRow();
```
次に、`getLastRow()`で、最終行を取得しています。

#### for文の処理

```javascript
    for(let i = last_row; i >= 1; i--) {
      if(data.getRange(i,1).getValue() != '') {
        const j = i + 1;
        data.getRange(j,1).setValue(nickname);
        data.getRange(j,2).setValue(user_id);
        data.getDataRange().removeDuplicates([2]);
        break;
      }
    }
```
先ほど取得した最終行の１行下に情報を転記します

```javascript
const j = i + 1;
data.getRange(j,1).setValue(nickname);
data.getRange(j,2).setValue(user_id);
```

`const j = i + 1;`で最終行の次の行を指定し、そこにsetValueで値を入力しています。

ここで一つ注意点があります。フォローイベントは友達追加時だけでなく、ブロック解除時にも発生するため、その度にIDが転記されてしまいます。そのため、重複した場合に削除するための処理を書かなくてはなりません。

```javascript
data.getDataRange().removeDuplicates([2]);
```
`.removeDuplicates([2])`という風に書いてあげるだけで簡単に重複を消去できます。
（[2]でB列の重複をチェック、[1]でA列の重複をチェックできる）

## 終わりに
　これで無事ユーザーネームとユーザーIDを取得し転記することができました。ここで転記した情報を用いれば様々なBotが作成できそうですね。ちなみに筆者はサークルのメンバーの誕生日がきたら全員に個チャで通知するBotを作成してみました。