見出し画像

【GAS】Google Apps Script 活用事例 Google Task APIを使ってみよう。

Evernote APIや、Twitter APIなどを自分に教えてくれた方が、ブログで触れていて、そういう事が出来るらしいということを知っていたのですが、まとまった時間が取れたので、自分でも手を動かしてやってみました。

APIの出力結果が、どうも変わったようです。以前は、getItem()で取得出来たようですが、今は、オブジェクトの指定で取得出来ます。

画像1

難しい事は、ほとんどなくサービスのプラスマークを押して追加するだけ。拍子抜けするくらい簡単です。

タスクの登録先名を取得する

画像2

const tasks = Tasks.Tasklists.list();
const items = tasks.items;

console.log(items);

これで、登録先のリスト名などがオブジェクトで取得できます。不要な情報が多かったので、reduceメソッドで削っています。

/*
{ selfLink: 'https:********',
etag: '"********************"',
updated: '2021-03-09T09:10:57.915Z',
title: 'デフォルト',
id: '*******************',
kind: 'tasks#taskList' }
*/
//取得したオブジェクトから必要なものだけ取り出す
 const reducer = (accumulator, current) => {
 const {title, id} = current;
   accumulator.push([title, id]);
   return accumulator;
 };
 
const results = items.reduce(reducer, []);
console.log(results);

この書き方は、最近覚えました。const {title, id} = この部分は分割代入と言います。

各タスクの取得は、どうやって出来るの?

//タスクの登録先IDと、各タスクのID
const task = Tasks.Tasks.get('***********', '************');
console.log(task);
/*
{ updated: '2021-03-09T04:20:38.000Z',
selfLink: 'https:/**********',
id: '***********',
etag: '"**************"',
position: '00000000000000000000',
status: 'needsAction',
kind: 'tasks#task',
title: 'ネットスーパー注文' }
*/

画像3

positionは、親タスク、小タスクみたいな感じで登録できるのですが、どうもそれに関係していそうです。WBS(Work Breakdown Structure)みたいにタスクを細分化して登録することを想定しているのではないでしょうか....多分

String indicating the position of the task among its sibling tasks under the same parent task or at the top level. If this string is greater than another task's corresponding position string according to lexicographical ordering, the task is positioned after the other task under the same parent task (or at the top level). This field is read-only. Use the "move" method to move the task to another position.

同じ親タスクの下または最上位レベルでの兄弟タスク間のタスクの位置を示す文字列。この文字列が辞書式順序に従って別のタスクの対応する位置文字列よりも大きい場合、タスクは同じ親タスクの下(または最上位)の他のタスクの後に配置されます。このフィールドは読み取り専用です。 「move」メソッドを使用して、タスクを別の位置に移動します。
{ selfLink: 'https://www.googleapis.com/*********',
id: '****************',
parent: '**************',
kind: 'tasks#task',
position: '00000000000000000002',
etag: '"****************"',
updated: '2021-03-09T10:41:34.000Z',
status: 'needsAction',
title: 'たらこ' },

親タスク、小タスクまでの登録は可能で、孫タスクの登録は出来ないようです。僕の場合は、そこまで必要ないんですけどね。最後に一つ言わせて欲しい....何だよ、Tasks.Tasksって(笑)分かりにっくい!!。

日付の扱いに注意が必要かもしれない。

const newTask = {
   title: '蛍光灯を買う', //  タイトル
   notes: 'ケーヨーデイツーで購入する', // メモ
     due: '2021-03-11T10:00:00.000Z' // 締切日。日付のフォーマットはRFC3339に準拠
 };

Tasks.Tasks.insert(newTask, 'タスク登録先ID');

日付の末尾などを省略すると、APIのリクエストに失敗します。

GoogleJsonResponseException: API call to tasks.tasks.insert failed with error: Request contains an invalid argument.

GoogleJsonResponseException:tasks.tasks.insertへのAPI呼び出しがエラーで失敗しました:リクエストに無効な引数が含まれています。
function test(){
 const stringDate = Utilities.formatDate(new Date(),"JST", "yyyy-MM-dd'T'HH:mm:ss'Z'");
 console.log(stringDate);//2021-03-09T20:21:44Z
}

日付の登録は出来ましたが、時間の登録は出来ませんでした。下記のブログでも出来なかったと書かれていました。

スマホアプリやWeb画面ではタスクに対して日付だけでなく時間も指定できますが、APIだと設定できないようです。時間を渡しても無視されました。

スクリーンショット 2021-03-12 12.36.06

