I'm facing problem with Google push notifications (for drive). I use service account which works perfectly for all other drive operations except drive changes watch.
Below is application code which now fails with "Unauthorized WebHook callback channel" exception. I also dumped requests and responses which are generated when drive.changes.watch.execute is called.
Target notification address is whitelisted in APIs & auth Push control panel (I even listed it in Javascript origins and referrers) and now I'm stuck with this 401 Unauthorized error.
Does someone know where I'm making mistake? Thanks for any help.
PrivateKey serviceAccountPrivateKey = SecurityUtils.loadPrivateKeyFromKeyStore(SecurityUtils.getPkcs12KeyStore(), p12File, "notasecret", "privatekey", "notasecret"); JsonFactory jsonFactory = new JacksonFactory(); HttpTransport t = GoogleNetHttpTransport.newTrustedTransport(); GoogleCredential gc = new GoogleCredential.Builder() .setTransport(t) .setJsonFactory(jsonFactory) .setServiceAccountScopes(Collections.singleton(DriveScopes.DRIVE)) .setServiceAccountPrivateKey(serviceAccountPrivateKey) .setServiceAccountId(Config.SERVICE_ACCOUNT_ID) .setServiceAccountUser(Config.SERVICE_ACCOUNT_USER) .build(); drive = new Drive.Builder(t, jsonFactory, null).setHttpRequestInitializer(gc).setApplicationName(cfg.getStringParam(Config.GAE_APPLICATION_NAME)).build(); // THIS WORKS Changes.List request = drive.changes().list(); ChangeList changes = request.execute(); // THIS DOES NOT WORK Channel channel = new Channel(); channel.setId(UUID.randomUUID().toString()); channel.setType("web_hook"); channel.setAddress(Config.PUSH_NOTIFICATION_ADDRESS); Channel c = drive.changes().watch(channel).execute(); -------------- REQUEST -------------- POST https://www.googleapis.com/drive/v2/changes/watch Accept-Encoding: gzip Authorization: Bearer XXX User-Agent: XXX Google-HTTP-Java-Client/1.17.0-rc (gzip) Content-Type: application/json; charset=UTF-8 Content-Length: 118 CONFIG: curl -v --compressed -X POST -H 'Accept-Encoding: gzip' -H 'Authorization: Bearer XXX' -H 'User-Agent: XXX Google-HTTP-Java-Client/1.17.0-rc (gzip)' -H 'Content-Type: application/json; charset=UTF-8' -d '@-' -- 'https://www.googleapis.com/drive/v2/changes/watch' << $$$ CONFIG: {"address":"XXX","id":"8078114c-fba0-44e7-a34c-cb391ea40061","type":"web_hook"} -------------- RESPONSE -------------- 401 OK www-authenticate: Bearer realm="https://accounts.google.com/AuthSubRequest", error=invalid_token -------------- REQUEST -------------- POST https://accounts.google.com/o/oauth2/token -------------- RESPONSE -------------- 200 OK { "access_token" : XXX, "token_type" : "Bearer", "expires_in" : 3600 } -------------- REQUEST -------------- POST https://www.googleapis.com/drive/v2/changes/watch -------------- RESPONSE -------------- 401 OK www-authenticate: Bearer realm="https://accounts.google.com/AuthSubRequest", error=invalid_token ... ... ... -------------- RESPONSE -------------- 200 OK content-type: application/json; charset=utf-8 cache-control: no-cache, no-store, max-age=0, must-revalidate pragma: no-cache expires: Fri, 01 Jan 1990 00:00:00 GMT date: Wed, 28 May 2014 20:51:19 GMT content-disposition: attachment; filename="json.txt"; filename*=UTF-8''json.txt content-encoding: gzip x-content-type-options: nosniff x-frame-options: SAMEORIGIN x-xss-protection: 1; mode=block server: GSE alternate-protocol: 443:quic transfer-encoding: chunked { "access_token" : XXX, "token_type" : "Bearer", "expires_in" : 3600 } { "error": { "errors": [ { "domain": "global", "reason": "push.webhookUrlUnauthorized", "message": "Unauthorized WebHook callback channel: XXX" } ], "code": 401, "message": "Unauthorized WebHook callback channel: XXX" } }
To request push notifications, you need to set up a notification channel for each resource you want to watch. After your notification channels are set up, the Google Calendar API will inform your application when any watched resource changes.
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. Set up a notification channel for each resource endpoint you want to watch. A channel specifies routing information for notification messages.
To use push notifications, you need to do three things: Register the domain of your receiving URL. 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.
Note that the Google Calendar API will be able to send notifications to this HTTPS address only if there is a valid SSL certificate installed on your web server. Invalid certificates include: Self-signed certificates. Certificates signed by an untrusted source. Certificates that have been revoked.
You have to add your domain to the developers console.
How to:
After that it should work unless there's something else wrong with what you're doing :p
For me, as I put in a comment above,
The Domain Verification was not saving in google developer console (refresh the page and it was gone). The problem ultimately ended up being I was logged in as two google accounts, my gmail account and my company account. Adding the domain verification seemed to get confused about the account and not save the domain settings.
Try logging in using a different browser or incognito session if you use multiple google accounts.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With