Line Botを開発するならGoogle Apps Script(GAS)が最強だった


Google Apps Script(以下GAS)を使えば、Googleが提供する諸々のサービス、Gmail、カレンダー、スプレッドシート、ドライバーをJavaScriptのコードベースで操作することが可能になります。

このGASとLineBot開発の相性がとても良いです!

今回私は、スプレッドシートに登録しておいた英単語を、LineBotで定期的にリマインドしてくれる、個人ツールを開発しました。その開発過程を紹介しながら、GASとLineBotの相性の良さをご紹介できればと思います。

Google Apps Script(GAS)とは

スクリーンショット 2019-03-20 10.48.19

Googleによって開発された、スクリプト言語です。JavaScriptをベースにしていますが、クライアント側ではなく、サーバ側(Google Cloud)内で実行されます。

GASで提供されているライブラリ使うことで、Googleが提供する数多くのサービスをコードベースで操作することが可能になるため、業務の自動化・効率化が期待できます。

GASでLINE BOTを開発するメリット

私が感じたメリットは以下の三点です。

**つまり、アイデアを簡単に形にできます **

前回は、こちらにもあるように、勉強を兼ねてGo+herokuでデータベースを使ってLineBotを大々的に開発しました。しかし、正直オーバスペックなのに加えて、工数も結構かかってしまいました。

簡単ツールに、サーバ代や工数をかけるのは勿体無いですよね!GASを使えば、アイデアをサクッとLINE Botに落とし込むことができます。

ここからは、実際に開発の過程をお見せしたいと思います。1、2時間もあれば完成するはずです。

実践編

1. 作成したLine Bot

来月にTOEFLを受験する予定があり、現在、語彙力増強のために英単語帳を進めています。 そこで、スプレッドシート上に登録した英単語を毎日定刻にライン上に配信してくれるLine botを作成します。

忘却曲線

効率よく暗記をするために、学術的な知見としてよく挙げられるものに、エンビグハウスの忘却曲線があります。誰もが一度は目にしたことがあるのではないでしょうか?(wikipediaより引用)

ebbinghaus

横軸が経過日数。縦軸が節約率を示しています。エンビグハウスの実験によると、記銘したのちに1日の間に急激な節約率の低下が起きますが、その後の低下はなだらかになるそうです。しかし、グラフを見ていただければわかるように、繰り返し学習をするうちに、低下具合がなだらかになる様子が見て取れます。

要は、繰り返し学習をするたびに定着度が上がっていくということですね。

反復のサイクルを自動化

筆者は怠惰な性格のため、この反復するというサイクルを怠ってしまいがちです。

そこで、Line Botに復習用のミニテストを配信してもらい、Line上でタスクを解くことで復習をするという制約を自分に課したいと思います。このタスクを、忘却曲線を参考にして、単語を記銘後の1、3、6、10、15日後にLine配信するように設定しておきます。

学習のおおまかな流れは次のようになります。

gas+linebot

本来なら自分で予定を立てるなどして、ⅰ)復習日を決め、ⅱ)当日に復習をしなくてはならないことを思い出し、ⅲ)実行をするという、3ステップが必要になります。このⅱ)とⅲ)の工程は、筆者的には、かなりエネルギーを使う部分です。この箇所をLineでBot化しておけば、普段は、上記の①②の工程に、100%のエネルギーを費やすことができるようになります。

2. Line Developersの登録

Line Developers > Messaging APIから新規チャンネルの作成を行います。

Push通知を使うので、プランはDeveloper Trialを選択します。後ほど、GASをコーディングする際にアクセストークンYour user IDの箇所は使用するので、メモしておきましょう!

3. スプレッドシートの構造

スプレッドシードには以下の構造で記述していきます。

ebbinghaus

日付を元に配信日を決定するので、dateは必須です。残りは、好みに応じて好きに変えても良いかもしれませんね。

4. GASのコーディング

それでは、スプレッドシートから現在の1,3,6,10,15日前に登録した単語群を抽出して配信するスクリプトを記述していきます。スプレッドシートのツール > スクリプト エディタからGAS用のエディタを開いて、以下のコードを記述します。

var CHANNEL_ACCESS_TOKEN = 'アクセストークン'; 
var USER_ID = 'ユーザID';

// idとスペル, 訳ををContentオブジェクトとして管理
var Content = function(id, spell, translation) {
  this.id = id;
  this.spell = spell;
  this.translation = translation;
};

