/gmail.js

JavaScript API for Gmail

Primary LanguageJavaScriptMIT LicenseMIT

Gmail.js - JavaScript API for Gmail

Note: The new Content Security Policy will prevent direct injection. Here is how to get around it

Note: This is not an official Gmail API, and isn't affiliated with Google.

Note: Gmail.js requires jQuery to work

TL;DR Summary

  • Lots of api methods to work with gmail. Useful for chrome extensions
  • Most of them dont take arguments, they work on what is currently visible on the screen
  • I still need to add implementation for chrome extension, works by injecting js for now
  • Main methods allow you to observe certain events with gmail.observe.on('lots_of_actions_here', callback()) or similar gmail.observe.before(...) and gmail.observe.after(...)
  • Click on a method link to view more detailed docs
  • Create an issue/pull request for feedback, requests and fixes

Examples

Content Security Policy

The new Content Security Policy will prevent direct injection. Please see the following repository to get around the policies. More details can also be found in issue #75

Setup

  • Gmail.js requires jQuery to work

Quick Usage - Chrome Console

// {inject jquery.js} by copy pasting this in your console
var jq = document.createElement('script');
jq.src = "https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js";
document.getElementsByTagName('body')[0].appendChild(jq);

// {inject gmail.js} by copy pasting gmail.js contents or via url like jquery above
// var Gmail = {.....} // paste gmail.js code here

// start using!
// you can also pass in a reference to jQuery upon init - Gmail(localJQuery)
var gmail = Gmail();
gmail.get.user_email();

Methods

Summary (click for more info)

GET

CHECK

CHAT

OBSERVE

  • gmail.observe .http_requests()
  • gmail.observe .actions()
  • gmail.observe .off(action,type)
  • gmail.observe .on(action, callback)
    • poll - When gmail automatically polls the server to check for new emails every few seconds
    • new_email - When a new email appears in the inbox
    • open_email - When an email is opened from the inbox view
    • refresh - When you click the refresh button
    • unread - When a conversation(s) is marked unread
    • read - When a conversation(s) is marked read
    • delete - When a conversation(s) is deleted
    • delete_message_in_thread - When a conversation(s) is deleted inside a thread
    • mark_as_spam - When a conversation(s) is marked as spam
    • mark_as_not_spam - When a conversation(s) is unchecked as spam
    • label - When a conversation(s) get applied a label
    • archive - When a conversation(s) is archieved
    • move_to_inbox - When a conversation(s) is moved to the inbox
    • delete_forever - When a conversation(s) is deleted forever
    • star - When a conversation(s) is starred
    • unstar - When a conversation(s) is unstarred
    • mark_as_important - When a conversation(s) is marked as important
    • mark_as_not_important - When a conversation(s) is marked as not important
    • filter_messages_like_these - When a filter button is triggered for a conversation
    • mute - When a conversation(s) is muted
    • unmute - When a conversation(s) is unmuted
    • add_to_tasks - When an item is added to google tasks
    • move_label - When a conversation(s) is moved to a label folder
    • save_draft - When a draft is saved
    • discard_draft - When a draft is dicarded
    • send_message - When a message is sent
    • expand_categories - When a category is expanded from the left nav sidebar
    • restore_message_in_thread - When a deleted message is restored inside a thread
    • delete_label - When a label is deleted
    • show_newly_arrived_message - When inside an email and a new email arrives in the thread
    • upload_attachment - When an attachment is being uploaded to an email being composed
  • gmail.observe .before(action, callback)
  • gmail.observe .after(action, callback)
  • gmail.observe .bind(type, action, callback) - implements the on, after, before callbacks
  • gmail.observe .bound(action, type)
  • gmail.observe .bound(action, type) - checks if a specific action and/or type has any bound observers
  • gmail.observe .trigger(type, events, xhr) - fires any specified events for this type (on, after, before) with specified parameters

DOM

