GoogleAppsScript
gas
Slack

英語学習システムをSlackとGASで作る

はじめに

仕事で海外とのやり取りが必須であり,必死で英語を勉強中.
Inputを増やしているが,日々のインプットを復習する機会がほしいと感じていた.
そこで,SlackとGoogleAppsScript(GAS)を利用して,英語学習システムを構築してみた.

具体的には,個人用Slacワークスペースに英語学習用チャネルを作成して,
OutgoingWebhookを利用して以下機能を実装した.

  • SlackからGoogle翻訳(和訳、英訳)
  • Slackから学習した英文を記録
  • Slackへ学習内容の復習を通知

実装機能

SlackからGoogle翻訳(和訳、英訳)

Google翻訳でぱぱっと意味を確かめたい/英訳したいな,と思う機会が多かったので,SlackからGoogle翻訳が使えるようにしてみた.

「en 英語文」と入力すると和訳させる,「ja 日本語文」と入力すると英訳されるようにした.

Slackから学習した英文を記録

「learn 英語文:意訳やメモ」と入力すると,スプレッドシートに
タイムスタンプ,英語文,意訳やメモ,英語文のGoogle翻訳による和訳結果
を記録する.

Slackへ学習内容の復習を通知

上記で記録しているデータを,復習としてSlackへ通知する.
やり方は,タイムスタンプで判別して抽出する.
ここでは3つの復習パターンでSlack通知するようにした.

No. 投稿内容 投稿間隔
1 昨日の記録内容 毎日
2 昨日〜1週間前の記録内容 毎週土曜日
3 1週間前〜2週間前の記録内容 毎週日曜日

GAS

doPost(e)

下記のSlack投稿に対応して動作する.

トリガーワード 入力 動作
ja 日本語 英訳
en 英語 和訳
learn 学習内容:メモ スプレッドシートに保存
function doPost(e) {

  // token確認
  var verify_token = LogGasApp.token_learning;
  if (verify_token != e.parameter.token || e.parameter.user_name=="slackbot") {
    throw new Error("invalid token.");
  }

  // check trigger_word
  var trword = e.parameter.trigger_word;
  var text = e.parameter.text;
  if(trword == "learn"){
    // learning
    text = text.substr(6); // remove trigger_word from text
    postLearning(text);
    var message = "What you learned was posted";
  }else if(trword == "ja"){
    //ja
    text = text.substr(3); // remove trigger_word from text
    var translated = LanguageApp.translate(text,"ja","en");
    var message = "en: "+translated;
  }else if(trword == "en"){
    //en
    text = text.substr(3); // remove trigger_word from text
    var translated = LanguageApp.translate(text,"en","ja");
    var message = "ja: "+translated;
  }

  // message
  var payload = {
    "text": message
  }
  var option = {
    "method": "POST", //POST送信
    "contentType": "application/json",
    "payload": JSON.stringify(payload) //POSTデータ
  }
  UrlFetchApp.fetch(LogGasApp.url_learning, option);
}

postLearning(test)

Slackにて[learn 学習内容:メモ]と投稿すると,スプレッドシートに保存する.

//=======================================================
// 学習内容を投稿
//=======================================================
function postLearning(test) {
  var sheet = SpreadsheetApp.openById(LogGasApp.ss_english).getSheetByName("fromSlack");
  var num = sheet.getLastRow();
  var text=test.split(":");
  var translated = LanguageApp.translate(text[0], "en", "ja");

  sheet.getRange(num+1,1).setValue(new Date());
  sheet.getRange(num+1,2).setValue(text[0]);
  sheet.getRange(num+1,3).setValue(text[1]);
  sheet.getRange(num+1,4).setValue(translated);
}

動作イメージ(en, ja)
スクリーンショット 2017-11-15 23.32.39.png

動作イメージ(learn)
スクリーンショット 2017-11-15 23.30.31.png

review

reviewYesterday(), review7days(), reviewLastWeek() の3種類をそれぞれタイムトリガーをセットして実行させる.

//============ review: 英語の復習(昨日) ============
function reviewYesterday() {
  return postReview(1,0,"");
}
//============ review: 英語の復習(1週間) ============
function review7days() {
  return postReview(7,0,"");
}
//============ review: 英語の復習(2週間前〜1週間前) ============
function reviewLastWeek() {
  var message="You learned these in the last week. Let's review! \n\n";
  return postReview(14,8,message);
}


//=======================================================
// postReview: 復習を投稿する
//=======================================================
function postReview(start,end,message) {
  var sheet = ss_english.getSheetByName("フォームの回答 1");
  var num = sheet.getLastRow();
  var data = sheet.getRange(2, 1, num-1,2).getValues();
  var sheet2 = ss_english.getSheetByName("fromSlack");
  var num2 = sheet2.getLastRow();
  var data2 = sheet2.getRange(2, 1, num2-1,4).getValues();
  var dash = "----------------------------------"

  if (message=="") {
    var message= "You learned these in the last "
               + (start-end) + " days. Let's review! \n\n";
  }

  message = dateCheck(message,data,num,start,end);
  message = dateCheck(message,data2,num2,start,end);

  return postMessage("translation",message);

  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  function dateCheck(message,data,num,start,end){
    var today = new Date();
    var start = new Date(today.getFullYear(), today.getMonth(),today.getDate()-start);
    //Logger.log("start:"+start);
    start=start.getTime();
    var end = new Date(today.getFullYear(), today.getMonth(),today.getDate()-end);
    //Logger.log("end:"+end);
    end=end.getTime();
    for (var i=0; i<num-1; i++) {
      var date = data[i][0];
      var time = date.getTime();

      if (time > start && end > time) {      
        message = message + "\n" + dash + dash ;
        var text = data[i][1];
        var memo = data[i][2];
        var translated = LanguageApp.translate(text, "en","ja");
        var message = message + "\n\n" 
                    + formatedDate(date) + ": "
                    + "<"+text + "> : " + translated
                    + " "
                    + "{" + memo + "}";
      }
      var date_check = date.getDate();
    }

    Logger.log(message);
    return message;
  }
  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
}

動作イメージ
スクリーンショット 2017-11-15 23.30.54.png

最後に

タイムトリガーをリマインダや復習目的に使うのは便利かもしれない
復習内容についても単純に時期で判断するだけではなく,クイズ形式にしたり,正解・不正解を記録しても面白いかも