シートに完了したタスクを書き出すスクリプト全文

/**
* タスク登録先名とタスクリストIDを2次元配列で取得する。
* 01.0_taskListに記載
* [['デフォルト', 'ID'], ['イラスト','ID']]
* 
*
* @return {number} 2次元配列
*
*/

function getAllTaskListIds_() {
 const tasks  = Tasks.Tasklists.list();
 const items  = tasks.items;

 //console.log(items);
 
 //取得したオブジェクトから必要なものだけ取り出す
 const reducer = (accumulator, current) => {
 const {title, id} = current;
   accumulator.push([title, id]);
   return accumulator;
 };

 const results = items.reduce(reducer, []);
 console.log(results);

 return results
 
}




/**
* タスク登録先名、IDからタスクリストID or タスクの登録先を返す
* 01.0_taskListに記載
*
* @param  {string} IDか、タスクの登録先を文字列で指定
* @param  {number} 列を数字で指定
* @return {number} タスクリストID or タスクの登録先
*
*/

function getTaskIdOrName_(value, column){
 const values  = getAllTaskListIds_();
 const results = values.filter(array => {
   if(array.indexOf(value) !== -1){
     return array;
   }
 });

 //[['タスク名','ID']]
 const taskInfo = results.flat()[column];
 console.log(taskInfo);

 return taskInfo
}





/**
* 各タスクの登録先から、タスクを取得してシートに書き込む
* トリガーの頻度:
* トリガーを登録したアカウント: 
*
*/

function getTasksToSheet() {
 const allTasks = getAllTaskListIds_();
 const idArray  = generateArray_(allTasks, 1);
 const sheet    = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('タスク一覧');

 console.log('タスク登録先ID\n', idArray);

 //それぞれのタスクを取得し続けて、シートの最終行に書き込む
 idArray.map(id => {
   const values  = loadTasks_(id);

   //valuesが空だったら、処理を終了
   if(values === undefined){return};

   //最終行を取得して、シートへ書き出す
   const lastRow = sheet.getLastRow() + 1;
   sheet.getRange(lastRow, 1, values.length, values[0].length).setValues(values);
 });//map
}




/**
* 各タスクの登録先IDから、タスクを取得する
* 
* @param  {string} タスクの登録先ID
* @return {object} 2次元配列
*/

function loadTasks_(id) {
 const now       = new Date();
 const yesterday = new Date();
 yesterday.setDate(yesterday.getDate() - 1);
 
 //終了したタスクのみを取得する。
 const options = {
   showCompleted: true,
   showDeleted: true,
   showHidden: true,
   completedMax: now.toISOString(),
   completedMin: yesterday.toISOString()
 };
 
 const tasks = Tasks.Tasks.list(id, options);
 const items = tasks.items;

 console.log(items);

 //タスクが何も登録されていない場合はスキップ
 if(items === undefined){return};
 console.log('items タスクの登録数', items.length);

 
 const formatDate   = (date, number, format) => {
  date.setDate(date.getDate() + number);
  return Utilities.formatDate(date, 'JST', format);
 }
 
 const today = formatDate(new Date(), 0, 'yyyy/MM/dd');
 
 const taskListName = getTaskIdOrName_(id, 0); //['タスク登録先名', 'ID']
 console.log(taskListName);
 

 //ID、タスク、登録先、締め切り、ステータス、優先度 
 const reducer = (accumulator, current) => {
   let { id, title, due, status } = current;
   
   //dueがもし、undefinedだったら、今日の日付を代入する。
   //締め切り日は文字列で取得されるので、10文字を切り出して、dateオブジェクト化している
   //2021-03-09 10文字

   if(due    === undefined){ due = today };
   if(due    !== undefined){ due = formatDate(new Date(due.slice(0, 10)), 0, 'yyyy/MM/dd')}
   if(status === 'needsAction'){status = '未着手'};

   accumulator.push([id, title, taskListName, due, status]);
   return accumulator;
 };//reducer

 //オブジェクトから必要なものに絞って2次元配列へ変換
 const results  = items.reduce(reducer, []); //[[],[]] 2次元配列
 console.log(results);
 
 return results
}

完了したタスクを書き出したい場合は、どうやら引数を指定すれば良いらしいです。新しいIDE素晴らしい。ちゃんとサジェスチョンでどう記述すればいいか教えてくれます。

スクリーンショット 2021-03-09 22.34.31

showCompleted: true,
showDeleted: true,
showHidden: true,


この記事が参加している募集

#最近の学び

181,025件

この記事が気に入ったらサポートをしてみませんか?