These methods return the DOM data itself

  • gmail.dom .inboxes()
  • gmail.dom .inbox_content()
  • gmail.dom .email_subject()
  • gmail.dom .email_body()
  • gmail.dom .email_contents()
  • gmail.dom .get_left_sidebar_links()
  • gmail.dom .search_bar()
  • gmail.dom .compose() - compose dom object - receives the DOM element for the compose window and provides methods to interact
  • gmail.dom .composes() - retrives an array of gmail.dom.compose objects representing any open compose windows

TOOLS

These are some helper functions that the rest of the methods use. See source for input params

  • gmail.tools infobox(message, time)
    • Adds the yellow info box on top of gmail with the given message
  • gmail.tools .xhr_watcher()
  • gmail.tools .parse_url()
  • gmail.tools .deparam()
  • gmail.tools .parse_view_data()
  • gmail.tools .parse_email_data()
  • gmail.tools .extract_email_address(str)
  • gmail.tools .extract_name(str)
  • gmail.tools .make_request()
  • gmail.tools .sleep(ms)
  • gmail.tools .multitry(ms_delay, tries, func, bool_success_check)
  • gmail.tools .i18n(label)

TRACKER

These are some of the variables that are tracked and kept in memory while the rest of the methods are in use.

  • gmail.version
  • gmail.tracker .events
  • gmail.tracker .xhr_init
  • gmail.tracker .xhr_open
  • gmail.tracker .xhr_send
  • gmail.tracker .watchdog
  • gmail.tracker .view_data
  • gmail.tracker .email_data
  • gmail.tracker .ik
  • gmail.tracker .rid

Details

gmail.get.visible_emails()

Returns a list of emails from the server that are currently visible in the inbox view. The data does not come from the DOM

[{"id": "1425a3693a4c45d0",
  "title": "<b>What if video games were real? On YouTube</b>",
  "excerpt": "View email in a web browser Header Super Mario Brothers Parkour by Warialasky Super Mario Brothers",
  "time": "Fri, Nov 15, 2013 at 12:23 AM",
  "sender": "noreply@youtube.com",
  "attachment": "",
  "labels": ["^all", "^i", "^smartlabel_social", "^unsub"]}]

gmail.get.email_data(email_id=undefined)

Returns an object representation of the opened email contents and metadata. It takes the optional email_id parameter where the data for the specified id is returned instead of the email currently visible in the dom

{
  "first_email": "141d44da39d6caf8",
  "last_email": "141d44da39d6caf8",
  "total_emails": 1,
  "total_threads": ["141d44da39d6caf8"],
  "people_involved": [
    ["Kartik Talwar", "hi@kartikt.com"],
    ["California", "california@gmail.com"]
  ],
  "subject": "test",
  "threads": {
    "141d44da39d6caf8": {
      "reply_to_id": "",
      "is_deleted" : false,
      "from": "California",
      "to" : ["hi@kartikt.com"],
      "cc" : [],
      "bcc" : [],
      "from_email": "california@gmail.com",
      "timestamp": 1382246359000,
      "datetime": "Sun, Nov 20, 2013 at 1:19 AM",
      "content_plain": "another test",
      "subject": "test",
      "content_html": "<div dir=\"ltr\">another test</div>\n"
    }
  }
}

gmail.get.displayed_email_data()

Returns an object representation of the emails that are being displayed.

{
  "first_email": "145881e7a8befff6",
  "last_email": "145881e7a8befff6",
  "total_emails": 1,
  "total_threads": ["145881e7a8befff6"],
  "people_involved": [
    ["Kartik Talwar", "hi@kartikt.com"],
    ["California", "california@gmail.com"]
  ],
  "subject": "test",
  "threads": {
    "145881e7a8befff6": {
      "reply_to_id": "",
      "is_deleted" : false,
      "from": "California",
      "to" : ["hi@kartikt.com"],
      "cc" : [],
      "bcc" : [],
      "from_email": "california@gmail.com",
      "timestamp": 1382246359000,
      "datetime": "Sun, Nov 20, 2013 at 1:19 AM",
      "content_plain": "another test",
      "subject": "test",
      "content_html": "<div dir=\"ltr\">another test</div>\n"
    }
  }
}

