Talk about add-ons and extension development.
user2018
Posts: 88Joined: September 23rd, 2018, 11:07 am
Posted September 30th, 2018, 9:58 am
Using JavaScript, I would like to go to the message that has a specific messageID. I know that it is possible to do this if you have the message's URI, by using:
var messenger = Cc["@mozilla.org/messenger;1"].createInstance(Ci.nsIMessenger); var msgHdr = messenger.msgHdrFromURI(messageURI); gFolderDisplay.selectMessage(msgHdr);
Is there an alternative for the cases when we don't have the URI of the message but we have its messageID?
Thanks a lot.
DanRaisch
Moderator

Posts: 124270Joined: September 23rd, 2004, 8:57 pmLocation: Somewhere on the right coast
Posted September 30th, 2018, 10:13 am
Moving to Thunderbird Support.
morat
Posts: 4287Joined: February 3rd, 2009, 6:29 pm
Posted September 30th, 2018, 11:56 am
It is possible to find the same message id in multiple folders, like in the inbox and all mail folders in a google mail account. Try these: - Code: Select all
// show msgUri of selected message var msgHdr = gFolderDisplay.selectedMessage; var msgUri = msgHdr.folder.getUriForMsg(msgHdr); alert(msgUri);
- Code: Select all
// select folder and message using msgUri var msgUri = "imap-message://username%40gmail.com@imap.googlemail.com/INBOX#123"; var msgHdr = messenger.msgHdrFromURI(msgUri); gFolderTreeView.selectFolder(msgHdr.folder); gFolderDisplay.selectMessage(msgHdr);
- Code: Select all
// show messageId of selected message var msgHdr = gFolderDisplay.selectedMessage; var messageId = msgHdr.messageId; alert(messageId);
- Code: Select all
// select message in current folder using messageId var messageId = "123456789@example.org"; var folder = gFolderDisplay.displayedFolder; var msgHdr = folder.msgDatabase.getMsgHdrForMessageID(messageId); gFolderDisplay.selectMessage(msgHdr);
The following examples use a recursive function. - Code: Select all
// show all folders function checkSubFolders(aFolder) { if (!aFolder.hasSubFolders) { return; } var enumerator = aFolder.subFolders; while (enumerator.hasMoreElements()) { var folder = enumerator.getNext(). QueryInterface(Components.interfaces.nsIMsgFolder); allFolders.push(folder.URI); checkSubFolders(folder); } } var am = Components.classes["@mozilla.org/messenger/account-manager;1"]. getService(Components.interfaces.nsIMsgAccountManager); var allServers = am.allServers; var numServers = allServers.length; var allFolders = new Array(); for (var i = 0; i < numServers; i++) { var server = allServers. queryElementAt(i, Components.interfaces.nsIMsgIncomingServer); checkSubFolders(server.rootFolder); } var data = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">'; data += "<html><head><title>Example</title>"; data += '<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">'; data += "</head><body><pre>" + allFolders.join("\n") + "</pre></body></html>"; document.getElementById("tabmail").openTab("contentTab", { contentPage: "data:text/html;charset=utf-8;base64," + btoa(data), background: false, });
- Code: Select all
// select folder and message using messageId var messageId = "123456789@example.org"; function checkSubFolders(aFolder) { if (!aFolder.hasSubFolders) { return; } var enumerator = aFolder.subFolders; while (enumerator.hasMoreElements()) { var folder = enumerator.getNext(). QueryInterface(Components.interfaces.nsIMsgFolder); var msgHdr = folder.msgDatabase.getMsgHdrForMessageID(messageId); if (msgHdr) { gFolderTreeView.selectFolder(msgHdr.folder); gFolderDisplay.selectMessage(msgHdr); alert("Click OK to continue."); } checkSubFolders(folder); } } var am = Components.classes["@mozilla.org/messenger/account-manager;1"]. getService(Components.interfaces.nsIMsgAccountManager); var allServers = am.allServers; var numServers = allServers.length; for (var i = 0; i < numServers; i++) { var server = allServers. queryElementAt(i, Components.interfaces.nsIMsgIncomingServer); checkSubFolders(server.rootFolder); }
P.S. It's best to post such topics in the Extension Development forum.
Last edited by morat on October 3rd, 2018, 8:00 am, edited 2 times in total.
DanRaisch
Moderator

