Google应用脚本执行API服务授权每小时失败一次

Coe*_*aar 5 c# google-apps-script google-oauth execution-api

我每隔1.5分钟就用我的C#app执行一次Google应用程序脚本.应用脚本在电子表格和编辑表单之间移动内容.我也使用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;

        }

    }
}
Run Code Online (Sandbox Code Playgroud)

我得到这样的服务:

 var credential = Authentication.getCredential(CLIENT_ID, CLIENT_SECRET, Environment.UserName);
 DriveService driveService = Authentication.DriveAuthenticateOauth(credential);
 ScriptService scriptService = Authentication.ScriptsAuthenticateOauth(credential);
Run Code Online (Sandbox Code Playgroud)

但是在一小时结束时,应用程序脚本调用会引发以下错误:

Script error message: Authorization is required to perform that action.
Run Code Online (Sandbox Code Playgroud)

需要明确的是,它可以在其他所有时间运行,而不是在接近结束时的那5分钟内.我确实在我的开发人员控制台上以及在应用程序脚本编辑器中的资源>高级Google服务...下激活了Google Drive API.

那么发生了什么?这可以修复吗?

Coe*_*aar 2

经过进一步研究,我发现只需从脚本编辑器运行该脚本即可防止此错误。这是我找到的信息:

执行该操作需要授权。

此错误表明该脚本缺少运行所需的授权。当脚本在脚本编辑器中或从自定义菜单项运行时,会向用户显示授权对话框。但是,当脚本作为服务运行、嵌入 Google 协作平台页面或从触发器运行时,无法显示对话框并显示此错误。要授权脚本,请打开脚本编辑器并运行任何函数。为了避免此错误,请记住在向脚本添加新服务或功能后在脚本编辑器中运行脚本一次。

来源: 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);
Run Code Online (Sandbox Code Playgroud)

对此:

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);
Run Code Online (Sandbox Code Playgroud)

这本身并没有解决我的问题,但它有助于避免 OAuth 怪癖,并且可以防止不必要的令牌刷新。