Using the Multiple Accounts API
By Alec Flett firstname.lastname@example.org
The account system consists of:
Here's an example of a common setup.
The Account Manager (nsIMsgAccountManager): There is a single account manager
in the the client, which maintains the list of accounts, servers, etc.
It is also responsible for the creation of any new account-related objects.
The account manager maintains the main list of Accounts.
Accounts (nsIMsgAccount): An account consists of a single incoming server,
and one or more identities. An account is merely a container to bind incoming
servers and identities together.
Incoming Servers (nsIMsgIncomingServer): An incoming server represents
a remote message store such as a POP, IMAP, or NNTP server. It holds all
the information necessary to retrieve mail from the remote server, such
as hostname, user login name, and biff settings.
Identities (nsIMsgIdentity): An identity contains all the information necessary
to compose and outgoing mail message. It includes a user's full
name and e-mail address.
SMTP Servers (nsISmtpServer): An SMTP server is not tied to any of the above and can be retrieved from the SMTP Service (nsISmtpService).
(You'll have to pardon the crude drawing for now)
+- Account 1
| +- Incoming Server 1 (imap.mywork.com IMAP Server, my work account)
| +- Identity 1 (Alec Flett <email@example.com>)
+- Account 2
| +- Incoming Server 2 (pop.myisp.com POP Server, my ISP account)
| +- Identity 2 (Alec Flett <firstname.lastname@example.org>)
+- Account 3
| +- Incoming Server 3 (news.myisp.com NNTP server, my ISP's server)
| +- Identity 3 (Alec Flett <alecfNOSPAM@myisp.com>)
+- Account 4
+- Incoming Server 4 (news.mozilla.org NNTP server, mozilla devel)
+- Identity 2 (Alec Flett <email@example.com>)
+- Identity 3 (Alec Flett <alecfNOSPAM@myisp.com>)
This is the internal structure that the mail client maintains,
but it is presented to the user in a few different ways.
(You may have noticed that Identities 2 and 3 are shared between a few accounts...more on that later)
Servers are show in the folder pane, and in any place where the user must browse or choose folders, such as the new folder dialog, search, filters, etc. The view shows a flat, unified view of all the servers. The above example would look like this:
Relevant API calls:
alecf on imap.mywork.com
alecf on pop.myisp.com
- nsIMsgAccountManager.allServers: a list of all servers held by all accounts.
Identities are used in the compose window. If identities are shared between accounts, you will only see that identity once in the list.
In the above example, the list of identities would be as follows:
Relevant API calls:
Alec Flett <firstname.lastname@example.org>)
Alec Flett <email@example.com>)
Alec Flett <alecfNOSPAM@myisp.com>)
- nsIMsgAccountManager.allServers: a list of all servers across all accounts
The accounts are stored in the preferences. The accounts, identities, and servers are all linked via keys. Keys are simply internal strings that uniquely identify each account, identity and server. The keys are also used to decide the name of each of the preferences that hold the object's data.
As an example, the above structure would be represented in your preferences like this:
There is a lot of information missing here of course.
The keys used here are the account1, server1, id1, etc. These keys are listed in the value of some of these preferences, such as "mail.accountmanager.accounts", and are used to construct the preference names, such as "mail.account.account1.server". This the way accounts know which server and which identities they contain.
It is possible to create and modify accounts through the account manager API. The account manager is responsible for the creation of all accounts, incoming servers, and identities. You should not use CreateInstance() to create any of the relevant objects because the account manager needs to keep track of all of these objects as they are created.
To create accounts using the API, you should do the following:
- Create a fresh identity with createIdentity();
- Assign values to the various identity properties as necessary.
- Create a fresh incoming server with createIncomingServer(). You will need to pass it the server type as a string, from the list above.
- Assign values to the various server properties as necessary. The most important properties here are the userName and the hostname.
- Create a fresh account with createAccount();
- Assign the server to the account with the incomingServer attribute.
- Assign the identity to the account with the AddIdentity() method.
Some sample code: (where accountManager is the account manager.
var identity = accountManager.createIdentity();
var server = accountManager.createIncomingServer("pop3");
server.userName = "fred";
server.hostname = "pop.myisp.com";
var account = accountManager.createAccount();
account.incomingServer = server;
That's it! Now you have a working account, identity, and server.
It is possible, through some tricks with server and identity keys, to share servers and identities between accounts. You can do this by referring to the same identity or server key in the preferences, or with clever calls to the account manager. (Left as an exercise for the reader.)This will work but it is not supported. The UI will act slighty strange when you share information between accounts. The current plans prevent sharing of information between accounts using the UI.
Relevant API calls:
- nsIMsgAccount nsIMsgAccountManager.createAccount()
- nsIMsgAccount nsIMsgAccountManager.getAccount(in string key)
- nsIMsgIncomingServer nsIMsgAccountManager.createIncomingServer(in string type)
- nsIMsgIncomingServer nsIMsgAccountManager.getIncomingServer(in string key)
SMTP Servers are kept separately from all the other account management stuff. A user's SMTP servers are not actually dependant on any of the account settings. The only thing that determines which SMTP server a user should use is their physical connection to the internet. For instance, if a user is connected to the internet through MyISP, Inc. then he or she must use MyISP's SMTP server, no matter what identity they will be sending mail with.
The SMTP server list is accessable through the SMTP Service. You can add (and eventually delete) servers and have a default server.
SMTP servers are stored in your preferences in a manner resembling the accounts:
You can add new SMTP servers using the SMTP service.
var server = smtpService.createSmtpServer();
server.hostname = "smtp.myisp.com";
The default SMTP server is the first server in the list in your preferences. Currently, you can set the default SMTP server to something else by setting the defaultServer property on the smtpService, but that will not be saved to disk. Eventually there will be the concept of a session default server, and a permenant default server.
Relevant API calls:
- nsISmtpService.smtpServers: list of SMTP servers
- nsISmtpService.createSmtpServer(): Create a new SMTP server
- nsISmtpServer.hostname, nsISmtpServer.username: Useful properties of the SMTP server.
(When brendan's idldoc comes along, I'll just link to that)
All preferences are strings, unless otherwise noted.
The incoming server associated with this account. The preference is the preference "key" used, such as "server1".
The list of identites associated with this account. The preference is a comma-seperated list of preference "keys" such as "identity1,identity2".
The following are specific to IMAP:
- Preference: mail.server.server.type: String id of the server type: pop3, nntp, imap, or local
- Preference: mail.server.server.hostname - hostname of the server
- Preference: mail.server.server.username - user login name
- Preference: mail.server.server.password - user login password
- Preference: mail.server.server.check_new_mail - boolean, should we check for new mail on a regular basis?
- Preference: mail.server.server.check_time - integer, number of minutes between checks for new mail
- Preference: mail.server.server.remember_password - boolean, should we remember the password?
- Preference: mail.server.server.download_on_biff. - boolean, Should we download new messags on biff (true) or just alert user that there is new mail (false)
- Preference: mail.server.server.directory - local platform-specific path to store messages and folder indexes
- Preference: mail.server.server.name - User-visible name of server
- Preference: mail.server.server.admin_url - administration URL for server
- Preference: mail.server.server.using_subscription - boolean, should we use subscriptions? (i.e. use LSUB instead of LIST)
- Preference: mail.server.server.cleanup_inbox_on_exit - boolean, should we purge the inbox when we quit?
- Preference: mail.server.server.dual_use_folders - boolean - can folders contain both folders and messages?
- Preference: mail.server.server.empty_trash_on_exit boolean, (should not be imap-specific) - should we empty this server's trash when we quit?
- Preference: mail.server.server.offline_download - boolean, is this server marked for offline download?
- Preference: mail.server.server.override_namespaces - boolean, should we override namespaces on this server?
- Preference: mail.server.server.max_cached_connections - integer, max number of connections left open to the server
- Preference: mail.server.server.empty_trash_threshhold integer, (should not be imap-specific) max k of wasted diskspace before we purge a folder
- Preference: mail.server.server.delete_model - integer, delete model (move to trash, IMAP delete, purge immediately, not sure of values)
- Preference: mail.server.server.timeout - integer, number of minutes a connection is idle before we drop it
- Preference: mail.server.server.capability - list of capabilities of this server
- Preference: mail.server.server.namespace.public - the server's namespace for public folders
- Preference: mail.server.server.namespace.personal - the server's namespace for personal folders
- Preference: mail.server.server.namespace.other_users - the server's namespace for other user's folders
The following are specific to POP:
- Preference: mail.server.server.leave_on_server - boolean, should we leave messages on the server after we have downloaded them?
- Preference: mail.server.server.delete_mail_left_on_server - boolean, when we delete a message locally, should we delete that message on the server?
The following are specific to news:
- Preference: mail.server.server.newsrc.file - platform specific file path to newsrc file
Preference: mail.identity.identity.fullName - the user's full name, i.e. John Smith
Preference: mail.identity.identity.useremail - the user's e-mail address, i.e. firstname.lastname@example.org
Preference: mail.identity.identity.reply_to - reply to address during message composition, should only be used if different than useremail. (ReplyTo: header in mail messages)
Preference: mail.identity.identity.organization - User's organization (Organization: header in mail messages)
Preference: mail.identity.identity.compose_html - boolean, should we compose messages in HTML (true) or Plain Text (false)?
Preference: mail.identity.identity.attach_vcard - boolean, should we attach the vCard?
Preference: mail.identity.identity.attach_signature - boolean, should we attach the signature?
Preference: mail.identity.identity.fcc - boolean, should we keep a copy of messages in our sent folder?
Preference: mail.identity.identity.fcc_folder - URI of folder to put sent messages in
Preference: mail.identity.identity.bcc_self - boolean, should we blind carbon copy (BCC) this identity with each e-mail sent with this identity?
Preference: mail.identity.identity.bcc_other - boolean, should we BCC other e-mail addresses with each mail sent with this identity?
Preference: mail.identity.identity.bcc_other_list - comma-seperated list of other addresses to BCC
Preference: mail.identity.identity.draft_folder - URI of folder to use for drafts
Preference: mail.identity.identity.stationary_folder - URI of folder to use for stationary (called Templates in 4.x)
Preference: mail.identity.identity.spam_folder - URI of folder to use for SPAM (I think this is cut)