I am currently developing system synchronizing files between Google Drive and external storage. I am trying to process push notifications. I was already able to register for them and receive them. After receiving each notification, I acquire list of changes using proper endpoint and try to get a new version of file if necessary, so the flow is like that:
Subscribe to notifications using changes.watch
Receive some push message with url to changes
Use API with provided query to get changes on changes.list endpoint
Filter items that changed after particular moment
Get content of file and transfer it to another service
It seems that after initial notify message, Google starts spamming a new one, always after getting file. I suspect that the action of getting file content is changing some timestamp on file and therefore - its content is changed.
Is it possible not to modify file in any way when getting its content?
EDIT:
It seems that this behaviour concerns files.export endpoint as well - Exporting Google Doc as PDF leads to notifications spam too. Commenting out export part in a code stops them from coming.
You're getting spammed since Changes: watch listens more to changes made by a user, not the file itself.
What you need to use in this scenario is Files: watch. It subscribes you to listen to changes to the file itself.
Related
I am building an expressjs application using the google drive api that notifies the user whenever there is a file change in their google drive through webhooks. However, i am also receiving webhooks when i open/view a folder or a file, which is completely unnecessary. Is it possible to only receive webhooks whenever a new file is created or deleted in the drive? And if so, how do i do it?
There is no direct way unfortunately.
You will likely have to make another request once your app has been notified of a change. Its possible you may have to persist some data to compare with depending on what you need to do exactly. The watch endpoint, as you have seen, will notify you of almost every change, including views. So you'll need to find a way to filter these out.
If you are trying to get create/deleted times only then I would suggest taking the file id from the change notification and making a request to get the file metadata and seeing if the file was created in the last 5 minutes (or less) for example. You can speed this up by only getting the createdTime field for instance.
For deleted, you can either get the type of change directly from the change notification, but this will only notify you if you have deleted it permanently i.e. not in the trash. Trash events look just the same as the others. If you need trash notifications, it is going to be more complicated. There is a trashed attribute, but not a timestamp for it. If you need this then you will probably have to keep a snapshot of which files are trashed and then every time you get a request, check to see if the file that changed is now trashed.
There is an active feature request for this
Support event type filtering for Changes watch channel
Go and give it a ☆ to let Google know that you want this feature!
I'd like to use the /watch (doc) API endpoint for subscribing a remote url to receive informations about changes in Google Drive.
The webhook received doesn't contain any body as specified in the documentation but contains headers which should help to understand what happened on the user's account.
Problem is that the headers doesn't contain anything useful and contains incorrect values too.
I'm saving a pageToken that I'm using to retrieve changes but when receiving multiple concurrent requests there's an high risk to receive the same change twice.
Is there a safe way to understand what happened hook by hook?
Currently the bane of my existence is dealing with users email signatures at work, changing names, titles, departments, new users...it's all annoying. Currently I manage it with GAM and a semi templated HTML file to push changes, which works okay, but it's still a manual process. What I'm looking to do is create a small app script or app engine project that can...
detect a new or changed user
pull the fields needed to fill in their signature template
push the changes to their account
2 & 3 are no problem at all, it's #1 that I cannot find a reasonable solution to.
I had thought about using the google apps audit settings to email a specific mailbox when a new user is created, but that will only catch new users, not changes in titles and such. My only apparent option is something that runs periodically checking all the users signatures against what my script would generate and updating if needed, but that's hardly efficient and creates a potential timelapse in the waiting period meaning when people want things 'done now' (which is of course, every request), it will mean I manually trigger the job; effectively bringing me back to my original solution.
Is there any kind of user feed that contains changes available in google apps? Maybe google has a POST hook that hits a predefined URL on changes?
You can probably use push notifications for this https://developers.google.com/drive/web/push using the users.watch method https://developers.google.com/admin-sdk/directory/v1/reference/users/watch
So, I've gotten to the point in my app where I can retrieve a list of spreadsheet documents from a user's Google Drive account by using the Google Spreadsheet API. I populate the file list in a ui control that users can click on to then retrieve the list of its worksheets. It's working as expected in some cases, but in others it is not. In my request, I use the url that comes back from the file list, and even so, the API responds with:
Sorry, the file you have requested does not exist.
Make sure that you have the correct URL and that the owner of the file hasn't deleted it.
Well, surely the file wasn't deleted. I got it back in the response to my request for the files list. I also can get to the file via a normal web browser. Also, the URL is correct because that's the one the API responded with. My code does not manipulate the url that comes back in that initial files response. In fact, here is the URL that is used to grab the worksheets:
https://spreadsheets.google.com/feeds/worksheets/{long key here}/private/full
So, my question is why does my request for some worksheets come back with a response with the actual list of worksheets, but on others (which I have access to, and I know exists) I get the faulty response.
Thanks,
Arie
My app is using OAuth 2.0 and I ran into the same error with new Google Sheets. What fixed that was making a change in scope param sent during OAuth's authorize call and then reauthorising (reinitiating OAuth flow and obtaining new tokens).
Until now scope in my app was just:
https://spreadsheets.google.com/feeds
Updated scope and solution to the issue in my case:
https://spreadsheets.google.com/feeds https://docs.google.com/feeds
I'm running into this in my own stuff. At least for what I'm running into, it seems to be an issue with New Sheets. I'm sorry to not have more of a solution (I'm still trying to find out what to fix on my end) but this may help you narrow down the issue.
I want to develop an app that listens to Box Webhooks events for a file create or upload event, and then reads the content of that newly created/uploaded file.
However, I am not able to do so because as far as I understand I need an access token to be able to read contents of a file, but the Box Webhooks [create/upload] event does not provide me with any access token.
Could you please suggest a way using which I can implement my app?
Webhooks are kinda like a postcard. They only give you the bare minimum of info to tell you what file has changed. They're being sent over the wire to an unauthenticated destination, so when a webhook goes out, it can't have a lot of secret information already in it.
It's up to you to catch that webhook, look at the file-id (and potentially some other info, like the user-id) and know what user to have login and get the additional information.
If your application is server-side, and the users have signed in, then you'll already have their credentials, and you can go get the extra info.
If your application is a mobile app with no server side, then you will have to have the client make the extra API calls to get the details.