Posts: 124270Joined: September 23rd, 2004, 8:57 pmLocation: Somewhere on the right coast
Posted October 1st, 2018, 3:40 am
Moving to Extension Development as recommended by morat.
user2018
Posts: 88Joined: September 23rd, 2018, 11:07 am
Posted October 1st, 2018, 11:37 am
Thank you very much for this great suggestion. I tried it but, when it starts traversing folders I eventually get the following exception:
Exception: [Exception... "Component returned failure code: 0x80550005 [nsIMsgFolder.msgDatabase]" nsresult: "0x80550005 (<unknown>)" location: "JS frame :: Scratchpad/1 :: checkSubFolders :: line 30" data: no]
As I added some "alert" for debugging purposes, line in my code 30 is:
var msgHdr = folder.msgDatabase.getMsgHdrForMessageID(messageId);
Any ideas about what could be wrong?
morat
Posts: 4287Joined: February 3rd, 2009, 6:29 pm
Posted October 1st, 2018, 2:22 pm
I don't know the best way to deal with an outdated msf condition. Error: uncaught exception... 0x80550005 [nsIMsgFolder.msgDatabase] http://bugzilla.mozilla.org/show_bug.cgi?id=493429Try this: - Code: Select all
// select folder and message using messageId var messageId = "123456789@example.org"; function checkSubFolders(aFolder) { if (!aFolder.hasSubFolders) { return; } var enumerator = aFolder.subFolders; while (enumerator.hasMoreElements()) { var folder = enumerator.getNext(). QueryInterface(Components.interfaces.nsIMsgFolder); var msgHdr = null; try { msgHdr = folder.msgDatabase.getMsgHdrForMessageID(messageId); } catch (e) { Components.utils.reportError(e); Services.console.logStringMessage("Debug: " + folder.URI); } if (msgHdr) { gFolderTreeView.selectFolder(msgHdr.folder); gFolderDisplay.selectMessage(msgHdr); alert("Click OK to continue."); } checkSubFolders(folder); } } var am = Components.classes["@mozilla.org/messenger/account-manager;1"]. getService(Components.interfaces.nsIMsgAccountManager); var allServers = am.allServers; var numServers = allServers.length;
MailUtils.discoverFolders(); // make sure folder tree is initialized
for (var i = 0; i < numServers; i++) { var server = allServers. queryElementAt(i, Components.interfaces.nsIMsgIncomingServer); checkSubFolders(server.rootFolder); }
Maybe try to force a reparse somehow. Similar thread: viewtopic.php?f=19&t=3041079
user2018
Posts: 88Joined: September 23rd, 2018, 11:07 am
Posted October 2nd, 2018, 12:10 am
Thanks a lot! This is really very useful. I tried the code in another computer and it works, even without the extra code for reparsing. So I think that I should assume that in the first computer I was using there are problems with some .msf files, which could also be probably solved by clicking on the folder and selecting "Properties"->"Repair Folder" (clicking) or by deleting the .msf files and let Thunderbird rebuild them. Did I interpret the problem correctly?
I found another minor issue. I was trying to avoid searching in special/virtual folders such as saved search folders by adding this:
if (aFolder.getFlag(MSG_FOLDER_FLAG_VIRTUAL) == true) { return; }
However, I get an error that the MSG_FOLDER_FLAG_VIRTUAL symbol cannot be found. Do I need to declare it or is there any way to import/include the nsMsgFolderFlags.h? This is probably a very simple question, but I am having a hard time to find an answer, as in the sample code I found they seem to be using the constant MSG_FOLDER_FLAG_VIRTUAL directly in the code. Adding the following line in my code solves the problem, but it does not seem to be the right way to do it:
var MSG_FOLDER_FLAG_VIRTUAL = 0x0020;
Thank you.
morat
Posts: 4287Joined: February 3rd, 2009, 6:29 pm
Posted October 2nd, 2018, 7:27 am
I don't know if you need to do a folder repair. Normally, a user selection of a folder would force a reparse. Try these: - Code: Select all
var folder = gFolderDisplay.displayedFolder; if (folder.getFlag(Components.interfaces.nsMsgFolderFlags.Virtual)) { alert("folder is a virtual folder"); } else { alert("folder is not a virtual folder"); }
- Code: Select all
var folder = gFolderDisplay.displayedFolder; if (folder.flags & Components.interfaces.nsMsgFolderFlags.Virtual) { alert("folder is a virtual folder"); } else { alert("folder is not a virtual folder"); }
- Code: Select all
var folder = gFolderDisplay.displayedFolder; var trashFolder = folder.rootFolder. getFolderWithFlags(Components.interfaces.nsMsgFolderFlags.Trash); alert(folder.URI + "\n" + trashFolder.URI);
Reference http://developer.mozilla.org/en/XPCOM_I ... IMsgFolderhttp://dxr.mozilla.org/comm-esr60/sourc ... rFlags.idlUnfortunately, the docs aren't that great so you need to search the source. I like to unzip the omni.ja file and do a search... - Code: Select all
findstr /spc:"getFlag" *
Findstr command http://ss64.com/nt/findstr.htmlSometimes searching the omni.ja file is easier than seaching the source online. Search "getFlag" in Thunderbird 60 http://dxr.mozilla.org/comm-esr60/search?q=getFlag
user2018
Posts: 88Joined: September 23rd, 2018, 11:07 am
Posted October 3rd, 2018, 1:36 am
Thanks a lot. This looks really nice. However, now I get a similar component failure error when I try to go to a message directly using the URI of the message:
Exception: [Exception... "Component returned failure code: 0x80070057 (NS_ERROR_ILLEGAL_VALUE) [nsIMessenger.msgHdrFromURI]" nsresult: "0x80070057 (NS_ERROR_ILLEGAL_VALUE)" location: "JS frame :: Scratchpad/1 :: <TOP_LEVEL> :: line 62" data: no]
I tried to solve it with a similar solution, but I keep getting the same error:
var messenger = Cc["@mozilla.org/messenger;1"].createInstance(Ci.nsIMessenger); var msgHdr = null; try { msgHdr = messenger.msgHdrFromURI(messagePointer); } catch (e) { Components.utils.reportError(e); Services.console.logStringMessage("Debug: " + messagePointer); } if (msgHdr) { gFolderTreeView.selectFolder(msgHdr.folder); gFolderDisplay.selectMessage(msgHdr); }
Any ideas? Thank you very much.
morat
Posts: 4287Joined: February 3rd, 2009, 6:29 pm
Posted October 3rd, 2018, 5:52 am
Is the messagePointer a message URI or a folder URI? I get the same error with the following code. - Code: Select all
var msgHdr = gFolderDisplay.selectedMessage; var msgUri = msgHdr.folder.getUriForMsg(msgHdr); msgHdr = messenger.msgHdrFromURI(msgUri); msgHdr = messenger.msgHdrFromURI(msgHdr.folder.URI); // error
user2018
Posts: 88Joined: September 23rd, 2018, 11:07 am
Posted October 3rd, 2018, 6:17 am
In my case, it is a message URI.
Return to Extension Development
Who is online
Users browsing this forum: No registered users and 1 guest
|