Setting up push notifications (via watch) for a file on Google Drive, with an App Script Web App as a web-hook end-point is a painful experience for the uninitiated.
There are 2 major hurdles to overcome:
- Site verification/Domain registration for your web-hook endpoint
- Retrieving HTTP request headers when your endpoint receives a message
The first is problematic since web app urls cannot be verified using the Search Console. The current work-around is to deploy the published web app as an add-on which somehow verifies the web app's url (as per +Spencer Easton's discoveries).
EDIT: For stand-alone scripts, there is an option under the Publish menu to register a published web app with chrome webstore. Once registered the web app url can be verified from the search console.
Which leads us into the second issue. The majority of notification messages generated and sent by 'watched' files do not have a POST body; message state is primarily stored as custom HTTP headers (whose names are pre-fixed with 'x-goog-...").
This is a critical issue since we cannot currently retrieve HTTP headers from incoming POST requests made to a Web App URL. There are no properties on the event object passed to a doPost() invocation that would allow you to inspect them.
Some solutions work around this limitation by switching from a 'Files' based watch to a 'Changes' based watch as it returns a POST body for a few of its events. But now you're tracking changes globally across your Drive without the ability to pinpoint the file that may have triggered the event. Other solutions fall back on time-based triggers to create a custom push notification flow.
Each of the aforementioned techniques has their pros and cons but I think I found a better way (its not without it's own drawbacks). This method leverages Firebase cloud hosting and cloud functions. But you must Enable Billing on your google platform account for this method to work. You get 2 million free requests per month before incurring any charges after which you pay $0.0000004 per invocation. That's a good trade-off in my book. (Ideally, we should be able to make calls to google owned domains for free but that doesn't seem to be the case here.)
This approach uses a cloud-function as a middle man to capture the incoming HTTP request headers and rePOST them to the web app url in a POST body. Using this method we can actually watch for changes in a specific File as opposed to watching for global changes in the Drive.
Here's a general guide:
Using firebase hosting create a site and verify via Search Console. The verification process will require that you upload a special html file to the site's public folder. You'll also need to register your domain (see Push Notification link at page bottom for details).
Firebase Hosting and Deployment
https://firebase.google.com/docs/hosting/deploying
Search Console https://www.google.com/webmasters/tools/home?hl=en
Prep the site to use cloud-functions and set up routes (via rewrites) so that a path on the site will trigger the function:
Firebase Cloud Function integration https://firebase.google.com/docs/hosting/functions
Next step, write a cloud function that will parse incoming request headers and re-POST them in the message body sent to your target Web App. If you're clever about it you can make it more dynamic by sending the web app url as part of the notification (via the token parameter - see Push Notifications documentation linked below).