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