GmailThread ID is evil

Seems like GmailThread.getId() isn't always persistent. What good is a primary key which can occasionally change its value? I've now verified that this behavior is so unexpected that it is documented as well.

The recommended workaround is to not use the Thread ID, but use the ID of each message instead. However, this gets messy as if you want a persistent reference to a thread, you need to do the following dance:

var id = thread.getMessages()[0].getId();
// serialize id, and read it back later
var thread2 = GmailApp.getMessageById(id).getThread();

Which kind of defeats the purpose of not needing to do slow fetching of all messages of each thread to draw conclusions about the thread itself when processing a search result. Yes, I'm trying to simulate Gmail filters by hand and need to watch out for quotas. I think I'm going for a hack based on getFirstMessageSubject() and/or getPermaLink(). And before you ask: no, there is no such thing as getThreadByPermaLink().

After seeing this, I wouldn't be surprised if a future erratum of the documentation stated that "sorry, actually the message ID can change as well depending on the current state of starring, unread status, or the time of day."

update 1: Consider what happens if the user deletes the pinned first message of a thread. We're lucky that the trash folder is accessible for 30 days. Unfortunately, that's not enough time for all use cases and the user can also manually purge messages from there. Actually a complete workaround would involve storing the ID of every message in a thread along with the permalink, which is ridiculous. At this point, parsing the HTML page pointed to by the permalink is starting to get an ever viable solution, though that could hit an URLFetch quota pretty fast.

update 2: After some months of testing, I conclude that the permalink URL based workaround doesn't work. The thread URL is only differentiated by a thread ID, so back to the drawing board. I'll be using a redundantly keyed map with getId() and when no match is found I'll resort to getFirstMessageSubject() with a verification step involving getMessages()[0].getId() (or if that changes as well, move to getDate() and getFrom()) and perhaps I could also try getLabels(), isImportant(), isInChats() and isInInbox() as well if this occurs more often.

Comments

Popular posts from this blog

Tftp secret of TL-WR740N uncovered

Hidden TFTP of TP-Link routers

Haskell for embedded: C output, compilers, monads, Timber