Google Apps Script中OAuth2配置问题:AccessToken获取失败
Let’s walk through fixing this issue since you’ve already checked the critical prerequisites (whitelist approval, API enabled, valid client ID/secret). Here are the key fixes and checks to apply:
1. Fix the Reversed Logic in showSidebar()
Your current showSidebar() has backwards logic that misrepresents access status, which might be causing confusion (and even preventing you from confirming successful authorization):
Original (buggy) code:
if (!gmbService.hasAccess()) { // Shows authorization link } else { Logger.log("No Access") // This is wrong! hasAccess() = true means access IS granted }
Corrected code:
function showSidebar() { var gmbService = getGmbService(); if (!gmbService.hasAccess()) { var authorizationUrl = gmbService.getAuthorizationUrl(); var template = HtmlService.createTemplate( '<a href="<?= authorizationUrl ?>" target="_blank">Authorize</a>. ' + 'Reopen the sidebar when the authorization is complete.'); template.authorizationUrl = authorizationUrl; var page = template.evaluate(); DocumentApp.getUi().showSidebar(page); } else { Logger.log("Access granted!"); DocumentApp.getUi().showSidebar(HtmlService.createHtmlOutput('Already authorized! You can run your test now.')); } }
This will correctly show a success message when authorization is valid, instead of misleading you with "No Access".
2. Fix the testRequest() Function
You’re making two mistakes here that could compound the issue:
- Adding a
payloadto a GET request (payloads are for POST/PUT, not GET) - Trying to retrieve an access token without first checking if access is granted
Corrected testRequest():
function testRequest() { var gmbService = getGmbService(); if (!gmbService.hasAccess()) { Logger.log('Error: No access - please authorize first via showSidebar()'); showSidebar(); return; } var accessToken = gmbService.getAccessToken(); Logger.log('Valid Access Token Retrieved: ' + accessToken.substring(0, 20) + '...'); // Log first 20 chars for privacy var options = { "headers": { "Authorization": 'Bearer ' + accessToken }, "method": 'GET', "muteHttpExceptions": true }; // Move pageSize to the URL query string for GET requests var response = UrlFetchApp.fetch("https://mybusiness.googleapis.com/v4/accounts?pageSize=5", options); Logger.log('Response Status Code: ' + response.getResponseCode()); Logger.log('Response Content: ' + response.getContentText()); }
3. Verify Token Persistence & Debug the Callback
To confirm if tokens are being saved correctly, add debug logging to your authCallback function:
function authCallback(request) { var gmbService = getGmbService(); var isAuthorized = gmbService.handleCallback(request); // Debug: Check what's stored in user properties var storedProps = PropertiesService.getUserProperties().getProperties(); Logger.log('Stored OAuth Properties: ' + JSON.stringify(storedProps)); if (isAuthorized) { return HtmlService.createHtmlOutput('Success! You can close this tab and reopen the sidebar.'); } else { return HtmlService.createHtmlOutput('Denied. You can close this tab'); } }
After authorization, check the Apps Script logs to see if a token entry (starting with oauth2.gmb) exists. If not, double-check your client ID/secret for typos.
4. Clear Stale Tokens & Re-Authorize
Old invalid tokens can linger in property storage. Run this function to reset everything, then re-authorize:
function clearGmbTokens() { PropertiesService.getUserProperties().deleteProperty('oauth2.gmb'); CacheService.getUserCache().remove('oauth2.gmb'); Logger.log('GMB OAuth tokens cleared successfully'); }
5. Double-Check Client ID Type
Ensure your OAuth2 client ID in the Google Cloud Console is set to Web application (not Desktop or Mobile). For Apps Script, Web application is the correct type, and the OAuth2 library will automatically handle the redirect URI.
内容的提问来源于stack exchange,提问作者Kjacoby