gmail.get.user_email()

Returns the current user's email address

"california@gmail.com"

gmail.get.storage_info()

Returns current user's file storage stats

{
  "used": "0 GB",
  "total": "15 GB",
  "percent": 0
}

gmail.get.current_page()

Returns what page of gmail the user is currently on. These are the possible responses

['sent', 'inbox', 'starred', 'drafts', 'imp', 'chats', 'all', 'spam', 'trash', 'settings'] // pages
null // inside email conversation
"/search/[.+]" // inside search view
"/label/[.+]" // inside label view
"/category/[.+]" // inside category view
"/settings/[.+]" // settings sub-page (excluding settings root page)

gmail.get.email_subject()

Returns the opened email's subject from the DOM

"test"

gmail.get.email_id()

Gets current email's ID

"141de25dc0b48e4f"

gmail.get.email_ids()

Returns a list of email IDs for each thread in the conversation

["141de25dc0b48e4f"]

gmail.get.compose_ids()

Returns the latest/last email id of emails that have been saved as drafts (currently open)

["14469c73bba6ff53", "14469c7b8581ccfa"]

gmail.get.search_query()

Returns the search bar data

"from:hi@kartikt.com is:unread"

gmail.get.unread_emails()

Returns a count of total unread emails for the current account.

{
  "inbox": 2,
  "drafts": 0,
  "spam": 0,
  "forum": 0,
  "notifications": 0,
  "promotions": 0,
  "social": 0
}

You can also request the data individually

  • gmail.get.unread_inbox_emails()
  • gmail.get.unread_draft_emails()
  • gmail.get.unread_spam_emails()
  • gmail.get.unread_forum_emails()
  • gmail.get.unread_update_emails()
  • gmail.get.unread_promotion_emails()
  • gmail.get.unread_social_emails()

gmail.get.last_active()

Gets user's account activity data

{
  "time": "9:41 pm",
  "ip": "54.234.192.48",
  "mac_address": "2620:101:f000:702:a966:ab42:4a46:195e",
  "time_relative": "31 minutes ago"
}

gmail.get.loggedin_accounts()

Returns a list of signed-in accounts (multiple user accounts setup in gmail)

[{"name":"California","email":"california@gmail.com"}]

gmail.get.beta()

Although hand picked, this method returns the checks on beta features and deployments

{"new_nav_bar":true}

gmail.check.is_thread()

Returns True if the conversation is threaded False otherwise

gmail.check.is_preview_pane()

Returns True if gmail is in split pane mode (vertical or horizontal) False otherwise

gmail.check.is_multiple_inbox()

Returns True if user has multiple inbox lab enabled, False otherwise

gmail.check.is_horizontal_split()

Returns True if the pane split mode is horiontal False otherwise

gmail.check.are_shortcuts_enabled()

Returns True if user has enabled mail action shortcuts, False otherwise

gmail.check.is_vertical_split()

Returns True if the pane mode is vertical False otherwise

gmail.check.is_tabbed_inbox()

Returns True if tabbed inbox view is enabled False otherwise

gmail.check.is_right_side_chat()

Returns True if chat is on the right sidebar False otherwise

gmail.check.is_conversation_view()

Returns True if emails are displayed as threads, False otherwise (i.e. displayed individually)

gmail.check.is_google_apps_user()

Returns True if the current user is google apps user (email not ending in gmail.com) False otherwise

gmail.check.is_inside_email()

Returns True if you are currently inside an email conversation False otherwise

gmail.check.is_priority_inbox()

Returns True if priority inbox is enabled False otherwise

gmail.check.is_rapportive_installed()

Returns True if rapportive chrome extension is installed False otherwise

gmail.check.is_streak_installed()

Returns True if streak chrome extension is installed False otherwise

gmail.check.is_anydo_installed()

Returns True if any.do chrome extension is installed False otherwise

gmail.check.is_boomerang_installed()

