Skip to content

Instantly share code, notes, and snippets.

@merrilymeredith
Created October 8, 2018 04:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save merrilymeredith/86fa75c95a2441c03170af7ea8ec2681 to your computer and use it in GitHub Desktop.
Save merrilymeredith/86fa75c95a2441c03170af7ea8ec2681 to your computer and use it in GitHub Desktop.
Google Apps Script for improving my gmail experience
"use strict"
// set to trigger daily 3a-4a
function archiveInbox() {
var count
do {
count = archiveInboxIncremental()
}
while (count !== 0)
}
function archiveInboxIncremental() {
var threads = GmailApp.search('in:inbox is:read -is:starred older_than:30d', 0, 50)
GmailApp.moveThreadsToArchive(threads)
Logger.log('Archived %s threads.', threads.length)
return threads.length
}
// My configuration: I'm filing messages that match
// 'from:(cases@mycompany.fogbugz.com) subject:(-"[bugzid:" "Fogbugz Case")'
// into Sort/fogbugz-new, skipping inbox. `search` returns just what's currently
// in the label, and `work_label` is the internal name for this label. Messages
// get a simple thread reference, adjusted subject, and are reinserted set as
// unread and in inbox. A simple munge is applied to Message-ID to keep gmail
// from regarding it as a duplicate before the original is removed.
// This was later adjusted for the change to the name "manuscript" and also to
// flag messages on tickets assigned to me.
"use strict"
var search = 'label:sort-fogbugz-new'
var work_label = 'Label_19'
var fogbugz_me = 'Meredith'
// set to trigger every minute
function threadFogBugz() {
var msgList = Gmail.Users.Messages.list('me', {q: search})
if (msgList.resultSizeEstimate === 0) return
Logger.log('Found %s messages', msgList.messages.length)
for (var i in msgList.messages) {
checkAndRewrite(msgList.messages[i].id)
}
}
function checkAndRewrite(msgid) {
var message = Gmail.Users.Messages.get('me', msgid, {format: 'raw'})
var labels = editLabels(message.labelIds)
var split_msg = header_split(ab_to_string(message.raw))
var headers = split_msg[0]
var body = split_msg[1]
if (isThreaded(headers)) return
var bugzid = findBugzid(headers)
if (!bugzid) return
var ref_msgid = '<bugzid@' + bugzid + '>'
var new_message = [
headers
.replace(/^Message-ID: <([^>]+)>/im, 'Message-ID: <$1-->')
.replace(/^Subject: +Manuscript \(Case \d+\)/im, 'Subject: [bugzid:' + bugzid + ']'),
'References: ' + ref_msgid,
'In-Reply-To: ' + ref_msgid,
'',
body,
].join("\r\n")
var new_labels = editLabels(message.labelIds)
if (isAssignedToMe(body)) new_labels.push('IMPORTANT', 'STARRED')
var resp = Gmail.Users.Messages.insert(
{
labelIds: new_labels,
threadId: message.threadId,
},
'me',
Utilities.newBlob(new_message, 'message/rfc822'),
{uploadType: 'multipart', internalDateSource: 'dateHeader'}
)
if (resp && resp.id) {
Gmail.Users.Messages.remove('me', msgid)
}
}
function editLabels(labels) {
return labels
.filter(function (label) {
return label !== work_label
})
.concat(['INBOX', 'UNREAD'])
}
function isThreaded(headers) {
return headers.match(/^References:|^In-Reply-To:/im) !== null
}
function isAssignedToMe(body) {
return body.match(new RegExp('^Assigned To:\\s+' + fogbugz_me + '$', 'm')) !== null
}
function findBugzid(headers) {
var re = /^Subject: +Manuscript \(Case (\d+)\)/im
var match
if ((match = re.exec(headers)) !== null) {
return match[1]
}
return null
}
function header_split(message) {
var split = message.indexOf("\r\n\r\n");
return [message.slice(0, split), message.slice(split + 4)]
}
function ab_to_string(ab) {
return Utilities.newBlob(ab).getDataAsString()
}
@merrilymeredith
Copy link
Author

I've been using these scripts for a few years now and wanted to publish them beyond sharing with coworkers. The first just archives read and unflagged messages out of my inbox after 30 days, so the inbox folder in IMAP doesn't grow forever. The second rewrites messages from FogBugz tickets to actually thread together (flatly), have a less verbose subject line, and flag them if it's actually assigned to me at the time.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment