API suddently started throwing Error: Access not granted or expired. Service_.getAccessToken Service.gs:466 error
API suddently started throwing Error: Access not granted or expired. Service_.getAccessToken Service.gs:466 error
我目前正在 运行 Google 脚本上的一些脚本来调用 Salesforce REST API 并将数据下载到 Google 表格中。
我正在使用 Google 表格库 ID 1B7FSrk5Zi6L1rSxxTDgDEUsPzlukDsi4KGuTMorsTQHhGBzBkMun4iDF
,这是可以在 github here.
上找到的 OAuth2 库
然后,我按照指示使用以下调用通过以下代码实际验证 Salesforce API:
var CLIENT_ID = {I get this from the connected SalesForce app};
var CLIENT_SECRET = {I get this from the connected SalesForce app};
function getService() {
// Create a new service with the given name. The name will be used when
// persisting the authorized token, so ensure it is unique within the
// scope of the property store.
return OAuth2.createService('salesforce')
// Set the endpoint URLs
.setAuthorizationBaseUrl('https://flolive.my.salesforce.com/services/oauth2/authorize')
.setTokenUrl('https://flolive.my.salesforce.com/services/oauth2/token')
// Set the client ID and secret, from the Google Developers Console.
.setClientId(CLIENT_ID)
.setClientSecret(CLIENT_SECRET)
// Set the name of the callback function in the script referenced
// above that should be invoked to complete the OAuth flow.
.setCallbackFunction('authCallback')
// Set the property store where authorized tokens should be persisted.
.setPropertyStore(PropertiesService.getDocumentProperties())
// .setCache(CacheService.getDocumentCache())
// Set the scopes to request (space-separated for Google services).
// .setScope('r_organization_social,r_basicprofile,r_liteprofile,rw_organization_admin,r_ads_reporting,r_ads')
// Below are salesforce-specific OAuth2 parameters.
.setParam('response_type', 'code')
// Forces the approval prompt every time. This is useful for testing,
// but not desirable in a production application.
//.setParam('approval_prompt', 'force');
}
function authCallback(request) {
var salesforceService = getService();
var isAuthorized = salesforceService.handleCallback(request);
if (isAuthorized) {
return HtmlService.createHtmlOutput('Success! You can close this tab.');
} else {
return HtmlService.createHtmlOutput('Denied. You can close this tab');
}
}
function logOut() {
PropertiesService.getDocumentProperties().deleteAllProperties();
PropertiesService.getUserProperties().deleteAllProperties();
var service=getService();
service.reset();
}
function salesforceAPI() {
var service = getService();
if (service.hasAccess()) {
//exchange authorisation code for access token
// sheet.getSheetByName('Settings').getRange(3,2).setValue(getService().getAccessToken());
var tokenURL = 'https://flolive.my.salesforce.com/services/oauth2/token';
var parameters = 'grant_type=authorization_code&code='+getService().getAccessToken()+'&redirect_uri='+getService().redirect_uri+'&client_id='+CLIENT_ID+'&client_secret='+CLIENT_SECRET;
var options = {
'method': 'POST',
'contentType': 'application/x-www-form-urlencoded',
'muteHttpExceptions': true,
'payload': parameters
}
var response = UrlFetchApp.fetch(tokenURL,options);
var json = JSON.parse(response.getContentText());
console.log(json);
//sheet.getSheetByName('Settings').getRange(3,3).setValue(json.items);
return json;
} else {
var authorizationUrl = service.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();
SpreadsheetApp.getUi().showModalDialog(page,'Authorise salesforce');
Logger.log(getService().getAccessToken());
}
}
现在我对此没有问题。我打的所有电话都有效。我在连接的应用程序中检查了回调url,一切正常。
当我尝试将一些数据输出到不同的工作表时,一切都停止了。
所以现在我有 2 个工作表。
SF API 后端 - 这是我放置 API 所有设置和参考的地方
记录的会议 - 这是我输出我试图提取的数据的地方,这些数据是活动。
起初一切正常,我可以正常输出。但是,当我添加 API 后端工作表时,起初它不起作用。我没有收到任何错误,也没有收到任何数据。
我以为是因为它需要一个不同的回调url,所以我添加了它。然后,出于某种原因,我使用了上面提到的 logOut() 函数来尝试重置连接。
那是我开始收到此错误的时候 错误:访问未被授予或已过期。
Service_.getAccessToken@Service.gs:466.
我上网查了下,觉得跟PropertyService
有关系。所以我删除了所有 PropertyService
键。我什至将 getService()
函数从 .setPropertyStore(PropertiesService.getDocumentProperties())
切换到 .setCache(CacheService.getDocumentCache())
(现在已被注释掉)。
还是一样的错误。
然后我进入 Salesforce 并获得一个设置的访问令牌并用它替换 +getService().getAccessToken()
。
我收到此错误 TypeError: 无法读取未定义的 属性 'setClientId'
在 getService(SalesForceAuthentication:15:7)
在 salesforceAPI(SalesForceAuthentication:56:17)
我不确定为什么会出现该错误,因为我更改的代码甚至不在该函数中。
这就是我目前所在的位置。
我没有看到任何被列入黑名单的内容或任何会混淆或阻止它的设置。
我什至尝试重建整个东西,然后将代码(仅代码)复制到不同的脚本。我得到了同样的错误 错误:访问未被授予或已过期。
Service_.getAccessToken@Service.gs:466.
这让我认为客户端 Secret/Client Id 以某种方式被阻止。
问题:
当您使用getDocumentProperties()存储授权数据时:
Gets a property store (for this script only) that all users can access within the open document, spreadsheet, or form
如果您使用与存储数据的电子表格不同的电子表格,则数据不可用。
解决方案:
如果您希望它适用于多个电子表格,请改用 getScriptProperties() or getUserProperties(),它可以保留在多个文档上(仅当您使用相同的脚本时)。
.setPropertyStore(PropertiesService.getScriptProperties())
我目前正在 运行 Google 脚本上的一些脚本来调用 Salesforce REST API 并将数据下载到 Google 表格中。
我正在使用 Google 表格库 ID 1B7FSrk5Zi6L1rSxxTDgDEUsPzlukDsi4KGuTMorsTQHhGBzBkMun4iDF
,这是可以在 github here.
然后,我按照指示使用以下调用通过以下代码实际验证 Salesforce API:
var CLIENT_ID = {I get this from the connected SalesForce app};
var CLIENT_SECRET = {I get this from the connected SalesForce app};
function getService() {
// Create a new service with the given name. The name will be used when
// persisting the authorized token, so ensure it is unique within the
// scope of the property store.
return OAuth2.createService('salesforce')
// Set the endpoint URLs
.setAuthorizationBaseUrl('https://flolive.my.salesforce.com/services/oauth2/authorize')
.setTokenUrl('https://flolive.my.salesforce.com/services/oauth2/token')
// Set the client ID and secret, from the Google Developers Console.
.setClientId(CLIENT_ID)
.setClientSecret(CLIENT_SECRET)
// Set the name of the callback function in the script referenced
// above that should be invoked to complete the OAuth flow.
.setCallbackFunction('authCallback')
// Set the property store where authorized tokens should be persisted.
.setPropertyStore(PropertiesService.getDocumentProperties())
// .setCache(CacheService.getDocumentCache())
// Set the scopes to request (space-separated for Google services).
// .setScope('r_organization_social,r_basicprofile,r_liteprofile,rw_organization_admin,r_ads_reporting,r_ads')
// Below are salesforce-specific OAuth2 parameters.
.setParam('response_type', 'code')
// Forces the approval prompt every time. This is useful for testing,
// but not desirable in a production application.
//.setParam('approval_prompt', 'force');
}
function authCallback(request) {
var salesforceService = getService();
var isAuthorized = salesforceService.handleCallback(request);
if (isAuthorized) {
return HtmlService.createHtmlOutput('Success! You can close this tab.');
} else {
return HtmlService.createHtmlOutput('Denied. You can close this tab');
}
}
function logOut() {
PropertiesService.getDocumentProperties().deleteAllProperties();
PropertiesService.getUserProperties().deleteAllProperties();
var service=getService();
service.reset();
}
function salesforceAPI() {
var service = getService();
if (service.hasAccess()) {
//exchange authorisation code for access token
// sheet.getSheetByName('Settings').getRange(3,2).setValue(getService().getAccessToken());
var tokenURL = 'https://flolive.my.salesforce.com/services/oauth2/token';
var parameters = 'grant_type=authorization_code&code='+getService().getAccessToken()+'&redirect_uri='+getService().redirect_uri+'&client_id='+CLIENT_ID+'&client_secret='+CLIENT_SECRET;
var options = {
'method': 'POST',
'contentType': 'application/x-www-form-urlencoded',
'muteHttpExceptions': true,
'payload': parameters
}
var response = UrlFetchApp.fetch(tokenURL,options);
var json = JSON.parse(response.getContentText());
console.log(json);
//sheet.getSheetByName('Settings').getRange(3,3).setValue(json.items);
return json;
} else {
var authorizationUrl = service.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();
SpreadsheetApp.getUi().showModalDialog(page,'Authorise salesforce');
Logger.log(getService().getAccessToken());
}
}
现在我对此没有问题。我打的所有电话都有效。我在连接的应用程序中检查了回调url,一切正常。
当我尝试将一些数据输出到不同的工作表时,一切都停止了。
所以现在我有 2 个工作表。
SF API 后端 - 这是我放置 API 所有设置和参考的地方 记录的会议 - 这是我输出我试图提取的数据的地方,这些数据是活动。
起初一切正常,我可以正常输出。但是,当我添加 API 后端工作表时,起初它不起作用。我没有收到任何错误,也没有收到任何数据。
我以为是因为它需要一个不同的回调url,所以我添加了它。然后,出于某种原因,我使用了上面提到的 logOut() 函数来尝试重置连接。 那是我开始收到此错误的时候 错误:访问未被授予或已过期。 Service_.getAccessToken@Service.gs:466.
我上网查了下,觉得跟PropertyService
有关系。所以我删除了所有 PropertyService
键。我什至将 getService()
函数从 .setPropertyStore(PropertiesService.getDocumentProperties())
切换到 .setCache(CacheService.getDocumentCache())
(现在已被注释掉)。
还是一样的错误。
然后我进入 Salesforce 并获得一个设置的访问令牌并用它替换 +getService().getAccessToken()
。
我收到此错误 TypeError: 无法读取未定义的 属性 'setClientId' 在 getService(SalesForceAuthentication:15:7) 在 salesforceAPI(SalesForceAuthentication:56:17)
我不确定为什么会出现该错误,因为我更改的代码甚至不在该函数中。
这就是我目前所在的位置。
我没有看到任何被列入黑名单的内容或任何会混淆或阻止它的设置。
我什至尝试重建整个东西,然后将代码(仅代码)复制到不同的脚本。我得到了同样的错误 错误:访问未被授予或已过期。 Service_.getAccessToken@Service.gs:466.
这让我认为客户端 Secret/Client Id 以某种方式被阻止。
问题:
当您使用getDocumentProperties()存储授权数据时:
Gets a property store (for this script only) that all users can access within the open document, spreadsheet, or form
如果您使用与存储数据的电子表格不同的电子表格,则数据不可用。
解决方案:
如果您希望它适用于多个电子表格,请改用 getScriptProperties() or getUserProperties(),它可以保留在多个文档上(仅当您使用相同的脚本时)。
.setPropertyStore(PropertiesService.getScriptProperties())