How to receive Google Push Notifications

51 views
Skip to first unread message

Anders Vincent Lund

unread,
Jan 16, 2017, 6:29:53 AM1/16/17
to Google APIs Explorer Users Forum
I just managed to call the Google Drive API to enable push notifications for a file.

The code setting up the push notifications look like this:



   
public class SampleServlet extends AbstractAppEngineAuthorizationCodeServlet {
       
private final static Logger logger = Logger.getLogger(SampleServlet.class.getName());
       
private static final long serialVersionUID = 1L;
       
// Constants omitted
   
       
@Override
       
public void doGet(HttpServletRequest req, HttpServletResponse resp)
               
throws IOException, ServletException {
   
           
AuthorizationCodeFlow authFlow = initializeFlow();
           
Credential credential = authFlow.loadCredential(getUserId(req));
   
           
StringBuilder resultFromWatch = new StringBuilder();
           
Drive drive = new Drive.Builder(Utils.HTTP_TRANSPORT, Utils.JSON_FACTORY, credential).setApplicationName("t").build();
   
           
try {
               
Optional<Channel> channel = watchFile(drive, FILE_ID, CHANNEL_ID, "web_hook", PUSH_URL);
               
String channelStringTmp;
               
if (channel.isPresent()) {
                    channelStringTmp
= channel.get().toString();
               
} else {
                    channelStringTmp
= "null...";
               
}
                resultFromWatch
.append(channelStringTmp);
           
} catch (Exception e) {
                resultFromWatch
.append(e.getMessage());
           
}
   
           
final UserService userService = UserServiceFactory.getUserService();
           
final String thisUrl = req.getRequestURI();
           
// Send the results as the response
           
PrintWriter respWriter = resp.getWriter();
            resp
.setStatus(200);
            resp
.setContentType("text/html");
   
            addLoginLogoutButtons
(req, resp, resultFromWatch, userService, thisUrl, respWriter);
       
}
   
       
private static Optional<Channel> watchFile(Drive service, String fileId,
                                                   
String channelId, String channelType, String channelAddress) throws IOException {
           
final Channel returnValue;
           
Channel channel = new Channel();
            channel
.setId(channelId);
            channel
.setType(channelType);
            channel
.setAddress(channelAddress);
           
Drive.Files tmp = service.files();
            returnValue
= tmp.watch(fileId, channel).execute();
           
return Optional.fromNullable(returnValue);
       
}
   
       
@Override
       
protected AuthorizationCodeFlow initializeFlow() throws ServletException, IOException {
           
return Utils.initializeFlow();
       
}
   
       
@Override
       
protected String getRedirectUri(HttpServletRequest req) throws ServletException, IOException {
           
return Utils.getRedirectUri(req);
       
}
   
}



After having called the servlets doGet from my browser and logging in I get this as response:

    {
     
"expiration": "1484565747000",
     
"id": SAME_ID_AS_DEFINED_IN_SERVLET,
     
"kind": "api#channel",
     
"resourceId": A_NEW_ID,
     
"resourceUri": "https:\/\/www.googleapis.com\/drive\/v3\/files\/FILE_ID?acknowledgeAbuse=false&alt=json"
   
}



Next step is to define my controller that receives notifications when the file is modified. Looks like this:


    @RestController
   
@RequestMapping(/*PUSH_URL*/)
   
public class ConcreteFileWatchController implements FileWatchController {
       
private final static Logger logger = Logger.getLogger(ConcreteFileWatchController.class.getName());
   
       
@RequestMapping(method = RequestMethod.POST)
       
@ResponseStatus(value = HttpStatus.OK)
       
@Override
       
public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
            logger
.info("Received watch call");
       
}
   
}


Finally I try to modify the file after having deployed the application(it is deployed on Google App Engine) and after looking at the logs in GAE I can see that there has been a call. However, my receiving method is not executed. I only see a 302 in the log with a big json attached to it. Can't really see any error except that I don't notice that my method is called. The path even looks correct in the log. What could I be doing wrong?

John Boswell

unread,
Jan 17, 2017, 5:22:42 PM1/17/17
to Google APIs Explorer Users Forum
The only things I can think of are:
- Make sure you're giving the right file id (it's an easy mistake to make).
- Make sure you're following all the instructions here: https://developers.google.com/drive/v3/web/push.

I don't really know a lot about this API, and this forum is more general, so you might get some more specific help asking here: https://developers.google.com/drive/v3/web/support

mizes...@gmail.com

unread,
Mar 9, 2018, 9:02:07 AM3/9/18
to Google APIs Explorer Users Forum

After having set-up everything I'm getting error:

    ...
    errors": [
        {
            "domain": "global",
            "reason": "push.webhookUrlUnauthorized",
            "message": "Unauthorized WebHook callback channel: https://app.example.com"
        }
    ],
    ...
Reply all
Reply to author
Forward
0 new messages