drive.changes().watch returns GoogleJsonResponseException: 401 Unauthorized 没有任何消息

drive.changes().watch returns GoogleJsonResponseException: 401 Unauthorized without any message

我正在尝试观察 Google 驱动器中的变化,并收到 401 异常。搜到这里,发现人家有详细的留言,为什么我什么都没有,却不是未经授权的。

这里是我使用的代码:

public static void main(String[] args) {
    try {


        httpTransport = GoogleNetHttpTransport.newTrustedTransport();
        dataStoreFactory = new FileDataStoreFactory(DATA_STORE_DIR);

        // authorization
        GoogleCredential credential = GoogleCredential.getApplicationDefault()
                .createScoped(DriveScopes.all());

        boolean refreshed = credential.refreshToken();

        // set up the global Drive instance
        drive = new Drive.Builder(httpTransport, JSON_FACTORY, credential)
                .setApplicationName(APPLICATION_NAME)
                .build();

        Channel channel = new Channel();
        channel.setId(UUID.randomUUID().toString());
        channel.setType("web_hook");
        //my ip here
        channel.setAddress("https://com.example:");

        StartPageToken pageToken = drive.changes().getStartPageToken().execute();
        System.out.println(pageToken.getStartPageToken());
        Channel changesChannel = drive.changes().watch(pageToken.getStartPageToken(), channel).execute();
        System.out.println(changesChannel.getExpiration());

        return;
    } catch (IOException e) {
        System.err.println(e.getMessage());
        e.printStackTrace();
    } catch (Throwable t) {
        t.printStackTrace();
    }
    System.exit(1);
}

更多信息:

  1. 这是一个服务帐户。它具有所有者权限
  2. 我在本地计算机上使用它
  3. drive.files().list() 工作正常
  4. drive.about().get() 工作正常

我得到的异常是:

com.google.api.client.googleapis.json.GoogleJsonResponseException: 401 Unauthorized at com.google.api.client.googleapis.json.GoogleJsonResponseException.from(GoogleJsonResponseException.java:145) at com.google.api.client.googleapis.services.json.AbstractGoogleJsonClientRequest.newExceptionOnError(AbstractGoogleJsonClientRequest.java:113) at com.google.api.client.googleapis.services.json.AbstractGoogleJsonClientRequest.newExceptionOnError(AbstractGoogleJsonClientRequest.java:40) at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.interceptResponse(AbstractGoogleClientRequest.java:321) at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:1065) at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:419) at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:352) at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.execute(AbstractGoogleClientRequest.java:469) at main.lambda.GoogleDrive2.main(MyClass.java:142)

我的 pom.xml 依赖项:

<dependency>
        <groupId>com.google.api-client</groupId>
        <artifactId>google-api-client</artifactId>
        <version>1.20.0</version>
    </dependency>
    <dependency>
        <groupId>com.google.oauth-client</groupId>
        <artifactId>google-oauth-client</artifactId>
        <version>1.22.0</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/com.google.api-client/google-api-client-extensions -->
    <dependency>
        <groupId>com.google.api-client</groupId>
        <artifactId>google-api-client-extensions</artifactId>
        <version>1.6.0-beta</version>
    </dependency>
    <dependency>
        <groupId>com.google.oauth-client</groupId>
        <artifactId>google-oauth-client-jetty</artifactId>
        <version>1.22.0</version>
    </dependency>
    <dependency>
        <groupId>com.google.apis</groupId>
        <artifactId>google-api-services-drive</artifactId>
        <version>v3-rev70-1.22.0</version>
    </dependency>

在花了几个小时并仔细阅读了文档之后,我终于找到了问题所在。

如推送通知文档 (https://developers.google.com/drive/v3/web/push) 中所写:

To use push notifications, you need to do three things:

  1. Register the domain of your receiving URL. ...

  2. Set up your receiving URL, or "Webhook" callback receiver.

    This is an HTTPS server that handles the API notification messages that are triggered when a resource changes.

  3. Set up a notification channel for each resource endpoint you want to watch.

    A channel specifies routing information for notification messages. As part of the channel setup, you identify the specific URL where you want to receive notifications. Whenever a channel's resource changes, the Drive API sends a notification message as a POST request to that URL.

这意味着您应该有一个域,您应该在 google 确认它,然后才能使用 watch API。

P.S。我仍然认为在这种情况下响应 GoogleJsonResponseException: 401 Unauthorized 是荒谬的,但希望它能帮助其他面临同样问题的人。