"未找到请求的实体。" - Apps Script Execution API错误

时间:2018-03-10 08:13:46

标签: java google-api-java-client google-apps-script-api

我们在五个G Suite帐户中安装了一个Apps脚本。我正在从Google App Engine中部署的Java代码中调用应用程序脚本。我在属性文件中存储了五个刷新令牌,并在调用Apps脚本之前以循环方式将它们设置在GoogleCredential中。当我尝试调用Apps脚本Requested entity was not found.时,会返回错误。但是当我创建一个简单的java程序来调用Apps脚本时,相同的刷新令牌和客户机密码工作正常。

@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);
    }

}

2 个答案:

答案 0 :(得分:1)

您正在将Execution API部署到独立脚本类型或容器绑定脚本类型的项目中。然后使用API​​调用项目中的函数。在这种情况下,发生Requested entity was not found.的错误。如果我的理解是正确的,我也遇到了同样的情况。那么如何确认以下几点呢?

  1. 使用“保存”按钮,再次保存正在部署API可执行文件的项目。
    • 这对我来说非常重要。
  2. 将项目另存为新版本,然后重新部署API。
  3. 是否从使用Apps Script API的项目中检索客户端ID和客户端密钥。
    • 是否从这些客户端ID和客户端密钥中检索访问令牌。
  4. 范围是否包括https://www.googleapis.com/auth/drivehttps://www.googleapis.com/auth/drive.scriptshttps://www.googleapis.com/auth/script.external_request
  5. 是否启用了执行API。
  6. 如果您只想使用curl命令进行测试,您还可以使用以下命令。

    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"
    

    确认以上几点后,请再试一次。如果这些对你没用,我很抱歉。或者,如果我误解了你的问题,我真的很抱歉。

答案 1 :(得分:0)

问题不在于Apps脚本或App Engine项目的配置。我在GoogleCredential方法中创建了一个@PostConstruct对象,并在调用Apps脚本之前从预先生成的标记列表中设置了刷新标记(credential.setRefreshToken())。即使我已经为同一组客户端ID和客户端密钥创建了刷新令牌,我也收到了错误。因此,我创建多个GoogleCredential对象作为刷新令牌的数量,而不是在多个刷新令牌中重复使用凭证对象。

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);
}