> ## Documentation Index
> Fetch the complete documentation index at: https://docs.coreflux.org/llms.txt
> Use this file to discover all available pages before exploring further.

# Google Drive

> Client-mode REST API connector for a curated Google Drive API v3 slice: about smoke, list/search files, get/create/update/delete file metadata, and simple media upload

Technical Preview

## Overview

A client-mode connector for a **curated** slice of [Google Drive API v3](https://developers.google.com/workspace/drive/api/reference/rest/v3) under `https://www.googleapis.com`:

| Catalog connector event | Entity / path | Notes |
| - | - | - |
| GET files?q= | `GET /drive/v3/files?q=...&pageSize=...` | Search / list — `q` must be URL-encoded |
| PATCH file metadata | `PATCH /drive/v3/files/{fileId}` | Rename, describe, tag `appProperties`, trash |
| POST upload (advanced) | `POST /upload/drive/v3/files?uploadType=media` | Simple media upload (≤5 MB, content only) |
| (supporting) about.get | `GET /drive/v3/about?fields=user,storageQuota` | Credential smoke |
| (supporting) files.get | `GET /drive/v3/files/{fileId}` | File metadata |
| (supporting) files.create | `POST /drive/v3/files` | Metadata-only file or folder |
| (supporting) files.delete | `DELETE /drive/v3/files/{fileId}` | Permanent delete (skips trash) |

Default `BASE_ADDRESS` is `https://www.googleapis.com` (no trailing slash). Metadata endpoints start with `/drive/v3/`; media uploads use `/upload/drive/v3/`. Topics use `storage/google-drive/<object>/<verb>`.

See the base guide: [REST API Connectors](/latest/lot-language/routes/rest-api-routes).

> [!NOTE]
>
> **Search queries:** put the Drive query in `{value.json.q}` already URL-encoded. Example: `name contains 'line-a' and trashed=false` → `name%20contains%20%27line-a%27%20and%20trashed%3Dfalse`. Send `"q": ""` to list everything visible to the token.

> [!NOTE]
>
> **Shared drives:** every event sends `supportsAllDrives=true` and the list event also sends `includeItemsFromAllDrives=true`, so files in shared drives work without extra flags.

> [!NOTE]
>
> Prefer Hub secrets for access tokens (`GET SECRET "GOOGLE_DRIVE_TOKEN"` or `"GOOGLE_ACCESS_TOKEN"`). Scope: `https://www.googleapis.com/auth/drive.file` (least privilege, files the app created or opened) or `https://www.googleapis.com/auth/drive` (full). This template has not been verified against a live Google Cloud project. Status remains blocked until an authenticated live smoke succeeds.

## Basic Syntax

```lot wrap theme={"theme":"css-variables","languages":{"custom":["/languages/lot.json"]}}
# Coreflux REST_API template — Google Drive API v3
# Auth: Bearer {value.json.api_token}
# BASE_ADDRESS: https://www.googleapis.com

DEFINE ROUTE GoogleDriveRestApi WITH TYPE REST_API
    ADD REST_API_CONFIG
        WITH BASE_ADDRESS "https://www.googleapis.com"
        WITH ENABLE_CLIENT "true"
        WITH USE_SSL "true"
        WITH REQUEST_TIMEOUT '60'
        WITH DEFAULT_CONTENT_TYPE "application/json"
        # Auth (prefer Hub secrets / GET SECRET):
        #   OAuth 2.0 access token on each MQTT payload → header below.
        #   Optional: WITH PASSWORD GET SECRET "GOOGLE_DRIVE_TOKEN"
        #     (only if your broker maps PASSWORD into Authorization for REST_API).
        #   Scope: https://www.googleapis.com/auth/drive or .../auth/drive.file
    ADD EVENT GetAbout
        WITH SOURCE_TOPIC "storage/google-drive/about/get"
        WITH DESTINATION_TOPIC "storage/google-drive/about/get/response"
        WITH METHOD "GET"
        WITH ENDPOINT "/drive/v3/about?fields=user,storageQuota"
        WITH HEADERS
            ADD "Accept" "application/json"
            ADD "Authorization" "Bearer {value.json.api_token}"
    ADD EVENT ListFiles
        WITH SOURCE_TOPIC "storage/google-drive/files/list"
        WITH DESTINATION_TOPIC "storage/google-drive/files/list/response"
        WITH METHOD "GET"
        WITH ENDPOINT "/drive/v3/files?q={value.json.q}&pageSize={value.json.pageSize}&supportsAllDrives=true&includeItemsFromAllDrives=true&fields=nextPageToken,files(id,name,mimeType,size,modifiedTime,parents)"
        WITH HEADERS
            ADD "Accept" "application/json"
            ADD "Authorization" "Bearer {value.json.api_token}"
    ADD EVENT GetFile
        WITH SOURCE_TOPIC "storage/google-drive/file/get"
        WITH DESTINATION_TOPIC "storage/google-drive/file/get/response"
        WITH METHOD "GET"
        WITH ENDPOINT "/drive/v3/files/{value.json.fileId}?supportsAllDrives=true&fields=id,name,mimeType,size,modifiedTime,parents,appProperties,webViewLink"
        WITH HEADERS
            ADD "Accept" "application/json"
            ADD "Authorization" "Bearer {value.json.api_token}"
    ADD EVENT CreateFile
        WITH SOURCE_TOPIC "storage/google-drive/file/create"
        WITH DESTINATION_TOPIC "storage/google-drive/file/create/response"
        WITH METHOD "POST"
        WITH ENDPOINT "/drive/v3/files?supportsAllDrives=true&fields=id,name,mimeType,parents"
        WITH HEADERS
            ADD "Accept" "application/json"
            ADD "Content-Type" "application/json"
            ADD "Authorization" "Bearer {value.json.api_token}"
        WITH BODY "{payload}"
    ADD EVENT UpdateFile
        WITH SOURCE_TOPIC "storage/google-drive/file/update"
        WITH DESTINATION_TOPIC "storage/google-drive/file/update/response"
        WITH METHOD "PATCH"
        WITH ENDPOINT "/drive/v3/files/{value.json.fileId}?supportsAllDrives=true&fields=id,name,mimeType,parents,trashed,appProperties"
        WITH HEADERS
            ADD "Accept" "application/json"
            ADD "Content-Type" "application/json"
            ADD "Authorization" "Bearer {value.json.api_token}"
        WITH BODY "{payload}"
    ADD EVENT DeleteFile
        WITH SOURCE_TOPIC "storage/google-drive/file/delete"
        WITH DESTINATION_TOPIC "storage/google-drive/file/delete/response"
        WITH METHOD "DELETE"
        WITH ENDPOINT "/drive/v3/files/{value.json.fileId}?supportsAllDrives=true"
        WITH HEADERS
            ADD "Accept" "application/json"
            ADD "Authorization" "Bearer {value.json.api_token}"
    ADD EVENT UploadFileMedia
        WITH SOURCE_TOPIC "storage/google-drive/file/upload"
        WITH DESTINATION_TOPIC "storage/google-drive/file/upload/response"
        WITH METHOD "POST"
        WITH ENDPOINT "/upload/drive/v3/files?uploadType=media&supportsAllDrives=true&fields=id,name,mimeType,size"
        WITH HEADERS
            ADD "Accept" "application/json"
            ADD "Content-Type" "application/json"
            ADD "Authorization" "Bearer {value.json.api_token}"
        WITH BODY "{payload}"
```

## Auth

1. Enable **Google Drive API** on a Google Cloud project.
2. Obtain an OAuth 2.0 user access token **or** a service-account access token. A service account has its own Drive: share the target folder (or shared drive) with the service-account email, or use domain-wide delegation in Google Workspace.
3. Scope: `https://www.googleapis.com/auth/drive.file` covers files the connector creates. Use `https://www.googleapis.com/auth/drive` to read or update files created elsewhere. Use `.../drive.metadata.readonly` only if you stick to GET events.
4. Pass `api_token` on each MQTT payload → `Authorization: Bearer {value.json.api_token}`. Prefer Hub secrets / `GET SECRET "GOOGLE_DRIVE_TOKEN"` or `"GOOGLE_ACCESS_TOKEN"`. Never commit real tokens.

Access tokens expire after about one hour. Refresh them outside the connector (service-account JWT exchange or OAuth refresh token) and update the secret.

## MQTT topics

| Event | Source topic | Response topic |
| - | - | - |
| GetAbout | `storage/google-drive/about/get` | `.../about/get/response` |
| ListFiles | `storage/google-drive/files/list` | `.../files/list/response` |
| GetFile | `storage/google-drive/file/get` | `.../file/get/response` |
| CreateFile | `storage/google-drive/file/create` | `.../file/create/response` |
| UpdateFile | `storage/google-drive/file/update` | `.../file/update/response` |
| DeleteFile | `storage/google-drive/file/delete` | `.../file/delete/response` |
| UploadFileMedia | `storage/google-drive/file/upload` | `.../file/upload/response` |

## Example payloads

**Credential smoke** (`GetAbout`):

```json theme={"theme":"css-variables","languages":{"custom":["/languages/lot.json"]}}
{
  "api_token": "YOUR_OAUTH_OR_SA_ACCESS_TOKEN"
}
```

**Search a line folder** (`ListFiles`):

```json theme={"theme":"css-variables","languages":{"custom":["/languages/lot.json"]}}
{
  "api_token": "YOUR_OAUTH_OR_SA_ACCESS_TOKEN",
  "q": "%27YOUR_FOLDER_ID%27%20in%20parents%20and%20trashed%3Dfalse",
  "pageSize": 20
}
```

> [!NOTE]
>
> **Body fields:** `CreateFile`, `UpdateFile`, and `UploadFileMedia` send `{payload}` as the body. Google APIs can reject unknown JSON fields (such as `api_token` or `fileId`) with HTTP 400. If your broker forwards the whole payload, publish only Drive file fields and inject the Bearer from a Hub secret or connector wiring.

**Create a per-device folder** (`CreateFile`):

```json theme={"theme":"css-variables","languages":{"custom":["/languages/lot.json"]}}
{
  "api_token": "YOUR_OAUTH_OR_SA_ACCESS_TOKEN",
  "name": "line-a-sensor-01",
  "mimeType": "application/vnd.google-apps.folder",
  "parents": ["YOUR_PARENT_FOLDER_ID"],
  "appProperties": { "deviceId": "line-a-sensor-01", "site": "porto" }
}
```

**Rename and tag a report** (`UpdateFile`):

```json theme={"theme":"css-variables","languages":{"custom":["/languages/lot.json"]}}
{
  "api_token": "YOUR_OAUTH_OR_SA_ACCESS_TOKEN",
  "fileId": "YOUR_FILE_ID",
  "name": "shift-report-2026-10-04.json",
  "description": "Shift A telemetry snapshot",
  "appProperties": { "shift": "A", "status": "final" }
}
```

**Move to trash** (recoverable — prefer this over `DeleteFile`):

```json theme={"theme":"css-variables","languages":{"custom":["/languages/lot.json"]}}
{
  "api_token": "YOUR_OAUTH_OR_SA_ACCESS_TOKEN",
  "fileId": "YOUR_FILE_ID",
  "trashed": true
}
```

**Delete permanently** (`DeleteFile` → HTTP 204):

```json theme={"theme":"css-variables","languages":{"custom":["/languages/lot.json"]}}
{
  "api_token": "YOUR_OAUTH_OR_SA_ACCESS_TOKEN",
  "fileId": "YOUR_FILE_ID"
}
```

## Uploads (advanced)

`UploadFileMedia` uses `uploadType=media`: the whole MQTT payload becomes the file content (`application/json`, up to 5 MB). Drive names the file `Untitled` with no parent, so follow with `UpdateFile` using the returned `id` to set `name` and move it with `addParents`.

> [!WARNING]
>
> With `uploadType=media`, everything in `{payload}` is stored in the file. Do not put `api_token` in the payload for this event in production. Inject the Bearer from a Hub secret or connector wiring instead, or the token ends up inside the uploaded file.

`uploadType=multipart` (metadata and content in one `multipart/related` request) and `uploadType=resumable` (large files) are not templated. They need a multipart body or a two-step session that a single MQTT JSON payload does not map to cleanly.

## Push notifications

Drive can push change notifications (`files.watch`, `changes.watch`) to an HTTPS webhook. That is a server-mode companion (`ENABLE_SERVER`) and is not part of this client template.

## Quotas and limits

Google Drive API enforces [per-project and per-user quotas](https://developers.google.com/workspace/drive/api/guides/limits). Bursts from many devices can return HTTP 403 `userRateLimitExceeded` or 429. Batch snapshots at the edge and back off on errors.

## Deploy notes

* Deploy **only** `GoogleDriveRestApi.lot` with `-addRoute` / Hub deploy. Do **not** deploy `hub-metadata.lot`.
* Hub listing uses `hub-metadata.lot` (`WITH IMAGE`, `WITH STATUS "beta"`, doclink).
* Suggested branches (Hugo pushes): `feat/rest-api-route-google-drive`, `feat/docs-rest-api-google-drive`.

## Related

* [REST API Connectors](/latest/lot-language/routes/rest-api-routes)
* [REST API Apps catalog](/latest/lot-language/routes/rest-api-apps)
* [Google Sheets](/latest/lot-language/routes/rest-api-apps/google-sheets)
* [Google Cloud Storage](/latest/lot-language/routes/rest-api-apps/google-cloud-storage)
* [Google Drive API reference](https://developers.google.com/workspace/drive/api/reference/rest/v3)
* Discovery: `https://www.googleapis.com/discovery/v1/apis/drive/v3/rest`


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.