我大约每1.5分钟使用C#应用程序执行一次Google Apps脚本。apps脚本在电子表格之间移动内容,并编辑工作表。我也使用Drive 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);
但是大约一小时后,apps脚本调用将引发以下错误:
Script error message: Authorization is required to perform that action.
需要明确的是,它在所有其他时间都起作用,而并非在小时结束时的那5分钟内起作用。我确实在开发人员控制台和应用程序脚本编辑器中的资源>高级Google服务...下都激活了Google Drive API。
那么发生了什么?这个可以解决吗?
经过进一步研究,我发现只需从脚本编辑器运行脚本即可防止此错误。这是我发现的信息:
需要授权才能执行该操作。
此错误表明脚本缺少运行所需的授权。在脚本编辑器中或从自定义菜单项中运行脚本时,将向用户显示授权对话框。但是,当脚本作为服务运行,嵌入到Google Sites页面或从触发器运行时,将无法显示对话框,并显示此错误。要授权脚本,请打开脚本编辑器并运行任何功能。为避免此错误,请记住在向脚本添加新的服务或功能之后,在脚本编辑器中运行一次脚本。
来源:https://developers.google.com/apps-script/troubleshooting#common_errors
我对代码进行的另一个相关改进是在创建两个服务中的每一个之前获取凭据对象的新副本:换句话说,我对此进行了更改:
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怪癖,并可以防止不必要的令牌刷新。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句