Returns True if boomerang chrome extension is installed False otherwise

gmail.check.is_xobni_installed()

Returns True if xobni chrome extension is installed False otherwise

gmail.check.is_signal_installed()

Returns True if Signal chrome extension is installed False otherwise

gmail.chat.is_hangouts()

Returns True if the account supports the new hangout UI for chat False otherwise (native chat window)

gmail.observe.http_requests()

After an observer has been bound through gmail.observe.bind() (via a call to events gmail.observe.before(), gmail.observe.on(), or gmail.observe.after()), this method keeps track of the last 50 http events. The items contain the sent requested parameterized data

[{
  "method": "POST",
  "url": {
    "ui": "2",
    "ik": "13fa7f7088",
    "rid": "ed0e..",
    "view": "tl",
    "start": "0",
    "num": "30",
    "lhop": "169846",
    "ltup": "%5Ei",
    "slmm": "1427abc6106ac10b",
    "scid": "q2h353hw6dv9",
    "avw": "1194",
    "ntlv": "10",
    "auto": "1",
    "ver": "-z-h-bKmWwI.en.",
    "am": "!6hSPXvkvPMjmReGu2-2BQXCk3IltF-jNSk0J8Cg_jNeaoSbpJgHQYdkXe6T_WPYyyATD3DSiOA",
    "vas": "1",
    "ari": "120",
    "_reqid": "4582876",
    "pcd": "1",
    "mb": "0",
    "rt": "j",
    "search": "inbox"
  },
  "body": "",
  "url_raw": "?ui=2&ik=13fa7f7088&rid=ed0e..&view=tl&start=0&num=30&lhop=169846&ltup=%5Ei&slmm=1427abc6106ac10b&scid=q2h353hw6dv9&avw=1194&ntlv=10&auto=1&ver=-z-h-bKmWwI.en.&am=!6hSPXvkvPMjmReGu2-2BQXCk3IltF-jNSk0J8Cg_jNeaoSbpJgHQYdkXe6T_WPYyyATD3DSiOA&vas=1&ari=120&_reqid=4582876&pcd=1&mb=0&rt=j&search=inbox"
}]

gmail.observe.actions()

Similar to gmail.obsere.http_requests() this keeps track of the last 10 gmail actions (vs all http requests). Actions here correspond to things like clicking refres, archiving, deleting, starring etc.

gmail.observe.on(action, callback)

This is the key feature of gmail.js. This method allows you to add triggers to all of these actions so you can build your custom extension/tool with this library.

You simply specify the action nane and your function that the method will return data to when the actions are triggered and it does the rest. You can have multiple triggers

Your callback will be fired directly after Gmail's XMLHttpRequest has been sent off the the Gmail servers.

Available Actions

  • poll - When gmail automatically polls the server to check for new emails every few seconds
  • new_email - When a new email appears in the inbox
  • open_email - When a new email appears in the inbox
  • refresh - When you click the refresh button
  • unread - When a conversation(s) is marked unread
  • read - When a conversation(s) is marked read
  • delete - When a conversation(s) is deleted
  • delete_message_in_thread - When a conversation(s) is deleted inside and is part of a thread
  • mark_as_spam - When a conversation(s) is marked as spam
  • mark_as_not_spam - When a conversation(s) is unchecked as spam
  • label - When a conversation(s) get applied a label
  • archive - When a conversation(s) is archieved
  • move_to_inbox - When a conversation(s) is moved to the inbox
  • delete_forever - When a conversation(s) is deleted forever
  • star - When a conversation(s) is starred
  • unstar - When a conversation(s) is unstarred
  • mark_as_important - When a conversation(s) is marked as important
  • mark_as_not_important - When a conversation(s) is marked as not important
  • filter_messages_like_these - When a filter button is triggered for a conversation
  • mute - When a conversation(s) is muted
  • unmute - When a conversation(s) is unmuted
  • add_to_tasks - When an item is added to google tasks
  • move_label - When a conversation(s) is moved to a label folder
  • save_draft - When a draft is saved
  • discard_draft - When a draft is dicarded
  • send_message - When a message is sent
  • expand_categories - When a category is expanded from the left nav sidebar
  • restore_message_in_thread - When a deleted message is restored inside a thread
  • delete_label - When a label is deleted
  • show_newly_arrived_message - When inside an email and a new email arrives in the thread

The on method also supports observering specific DOM events in the Gmail Interface (for example when a new compose window is opened). These are only available via the on method (not the before or after methods)

gmail.observe.on("unread", function(id, url, body, xhr) {
  console.log("id:", id, "url:", url, 'body', body, 'xhr', xhr);
})

gmail.observe.on("read", function(id, url, body, xhr) {
  console.log("id:", id, "url:", url, 'body', body, 'xhr', xhr);
})

gmail.observe.on("delete", function(id, url, body, xhr) {
  console.log("id:", id, "url:", url, 'body', body, 'xhr', xhr);
})

gmail.observe.on("mark_as_spam", function(id, url, body, xhr) {
  console.log("id:", id, "url:", url, 'body', body, 'xhr', xhr);
})

gmail.observe.on("mark_as_not_spam", function(id, url, body, xhr) {
  console.log("id:", id, "url:", url, 'body', body, 'xhr', xhr);
})

gmail.observe.on("label", function(id, url, body, label, xhr) {
  console.log("id:", id, "url:", url, 'body', body, "label", label, 'xhr', xhr);
})

gmail.observe.on("archive", function(id, url, body, xhr) {
  console.log("id:", id, "url:", url, 'body', body, 'xhr', xhr);
})

gmail.observe.on("move_to_inbox", function(id, url, body, xhr) {
  console.log("id:", id, "url:", url, 'body', body, 'xhr', xhr);
})

gmail.observe.on("delete_forever", function(id, url, body, xhr) {
  console.log("id:", id, "url:", url, 'body', body, 'xhr', xhr);
})

gmail.observe.on("delete_message_in_thread", function(id, url, body, xhr) {
  console.log("id:", id, "url:", url, 'body', body, 'xhr', xhr);
})

gmail.observe.on("restore_message_in_thread", function(id, url, body, xhr) {
  console.log("id:", id, "url:", url, 'body', body, 'xhr', xhr);
})

gmail.observe.on("star", function(id, url, body, xhr) {
  console.log("id:", id, "url:", url, 'body', body, 'xhr', xhr);
})

gmail.observe.on("unstar", function(id, url, body, xhr) {
  console.log("id:", id, "url:", url, 'body', body, 'xhr', xhr);
})

gmail.observe.on("mark_as_important", function(id, url, body, xhr) {
  console.log("id:", id, "url:", url, 'body', body, 'xhr', xhr);
})

gmail.observe.on("mark_as_not_important", function(id, url, body, xhr) {
  console.log("id:", id, "url:", url, 'body', body, 'xhr', xhr);
})

gmail.observe.on("filter_messages_like_these", function(id, url, body, xhr) {
  console.log("id:", id, "url:", url, 'body', body, 'xhr', xhr);
})

gmail.observe.on("mute", function(id, url, body, xhr) {
  console.log("id:", id, "url:", url, 'body', body, 'xhr', xhr);
})

gmail.observe.on("unmute", function(id, url, body, xhr) {
  console.log("id:", id, "url:", url, 'body', body, 'xhr', xhr);
})

gmail.observe.on("add_to_tasks", function(url, body, data, xhr) {
  console.log("url:", url, 'body', body, 'task_data', data, 'xhr', xhr);
})

gmail.observe.on("move_label", function(id, url, body, xhr) {
  console.log("id:", id, "url:", url, 'body', body, 'xhr', xhr);
})

gmail.observe.on("save_draft", function(url, body, data, xhr) {
  console.log("url:", url, 'body', body, 'email_data', data, 'xhr', xhr);
})

gmail.observe.on("discard_draft", function(id, url, body, xhr) {
  console.log("id:", id, "url:", url, 'body', body, 'xhr', xhr);
})

gmail.observe.on("send_message", function(url, body, data, xhr) {
  console.log("url:", url, 'body', body, 'email_data', data, 'xhr', xhr);
})

gmail.observe.on("expand_categories", function(url, body, data, xhr) {
  console.log("url:", url, 'body', body, 'expanded_data', data, 'xhr', xhr);
})

gmail.observe.on("delete_label", function(id, url, body, xhr) {
  console.log("id:", id, "url:", url, 'body', body, 'xhr', xhr);
})

gmail.observe.on("show_newly_arrived_message", function(id, url, body, xhr) {
  console.log("id:", id, "url:", url, 'body', body, 'xhr', xhr);
})

gmail.observe.on("poll", function(url, body, data, xhr) {
  console.log("url:", url, 'body', body, 'data', data, 'xhr', xhr);
})

gmail.observe.on("new_email", function(id, url, body, xhr) {
  console.log("id:", id, "url:", url, 'body', body, 'xhr', xhr);
})

gmail.observe.on("refresh", function(url, body, data, xhr) {
  console.log("url:", url, 'body', body, 'data', data, 'xhr', xhr);
})

gmail.observe.on("open_email", function(id, url, body, xhr) {
  console.log("id:", id, "url:", url, 'body', body, 'xhr', xhr);
  console.log(gmail.get.email_data(id));
})

gmail.observe.on("upload_attachment", function(file, xhr) {
  console.log("file", file, 'xhr', xhr);
})

gmail.observe.before(action, callback)

Similar to gmail.observe.on, this method allows you to bind callbacks to specific events.

All of the standard actions in gmail.observe.on work here, with the exception of the DOM actions

The main difference between on and before is that these callbacks are fired before Gmail's XMLHttpRequest has been sent off the the Gmail servers. This means, where relevant, your callback function can change it prior to it departing by editing the xhrParams.body_params object in the passed xhr parameter.

gmail.observe.before('send_message', function(url, body, data, xhr){
  var body_params = xhr.xhrParams.body_params;

  // lets cc this email to someone extra if the subject is 'Fake example'
  if(data.subject == 'Fake example') {
    if(body_params.cc) {
      if(typeof body_params.cc != 'object') body_params.cc = [ body_params.cc ];
    } else {
      body_params.cc = [];
    }
    body_params.cc.push('brent@zeald.com');
  }

  // now change the subject
  body_params.subject = 'Subject overwritten!';
  console.log("sending message, url:", url, 'body', body, 'email_data', data, 'xhr', xhr);
});

gmail.observe.after(action, callback)

Similar to gmail.observe.on, this method allows you to bind callbacks to specific events.

All of the standard actions in gmail.observe.on work here, with the exception of the DOM actions

The main difference between on and after is that these callbacks are fired once Gmail's XMLHttpRequest has returned from the Gmail servers (on the XMLHttpRequest onreadystatechange event).

In addition to the usual parameters received by a callback, callbacks you define for an after event receive an additional response parameter prior to the last xhr parameter. This response parameter is a parsed object representation of the response from the Gmail servers.

So for example, the send_message action would receive:

gmail.observe.after("send_message", function(url, body, data, response, xhr) {
  console.log("message sent", "url:", url, 'body', body, 'email_data', data, 'response', response, 'xhr', xhr);
})

gmail.observe.off(action=null,type=null)

Turn off an observe action. Providing it no argument will disable all observers.

Type is either before, after, on or dom. If not specified will disable all types of specified observer.

gmail.observe.on('poll', function(x,y,z){});
gmail.observe.before('refresh', function(x,y,z){});
gmail.observe.after('send_message', function(x,y,z){});

gmail.observe.off('poll','on'); // disables on poll
gmail.observe.off('poll'); // disables all poll events of any type
gmail.observe.off(null,'before'); // disables all before observers
gmail.observe.off();  // disables all

Author and Licensing

twitter/therealkartik Inspired by gmailr.js
Kartik Talwar See License.md