Unfortunately this type of hacking isn't really sustainable. Even small tweaks to the Gmail UI often change the DOM in very unpredictable ways. When they released the new compose feature, pretty much every single Gmail Chrome extension broke.
We haven't really announced it yet, but I've been working on a new email platform with some friends to solve a lot of these issues. It's essentially Rails/Meteor for email features, and lets you skip past hacking Gmail or writing a full IMAP client.
It's called Inbox, and we're aiming to open source it in January. Ping me if you're interested in playing with it early. :)
Thanks for your feedback. I agree, which is why i decided to put it out there because I use the library in a chrome extension and if something breaks, I would be trying to get the extension fixed - patching gmail.js. Still better than finding random solutions from here and there or duplicating efforts. :-) I'd be interested in seeing what you guys are working so, so I'll ping you soon
Yeah, I'm certainly not meaning to belittle your efforts. I wrote something similar (based on jamesjyu's gmailr stuff) for my thesis last year. It's the best way to do it for relatively simple one-off projects.
The first big challenge is definitely just having a shared toolkit, but it's next to impossible to provide backwards-compatible APIs when the Gmail UI changes.
I have encountered this across various other google services. Case in point: I was hacking together a simple Alfred (http://www.alfredapp.com/) extension, using AppleScript to allow creating & searching of google keep notes. It broke about 2 days afterwards and, in the absence of official (stable) endpoints from google themselves, I gave up on the idea.
This! You're doing it right. I wish all the Gmail tweakers united to build a better platform rather than spend their time propping the old, PRISM-tainted, UI-crippled service.
It would be amazing if this were a service. Easier said than done, I know -- but, basically this but have it check a JSON file every few hours and gets the updated selectors.
(For people who don't know, all GMail's classes and IDs are things like '.xb3', and they change often.)
Having worked on Mozilla Add-ons for a long time, one of the biggest problems was by the time any G-Mail add-on was approved, it was already out of date again. API calls, when done correctly, are allowed by both Chrome and Firefox -- this could be a good solution.
(You could easily charge a few bucks for this, and even contact Firefox + Chrome about making sure the reviewers allow it. Market it as "cutting down on their time" since there will be less to review.)
As I understand, from one of the early Gmail product managers, element class names are the most stable of all the 'fingerprints'. The Javascript data structures are quite stable, and the element IDs change pretty much every session.
(Source: I'm the author of the ActiveInbox Gmail extension, and at various times have spoken to Gmail engineers directly).
I agree a service would be a useful thing. A killer bit of value would be if it could workaround Mozilla's addon rules. (We actually stopped publishing on Mozilla addons, because if Gmail changed, we couldn't wait 10 days to be "re-approved" to fix it, and as mentioned by gkoberger, Mozilla really clamps down on dynamic in-app updates).
Ymmv, but if it helps...
From the POV of an extension developer, service reliability is critical, and I'm not sure if there's enough GMail extension developers to be customers and make it economically viable?
If there is, I think the ideal service would taint DOM elements with class names to make the important things selectable (rather than a Javascript API to retrieve elements). That way, we could build our own selectors with fail safes to fall back on (and we don't have the security headache of incorporating your dynamically-updated code within our own protected sandbox. We can just share the modified DOM instead).
Whatever you do with it, I'm really impressed with how cleanly you built this kartikt!
Maybe it could just be a JSON file with the xpath of all important elements?
Also maybe it doesn't really have to be a service. It could just be a file on github, where anyone could issue a pull request if gets broken broken. That way way you would essentially crowd source it.
Google is aware that people are building tools on top of their UI. If they were against it, they could pretty easily thwart it (e.g. by randomizing their HTML/CSS, or by serve different versions to different users). The fact that they haven't taken time to do this is, I believe, evidence that they aren't hostile to these efforts.
Also, I've personally been in contact with people on the Gmail team about this kind of stuff. They are, generally, supportive, but they're very clear that they'll make no guarantees about stability.
Historically extensions for Gmail have often been problematic. A lot of people install them and then forget about them, and if something changes, they blame Gmail and there's errors that can't be reproduced. Plus there's the whole security issue of giving third party code access to your mails.
Neat suggestion. It could totally be uploaded to a cdn where people can simply import it and once a change occurs on Gmail and the script gets updated, everybody benefits.
That probably won't work. The add-on reviewers are very strict about running arbitrary code loaded from somewhere else, and no add-on using it would be approved. (After all, you could change your code and store people's emails.)
That being said, you should be able to use this to load new selector strings for the API:
It wouldn't necessarily need to be code. It could just be JSON data with updated selectors, etc. Just make sure you use JSON.parse on it, and there aren't any security issues from just fetching the data.
Interesting - and a very good job given what you have to work with. Surely its incredibly brittle, though? As soon as they release a new version of Gmail it's going to fail.
But then, I suppose that's how most Chrome extensions work.
However, it's even worse than you think. It's making a lot of references to minified/obfuscated names. Things like $('.nH.hx'). When I was working on a gmail script[1] a year or two ago, many of those were changing every few hours.
Yeah, the strange selector names that never cease to change were what ultimately caused me to abandon my relatively popular Chrome extension "Gmail Attachments to Drive". Having to constantly update the code every time Gmail changed just got old really, really fast.
Thanks for making the library, glad to see you put lots of time into the docs too. Hopefully the can of worms you've opened doesn't drive you crazy, personally I would've stopped the second I found myself writing something like this...
Author of Gmailr here, which apparently inspired this project. Kudos! Glad to see someone taking the ball and running with it. I haven't had time to update Gmailr lately, as it is something that needs active maintenance. The main challenge here is that Gmail will have continue to have bursts of updates that break extension libraries, with relatively long periods of stability.
Thanks James! Your library was the inspiration for the observer methods. I agree with the maintenance part but I think having this out there will help reduce duplicating efforts.
I'm curious why you'd use the DOM instead of making API calls to the server. If Google can do it as part of their UI surely a 3rd party script can too. Is the API more complex than the frequently changing DOM?
Most email data related methods are making the API calls. The DOM is being used for methods like checking if a user inside an email or if the user has preview panes enabled. Since the primary goal of the library is to aid with chrome extension development, checking items in the DOM is quicker.
Surely! I think the having it out there for anyone to contribute and modify will benefit all our us. Feel free to add on your suggestions or features that are missing :)
This is pretty useful. A couple months ago I started making a free self-hosted version of Boomerang for Gmail, but lost interest because I felt like I would have to devote most of my time to gmail's idiosyncrasies. Maybe it's time to get back to work.
Is there a way to add navigation events (eg. user opened email) to the observe gmail.observe API? Right now it looks like I would have to poll gmail.check.is_inside_email.
I use Selenium tests that run on a cron job to check for elements on third-party websites. This works great and I am able to keep the extension mostly up to date. One of the issues I have come up against is when a third-party A/B tests. I usually have to hack around and find an account with the B portion to make sure everything works.
Your name sounded very familiar, finally realized from where after reading the recent opendata email! Great job on this and the OpenDataUW API stuff. I am also admiring the PHP Scraper Class as I was planning on writing something similar.
Hey zrgiu_, there isn't a native observer for that action yet but the closest call is to check if the user is inside an email. I've created a gh issue out of it so hopefully you'll be able to set triggers with the observer method, instead of setInterval
AFAIK Gmail's implementation of IMAP is kind of borked and stuff like the "smart" categorization (e.g. social networks, notifications, etc) doesn't reflect into imap folders (or RSS their RSS feeds, for that matter). Labels do, though, with a workaround.
We haven't really announced it yet, but I've been working on a new email platform with some friends to solve a lot of these issues. It's essentially Rails/Meteor for email features, and lets you skip past hacking Gmail or writing a full IMAP client.
It's called Inbox, and we're aiming to open source it in January. Ping me if you're interested in playing with it early. :)