有什么方法可以为单个 Java 项目包含多个 Google API 服务(例如表格和文档)?

Is there some way to include multiple Google API services (e.g. Sheets and Docs) for a single Java project?

我第一次使用 Google 的 API 服务进行个人 Java 项目,涉及从 Google Sheet 读取数据并将相关信息写入单独的 Google 文档。

我使用了 Google 列出的两个 here and here 的快速入门指南。当遵循 Google Sheet 指南并使用我自己的文件对其进行测试时,我设法将所有内容设置好并且 运行 很好。

但是,尝试为 Doc 设置 API 似乎在尝试将我新生成的凭据(Google Doc)添加到已创建的 credentials.json 时出现问题文件。我认为这是因为已经为我的 Sheets 文件创建了凭据,所以我不能简单地添加新创建的凭据。我还尝试通过创建一个名为 doccredentials.json 的新凭证文件来尝试同时使用两者,但是在尝试再次执行 gradle run 以编译 Google Doc 时遇到了这个问题API 服务:

Exception in thread "main" com.google.api.client.googleapis.json.GoogleJsonResponseException: 403 Forbidden
{
  "code" : 403,
  "errors" : [ {
    "domain" : "global",
    "message" : "Insufficient Permission",
    "reason" : "insufficientPermissions"
  } ],
  "message" : "Request had insufficient authentication scopes.",
  "status" : "PERMISSION_DENIED"
}

我最好的猜测是 Sheet 的凭据正在被使用,但我不确定如何规避它。我还确保我的 CREDENTIALS_FILE_PATH 变量也设置到正确的位置,所以我很确定它正在尝试从正确的文件中读取。

如有任何建议,我们将不胜感激。谢谢。

编辑:这是我的身份验证代码块中的内容。它最初只是为了验证 Sheet API 而设置的,但是,在仔细检查之后,它似乎很可能是由于设置范围不正确造成的。关于如何允许范围同时适用于电子表格和文档的任何建议?:

private static Credential authorize() throws IOException, GeneralSecurityException {
    InputStream in = InventoryManagerSheet.class.getResourceAsStream("/credentials.json");
    GoogleClientSecrets clientSecrets = GoogleClientSecrets.load(JacksonFactory.getDefaultInstance(), new InputStreamReader(in));

    List<String> scopes = Arrays.asList(SheetsScopes.SPREADSHEETS);

    GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(GoogleNetHttpTransport.newTrustedTransport(), JacksonFactory.getDefaultInstance(),
    clientSecrets, scopes).setDataStoreFactory(new FileDataStoreFactory(new java.io.File("tokens"))).setAccessType("offline").build();

    Credential credential = new AuthorizationCodeInstalledApp(flow, new LocalServerReceiver()).authorize("user");

    return credential;
}

与您的错误消息相关的答案

我写这篇文章时没有看到你的代码,一旦你看到我会编辑它,但这可能会有所帮助。

"Request had insufficient authentication scopes.",

表示当前进行身份验证的用户没有授予您足够的权限来执行您正在尝试执行的操作。

您提到您正在关注的 tutorial 请求用户提供以下范围

private static final List<String> SCOPES = Collections.singletonList(DocsScopes.DOCUMENTS_READONLY);

您提到您想写信给 google 文档。如您所见,此范围仅允许对文档进行 READONLY 访问。您可能应该正在使用,但这只是一个猜测,您将不得不检查 java 客户端库中的名称是否不同。

private static final List<String> SCOPES = Collections.singletonList(DocsScopes.DOCUMENTS);

也可以是,您可以混合作用域。

private static final List<String> SCOPES = Collections.singletonList(DriveScopes.DRIVE);

完成后,您需要转到 CREDENTIALS_FILE_PATH 并删除为“用户”创建的凭据文件,这将强制您的代码再次请求用户授权并请求对您的文件的写入权限.

与您的实际问题相关的答案

现在回到你的问题,这与你的错误消息无关。您可以从诈骗应用程序访问两个不同的 api,但您需要为每个

创建一个服务

以下服务将使您能够访问 Google 文档 api

Docs service = new Docs.Builder(HTTP_TRANSPORT, JSON_FACTORY, getCredentials(HTTP_TRANSPORT))
                .setApplicationName(APPLICATION_NAME)
                .build();

以下服务将使您的代码能够访问 Google 驱动器 api

Drive service = new Drive.Builder(HTTP_TRANSPORT, JSON_FACTORY, getCredentials(HTTP_TRANSPORT))
                .setApplicationName(APPLICATION_NAME)
                .build();

只是给他们不同的名字。请记住为每个 api 添加所需的范围,您可以混合使用它们。