Como se autenticar programaticamente ao executar um aplicativo da Web do Apps Script de outro projeto do Apps Script
Eu sou novo no Apps Script e estou tentando entender os fundamentos da execução / acionamento de um script em uma conta usando outra. Com apenas uma ressalva: gostaria de executar o script com o usuário acessando o script em vez de o usuário possuir o script - a fim de atribuir o tempo de execução ao usuário acessando.
No entanto, estou tendo os seguintes problemas.
Começando com uma planilha de teste com compartilhamento definido como Qualquer pessoa com link pode editar e o seguinte código na página do projeto de script:
function doPost(e){
var sheet = SpreadsheetApp.openById('1tWV6ELJEGkWkSXvdf9kQemvH-tDVTx0od4JHht2ZBeU');
var tab = sheet.getSheetByName('ref');
tab.getRange(1,1).setValue(new Date());
return ContentService.createTextOutput(0)
}
function doGet(e){
return doPost(e)
}
e ter publicado o projeto como um aplicativo da Web com execução definida para acesso do usuário e acesso habilitado para qualquer pessoa. Inserir o seguinte link no navegador preenche manualmente a célula A1 com a hora atual e a página exibindo '0', conforme pretendido,
https://script.google.com/macros/s/AKfycbwNhYg1BRKi38pNf_z0peGuYt6gsqvauCvo-eiGgCYJJk4QDpjm/exec
SE eu entrar no link enquanto ainda estiver conectado com a conta que criou o SpreadSheet de teste.
Se eu entrar no link com um navegador diferente sem o login do GSuite, sou obrigado a fazer o login, o que também é o esperado. Afinal, uma conta do G Suite é necessária para executar o script por implantação do Web App.
No entanto, quando tentei acionar o script usando uma conta GSuite diferente e um projeto do Apps Script, ainda encontrei a página de login e também outros problemas. Fora de
function test1(){
const scriptURL='https://script.google.com/macros/s/AKfycbwNhYg1BRKi38pNf_z0peGuYt6gsqvauCvo-eiGgCYJJk4QDpjm/exec';
var response = UrlFetchApp.fetch(scriptURL)
Logger.log(response.getContentText())
}
function test2(){
const scriptURL='https://script.google.com/macros/s/AKfycbxay75fTBt3doTyMFUPK0-GpK9hMZ4hVkYdiwYUBMhPfEN6hUJH/exec';
var response = UrlFetchApp.fetch(scriptURL, {
method:'POST',
payload:'nothing'
});
Logger.log(response.getContentText())
}
function test3() {
var sheet = SpreadsheetApp.openById('AKfycbwNhYg1BRKi38pNf_z0peGuYt6gsqvauCvo-eiGgCYJJk4QDpjm');
Logger.log(sheet.getName());
}
function test4() {
var token = ScriptApp.getOAuthToken();
const scriptURL='https://script.google.com/macros/s/AKfycbxay75fTBt3doTyMFUPK0-GpK9hMZ4hVkYdiwYUBMhPfEN6hUJH/exec';
var response = UrlFetchApp.fetch(scriptURL, {
headers: {Authorization:'Bearer '+ token},
method:'GET',
payload:'nothing'
});
Logger.log(response.getContentText())
}
test1() produz um longo corpo de texto no Log começando com
Logging output too large. Truncating output.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta content="width=300, initial-scale=1" name="viewport">
<meta name="google-site-verification" content="LrdTUW9psUAMbh4Ia074-BPEVmcpBxF6Gwf0MSgQXZs">
<title>Sign in - Google Accounts</title>
<style>
e test2()retorna um erro
Exception: Request failed for https://script.google.com returned code 401. Truncated server response: <!DOCTYPE html><html lang="en"><head><meta name="description" content="Web word processing, presentations and spreadsheets"><meta name="viewport" c... (use muteHttpExceptions option to examine full response)
at test2(Code:23:30)
Nenhum dos testes acionou o script, doPost(e)pois a célula A1 não foi atualizada.
test1()parece encontrar a página de login. No entanto, ao mesmo tempo, test1()é executado por meio de uma conta do G Suite de login.
Também pode ser importante observar que test3()é possível acessar o arquivo Google SpreadSheet em questão. Eu também tentei ligar ScriptApp.getOAuthToken()porque não. test4()tem a mesma resposta que test1().
Não sei por onde começar a diagnosticar o erro encontrado em test2().
Como faço para contornar a página de login?
Em particular, há uma maneira de tornar o script acessível por qualquer outra conta do GSuite com permissão de acesso ao Google SpreadSheet em questão e executado pelo usuário que acessa em vez do usuário que possui o SpreadSheet?
O que estou fazendo de errado com a versão POST?
Qualquer ajuda é necessária!
Respostas
A partir de sua pergunta, entendi sua situação da seguinte maneira.
- O script de Web Apps é colocado no script de contêiner da planilha de
1tWV6ELJEGkWkSXvdf9kQemvH-tDVTx0od4JHht2ZBeU. - A planilha é compartilhada a partir
Anyone with the linkdeeditor. - Os aplicativos da Web são implantados como
Execute the app as: User accessing the web appseWho has access to the app: Anyone.
Esta resposta supõe meu entendimento acima. Então, quando meu entendimento não estiver correto, por favor me diga.
Pontos de modificação:
- Em
UrlFetchApp, quandopayload:'nothing'é usado, ele solicita como método POST mesmo quandomethod:'GET'é usado. Por favor, tome cuidado com isso. - Em seu script de Web Apps usa o escopo de
https://www.googleapis.com/auth/spreadsheets. Nesse caso, em um primeiro momento, é necessário autorizar o escopo pelo próprio navegador (o navegador de cada usuário). Quando isso não é feito, mesmo quando o script e o token de acesso com os escopos do lado do cliente estão corretos,Authorization neededocorre um erro de . Por favor, tome cuidado com isso. Parece que esta é a especificação atual. - Se todo o script (
test1totest4) do lado do cliente for o script da sua pergunta, os escopos serãohttps://www.googleapis.com/auth/script.external_requestehttps://www.googleapis.com/auth/spreadsheets. Acho que o escopo não é suficiente para solicitar os Web Apps. Neste caso, por exemplo, adicione// DriveApp.getFiles()ao editor de script. Com isso, o escopo dehttps://www.googleapis.com/auth/drive.readonlyé adicionado automaticamente pelo editor de script e esse escopo pode ser usado para solicitar aplicativos da Web. Além disso, você pode usar o escopo dehttps://www.googleapis.com/auth/drive.- No caso de escopos de
https://www.googleapis.com/auth/script.external_requestehttps://www.googleapis.com/auth/spreadsheets,Unauthorizedocorre um erro de .
- No caso de escopos de
Quando os pontos acima são refletidos em sua situação, torna-se o seguinte.
Uso:
1. Prepare o lado dos aplicativos da Web. (lado do servidor)
Nesse caso, acho que suas configurações podem ser usadas. Reimplante os aplicativos da Web como uma nova versão para o caso. E confirme o URL dos aplicativos da Web novamente.
2. Prepare o lado do cliente.
Acesse
https://script.google.com/macros/s/AKfycbxay75fTBt3doTyMFUPK0-GpK9hMZ4hVkYdiwYUBMhPfEN6hUJH/execusando o próprio navegador (lado do usuário.) E autorize os escopos de Web Apps.Eu gostaria de propor a modificação
test4()de seu script da seguinte maneira.function test4() { var token = ScriptApp.getOAuthToken(); const scriptURL='https://script.google.com/macros/s/AKfycbxay75fTBt3doTyMFUPK0-GpK9hMZ4hVkYdiwYUBMhPfEN6hUJH/exec'; var response = UrlFetchApp.fetch(scriptURL, { headers: {Authorization:'Bearer '+ token}, method: 'GET', // payload:'nothing', muteHttpExceptions: true }); Logger.log(response.getContentText()) // DriveApp.getFiles() // This is used for adding a scope of https://www.googleapis.com/auth/drive.readonly. This is used for requesting to Web Apps. }Por favor, corra
test4(). Por isso,0é retornado de Web Apps e você pode vê-lo no log.
Referências:
- Aproveitando as vantagens do Web Apps com o Google Apps Script
- buscar (url, params)