Tasks API 範例

 哈哈,完全理解!您說得對,上次整合 Calendar API 時,您主要透過複製範例程式碼並修改參數就成功了,這確實很方便!

不過,這次從 Calendar API 切換到 Tasks API,雖然很多基本概念是相似的(例如:都需要啟用 API、都需要 OAuth 授權流程、都需要用 fetch 發送請求),但具體的 API 細節是完全不同的。這就像您學會了怎麼寄信 (Calendar API),現在要學怎麼發送包裹 (Tasks API),流程有相似之處,但包裹單的填寫方式、郵寄規則都不同了。

您不能直接把 Calendar API 的程式碼拿來,只改個端點就用於 Tasks API。 您需要針對 Tasks API 的要求來調整程式碼,主要是以下幾個部分:

  1. 不同的 API 端點 (Endpoint URL):

    • Calendar API 新增事件是:https://www.googleapis.com/calendar/v3/calendars/primary/events

    • Tasks API 新增任務通常是:https://www.googleapis.com/tasks/v1/lists/@default/tasks (表示添加到使用者的預設任務列表)

  2. 不同的請求體 (Request Body) 結構:

    • Calendar API 需要 summary, start, end 等。

    • Tasks API 需要 title (任務標題),可以包含 notes (備註), due (截止日期/時間,格式是 RFC 3339 timestamp,例如 '2025-05-06T08:45:00.000Z') 等。

  3. 不同的 OAuth 範圍 (Scope):

    • 需要在 manifest.json 中請求 "https://www.googleapis.com/auth/tasks"

為了幫助您上手,這裡提供一個類似於之前 Calendar API 的 addTaskToGoogle 函數範例,您可以基於這個來修改:

      /**
 * 將任務新增到 Google Tasks 的預設列表。
 * @param {object} taskData 包含任務資訊的物件,例如 { title: '洗牙', due: '2025-05-06T08:45:00.000Z' }
 * @param {string} token 從 getAuthToken 獲取的 Access Token (需要包含 tasks scope)。
 * @returns {Promise<object>} 解析為創建的任務物件。
 */
async function addTaskToGoogle(taskData, token) {
  // Tasks API 的端點,通常是添加到預設列表 (@default)
  const tasklistId = '@default';
  const apiUrl = `https://www.googleapis.com/tasks/v1/lists/${tasklistId}/tasks`;

  // 準備請求體 (Request Body)
  // 至少需要 title,可以添加 due, notes 等
  const requestBody = {
    title: taskData.title,
    // 如果需要截止時間 (格式很重要!)
    ...(taskData.due && { due: taskData.due }), // RFC 3339 UTC timestamp, e.g., '2024-12-31T10:00:00.000Z'
    ...(taskData.notes && { notes: taskData.notes }), // 備註
    // 還有 status, parent 等其他欄位可用
  };

  try {
    const response = await fetch(apiUrl, {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${token}`,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify(requestBody)
    });

    if (!response.ok) {
      const error = await response.json();
      console.error('Error adding task via API:', error);
      // 拋出更詳細的錯誤,或者根據 status code 處理
      throw new Error(`Failed to add task: ${error.error?.message || response.statusText}`);
    }

    const createdTask = await response.json();
    console.log('Task created successfully:', createdTask);
    return createdTask; // 返回創建的任務物件,其中包含 Google 生成的 id 等資訊

  } catch (error) {
    console.error('Error during fetch to add task:', error);
    throw error; // 將錯誤向上拋出,讓調用者處理
  }
}

// --- 如何調用 (在獲取 token 之後) ---
/*
async function handleAddTaskClick(taskTitle, dueDateString) { // dueDateString 需為 RFC 3339 格式
  try {
    // 1. 獲取包含 tasks scope 的 token
    // 注意:如果 scope 變更,需要重新觸發授權流程
    const token = await getAuthToken(true); // 確保 getAuthToken 請求了 'tasks' scope

    // 2. 準備 taskData
    const taskData = {
      title: taskTitle
    };
    if (dueDateString) {
      // 重要:確保 dueDateString 是正確的 RFC 3339 UTC 格式
      // 例如: '2025-05-06T08:45:00.000Z'
      // 如果只有日期,格式是 'YYYY-MM-DD',但 Tasks API 可能需要時間部分 for reminder
      taskData.due = dueDateString;
    }

    // 3. 調用 addTaskToGoogle
    const createdTask = await addTaskToGoogle(taskData, token);

    // 4. (可選) 保存返回的 task ID 等資訊
    const googleTaskId = createdTask.id;
    console.log("Google Task ID:", googleTaskId);
    // saveTaskMapping(myInternalId, googleTaskId);

    alert('任務已成功新增到 Google Tasks!');

  } catch (error) {
    console.error('handleAddTasksClick error:', error);
    alert(`新增任務失敗: ${error.message}`);
  }
}
*/

// --- 處理時間格式 ---
// 您需要確保傳入的 'due' 是 RFC 3339 UTC 格式
// 例如,從日期時間選擇器獲取時間後轉換:
function convertToRFC3339UTC(date) {
  if (!date instanceof Date) {
    date = new Date(date); // 嘗試轉換
  }
  if (isNaN(date.getTime())) {
    return null; // 無效日期
  }
  // toISOString() 返回的格式就是 RFC 3339,且總是 UTC (結尾是 Z)
  return date.toISOString();
}

// 示例: const dueDate = new Date('2025-05-06T16:45:00+08:00'); // 假設本地時間是 +08:00
// const rfc3339Date = convertToRFC3339UTC(dueDate); // 結果會是 '2025-05-06T08:45:00.000Z'
// handleAddTaskClick("洗牙", rfc3339Date);
    

您需要做的步驟總結:

  1. Google Cloud Console: 啟用 Google Tasks API

  2. manifest.json:

    • "permissions" 中加入 "identity" (如果還沒有)。

    • "oauth2" -> "scopes" 陣列中加入 "https://www.googleapis.com/auth/tasks"。您可以保留 Calendar 的 scope,也可以移除,取決於您是否還需要 Calendar API。

    • "host_permissions" 中確保 https://www.googleapis.com/ 已包含。

  3. 重新載入擴充功能: 讓 Manifest 更改生效。使用者可能需要重新授權。

  4. 修改 JavaScript:

    • 使用上面提供的 addTaskToGoogle 範例作為基礎。

    • 確保您傳遞給 addTaskToGoogletaskData 包含 title,以及正確格式的 due 時間(如果需要)。

    • 修改您調用 getAuthToken 的地方,確保請求了新的 tasks scope(如果 manifest.json 變更了)。

    • 相應地調整獲取 Token 成功後的處理邏輯(現在是調用 addTaskToGoogle)。

這次確實需要您多做一些理解和修改,而不僅僅是改參數。但基本流程和 Promise/async/await 的使用方式是和之前一樣的。祝您順利!

留言

這個網誌中的熱門文章

Offscreen Canvas

外部網頁新增 Google 日曆行程(URL模板)

計算 Canvas 文字最大字體