我每1.5分钟用我的C#应用程序执行一次谷歌应用程序脚本。应用程序脚本将内容在电子表格和编辑工作表之间移动。我还使用了驱动API。
我的脚本运行时间很长,除了每小时有5分钟的授权错误之外。
下面是我处理授权的代码:
class Authentication
{
public static ScriptService ScriptsAuthenticateOauth(UserCredential credential)
{
try
{
ScriptService service = new ScriptService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = "MyApp",
});
return service;
}
catch (Exception ex)
{
Console.WriteLine(DateTime.Now.ToString("HH:mm") + ": An authentication error occurred: " + ex.InnerException);
return null;
}
}
public static UserCredential getCredential(string clientId, string clientSecret, string userName)
{
string[] scopes = new string[] { DriveService.Scope.Drive, // view and manage your files and documents
DriveService.Scope.DriveAppdata, // view and manage its own configuration data
DriveService.Scope.DriveAppsReadonly, // view your drive apps
DriveService.Scope.DriveFile, // view and manage files created by this app
DriveService.Scope.DriveMetadataReadonly, // view metadata for files
DriveService.Scope.DriveReadonly, // view files and documents on your drive
DriveService.Scope.DriveScripts, // modify your app scripts
ScriptService.Scope.Drive,
"https://www.googleapis.com/auth/spreadsheets",
"https://spreadsheets.google.com/feeds",
"https://docs.google.com/feeds"};
return GoogleWebAuthorizationBroker.AuthorizeAsync(new ClientSecrets { ClientId = clientId, ClientSecret = clientSecret }
, scopes
, userName
, CancellationToken.None
, new FileDataStore("Google.Sheet.Sync.Auth.Store")).Result;
}
public static DriveService DriveAuthenticateOauth(UserCredential credential)
{
try
{
DriveService service = new DriveService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = "MyApp",
});
// Console.WriteLine("Auth success");
return service;
}
catch (Exception ex)
{
// Console.WriteLine(ex.InnerException);
Console.WriteLine(DateTime.Now.ToString("HH:mm") + ": An authentication error occurred: " + ex.InnerException);
return null;
}
}
}我得到这样的服务:
var credential = Authentication.getCredential(CLIENT_ID, CLIENT_SECRET, Environment.UserName);
DriveService driveService = Authentication.DriveAuthenticateOauth(credential);
ScriptService scriptService = Authentication.ScriptsAuthenticateOauth(credential);但是,大约在一小时结束时,应用程序脚本调用会引发以下错误:
Script error message: Authorization is required to perform that action.我想说清楚的是,它总是在其他时间起作用,只是在接近尾声的那5分钟里就不行了。我在我的开发者控制台上激活了Google,在参考资料>高级Google服务下.在应用程序脚本编辑器。
那是怎么回事?能修好吗?
发布于 2015-11-16 09:24:14
在做了进一步的研究后,我发现脚本只需要从脚本编辑器中运行来防止这个错误。这是我发现的信息:
需要授权才能执行该操作. 此错误表示脚本缺乏运行所需的授权。在脚本编辑器或自定义菜单项中运行脚本时,将向用户显示授权对话框。但是,当脚本作为服务运行、嵌入Google站点页面或从触发器运行时,无法显示对话框并显示此错误。若要授权脚本,请打开“脚本编辑器”并运行任何函数。若要避免此错误,请记住在向脚本中添加新服务或功能后,在脚本编辑器中运行脚本一次。
来源:错误
我对代码进行的另一个相关改进是在创建这两个服务之前获取凭据对象的一个新副本:换句话说,我更改了以下内容:
var credential = Authentication.getCredential(CLIENT_ID, CLIENT_SECRET, Environment.UserName);
DriveService driveService = Authentication.DriveAuthenticateOauth(credential);
ScriptService scriptService = Authentication.ScriptsAuthenticateOauth(credential);对此:
var credential = Authentication.getCredential(CLIENT_ID, CLIENT_SECRET, Environment.UserName);
DriveService driveService = Authentication.DriveAuthenticateOauth(credential);
credential = Authentication.getCredential(CLIENT_ID, CLIENT_SECRET, Environment.UserName);
ScriptService scriptService = Authentication.ScriptsAuthenticateOauth(credential);这本身并没有解决我的问题,但它有助于避免OAuth怪癖,并且可以防止不必要的令牌刷新。
发布于 2015-11-16 21:21:08
您可能需要一个刷新令牌。访问令牌通常从Google设置为3600 s(1小时),而刷新令牌的生存期要长得多,并且在上一个令牌过期时可以轻松地获得新的访问令牌。这可能是一个很好的起点:关于令牌响应的Google .NET客户端信息
另外,如果您没有刷新令牌,但确实有访问令牌,则可以撤消先前的访问令牌,然后再进行身份验证。如果正确调用,新响应将具有一个刷新令牌“确保您得到的是"Bearer"令牌类型)。
有关于使用更长寿命的刷新令牌这里的更多信息。
发布于 2016-10-20 09:21:48
如果您的应用程序“在接近小时结束的5分钟内”失败,那么您很可能遇到了这个带有执行API的错误。
显然,对带有令牌的执行API的请求将在6分钟内到期,给出“需要授权.”。错误。这似乎与脚本的最大运行时间为6分钟这一事实有关。
解决办法是提前刷新令牌,如果您知道令牌何时到期(在Android上不是这样)。希望窃听器很快就能修好。
我不确定你是否真的解决了你的问题,或者你刚刚找到了一个很好的解决办法,但是你可能想把这个应用程序脚本问题作为主角,这样它就可以尽快解决了。
https://stackoverflow.com/questions/33362036
复制相似问题