L'API Google Apps Script fornisce un'interfaccia
Metodo scripts.run
che esegue da remoto una funzione Apps Script specificata. Puoi usare questo metodo
in un'applicazione di chiamata per eseguire una funzione in uno dei tuoi progetti di script
da remoto e ricevere una risposta.
Requisiti
Devi soddisfare i requisiti seguenti prima che un'applicazione di chiamata possa utilizzare
scripts.run
. Devi:
Esegui il deployment del progetto script come eseguibile dell'API. Puoi eseguire il deployment, annullare il deployment e rieseguire il deployment dei progetti in base alle esigenze.
Fornisci un token OAuth con ambito corretto per l'esecuzione. Questo token OAuth deve coprire tutti gli ambiti utilizzati dallo script, non solo quelli utilizzati dalla funzione chiamata. Consulta le elenco completo degli ambiti di autorizzazione nel riferimento al metodo.
Assicurati che lo script e il metodo OAuth2 dell'applicazione chiamante condividono un progetto Google Cloud comune. Il progetto Cloud deve essere un progetto Cloud standard. i progetti predefiniti creati per i progetti Apps Script non sono sufficienti. Puoi usare un progetto Cloud nuovo standard o uno esistente.
Abilitare l'API Google Apps Script nel progetto Cloud.
Il metodo scripts.run
La scripts.run
richiede informazioni che consentono l'identificazione della chiave per essere eseguito:
- L'ID del progetto di script.
- Il nome della funzione da eseguire.
- L'elenco di parametri richieste dalla funzione (se presenti).
Facoltativamente, puoi configurare lo script in modo che venga eseguito in modalità sviluppo.
Questa modalità viene eseguita con la versione salvata più recente del progetto di script
rispetto all'ultima versione di cui è stato eseguito il deployment. Per farlo, imposta il parametro
devMode
booleano nel campo
corpo della richiesta
a true
. Solo il proprietario dello script può eseguirlo in modalità sviluppo.
Gestione dei tipi di dati dei parametri
Utilizzo dell'API Apps Script
Metodo scripts.run
di solito comporta l'invio di dati ad Apps Script come parametri di funzione e
la restituzione dei dati come funzione restituisce valori. L'API può accettare e restituire solo
valori con tipi base: stringhe, array, oggetti, numeri e booleani. Questi
sono simili ai tipi base in JavaScript. Più complesso
Oggetti Apps Script come Documento
o Foglio non può essere passato
o dal progetto di script da parte dell'API.
Quando l'applicazione di chiamata è scritta in un linguaggio di tipo molto forte come
Java, passa i parametri come un elenco o un array di oggetti generici
corrispondenti a questi tipi di base. In molti casi, puoi applicare semplici
tipi automaticamente di conversione. Ad esempio, una funzione che prende un numero
può essere assegnato un oggetto Java Double
, Integer
o Long
come
senza ulteriori passaggi di gestione.
Quando l'API restituisce la risposta di funzione, spesso devi trasmettere il token al tipo corretto prima di poterlo utilizzare. Ecco alcuni esempi Esempi basati su Java:
- I numeri restituiti dall'API a un'applicazione Java vengono inviati come
java.math.BigDecimal
oggetti che potrebbero dover essere convertiti in Tipi di oggettoDoubles
oint
a seconda delle esigenze. Se la funzione Apps Script restituisce un array di stringhe, un'applicazione Java trasmette la risposta in un oggetto
List<String>
:List<String> mylist = (List<String>)(op.getResponse().get("result"));
Se vuoi restituire un array di
Bytes
, potrebbe essere utile per codificare l'array come stringa base64 all'interno della funzione Apps Script e restituiscono invece quella stringa:return Utilities.base64Encode(myByteArray); // returns a String.
Gli esempi di codice di esempio riportati di seguito illustrano alcuni modi di per interpretare la risposta dell'API.
Procedura generale
Di seguito viene descritta la procedura generale per l'utilizzo dell'API Apps Script per eseguire le funzioni di Apps Script:
Passaggio 1: configura il progetto Cloud comune
Sia lo script che l'applicazione di chiamata devono condividere lo stesso progetto cloud. Il progetto Cloud può essere un progetto esistente è stato creato un nuovo progetto per questo scopo. Una volta creato un progetto Cloud, devi cambiare il progetto di script per utilizzarlo.
Passaggio 2: esegui il deployment dello script come eseguibile dell'API
- Apri il progetto Apps Script con le funzioni che vuoi utilizzare.
- In alto a destra, fai clic su Esegui il deployment > Nuovo deployment.
- Nella finestra di dialogo che si apre, fai clic su Abilita tipi di deployment
> Eseguibile API.
- Nella sezione "Chi ha accesso" menu a discesa, seleziona gli utenti che possono chiamare le funzioni dello script utilizzando l'API Apps Script.
- Fai clic su Esegui il deployment.
Passaggio 3: configura l'applicazione di chiamata
L'applicazione chiamante deve abilitare l'API Apps Script e stabilire OAuth crendenti prima di poter essere utilizzato. Devi avere accesso al progetto Cloud per eseguire questa operazione.
- Configura il progetto Cloud utilizzato dall'applicazione e dallo script di chiamata. Per farlo:
- Apri il progetto dello script e fai clic su Panoramica
a sinistra.
- In Ambiti OAuth del progetto, registra tutti gli ambiti che come richiesto dallo script.
Nel codice dell'applicazione chiamante, genera un token di accesso OAuth per lo script per la chiamata API. Non si tratta di un token utilizzato dall'API stessa, ma di uno durante l'esecuzione. Dovrebbe essere creato utilizzando L'ID client del progetto Cloud e gli ambiti dello script che hai registrato.
Le librerie client di Google possono è utile per creare questo token e gestire OAuth per l'applicazione, che di solito consentono di creare "credenziali" di livello più alto oggetto utilizzando gli ambiti degli script. Consulta le Guide rapide per l'API Apps Script per gli esempi della creazione di un oggetto credenziali da un elenco di ambiti.
Passaggio 4: effettua la richiesta script.run
Dopo aver configurato l'applicazione di chiamata, puoi
scripts.run
chiamate. Ogni API
prevede i seguenti passaggi:
- Crea una richiesta API utilizzando l'ID script, il nome della funzione e qualsiasi altra parametri.
- Rendi
scripts.run
e includere il token OAuth dello script che hai creato nel intestazione (se utilizzi una richiestaPOST
di base) oppure utilizza un oggetto credenziali creato con gli ambiti degli script. - Consenti il completamento dell'esecuzione dello script. Gli script possono richiedere fino a di sei minuti, quindi la tua applicazione dovrebbe consentire questa operazione.
- Al termine, la funzione script può restituire un valore, che l'API invia nuovamente l'app all'applicazione se il valore è un tipo supportato.
Puoi trovare esempi di chiamate API script.run
di seguito.
Esempi di richieste API
I seguenti esempi mostrano come effettuare una richiesta di esecuzione dell'API Apps Script in
in vari linguaggi, richiamando una funzione Apps Script per stampare un elenco
cartelle nella directory radice dell'utente. L'ID script del progetto Apps Script
contenente la funzione eseguita deve essere specificato dove indicato con
ENTER_YOUR_SCRIPT_ID_HERE
. Gli esempi si basano
Librerie client delle API di Google per i rispettivi
lingue diverse.
Script di destinazione
La funzione in questo script utilizza l'API Drive.
Devi abilitare l'API Drive nella progetto che ospita lo script.
Inoltre, le applicazioni di chiamata devono inviare credenziali OAuth che includono il seguente ambito di Drive:
https://www.googleapis.com/auth/drive
Le applicazioni di esempio qui utilizzate utilizzano le librerie client di Google per creare credenziali per OAuth che utilizzano questo ambito.
/**
* Return the set of folder names contained in the user's root folder as an
* object (with folder IDs as keys).
* @return {Object} A set of folder names keyed by folder ID.
*/
function getFoldersUnderRoot() {
const root = DriveApp.getRootFolder();
const folders = root.getFolders();
const folderSet = {};
while (folders.hasNext()) {
const folder = folders.next();
folderSet[folder.getId()] = folder.getName();
}
return folderSet;
}
Java
/**
* Create a HttpRequestInitializer from the given one, except set
* the HTTP read timeout to be longer than the default (to allow
* called scripts time to execute).
*
* @param {HttpRequestInitializer} requestInitializer the initializer
* to copy and adjust; typically a Credential object.
* @return an initializer with an extended read timeout.
*/
private static HttpRequestInitializer setHttpTimeout(
final HttpRequestInitializer requestInitializer) {
return new HttpRequestInitializer() {
@Override
public void initialize(HttpRequest httpRequest) throws IOException {
requestInitializer.initialize(httpRequest);
// This allows the API to call (and avoid timing out on)
// functions that take up to 6 minutes to complete (the maximum
// allowed script run time), plus a little overhead.
httpRequest.setReadTimeout(380000);
}
};
}
/**
* Build and return an authorized Script client service.
*
* @param {Credential} credential an authorized Credential object
* @return an authorized Script client service
*/
public static Script getScriptService() throws IOException {
Credential credential = authorize();
return new Script.Builder(
HTTP_TRANSPORT, JSON_FACTORY, setHttpTimeout(credential))
.setApplicationName(APPLICATION_NAME)
.build();
}
/**
* Interpret an error response returned by the API and return a String
* summary.
*
* @param {Operation} op the Operation returning an error response
* @return summary of error response, or null if Operation returned no
* error
*/
public static String getScriptError(Operation op) {
if (op.getError() == null) {
return null;
}
// Extract the first (and only) set of error details and cast as a Map.
// The values of this map are the script's 'errorMessage' and
// 'errorType', and an array of stack trace elements (which also need to
// be cast as Maps).
Map<String, Object> detail = op.getError().getDetails().get(0);
List<Map<String, Object>> stacktrace =
(List<Map<String, Object>>) detail.get("scriptStackTraceElements");
java.lang.StringBuilder sb =
new StringBuilder("\nScript error message: ");
sb.append(detail.get("errorMessage"));
sb.append("\nScript error type: ");
sb.append(detail.get("errorType"));
if (stacktrace != null) {
// There may not be a stacktrace if the script didn't start
// executing.
sb.append("\nScript error stacktrace:");
for (Map<String, Object> elem : stacktrace) {
sb.append("\n ");
sb.append(elem.get("function"));
sb.append(":");
sb.append(elem.get("lineNumber"));
}
}
sb.append("\n");
return sb.toString();
}
public static void main(String[] args) throws IOException {
// ID of the script to call. Acquire this from the Apps Script editor,
// under Publish > Deploy as API executable.
String scriptId = "ENTER_YOUR_SCRIPT_ID_HERE";
Script service = getScriptService();
// Create an execution request object.
ExecutionRequest request = new ExecutionRequest()
.setFunction("getFoldersUnderRoot");
try {
// Make the API request.
Operation op =
service.scripts().run(scriptId, request).execute();
// Print results of request.
if (op.getError() != null) {
// The API executed, but the script returned an error.
System.out.println(getScriptError(op));
} else {
// The result provided by the API needs to be cast into
// the correct type, based upon what types the Apps
// Script function returns. Here, the function returns
// an Apps Script Object with String keys and values,
// so must be cast into a Java Map (folderSet).
Map<String, String> folderSet =
(Map<String, String>) (op.getResponse().get("result"));
if (folderSet.size() == 0) {
System.out.println("No folders returned!");
} else {
System.out.println("Folders under your root folder:");
for (String id : folderSet.keySet()) {
System.out.printf(
"\t%s (%s)\n", folderSet.get(id), id);
}
}
}
} catch (GoogleJsonResponseException e) {
// The API encountered a problem before the script was called.
e.printStackTrace(System.out);
}
}
JavaScript
/**
* Load the API and make an API call. Display the results on the screen.
*/
function callScriptFunction() {
const scriptId = '<ENTER_YOUR_SCRIPT_ID_HERE>';
// Call the Apps Script API run method
// 'scriptId' is the URL parameter that states what script to run
// 'resource' describes the run request body (with the function name
// to execute)
try {
gapi.client.script.scripts.run({
'scriptId': scriptId,
'resource': {
'function': 'getFoldersUnderRoot',
},
}).then(function(resp) {
const result = resp.result;
if (result.error && result.error.status) {
// The API encountered a problem before the script
// started executing.
appendPre('Error calling API:');
appendPre(JSON.stringify(result, null, 2));
} else if (result.error) {
// The API executed, but the script returned an error.
// Extract the first (and only) set of error details.
// The values of this object are the script's 'errorMessage' and
// 'errorType', and an array of stack trace elements.
const error = result.error.details[0];
appendPre('Script error message: ' + error.errorMessage);
if (error.scriptStackTraceElements) {
// There may not be a stacktrace if the script didn't start
// executing.
appendPre('Script error stacktrace:');
for (let i = 0; i < error.scriptStackTraceElements.length; i++) {
const trace = error.scriptStackTraceElements[i];
appendPre('\t' + trace.function + ':' + trace.lineNumber);
}
}
} else {
// The structure of the result will depend upon what the Apps
// Script function returns. Here, the function returns an Apps
// Script Object with String keys and values, and so the result
// is treated as a JavaScript object (folderSet).
const folderSet = result.response.result;
if (Object.keys(folderSet).length == 0) {
appendPre('No folders returned!');
} else {
appendPre('Folders under your root folder:');
Object.keys(folderSet).forEach(function(id) {
appendPre('\t' + folderSet[id] + ' (' + id + ')');
});
}
}
});
} catch (err) {
document.getElementById('content').innerText = err.message;
return;
}
}
Node.js
/**
* Call an Apps Script function to list the folders in the user's root Drive
* folder.
*
*/
async function callAppsScript() {
const scriptId = '1xGOh6wCm7hlIVSVPKm0y_dL-YqetspS5DEVmMzaxd_6AAvI-_u8DSgBT';
const {GoogleAuth} = require('google-auth-library');
const {google} = require('googleapis');
// Get credentials and build service
// TODO (developer) - Use appropriate auth mechanism for your app
const auth = new GoogleAuth({
scopes: 'https://www.googleapis.com/auth/drive',
});
const script = google.script({version: 'v1', auth});
try {
// Make the API request. The request object is included here as 'resource'.
const resp = await script.scripts.run({
auth: auth,
resource: {
function: 'getFoldersUnderRoot',
},
scriptId: scriptId,
});
if (resp.error) {
// The API executed, but the script returned an error.
// Extract the first (and only) set of error details. The values of this
// object are the script's 'errorMessage' and 'errorType', and an array
// of stack trace elements.
const error = resp.error.details[0];
console.log('Script error message: ' + error.errorMessage);
console.log('Script error stacktrace:');
if (error.scriptStackTraceElements) {
// There may not be a stacktrace if the script didn't start executing.
for (let i = 0; i < error.scriptStackTraceElements.length; i++) {
const trace = error.scriptStackTraceElements[i];
console.log('\t%s: %s', trace.function, trace.lineNumber);
}
}
} else {
// The structure of the result will depend upon what the Apps Script
// function returns. Here, the function returns an Apps Script Object
// with String keys and values, and so the result is treated as a
// Node.js object (folderSet).
const folderSet = resp.response.result;
if (Object.keys(folderSet).length == 0) {
console.log('No folders returned!');
} else {
console.log('Folders under your root folder:');
Object.keys(folderSet).forEach(function(id) {
console.log('\t%s (%s)', folderSet[id], id);
});
}
}
} catch (err) {
// TODO(developer) - Handle error
throw err;
}
}
Python
import google.auth
from googleapiclient.discovery import build
from googleapiclient.errors import HttpError
def main():
"""Runs the sample."""
# pylint: disable=maybe-no-member
script_id = "1VFBDoJFy6yb9z7-luOwRv3fCmeNOzILPnR4QVmR0bGJ7gQ3QMPpCW-yt"
creds, _ = google.auth.default()
service = build("script", "v1", credentials=creds)
# Create an execution request object.
request = {"function": "getFoldersUnderRoot"}
try:
# Make the API request.
response = service.scripts().run(scriptId=script_id, body=request).execute()
if "error" in response:
# The API executed, but the script returned an error.
# Extract the first (and only) set of error details. The values of
# this object are the script's 'errorMessage' and 'errorType', and
# a list of stack trace elements.
error = response["error"]["details"][0]
print(f"Script error message: {0}.{format(error['errorMessage'])}")
if "scriptStackTraceElements" in error:
# There may not be a stacktrace if the script didn't start
# executing.
print("Script error stacktrace:")
for trace in error["scriptStackTraceElements"]:
print(f"\t{0}: {1}.{format(trace['function'], trace['lineNumber'])}")
else:
# The structure of the result depends upon what the Apps Script
# function returns. Here, the function returns an Apps Script
# Object with String keys and values, and so the result is
# treated as a Python dictionary (folder_set).
folder_set = response["response"].get("result", {})
if not folder_set:
print("No folders returned!")
else:
print("Folders under your root folder:")
for folder_id, folder in folder_set.items():
print(f"\t{0} ({1}).{format(folder, folder_id)}")
except HttpError as error:
# The API encountered a problem before the script started executing.
print(f"An error occurred: {error}")
print(error.content)
if __name__ == "__main__":
main()
Limitazioni
L'API Apps Script presenta diverse limitazioni:
Un progetto Cloud comune. Lo script chiamato e lo script per le applicazioni deve condividere un progetto Cloud. Il progetto Cloud deve essere un progetto Cloud standard; i progetti predefiniti creati per i progetti Apps Script non sono sufficienti. La può essere un progetto nuovo o uno esistente.
Parametri di base e tipi restituiti. L'API non può passare o restituire Oggetti specifici di Apps Script (ad esempio Documenti, Blob Calendari, file di Drive e così via) nella un'applicazione. Solo i tipi base come stringhe, array, oggetti, numeri e possono essere passati e restituiti valori booleani.
Ambiti OAuth. L'API può eseguire solo script con almeno un ambito obbligatorio. Questo significa che non puoi utilizzare l'API per chiamare uno script che non richiede l'autorizzazione di uno o più servizi.
Nessun trigger.L'API non può creare Apps Script attivatori.