Java 使用服务帐户创建推送通知的Google驱动器通道

Java 使用服务帐户创建推送通知的Google驱动器通道,java,google-app-engine,google-api,google-drive-api,Java,Google App Engine,Google Api,Google Drive Api,我正在尝试创建一个频道,以便在谷歌电子表格上进行编辑时接收推送通知。该代码将在AppEngine标准Java8项目上执行 因为一个频道最多可以持续24小时,所以我正在创建一个cron,它将每天更新该频道 以下是我的配置: 我创建了一个服务帐户:xxxx@yyyy.iam.gserviceaccount.com 我验证了域:yyyy.appspot.com(在网站管理员工具中) 我将域添加到云控制台(部分API&Services->domain-Verification) 我创建了一个端点来处理

我正在尝试创建一个频道,以便在谷歌电子表格上进行编辑时接收推送通知。该代码将在AppEngine标准Java8项目上执行

因为一个频道最多可以持续24小时,所以我正在创建一个cron,它将每天更新该频道

以下是我的配置:

  • 我创建了一个服务帐户:
    xxxx@yyyy.iam.gserviceaccount.com
  • 我验证了域:
    yyyy.appspot.com
    (在
    网站管理员工具中
  • 我将域添加到云控制台(部分
    API&Services->domain-Verification
  • 我创建了一个端点来处理推送通知:
    https://yyyy.appspot.com/api/drive/push
  • sheetId是:
    foo\u bar
    (由电子表格浏览器url本身复制,如
    https://docs.google.com/spreadsheets/d/foo_bar/edit
  • 服务帐户是
    可以在工作表上编辑
使用Java库
GoogleAPI服务驱动器:v3-rev102-1.23.0
我创建了这段代码

public static void main(String[] args) throws IOException {
    String spreadsheetId = "foo_bar";
    InputStream json = GoogleDriveApi.class.getClassLoader().getResourceAsStream("bar.json");

    GoogleCredential credential = GoogleCredential.fromStream(json, new NetHttpTransport(), new JacksonFactory());
    if (credential.createScopedRequired()) {
        credential = credential.createScoped(Collections.singleton("https://www.googleapis.com/auth/drive.appdata"));
    }

    Drive service = new Drive.Builder(new NetHttpTransport(), new JacksonFactory(), credential).build();

    Channel channel = new Channel();
    channel.setAddress("https://example.com/api/drive/push");
    channel.setType("web_hook");
    channel.setId(UUID.randomUUID().toString());

    Watch action = service.files().watch(spreadsheetId, channel);
    System.out.println(action.execute().toPrettyString());
}
当我执行此代码时,会出现以下错误:

com.google.api.client.googleapis.json.GoogleJsonResponseException: 404 Not Found
{
  "code" : 404,
  "errors" : [ {
    "domain" : "global",
    "location" : "fileId",
    "locationType" : "parameter",
    "message" : "File not found: foo_bar.",
    "reason" : "notFound"
  } ],
  "message" : "File not found: foo_bar."
}
我引述

每个通知通道都与特定用户关联 以及特定资源(或一组资源)。一个手表请求将被删除 除非当前用户或服务帐户拥有或 具有访问此资源的权限

在我的案例中,服务帐户不拥有该资源(电子表格),但确实拥有该资源的权限(
可以编辑
权限,而不仅仅是
可以查看

可以使用服务帐户在Google Drive上创建频道吗?

API要求
https://www.googleapis.com/auth/drive
scope,在主要示例中,我只使用了
https://www.googleapis.com/auth/drive.appdata

使用下面这行代码,这个示例可以很好地工作

credential = credential.createScoped(Collections.singleton("https://www.googleapis.com/auth/drive"));

您使用的授权码是什么?您如何授权服务帐户?我用完整的代码更新了主要问题,包括身份验证