Google Drive Integration
Connect your agent to Google Drive for reading, writing, and managing files in selected folders.
Overview
The Google Drive integration uses a Google Cloud service account with folder access delegated from your Drive. You create the service account in your own Google Cloud project, share your Drive folders with the service account email, and the agent accesses only those shared folders.
Skills that use this integration:
int-google-drive— Read files, write outputs, manage folders in selected Drive folders
Agents that typically enable this integration:
- Google Ads Manager (creative assets for campaigns)
- Meta Ads Manager (creative assets for campaigns)
- TikTok Ads Manager (creative assets for campaigns)
- Social Manager (post-ready media library)
Availability
| Mode | Status | Notes |
|---|---|---|
| Service Account JSON | Available | Google Cloud service account with Drive API access. Folders shared by the user. |
Prerequisites
- A Wiro API key — Authentication.
- A deployed agent — Agent Overview.
- A Google account with a Drive you want the agent to access.
- A Google Cloud project to host the service account.
Setup
Step 1: Enable the Google Drive API
Google Cloud Console → select project → APIs & Services → Library → Google Drive API → Enable.
If your agent will also read/write Google Docs or Sheets, enable those APIs as well:
- Google Sheets API
- Google Docs API
Step 2: Create a service account
- IAM & Admin → Service accounts → Create service account.
- Name (e.g. "wiro-drive-agent").
- Skip role grant → Done.
- Open the service account → Keys → Add key → Create new key → JSON. Download.
- Note the service account email from the account details page — format:
[email protected].
Tip: In My Agents → open your agent → Credentials, upload the JSON and your service account email will appear with a Copy button.
Step 3: Share your Drive folders with the service account
For each folder you want the agent to access:
- Open Google Drive.
- Right-click the folder → Share.
- Paste the service account email from Step 2.
- Set role to Editor (if the folder lives in your My Drive) or Content manager (if the folder lives in a Shared Drive).
- Click Send.
Copy each folder's ID from its Drive URL — the part after /folders/. Example: from https://drive.google.com/drive/folders/1BxiMVs0XRA5nFMdKvBd the ID is 1BxiMVs0XRA5nFMdKvBd.
Google Workspace users: If you use a Shared Drive (Team Drive), add the service account as a member of the shared drive instead of sharing individual folders. All folders within the shared drive become accessible.
Step 4: Base64-encode the JSON
# Linux
base64 -w 0 drive-service-account.json > drive-sa.b64
# macOS
base64 -b 0 drive-service-account.json > drive-sa.b64
Step 5: Save to Wiro
curl -X POST "https://api.wiro.ai/v1/UserAgent/CredentialUpsert" \
-H "Content-Type: application/json" \
-H "x-api-key: YOUR_API_KEY" \
-d '{
"useragentguid": "your-useragent-guid",
"fields": [
{ "credentialkey": "google-drive", "fieldname": "serviceaccountjson", "fieldvalue": "eyJ0eXBlIjoic2VydmljZV9hY2NvdW50Ii..." },
{ "credentialkey": "google-drive", "parentfield": "folders", "ordinal": 0, "fieldname": "id", "fieldvalue": "1BxiMVs0XRA5nFMdKvBd" },
{ "credentialkey": "google-drive", "parentfield": "folders", "ordinal": 0, "fieldname": "name", "fieldvalue": "Creatives" },
{ "credentialkey": "google-drive", "parentfield": "folders", "ordinal": 1, "fieldname": "id", "fieldvalue": "2CyiNWt1YSB6oGNeL" },
{ "credentialkey": "google-drive", "parentfield": "folders", "ordinal": 1, "fieldname": "name", "fieldvalue": "Ad Assets" }
]
}'
| Field | Type | Description |
|---|---|---|
serviceaccountjson |
string | Base64-encoded service account JSON key. |
folders |
array | Array of { "id": string, "name": string } objects the agent should scan. name is the human-readable label — the agent uses it when reporting back to the operator ("scanned the Creatives folder..."); id is the Drive folder ID used in API calls. Pass an empty array to clear. |
Step 5b (optional): Discover folders via API
If you don't already have folder IDs from Step 3, or you want to verify that the service account has access to the expected folders before saving them, call the folder discovery endpoint. This is the same endpoint the Wiro Dashboard uses for its folder picker.
curl -X POST "https://api.wiro.ai/v1/UserAgentOAuth/GoogleDriveListFolders" \
-H "Content-Type: application/json" \
-H "x-api-key: YOUR_API_KEY" \
-d '{
"useragentguid": "your-useragent-guid",
"serviceaccountjson": "eyJ0eXBlIjoic2VydmljZV9hY2NvdW50Ii..."
}'
| Parameter | Type | Required | Description |
|---|---|---|---|
useragentguid |
string | Yes | Agent instance GUID. |
serviceaccountjson |
string | No | Base64-encoded SA JSON. Useful for previewing before saving. If omitted, the endpoint uses whatever JSON was already saved to the agent via Step 5. |
parentid |
string | No | Parent folder ID for subfolder listing. Omit (or pass empty) to list folders shared at the root level with the service account (Drive's sharedWithMe filter). When provided, returns folders whose parent is the given id — Drive's permission cascade lets the service account see children of any root it has access to, even if those children aren't shared individually. |
Response:
{
"result": true,
"serviceAccountEmail": "[email protected]",
"parentId": "",
"folders": [
{ "id": "1BxiMVs0XRA5nFMdKvBd", "name": "Creatives", "modifiedTime": "2026-04-10T12:34:00Z", "ownerName": "[email protected]" },
{ "id": "2CyiNWt1YSB6oGNeL", "name": "Ad Assets", "modifiedTime": "2026-04-12T09:12:00Z", "ownerName": "[email protected]" }
]
}
parentId echoes back whatever you passed in ("" for a root listing) so the caller can verify it landed on the level it expected — useful when the user navigates two levels deep quickly and you need to discard out-of-order responses. Only folders explicitly shared with the SA email (as Editor or Content manager — see Step 3) are returned at the root. Take the id values from the folders you want the agent to scan and pass them as the folders array in your final UserAgent/CredentialUpsert call (using parentfield: "folders" + ordinal per entry).
Listing subfolders
Use parentid to walk down the folder tree — first call without parentid to enumerate the roots the service account can see, then call again with parentid: "<root-id>" to list its children, and so on. The Wiro Dashboard's folder picker uses this exact pattern.
curl -X POST "https://api.wiro.ai/v1/UserAgentOAuth/GoogleDriveListFolders" \
-H "Content-Type: application/json" \
-H "x-api-key: YOUR_API_KEY" \
-d '{
"useragentguid": "your-useragent-guid",
"parentid": "1BxiMVs0XRA5nFMdKvBd"
}'
The response shape is identical — folders[] now contains the immediate children of 1BxiMVs0XRA5nFMdKvBd, and parentId echoes back "1BxiMVs0XRA5nFMdKvBd" so you can keep the picker UI in sync if the user clicks between levels quickly.
Two equivalent ways to run Steps 5–5b
- Upfront — you already know the folder IDs from Step 3. Call
UserAgent/CredentialUpsertonce with bothserviceaccountjsonandfolders. - Discovery (matches the Dashboard flow) — call
UserAgent/CredentialUpsertfirst with justserviceaccountjson(leavefoldersempty), then callUserAgentOAuth/GoogleDriveListFoldersto enumerate what the SA can see, then callUserAgent/CredentialUpsertagain with the pickedfoldersarray. The Dashboard uses this pattern — JSON upload renders the service account email, the user shares folders with it in Drive, and the folder picker lists the results.
Step 6: Start the agent
curl -X POST "https://api.wiro.ai/v1/UserAgent/Start" \
-H "Content-Type: application/json" \
-H "x-api-key: YOUR_API_KEY" \
-d '{ "guid": "your-useragent-guid" }'
Runtime Behavior
When the int-google-drive skill is enabled, the agent works only in the folders saved under folders[], each with its id and name; it can address a folder by either. With no folder saved, it has no Drive folder to work in.
Auth: the agent mints a short-lived OAuth access token from the service account you saved and sends it as Authorization: Bearer. Tokens expire after an hour, so a fresh one is minted before each API session.
Base URLs:
- Drive API:
https://www.googleapis.com/drive/v3/... - Sheets API:
https://sheets.googleapis.com/v4/... - Docs API:
https://docs.googleapis.com/v1/...
All list/get/upload calls pass supportsAllDrives=true + includeItemsFromAllDrives=true, so Shared Drives are supported automatically.
Files created by the agent
When the agent creates a file inside a user-shared folder, the file is owned by the service account, not the user. The user can see the file via folder permission inheritance, but may see it as "view only". To give the user write access on files the agent creates (role writer in the Drive API — shown as Editor in My Drive or Content manager in a Shared Drive), the skill grants permissions programmatically via POST /drive/v3/files/{fileId}/permissions. See the int-google-drive skill for details.
Troubleshooting
- 403 "The user does not have sufficient permissions for file": The folder hasn't been shared with the service account, or the service account was given a read-only role (Viewer / Commenter) instead of a write role. Go back to Google Drive → Share the folder with the SA email as Editor (My Drive) or Content manager (Shared Drive).
- 403 on specific file inside a shared folder: The file was added by someone else and hasn't inherited folder permissions yet. Force inheritance by resharing the folder, or share the specific file directly.
- "Invalid JWT token": Service account JSON corrupt or truncated. Re-encode (watch for line breaks — use
base64 -w 0on Linux,base64 -b 0on macOS). - Agent can't find new files: The agent only sees files inside folders listed in
folders. Add new folder IDs to the list and restart. - User sees files as "view only": Files created by the SA inside user folders are SA-owned. The skill should grant the user write access (role
writer— Editor in My Drive, Content manager in Shared Drive); if this step is skipped, the user sees view-only. Manual fix: right-click the file → Share → grant yourself write access.