// スプレッドシートとセルの数を取得
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var sheet = spreadsheet.getActiveSheet();
var n = sheet.getLastRow();


function main() {
  // 1,3,6,10,15日前に登録した単語を配信する, 好みに応じて変更
  // =================================
  var dates = [1,3,6,10,15]
  // =================================
  
  for (var i = 0; i < dates.length;  i++) {
    var date = previousDate(dates[i])
    var contents = fetchContents(date)
   
    var sp = spellText(contents)
    if (sp != ''){
      pushMessage(sp)
    }
    
    var tt = translationText(contents)
    if (tt != ''){
      pushMessage(tt)
    }
    
  }  
}

// lineにtextを配信する
function pushMessage(text) {
  //deleteTrigger();
  var postData = {
    "to": USER_ID,
    "messages": [{
      "type": "text",
      "text": text,
    }]
  };

  var url = "https://api.line.me/v2/bot/message/push";
  var headers = {
    "Content-Type": "application/json",
    'Authorization': 'Bearer ' + CHANNEL_ACCESS_TOKEN,
  };

  var options = {
    "method": "post",
    "headers": headers,
    "payload": JSON.stringify(postData)
  };
  var response = UrlFetchApp.fetch(url, options);
}

// n日前の日付を返す 20XX/XX/XX
function previousDate(num) {
  var dt = new Date();
  return  dt.getFullYear() + "/" +  (dt.getMonth() + 1) + "/"+ (dt.getDate() - num)
}

// スプレッドシートからdate日前のcontent群を取得
function fetchContents(date) {
  var contents = [];
  var range = sheet.getRange(2 ,1, n, 5).getValues();
  
  for (var i = 0;  i < n-1;  i++) {
    if (range[i][0].getFullYear() + "/" +  (range[i][0].getMonth() + 1) + "/"+ range[i][0].getDate() == date) {
      var content = new Content(range[i][1],range[i][2], range[i][3]);
      contents.push(content);
    }  
  }

  return contents
}

// 取得したcontentsから訳を抜き出してtext化
function translationText(contents) {
  var text = ''
   
  for (var i = 0;  i < contents.length;  i++) {
    text += contents[i].id + ": " + contents[i].spell + "\n";
  }
  
  return text
}

// 取得したcontentsからスペルを抜き出してtext化
function spellText(contents) {
  var text = ''
 
  for (var i = 0;  i < contents.length;  i++) {
    text += contents[i].id + ": " + contents[i].translation + "\n";
  }
  
  return text
}

スクリプトを記述し終えたら、公開 > ウェブアプリケーションとして導入を選択します。

現在のウェブアプリケーションのURLを取得してLine Developers > チャンネル基本設定 > Webhook URLにURLを追記しておきましょう!

5. スクリプトの定期実行

4でコーディングしたスクリプトを、毎日定刻に自動で実行するように設定します。herokuだとアドオンを追加したり、EC2だとcronの設定をしたり、いろいろと面倒ですがGASだと簡単に設定可能です。

まず、編集 > 現在のプロジェクトのトリガーを選択します。

続いて、右下にある+トリガーを追加 ボタンを押すと以下の画面が出てくるはずです。

実行する関数とイベントのソースを選択します。今回の場合は、毎日定期的にスクリプトを走らせたいので、時間主導型 を選択し、1日おきに実行するため、日付ベースのタイマーを選んでいます。この辺りは、お好みで調整してください。

登録が完了したら、あとは、決まった時間にスクリプトが走るのを待つだけです。エラー通知設定をONにしていると、スクリプトにエラーが起こった際にメールで知らせてくれるので便利です。

まとめ

Botを使って、効率よく単語を習得する方法について提案させていただきました。この方法がうまくいくかは、自分で使いながら試行錯誤していきたいと思います。

何よりもGASを使ったLine Bot開発の手軽さを実感していただければ嬉しいです。LineBotだけではなくSlackやスマートスピーカなどのインタフェースにも応用できそうですよね。いろんなアイデアが浮かんできませんか?

業務効率化やツール開発にぜひLine Bot × GAS使ってみてください!

参考文献

お世話になった記事です。

【保存版】初心者向け実務で使えるGoogle Apps Script完全マニュアル

Google Apps ScriptでLINE BOTつくったら30分で動かせた件

comments powered by Disqus