"Requested entity was not found." - Apps Script Execution API error

15,849

Solution 1

The issue was not with the configuration of Apps Script or the App Engine project. I was creating a GoogleCredential object in the @PostConstruct method and set the refresh tokens (credential.setRefreshToken()) from the list of pre-generated tokens before invoking the Apps Script. Even though I had created the refresh tokens for the same set of Client ID and Client Secret, I was getting the error. So, I am creating multiple GoogleCredential objects as the number of refresh tokens and not re-use the credentials object across multiple refresh tokens.

private GoogleCredential[] credentials;

@PostConstruct
private void createGoogleCredential() throws Exception {
    jsonFactory = JacksonFactory.getDefaultInstance();
    httpTransport = GoogleNetHttpTransport.newTrustedTransport();

    String[] refreshTokens = commaDelimitedListToStringArray(refreshTokensProp);
    numOfUsers = refreshTokens.length;

    credentials = new GoogleCredential[numOfUsers];
    for (int i=0; i<numOfUsers; i++) {
        GoogleCredential credential = new GoogleCredential.Builder()
                                        .setTransport(httpTransport)
                                        .setJsonFactory(jsonFactory)
                                        .setClientSecrets(clientId, clientSecret)
                                        .build();

        credential.setRefreshToken(refreshTokens[i]);

        credentials[i] = credential;
    }

    scriptIds = commaDelimitedListToStringArray(scriptsIdsProp);
}

Solution 2

You are deploying Execution API to a project of the standalone script type or the container-bound script type. And you call the function in the project using the API. Under the situation, the error of Requested entity was not found. occurs. If my understanding is correct, I had also experienced the same situation. So how about confirming the following points?

  1. Using the save button, save the project which is deploying API executable again.
    • This was very important for me.
  2. Save the project as a new version, and redeploy the API.
  3. Whether the client ID and client secret are retrieved from the project that Apps Script API is used.
    • Whether the access token is retrieved from these client ID and client secret.
  4. Whether the scope includes https://www.googleapis.com/auth/drive, https://www.googleapis.com/auth/drive.scripts and https://www.googleapis.com/auth/script.external_request.
  5. Whether Execution API is enabled.

If you want to simply test using curl command, you can also use the following command.

curl -X POST -L \
    -H "Authorization: Bearer ### access token ###" \
    -H "Content-Type: application/json" \
    -d "{function: '### function name ###',devMode: true}" \
    "https://script.googleapis.com/v1/scripts/### script ID ###:run"

After confirmed above points, please try again. If these were not useful for you, I'm sorry. Or if I misunderstand your question, I'm really sorry.

Share:
15,849
Mithun
Author by

Mithun

My linkedin profile: https://www.linkedin.com/in/mithungooty

Updated on June 26, 2022

Comments

  • Mithun
    Mithun about 2 years

    We have an Apps Script that is installed in five G Suite accounts. I am invoking the app scripts from the Java code that is being deployed in Google App Engine. I have stored the five refresh tokens in a properties file and set them in GoogleCredential in a round robin fashion before invoking the Apps Script. When I am trying to invoke the Apps Script Requested entity was not found., an error is returned. But the same refresh tokens and client secrets work fine when I create a simple java program to invoke the Apps Script.

    @Service
    public class GoogleAppsScriptServiceImpl {
        private String[] scriptIds;
    
        private String[] refreshTokens;
    
        private GoogleCerdential credential;
    
        public void executeAppsScript() {
            List<Object> params = new ArrayList<>();
            params.add(googleDocFileId);
    
            ExecutionRequest request = new ExecutionRequest()
                                            .setFunction(APPS_SCRIPT_FUNCTION_NAME)
                                            .setParameters(params);
    
            int index = new Random().nextInt(numOfUsers);
    
            Script scriptService = getScriptService(refreshTokens[index]);
            String scriptId = scriptIds[index];
    
            Operation operation = scriptService.scripts()
                                .run(scriptId, request)
                                .setQuotaUser(UUID.randomUUID().toString())
                                .execute();
        }
    
        private Script getScriptService(String refreshToken) {
            credential.setRefreshToken(refreshToken);
            return new Script.Builder(httpTransport, jsonFactory, credential)
                             .setApplicationName(APPLICATION_NAME)
                             .build();
        }
    
        @PostConstruct
        private void createGoogleCredential() throws Exception {
            jsonFactory = JacksonFactory.getDefaultInstance();
            httpTransport = GoogleNetHttpTransport.newTrustedTransport();
    
            credential = new GoogleCredential.Builder()
                                        .setTransport(httpTransport)
                                        .setJsonFactory(jsonFactory)
                                        .setClientSecrets(clientId, clientSecret)
                                        .build();
    
            refreshTokens = commaDelimitedListToStringArray(refreshTokensProp);
            numOfUsers = refreshTokens.length;
    
            scriptIds = commaDelimitedListToStringArray(scriptsIdsProp);
        }
    
    }