feat: add inlineData parameter to SSI custom function (deferred — Drive auth blocked)#20
Open
aaronbrezel wants to merge 4 commits into
Open
feat: add inlineData parameter to SSI custom function (deferred — Drive auth blocked)#20aaronbrezel wants to merge 4 commits into
aaronbrezel wants to merge 4 commits into
Conversation
DriveApp is unavailable in Google Apps Script custom function execution contexts, causing "permissions not sufficient" errors when SSI() is called with an inlineData argument. UrlFetchApp and ScriptApp.getOAuthToken() work in all contexts and are the GAS-documented pattern for this case. fetchAndEncodeFile now makes two Drive REST API calls via UrlFetchApp: one for file metadata (mimeType + size) and one for file content. Error responses from each call surface a descriptive message. Update drive.test.ts to mock the Drive REST API calls instead of DriveApp, and add fallback-message tests to restore 100% branch coverage on drive.ts. Update customFunctions.test.ts to use mockDriveApiFile() helper and a getGeminiPayload() helper that locates the Gemini call by URL regardless of how many Drive calls precede it. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Custom functions cannot use DriveApp or other OAuth-requiring services. Document the UrlFetchApp + ScriptApp.getOAuthToken() pattern as the correct alternative, with a pointer to fetchAndEncodeFile as an example. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Custom functions run in AuthMode.CUSTOM_FUNCTION, which scopes ScriptApp.getOAuthToken() to spreadsheets.currentonly only. Drive API calls with this token return 401 — not a permissions error, but an auth scope mismatch that cannot be resolved without a service account. - fetchAndEncodeFile: guard for null/insufficient token with a clear error pointing users to the Run AI menu tool - customFunctions.ts: revert the auth-error heuristic (no longer needed now that the error surfaces directly from fetchAndEncodeFile) - drive.ts / CLAUDE.md: accurately document the AuthMode.CUSTOM_FUNCTION constraint, why ScriptApp.getOAuthToken() doesn't help, and the service-account alternative with its UX trade-off - drive.test.ts: update null-token test assertion to match new message Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The cleanup commit on feature/ssi-custom-function removed inlineData from the footer stub, but feature/ssi-inline-data re-adds it to customFunctions.ts. The stub was out of sync, silently dropping the inlineData argument. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Deferred continuation of #18. Adds a fourth
inlineDataparameter toSSI()so users can attach Drive files as inline data parts in a cell formula.Status: blocked.
ScriptApp.getOAuthToken()inAuthMode.CUSTOM_FUNCTIONcontext returns a token scoped only tospreadsheets.currentonly— Drive API calls return 401. This PR captures the investigation and a workable starting point for a proper solution.Changes on this branch (on top of
develop)src/server/drive.ts:fetchAndEncodeFilereplaced with a Drive REST API implementation viaUrlFetchApp+ScriptApp.getOAuthToken(), replacing the DriveApp version that is unavailable in custom function context. Includes a null-token guard that returns an actionable error message.src/server/customFunctions.ts:inlineData?parameter restored;fetchAndEncodeFileandextractIdimports re-added;resolvedInlineDatablock re-added.rollup.config.js: SSI footer stub updated back to 4-parameter signature.CLAUDE.md:AuthMode.CUSTOM_FUNCTIONOAuth scope limitation documented.Why it's blocked
Custom functions in a bound Apps Script run with
AuthMode.CUSTOM_FUNCTION. The OAuth token available viaScriptApp.getOAuthToken()in this context has onlyspreadsheets.currentonlyscope — it cannot authorize Drive API requests. This is a GAS platform constraint for bound scripts.Possible paths forward
ANYONEorDOMAINaccess; call it from the custom function viaUrlFetchApp. The web app runs with full auth and can return the encoded file.Test plan
npm run test:coverage— all tests pass, all thresholds met (71 tests)npm run typecheck— no errorsnpm run build— SSI stub confirmed indist/index.jswith 4-parameter signature🤖 Generated with Claude Code