Todoist APIを使ったGoogle Apps Scriptでのタスク取得方法

この記事では、Google Apps Scriptを使用してTodoist APIからタスクを取得する方法を紹介します。REST APIとSync APIの両方を使用し、全タスクを効率的に取得できるスクリプトを作成します。

## 1. Todoist APIトークンの準備

まず、Todoist APIにアクセスするためのトークンが必要です。トークンはTodoistの開発者ページから取得できます。

1. [Todoist ヘルプ](https://todoist.com/ja/help/articles/find-your-api-token-Jpzx9IIlB) にアクセスして、取得方法を確認。
2. `API Token` を取得し、Google Apps Scriptのスクリプトプロパティに設定します。

### スクリプトプロパティへの設定方法

Google Apps Scriptのエディタで以下のように設定します。

1. スクリプトエディタを開く。
2. 「プロジェクトの設定」 > 「スクリプトプロパティ」 > 「スクリプト プロパティを追加」。
3. 「プロパティ」に `TODOIST_API_TOKEN` を設定し、「値」に取得した`APIトークン`を入力。

## 2. スクリプトの全体像

ここで紹介するスクリプトは、以下の2つのAPIからタスクを取得します。
- **REST API**: タスク情報をシンプルに取得したい場合に便利。
- **Sync API**: タスクやプロジェクトなど、より多くの情報を同期する際に使用。

### トークンの確認関数

まず、APIトークンが正しく設定されているか確認する内部関数を用意します。

```javascript
// Todoist API トークンの取得
const TOKEN = PropertiesService.getScriptProperties().getProperty('TODOIST_API_TOKEN');

// APIトークンの存在を確認する関数（内部関数）
function _checkToken() {
  if (!TOKEN) {
    throw new Error('API Token is not set. Please set TODOIST_API_TOKEN in Script Properties.');
  }
}
```

この関数では、スクリプトプロパティにAPIトークンが保存されているかどうかをチェックします。保存されていない場合、エラーを発生させます。

### 共通のオプション設定関数

次に、HTTPリクエスト時の共通設定をまとめた関数を作成します。これにより、リクエスト時のオプション設定を簡素化します。

```javascript
// 共通のオプション設定関数（内部関数）
function _getCommonOptions(method) {
  return {
    'method': method,
    'headers': {
      'Authorization': 'Bearer ' + TOKEN,
    }
  };
}
```

この関数は、HTTPメソッド（GETやPOSTなど）を引数として受け取り、認証ヘッダーとともにリクエストオプションを返します。

## 3. REST APIから全タスクを取得

以下のコードで、REST APIを使って全タスクを取得できます。

```javascript
// REST APIから全タスクを取得する関数（公開して使用）
function getAllTasksFromREST() {
  _checkToken(); // トークンの確認

  const url = 'https://api.todoist.com/rest/v2/tasks';
  const options = _getCommonOptions('get'); // 共通オプションを使用
  
  try {
    const response = UrlFetchApp.fetch(url, options);
    
    if (response.getResponseCode() !== 200) {
      throw new Error(`Failed to fetch tasks from REST API: ${response.getResponseCode()}`);
    }

    const tasks = JSON.parse(response.getContentText());
    return tasks; // 取得したタスクの配列を返す
  } catch (error) {
    Logger.log('Error fetching tasks from REST API: ' + error.message);
    Logger.log(error.stack); // スタックトレースをログに出力
    return [];
  }
}
```

### 処理の流れ
1. `UrlFetchApp.fetch` 関数を使用して、TodoistのREST APIにGETリクエストを送信。
2. レスポンスのステータスコードが200（成功）でなければエラーを投げる。
3. レスポンスをJSON形式でパースしてタスクの配列を返す。

### 例：取得したタスクのログ出力

```javascript
function logTasks() {
  const tasks = getAllTasksFromREST();
  Logger.log(tasks);
}
```

## 4. Sync APIから全タスクを取得

Sync APIでは、より多くのリソース（タスク、プロジェクトなど）を同期的に取得できます。

```javascript
// Sync APIからタスクを取得する関数（公開して使用）
function getTasksFromSync() {
  _checkToken(); // トークンの確認

  const url = "https://api.todoist.com/sync/v9/sync";
  const options = _getCommonOptions('post');
  
  // POSTリクエストのため、payloadを追加
  options.payload = {
    'sync_token': '*',  // 全タスクを取得
    'resource_types': '["items"]'
  };

  try {
    const response = UrlFetchApp.fetch(url, options);
    
    if (response.getResponseCode() !== 200) {
      throw new Error(`Failed to fetch tasks from Sync API: ${response.getResponseCode()}`);
    }

    const syncData = JSON.parse(response.getContentText());
    return syncData.items; // 取得したタスクの配列を返す
  } catch (error) {
    Logger.log('Error fetching tasks from Sync API v9: ' + error.message);
    Logger.log(error.stack); // スタックトレースをログに出力
    return [];
  }
}
```

### 処理の流れ
1. POSTリクエストに`sync_token`を`'*'`として送信し、全タスクを取得。
2. 成功時には`syncData.items`にタスクのリストが格納されます。

### 例：取得したSyncタスクのログ出力

```javascript
function logSyncTasks() {
  const syncTasks = getTasksFromSync();
  Logger.log(syncTasks);
}
```

## 5. エラー処理

どちらの関数でも、エラーが発生した場合はエラーメッセージとスタックトレースをログに記録することで、問題の追跡が容易になります。