ykokw.xyz blog logo

Blog Posts

No results for 'undefined'Powered by Algolia

タスク一覧は自動生成して、いつもほぼ所感だけ書いて提出してます。

準備するもの

  • Google Apps Script環境

  • G Suite内のTodoリスト

    • ここで管理しているTodoから日報を作成している
    • プロジェクトごとにリストを作成したのでアカウントごとのデフォルトリストは省いている
    • 完了済みのものはチェックマークがつく
    • 完了したサブタスクは親情報を失うので、サブタスクには未対応
  • Docbase Access Token

スクリプト

/*
 * config
 *
 */

var endpoint = 'YOUR_DOCBASE_ENDPOINT'; // メモの投稿APIのエンドポイント(pathが/postsのやつ)
var docbaseAccessToken = 'YOUR_DOCBASE_ACCESS_TOKEN';
// デフォルトのタスクリストは省くのでそのID
var defaultListId = 'YOUR_DEFAULT_TASK_ID'

// 日報のタイトルに入れる名前
var name = 'YOUR_NAME';

// Docbase上のタグ
var tags = ['TAG'];

// 日報を公開するDocbaseグループのID
var groupId = YOUR_DOCBASE_GROUP_ID;

function fetchTaskList() {
  const optionalArgs = {
    maxResults: 100
  };
  const res = Tasks.Tasklists.list(optionalArgs);
  const taskLists = res.items;
  return taskLists && taskLists.length > 0 ? taskLists.filter(function(list){ return list.id !== defaultListId }) : [];
}

function fetchTasks(taskListId) {
  const res = Tasks.Tasks.list(taskListId, {showHidden: true});
  const tasks = res.items;
  return tasks && tasks.length > 0 ? tasks : [];
}

function formatTasks(prefix, tasks) {
  if (!tasks || tasks.length === 0) return '';
  const formatedArr = tasks.filter(function(t){
    return prefix === '-' ? !t.parent : t.parent !== null;
  })
  .map(function(task){
    const subtasks = tasks.filter(function (t) {
      return t && t.parent === task.id
    });
    const subtasksMdStatusStr = formatTasks('  -', subtasks);
    const mdStatusStr = task.status === 'completed' ? '[x]' : '[ ]';
    return Utilities.formatString("\n%s %s %s%s", prefix, mdStatusStr, task.title, subtasksMdStatusStr);
  });
  return formatedArr.join('');
}

function createReportBody(){
  const taskList = fetchTaskList();
  const taskSummaryStr = taskList.reduce(function(str, list) {
    const tasks = fetchTasks(list.id);
    const formatedTasks = formatTasks('-', tasks);
    return str + Utilities.formatString("### %s\n\n%s\n\n",list.title, formatedTasks);
  }, '## 所感\n\n\n## 詳細\n\n\n');
  return taskSummaryStr;
}

function testReportBody(){
  Logger.log(createReportBody());
}

function postToDocbase(){
  delTrigger();

  const data = {
    title: Utilities.formatString('【日報】 %s %s', Utilities.formatDate(new Date(), 'Asia/Tokyo', 'yyyyMMdd'), name),
    body: createReportBody(),
    draft: true,
    scope: 'group',
    tags: tags,
    groups: [groupId],
    notice: false
  };
  const options = {
    'method' : 'post',
    'contentType': 'application/json',
    'headers': { 'X-DocBaseToken' : docbaseAccessToken },
    // Convert the JavaScript object to a JSON string.
    'payload' : JSON.stringify(data)
  };
  UrlFetchApp.fetch(endpoint, options);
}


function setTrigger(){
  var setTime = new Date();
  if (!isBusinessDay(setTime)) return;
  setTime.setHours(18);
  setTime.setMinutes(05);
  Logger.log(Utilities.formatDate(setTime, 'Asia/Tokyo', 'yyyyMMdd HH:mm:ss'));
  ScriptApp.newTrigger('postToDocbase').timeBased().at(setTime).create();
}
 
function delTrigger() {
  var triggers = ScriptApp.getProjectTriggers();
  triggers.map(function(trigger){
    if (trigger.getHandlerFunction() == 'postToDocbase') {
      ScriptApp.deleteTrigger(trigger);
    }
  });
}
               
function isBusinessDay(date){
  if (date.getDay() == 0 || date.getDay() == 6) {
    return false;
  }
  var calJa = CalendarApp.getCalendarById('ja.japanese#holiday@group.v.calendar.google.com');
  if(calJa.getEventsForDay(date).length > 0){
    return false;
  }
  return true;
}

This content is built with Gatsby