Hey all — I've been working on getting the Google Docs Update custom action working and also building a Google Slides custom action from scratch. Hit a few issues along the way that I think are worth sharing since I couldn't find anyone else talking about them.
The Problem: oneOf Error on Google Docs batchUpdate
If you're using the Google Docs Update action (the one from the developer docs example), you might hit this error when the agent tries to use both insertText and replaceAllText:
"Invalid value at 'requests[0]' (oneof), oneof field 'request' is already set. Cannot set 'replaceAllText'"
What's happening: Google's batchUpdate API treats each request object as a "union field" — meaning each item in the requests array can only contain ONE operation type. But the example spec defines insertText and replaceAllText as sibling properties on the same object. The LLM sees both options and sometimes stuffs both into one request item, which Google rejects.
The fix: Add explicit descriptions on the request object saying "Include ONLY ONE of insertText or replaceAllText per item. Do not combine them in the same object." That solved it.
Other Issues I Hit
matchCase causing "missing required parameter": If matchCase isn't set as optional with a default value, the agent sometimes fails to populate it. Setting default: false in the schema fixed this.
$ref vs inline schemas: The developer docs say "no nested fields" for custom actions, but the Google Docs example itself uses nested objects 3-4 levels deep. I wasn't sure if $ref and components/schemas would be resolved correctly by Glean's parser, so I inlined everything to match the pattern of the working example. Can't confirm whether $ref works for request bodies — it does seem to work for response schemas based on the Jira example.
Full Document Replacement
My use case was replacing the entire body of a Google Doc (not just find-and-replace). This requires a get + delete + insert sequence which can't be done in a single custom action since each action is one endpoint. I ended up building a Google Apps Script that wraps all three steps into one POST call, then pointing a minimal custom action at that Apps Script URL.
Google Slides Custom Action
Built a custom action for Google Slides batchUpdate that supports:
- replaceAllText for template placeholder swaps (e.g. replacing {{COMPANY_NAME}} across all slides)
- - insertText for putting agent-generated content into a specific shape by objectId
Same union field pattern as Docs — each request item gets one operation only. One thing to note: insertText requires knowing the objectId of the target shape. For fixed templates you can hardcode these, but for dynamic discovery you'd need a separate GET action to read the presentation structure.
No native Slides actions exist in Glean right now, so this is built entirely as a custom action.
Happy to Share
If anyone's working on similar Google Workspace integrations and wants the corrected OpenAPI specs, happy to share them. Also curious if anyone else has hit the oneOf issue or has insight on whether Glean's parser resolves $ref in request body schemas.