サーティワンの日をお知らせするLINEBotを作った(2/2)

#前回の記事
[【JC・JK・JD必見】サーティワンの日をお知らせするLINEBotを作った](https://qiita.com/Sinhalite/items/56bdec0a7e06fd25afa1)
前回、サーティワンの日を欠かさずに通知する女子高生必携のLINEbotをつくったのですが、一般公開ができていませんでした。そこで今回は友達登録してくれた人のユーザIDを格納し、自分以外にもメッセージを送信できるように改修しました。

#アカウント
![IMG_3517.jpg](https://qiita-image-store.s3.amazonaws.com/0/104983/afb82619-5db6-d8c2-5c2b-515c55393a11.jpeg)

![IMG_3519.jpg](https://qiita-image-store.s3.amazonaws.com/0/104983/53185a70-8c59-0619-aefc-c13f75a6e64a.jpeg)

##登録用
![5UzWkRuZLr.png](https://qiita-image-store.s3.amazonaws.com/0/104983/8432f037-7ce5-e364-283a-17b1fdd61d02.png)
[スマホの方はこちらから](https://line.me/R/ti/p/5UzWkRuZLr)

For Developerアカウントなので、マックス50人までしか登録できません！！
早いもの勝ちです！！（誰も登録しない）

#概要
・友達登録時
LINEアプリ→LINE Messaging API→Google Apps Script→Googleスプレッドシート

・プッシュ送信時
Google Apps Script→LINE Messaging API→LINEアプリ

友達登録（ブロック）用とプッシュ送信用に、2つプログラムを作成します。
LINE管理画面のWebhook URLに友達登録用のプログラムを登録し、プッシュ送信用のプログラムは別立てで定期実行させます。

プッシュでメッセージを送るためには、送り先のユーザIDをどこかに記録しておく必要があります。
そうなると、記録するタイミングは友達登録の時しかありません。
友達登録のタイミングで、登録したユーザのユーザIDが送られてきますので、それをGoogleスプレッドシートに登録します。
スプレッドシートをDB代わりにするイメージです。プッシュ送信の際は、スプレッドシート内のユーザIDを宛先として読み込みます。

また友達登録を解除（ブロック）された際も、ユーザIDが送られてきますので、該当のユーザIDをスプレッドシートから削除します。

#コード
```javascript:webhook設定用
var CHANNEL_ACCESS_TOKEN = 'dummy';
var sheet = SpreadsheetApp.openById('dummy').getSheets()[0];

//ユーザIDを検索し、存在しなければユーザIDを追加する
function addUserId(user_id){
  var last_row = sheet.getLastRow();
  var target_cell = "A" + String(last_row + 1);
  var user_id_list = sheet.getRange(1,1,last_row+1).getValues();

  var registered_user_id_flag = 0
  for(var i=0;i<user_id_list.length;i++){
    if(user_id_list[i][0] === user_id){
      registered_user_id_flag = 1;
    }
  }
  
  if(registered_user_id_flag === 0){
    sheet.getRange(target_cell).setValue(user_id);
  }
}

//ユーザIDを検索し、存在していればユーザIDを削除する
function removeUserId(user_id){
  var last_row = sheet.getLastRow();
  var user_id_list = sheet.getRange(1,1,last_row+1).getValues();
  
  for(var i=0;i<user_id_list.length;i++){
    if(user_id_list[i][0] === user_id){
      sheet.deleteRows(i+1);
    }
  }
}

function doPost(e) {
  var user_id = JSON.parse(e.postData.contents).events[0].source.userId;
  var webhook_type = JSON.parse(e.postData.contents).events[0].type;

  if(webhook_type === "follow") {
    addUserId(user_id);
  }else if(webhook_type === "unfollow"){
    removeUserId(user_id);
  };
  
  return ContentService.createTextOutput(JSON.stringify({'content': 'post ok'})).setMimeType(ContentService.MimeType.JSON);
}

```

```javascript:プッシュ送信用
//メイン処理
//毎日AM7:00〜8:00に起動
function main() {
  var CHANNEL_ACCESS_TOKEN = 'dummy';
  var LINE_URL = 'https://api.line.me/v2/bot/message/multicast';
  var user_id_list = getUserID();
  
  var date = new Date();
  var month = Utilities.formatDate( date, 'Asia/Tokyo', 'MM');
  var day = Utilities.formatDate( date, 'Asia/Tokyo', 'dd');

//  Logger.log(month);
//  Logger.log(day);
  
  if(day === '31' || (day === '01' && month === '03')){
   var message = 'きょうは待ちに待ったサーティワンの日\uDBC0\uDC7F\nダブルコーン・ダブルカップが31%OFF!\n今すぐ近くの店舗へGO\uDBC0\uDC4B';
   push_message(LINE_URL,CHANNEL_ACCESS_TOKEN,user_id_list,message);
  }
}

//ユーザIDをスプレッドシートから取得する
function getUserID(){
  var ss = SpreadsheetApp.openById('dummy');
  var sheet = ss.getSheets()[0];
  var last_row = sheet.getLastRow();
  var user_id_list = sheet.getRange(1,1,last_row+1).getValues();
  
  for(var i=0;i<user_id_list.length;i++){
    user_id_list[i] = user_id_list[i][0];
  }

  return user_id_list;
}

//LINEへプッシュ送信
function push_message(LINE_URL,CHANNEL_ACCESS_TOKEN,user_id_list,message){
    UrlFetchApp.fetch(LINE_URL,{
      'method': 'post',
      'headers': {
          'Content-Type': 'application/json; charset=UTF-8',
          'Authorization': 'Bearer ' + CHANNEL_ACCESS_TOKEN
      },
      'payload': JSON.stringify({
        'to': user_id_list,
        'messages' : [
          {
            'type':'text',
            'text':message
          }
        ]
      })
    });
}
```
送信先を複数にするのは簡単で、POSTの送信先をmulticastに変更し、userIdを文字列から配列に変更するだけでOKです。

#おわりに
少しでも記事が参考になった、面白かったなどありましたら「いいねボタン」をクリックいただけると幸いです:bow_tone2: