
My Email sig tells everyone (and me) how many unread messages I have in my inbox. It’s been a nice motivator to keep on top of my mail. Another example of how increasing transparency, though sometimes uncomfortable, is generally a good thing if you can push yourself to do it.
I’ve had several people ask me about it, so I thought I’d just paste in the source code I used below. It’s a greasemonkey script that was quickly written for me by a nice guy named Valentin (you can find his info below). You have to run a browser on which you can install greasemonkey, but if it’s any use, here you go:
// ==UserScript==
// @name Gmail Inbox Unread Count Signature
// @namespace http://valentinlaube.de/projects/greasemonkey/
// @description Replaces the string %unread_count% in your signature with the number of unread messages in your inbox.
// @include http://mail.google.com/*
// @include https://mail.google.com/*
// ==/UserScript==
// helper function copied from “Google Image Relinker” Greasemonkey script
function selectNodes(doc, context, xpath) {
var nodes = doc.evaluate(xpath, context, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
var result = new Array( nodes.snapshotLength );
for (var x=0; x < result.length; x++)
{
result[x] = nodes.snapshotItem(x);
}
return result;
}
function GM_callback(fn) {
return function() {
setTimeout(fn, 0);
}
}
function getUnreadCount() {
var doc = g_gmail.getNavPaneElement().ownerDocument;
var label = selectNodes(doc, doc.body, “//a[contains(@title,'Inbox ')]“)[0];
var labelText;
if(label) {
labelText = label.textContent;
} else {
// maybe it is collapsed
label = selectNodes(doc, doc.body, “//span[contains(text(),'Mail ')]“)[0];
labelText = label;
}
var unreadCountString = label.textContent.match(/.*\((.*)\)/)[1];
return parseInt(unreadCountString);
}
function getTotalMessageCount() {
/*
var top_bar = g_gmail.getActiveViewElement().firstChild;
console.log(g_gmail.getMastheadElement());
var totalMessagesCountString = top_bar.textContent.match(/.* of ([0-9]*)/)[1];
*/
var doc = unsafeWindow.top.document.getElementById(“canvas_frame”).contentDocument;
var nodes = selectNodes(doc, doc.body, “//span[count(b)=3]/b”)
var totalMessagesCountString = nodes[nodes.length-1].textContent;
return totalMessagesCountString;
}
function getBodyTextElement() {
var activeElement = g_gmail.getActiveViewElement();
if(!activeElement) {
return false;
}
var doc = activeElement.ownerDocument;
if(!doc) {
return false;
}
var textarea = selectNodes(doc, doc.body, “//textarea[@name='body']“)[0];
return textarea;
}
function getBodyHTMLElement() {
var activeElement = g_gmail.getActiveViewElement();
if(!activeElement) {
return false;
}
var doc = activeElement.ownerDocument;
if(!doc) {
return false;
}
var iframebody=selectNodes(doc, doc.body, “//iframe[contains(@class,'editable')]“);
if(iframebody.length<1) {
return false;
}
return iframebody[iframebody.length-1].contentDocument.body;
}
function getBodyText(elm) {
return elm.value;
}
function getBodyHTML(elm) {
return elm.innerHTML;
}
function splitTextAtRegex(text, regex) {
var splitIndex = text.search(regex);
var before = text.slice(0, splitIndex);
var after = text.slice(splitIndex);
return [before, after];
}
function splitBodyText(body) {
return splitTextAtRegex(body, /^– $/m)
}
function splitBodyHTML(body) {
return splitTextAtRegex(body, /<br>– <br>/m)
}
function setBodyText(text) {
getBodyTextElement().value = text;
}
function setBodyHTML(text) {
getBodyHTMLElement().innerHTML = text;
}
function replaceSignature(signature) {
signature = signature.replace(/%unread_count%/m, getUnreadCount());
signature = signature.replace(/%total_count%/m, GM_getValue(“totalMessageCount”));
return signature;
}
function changeSignatureText() {
var elm = getBodyTextElement();
if(!elm) {
return;
}
message = getBodyText(elm);
[message, signature] = splitBodyText(message);
newSignature = replaceSignature(signature);
if(newSignature == signature) {
return;
}
setBodyText(message+newSignature)
}
function changeSignatureHTML() {
var elm = getBodyHTMLElement();
if(!elm) {
return;
}
message = getBodyHTML(elm);
[message, signature] = splitBodyHTML(message);
if(!signature) {
return;
}
var newSignature = replaceSignature(signature);
if(newSignature == signature) {
return;
}
setBodyHTML(message+newSignature);
}
function viewChangeCallback() {
// return when not in compose mode
if(g_gmail.getActiveViewType()!=”co” && unsafeWindow.top.location.hash!=”#compose”) {
if(unsafeWindow.top.location.hash==”#inbox”) {
GM_setValue(“totalMessageCount”, getTotalMessageCount());
}
return;
}
changeSignatureText();
changeSignatureHTML();
}
var g_gmail;
function gmailCallback() {
g_gmail = unsafeWindow.gmonkey.get(“1.0″);
try {
g_gmail.registerViewChangeCallback(GM_callback(viewChangeCallback));
window.setInterval(function(e) {
changeSignatureText();
changeSignatureHTML();
}, 500);
} catch (ex) {
// try again
window.setTimeout(gmailCallback, 500);
}
}
window.addEventListener(“load”, function() {
if (unsafeWindow.gmonkey) {
unsafeWindow.gmonkey.load(“1.0″, gmailCallback);
}
});