【Android】Toggl Track APIを使ってトラッキングの開始と停止をする（API v9バージョン）

タイムトラッキングツールの [Toggl Track](https://toggl.com/track/) のAPIを使って、トラッキングの開始と停止を試してみたのでメモとして投稿します。
（Android固有の話はほとんどありませんので、他のプラットフォームでも参考になるかもしれません。:information_desk_person_tone2:）

APIのドキュメントにちゃんとまとまっていますが、トラッキングの開始と停止をする最低限の方法をご紹介します。

■ 開始のAPI

https://developers.track.toggl.com/docs/api/time_entries#post-timeentries

■ 停止のAPI

 https://developers.track.toggl.com/docs/api/time_entries#put-timeentries

# APIトークンを取得する :mag:
APIを叩くにはメール・パスワードを指定する方法と、APIトークンを指定する方法の2パターンありますが、今回はAPIトークンを指定する方法を使用します。

https://developers.track.toggl.com/docs/authentication

APIトークンはToggl Trackのプロフィールページから取得できます。

https://track.toggl.com/profile

![スクリーンショット_2023-03-26_午前5_15_04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/995/6090226c-7194-54da-8c07-9229c5f61ef2.png)

# workspace_idを取得する :mag:
開始・停止のAPIには必須のパラメータとして `workspace_id` が必要になります。

自分のWorkspaceのIDですが、Toggl TrackのWeb版の「Reports」ページを選択した場合に表示されるパスが `workspace_id` のようでした。

![スクリーンショット_2023-03-26_午前5_21_25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/995/33d3e2f5-08ad-f963-2223-8993a22d2839.png)


# 通信周り定義 :pick:
Retrofitで定義しています。


```kotlin
interface TogglApiService {

    // 開始
    @POST("workspaces/{workspace_id}/time_entries")
    suspend fun workspacesTimeEntries(
        @Path("workspace_id") workspaceId: Int,
        @Body workspacesTimeEntriesRequest: WorkspacesTimeEntriesRequest,
    ) : WorkspacesTimeEntriesResponse

    // 停止
    @PATCH("workspaces/{workspace_id}/time_entries/{time_entry_id}/stop")
    suspend fun workspacesTimeEntriesStop(
        @Path("workspace_id") workspaceId: Int,
        @Path("time_entry_id") timeEntryId: Long,
    )
}
```

---

開始のリクエストで使うモデルです。

```kotlin
data class WorkspacesTimeEntriesRequest(
    val created_with: String = "From API",
    val workspace_id: Int,
    val start: String,
    val duration: Long,
    val description: String,
)
```

開始時のリクエストパラメータは↓にまとまっていますが、最低限のものを定義しています。

https://developers.track.toggl.com/docs/api/time_entries#body-2

`created_with` はトラッキングの作成に使用したサービス/アプリケーションを特定するために必要な指定。

`start` は開始時刻のUTCの文字列。

`duration` はトラッキングの存続期間。一番ハマりましたが、 :warning: **現在時刻から開始する場合は -1 * UNIX時刻（秒）を指定** する必要があります。 

`description` は開始したトラッキングのタイトルに当たる文字列。必須ではないです。

---

開始のレスポンスで使うモデルです。

```kotlin
data class WorkspacesTimeEntriesResponse(
    val id: Long,
)
```

開始したトラッキングのidだけを定義しています。

https://developers.track.toggl.com/docs/api/time_entries#response-2

# 実行 :rocket: 

OkHttp、Retrofit、Moshiを使ってAPIクライアントを雑に作成します。

```kotlin
val apiToken = "xxxx" // APIトークン
val workspaceId = 000000 // workspace_id

val apiClient: TogglApiService by lazy {
    val credential = Credentials.basic(apiToken, "api_token")
    val client = OkHttpClient.Builder().addInterceptor { chain ->
        val newRequest = chain.request().newBuilder()
            .header("Authorization", credential)
            .build()
        chain.proceed(newRequest)
    }.build()

    Retrofit.Builder().client(client)
        .baseUrl("https://api.track.toggl.com/api/v9/")
        .addConverterFactory(MoshiConverterFactory.create()).build()
        .create(TogglApiService::class.java)
}
```

## 開始処理 :timer: 

```kotlin
suspend fun start() {
    val zdt = ZonedDateTime.now()
    val workspacesTimeEntriesRequest = WorkspacesTimeEntriesRequest(
        workspace_id = workspaceId,
        start = zdt.format(DateTimeFormatter.ISO_INSTANT),
        duration = -1 * zdt.toEpochSecond(),
        description = "test",
    )

    val response = apiClient.workspacesTimeEntries(
        workspaceId = workspaceId,
        workspacesTimeEntriesRequest = workspacesTimeEntriesRequest,
    )

    Log.d("LOG", response.toString())
}
```

`ZonedDateTime.now()` で現在時刻を取得し、
- `start` に `DateTimeFormatter.ISO_INSTANT` というフォーマットを指定。
- `duration` に **-1 * UNIX時刻（秒）** を指定。
- `duration` （トラッキングの名前）は「test」を指定。

を行います。

成功すれば「test」とい名前でトラッキングが開始されます。 :thumbsup: 

## 停止処理 :stop_button:

```kotlin
suspend fun stop(id: Long) {
    apiClient.workspacesTimeEntriesStop(
        workspaceId = workspaceId,
        timeEntryId = id,
    )
}
```

開始のレスポンスに含まれる `id` を指定してあげるだけです。

成功すればトラッキングが停止されます。 :thumbsup_tone1: 

# まとめ
雑ですが、Toggl Track APIを使ってトラッキングの開始と停止をする方法をご紹介しました。
Toggl TrackはAPIが充実しているので、他にも色々と試してみたいところです。