LoginSignup
13

More than 5 years have passed since last update.

[GAS]GoogleSpreadSheetとLineBotでTODO管理

Posted at

経緯

社会人サークルとかで、エンジニア以外の人がいるような環境だと「TODO管理はしたいけど、Slackとかよくわからない」ということは多いと思います。
そんなときにLineのグループからTODO登録できたら便利だなーという発想のもと、
覚えたてのGASでLineからSpreadSheetにTODOを飛ばすBotを作ったので紹介です。

コード

// LINE Developers > Basic Information > Channel Access Token から取得
var channel_access_token = "your line bot token"; 

function doPost(e) {
  var posted_json = JSON.parse(e.postData.contents);
  var events = posted_json.events;
  events.forEach(function(event) {
    // コマンド書式判定
    if (event.message.type != "text" || isCommand(event.message.text) == false) {
      return;
    }

    var message = doTask(event.message.text);

    var postData = {
      "replyToken" : event.replyToken,
      "messages" : [
        {
          "type" : "text",
          "text" : message
        }
      ]
    };

    var options = {
      "method" : "post",
      "headers" : {
        "Content-Type" : "application/json",
        "Authorization" : "Bearer " + channel_access_token
      },
      "payload" : JSON.stringify(postData)
    };

    var reply = UrlFetchApp.fetch("https://api.line.me/v2/bot/message/reply", options);
  });
};


// コマンド書式判定
function isCommand(text) {
  var isCommnadText = false;
  var reg =/^bot:[cuh]:/i;

  if (text.match(reg)) {
    isCommnadText = true;
  }

  return isCommnadText;
}

// TODOリストドキュメントの操作
function doTask(command) {
  var spreadsheet = SpreadsheetApp.openByUrl("your todo list url");
  var sheets = spreadsheet.getSheets();
  for ( var i in sheets ){
    if ( sheets[i].getSheetName() == "TODO" ) {
      return orderTask(command, sheets[i])
    }
    return;
  }
}

// 命令判定と実行
function orderTask(command, sheet) {
  var message = "";
  var order = command.split(":");
  switch(order[1]) {
    case "h":
      message = showHelp();
      break;
    case "c":
      if (order.length != 6) {
        message = "書式に誤りがあります。\n[bot:c:担当者:期限:TODO:状態]の形式で入力してください。";
      } else {
        message = addRow(order[2], order[3], order[4], order[5], sheet);
      }
      break;
    case "u":
       if (order.length != 4) {
        message = "書式に誤りがあります。\n[bot:u:ID:状態]の形式で入力してください。";
       } else {
         message = updateRow(order[2], order[3], sheet);
      }
      break;
    default:
      message = "書式に誤りがあります。\nbot:c:担当者:期限:TODO:状態\nbot:u:ID:状態\nの形式で入力してください。";
      break;
  }

  return message;
}

// 新規追加
function addRow(person, limit, todo, state, sheetObj) {
  var lastRow = sheetObj.getLastRow();
  var lastRowId = sheetObj.getRange(lastRow, 1).getValue();

  if (lastRowId == "id") {
    lastRowId = 0;
  }

  sheetObj.getRange(lastRow+1, 1).setValue(lastRowId + 1); // id
  sheetObj.getRange(lastRow+1, 2).setValue(person); // 担当者
  sheetObj.getRange(lastRow+1, 3).setValue(limit); // 期限
  sheetObj.getRange(lastRow+1, 4).setValue(todo); // TODO
  sheetObj.getRange(lastRow+1, 5).setValue(state); // 状態

  return "ID:" + (lastRowId+1) + "にタスクを追加しました。";
}

// ステータス更新
function updateRow(id, state, sheetObj) {
  var lastRow = sheetObj.getLastRow();
  var lastRowId = sheetObj.getRange(lastRow, 1).getValue();
  if (id > lastRowId) {
    return "タスクリストに存在しないIDです。\nID:" + lastRowId + "が最大です。";
  }

  idNum = Number(id);
  sheetObj.getRange(idNum+1, 5).setValue(state); // 状態

  return "ID:"  + id + "の状態を「" + state + "」に更新しました。";
}

// ヘルプ
function showHelp() {
  return "bot:c:担当者:期限:TODO:状態\nbot:u:ID:状態";
}

感想

  • これだとスマホ(特にフリック入力)から入力しづらいので、コマンドは再考の余地あり。

参考

先人の知恵に感謝:pray:

LINE Botをサーバーレスで開発!Google Apps ScriptとLINE Messaging APIを使ってチャットボットを作ってみた
初心者がGASでSlack Botをつくってみた

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13