Autorizações da API do Google Apps Script para DriveApp.getFileById
Tenho um projeto do Google Cloud Platform (GCP) que executa quase todos os scripts / funções diretamente, mas alguns por meio de uma API. Tudo está acessível apenas internamente para o domínio do G Suite, e o tipo de aplicativo da tela de consentimento do OAuth é "Interno".
Eu tenho um script, que não é chamado por meio de uma API, mas diretamente em um cronômetro a cada x minutos. Executa um
DriveApp.getFileByID(pictureID)
Isso funciona muito bem! Sem problemas.
Também tenho um script diferente, no mesmo projeto do GCP, que em vez de ser acionado por um temporizador, é executado por meio de uma API. Aqui está a linha de código que o chama (não é muito importante):
var result = UrlFetchApp.fetch(url, options);
O script da API funciona muito bem! Até chegar às seguintes linhas:
try { var file = DriveApp.getFileById(pictureID); }
catch (e) {
Logger.log('e = ' + JSON.stringify(e));
return;
}
O resultado do log é
e = {"name":"Exception"}
Verifiquei que o pictureID é o mesmo do script não API que funciona. Estou fazendo uma "tentativa" neste script executado por API para ter certeza de que o software tem acesso ao arquivo, não para acessá-lo de fato.
Tenho certeza de que este é um problema de autorização. Eu uso o GCP há pouco tempo, tenho alguma experiência com autorizações, mas não muita.
Aqui estão alguns detalhes sobre as autorizações ...
Os scripts do projeto Propriedades do projeto (Arquivo / Propriedades do projeto) mostram que são necessários os seguintes escopos OAuth:
De acordo com a documentação do Google em https://developers.google.com/apps-script/reference/drive/drive-app#getfilebyidid,
Scripts that use this method require authorization with one or more of the following scopes:
https://www.googleapis.com/auth/drive.readonly
https://www.googleapis.com/auth/drive
Aqui estão os escopos que defini agora na tela de consentimento do GCP Oauth:
Como você pode ver, adicionei drive, drive.readonly e drive.file (que realmente não parece ser necessário).
Além de tudo isso, esse arquivo de imagem específico é armazenado no Google Drive do proprietário do projeto GCP, scripts e administrador de nível superior do domínio do G Suite. Isso nem sempre será o caso, pois os usuários compartilharão imagens de seu próprio Google Drive com este proprietário de software / GCP. No entanto, tenho a sensação de que mesmo agora o script disparado por um cronômetro funcionaria com esses arquivos compartilhados pelo usuário, mas não o script chamado por meio de uma API.
Tenho certeza de que é um problema do Auth, mas estou perdendo algo em algum lugar.
Obrigado pela ajuda!
Atualizar:
Aqui está o código do script que CHAMA o script da API (mudou alguns para confidencialidade), pois estou me perguntando se talvez o problema não esteja no lado do cliente / chamada. Talvez eu não esteja obtendo o OAuthToken corretamente? Ou o token não tem as permissões corretas?
var token = ScriptApp.getOAuthToken();
var header = {
"Content-Type": "application/json",
"Authorization": "Bearer " + token,
};
var parms = [id];
var data = {
"function": "updateSettings",
"parameters": parms,
"devMode": true,
}
var options = {
"method":"POST",
"headers": header,
"muteHttpExceptions": true,
"payload": JSON.stringify(data)
};
// Call the API
var result = UrlFetchApp.fetch(url, options);
Respostas
Descobri isso depois de entrar em contato com o Google e, infelizmente, não obtendo muita ajuda e mais algumas horas de tentativas e pesquisas ...
O que estava faltando era adicionar "oathScopes" ao arquivo manifest / appsscript.json. Eu brinquei com os escopos necessários e acabei com os dois a seguir mostrados abaixo. Eu descobri a solução olhando para esta resposta: Usando AuthToken obtido via ScriptApp.getAuthToken () para chamar aplicativos da web no GAS .
Dentro do editor de script, vá para Exibir / Mostrar arquivo de manifesto.
Aqui está o que parecia antes:
{
"timeZone": "America/New_York",
"dependencies": {
},
"webapp": {
"access": "MYSELF",
"executeAs": "USER_DEPLOYING"
},
"exceptionLogging": "STACKDRIVER",
"runtimeVersion": "V8"
}
e aqui está o que parece agora ...
{
"timeZone": "America/New_York",
"dependencies": {
},
"webapp": {
"access": "MYSELF",
"executeAs": "USER_DEPLOYING"
},
"exceptionLogging": "STACKDRIVER",
"runtimeVersion": "V8",
"oauthScopes": [
"https://www.googleapis.com/auth/drive",
"https://www.googleapis.com/auth/script.external_request"
]
}
Depois de adicionar, salvei appsscript.json. Em seguida, fui até o gatilho runOnEdit (o script de chamada), removi e adicionei novamente. No entanto, isso causou um erro de aparência desagradável:
Eu pesquisei e encontrei este post: Recebendo erro ao criar um novo gatilho no Apps Script . Então, executei o código no editor de script e, de fato, ele trouxe a tela de autenticação. Eu aprovei, readicionei a trigger, e agora tudo funciona muito bem na chamada da API!