2015-10-27 18 views
5

我每隔1.5分鐘執行一次我的C#應用​​程序的Google應用程序腳本。應用程序腳本在電子表格之間移動內容,並編輯表單。我也使用Drive API。谷歌應用程序腳本執行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分鐘內n一小時結束。我在我的開發人員控制檯上以及在應用腳本編輯器中的Resources> Advanced Google services ...下激活了Google Drive API。

那麼是怎麼回事?這可以解決嗎?

+1

似乎你傳遞了一個過期的訪問令牌。如果是這樣,請閱讀oauth2以及如何處理刷新和訪問令牌。 –

回答

2

經過進一步的研究,我發現腳本只是需要從腳本編輯器運行以防止出現此錯誤。這是我找到的信息:

Authorization is required to perform that action.

This error indicates that the script is lacking the authorization needed to run. When a script is run in the Script Editor or from a custom menu item an authorization dialog is presented to the user. However, when a script is run as a service, embedded with a Google Sites page, or run from a trigger the dialog cannot be presented and this error is shown. To authorize the script, open the Script Editor and run any function. To avoid this error, remember to run the script once in the Script Editor after adding new services or capabilities to your script.

來源:https://developers.google.com/apps-script/troubleshooting#common_errors

另一個相關改進我對代碼所做的,是爲了獲取證書的全新副本創建各2個服務之前對象:在其他也就是說,我改變了這個:

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怪癖,並且可以防止不必要的令牌刷新。

0

您可能需要刷新令牌。訪問令牌的設置一般只能在Google上運行3600秒(1小時),而刷新令牌的壽命要更長一些,旨在讓您在前一個令牌到期時輕鬆獲得新的訪問令牌。這可能是一個很好的開始:Google API .NET Client information on token responses

另外,如果您沒有刷新令牌,但您確實有訪問令牌,則可以撤銷先前的訪問令牌,然後再次進行驗證。新的響應將有如果調用正確刷新令牌「請確保你得到一個"Bearer"令牌類型)。

有關於使用不在人世刷新令牌here更多的信息。

0

如果您的應用程序失敗」只是在接近小時結束的5分鐘內「,您很可能遇到了this bug with the execution API

顯然,使用將在6分鐘內過期的令牌的執行API請求會給出」授權是必需的...「錯誤。這似乎與6分鐘是腳本的最大運行時間有關。

解決方法是事先刷新您的令牌,如果您知道何時會過期(Android上不是這種情況)。希望這個錯誤很快就會解決。

我不確定您是否設法真正解決了您的問題,或者您是否找到了一個很好的解決方法,但是您可能想要明確該Apps Script問題,以便它可以儘快修復。

相關問題