Mail Composition "Back End"
by Richard H. Pizzarro <rhp@netscape.com>
Contents
Overview
I've done considerable work in the past few weeks
reorganizing the Mail Composition back end, so I thought it would be helpful
to put together a small doc on the new interfaces and how one can use them.
The Mail Composition back end is responsible for the assembly and creation
of RFC822 messages to be delivered either via SMTP or NNTP services. You
also have the ability to save RFC822 files to disk, should you need this
data for some reason. Included in this functionality is the code to copy
the messages to the appropriate locations after delivery (i.e. a "Sent"
folder) as well as the ability to store messages for features like "Drafts"
and "Templates". Several (but not all) of these interfaces are specified
in IDL. This will change in the coming weeks and allow for developers to
write JavaScript to take advantage of the back end services. Also, I will
talk about some features though they may not be complete as of yet. I will
try to make comments for these exceptions.
Sending
Messages
The primary responsibility of the back end is for the creation and
sending of RFC822 messages. The interface that accomplishes this task is
the nsIMsgSend interface. The feedback mechanism is provided by
a nsIMsgSendListener which is implemented by the caller. The caller
has the ability to add or remove listener interfaces to the nsIMsgSend
object and the interface can support multiple listeners. (For detailed
information on the listener interfaces, see the Listener
Interfaces section of this document)
nsIMsgSend
The following describes the methods of the nsIMsgSend interface.
All of these methods are asynchronous operations.
The CreateAndSendMessage method will create an RFC822 message
and send it all in one operation as well as providing the ability to save
disk files for later use. The mode of delivery can also be specified for
the "Send Later", "Drafts" and "Templates" operations. (NOTE:
This method could easily be broken in to a few different calls. Currently,
this method does several functions depending on the arguments passed in,
but this could easily lead to confusion. This is something that very well
may change as time allows).
NS_IMETHOD
CreateAndSendMessage(
nsIEditorShell
*aEditor,
- the editor object for the mail compose operation.
If this is not null, the body will be extracted from this object and any
embedded objects or links will be sent as part of the message in MHTML
nsIMsgIdentity
*aUserIdentity,
- the user identity for the person doing the
send operation. This will be needed to determine the appropriate folder
for copy operations.
nsIMsgCompFields
*fields,
- the message composition fields. This will contain
all of the relevant header information for message creation
PRBool
digest_p,
- this is a flag that says that most of the documents
we are attaching are themselves messages, and so we should generate a multipart/digest
container instead of multipart/mixed. (It's a minor difference.)
PRBool
dont_deliver_p,
- If "dont_deliver_p" is false, then we actually
deliver the message to the SMTP and/or NNTP server
nsMsgDeliverMode
mode,
- mode is the delivery mode. This can be set
for the various modes of delivery. These can include nsMsgDeliverNow, nsMsgQueueForLater,
nsMsgSave, nsMsgSaveAs, nsMsgSaveAsDraft, nsMsgSaveAsTemplate.
nsIMessage
*msgToReplace,
- if the delivery mode is set to nsMsgSaveAsDraft,
this is a pointer to the the nsIMessage object for the message that needs
to be replaced
const char
*attachment1_type,
const char
*attachment1_body,
PRUint32
attachment1_body_length,
- the full text of the first attachment is provided
via `attachment1_type' `attachment1_body' and `attachment1_body_length'.
These may all be 0 if all attachments are provided externally.
const struct nsMsgAttachmentData *attachments,
- Subsequent attachments are provided as URLs
to load, described in the nsMsgAttachmentData structures.
const struct nsMsgAttachedFile *preloaded_attachments,
- attachments that are already locally stored
on disk (note: both attachments and preloaded_attachments cannot be specified
on a single call
void
*relatedPart /* nsMsgSendPart */,
- a related part for multipart related operations
nsIMsgSendListener
**aListenerArray) = 0;
- an array of listeners for the send operation.
this can be nsnull if you want to do the delivery operation "blind"
The SendMessageFile method will let the caller send a message
that has been created by another process (Note: CreateAndSendMessage can
accomplish this task).
NS_IMETHOD SendMessageFile(
nsIMsgIdentity
*aUserIdentity,
- the user identity for the person doing the
send operation. This will be needed to determine the appropriate folder
for copy operations.
nsIMsgCompFields
*fields,
- the message composition fields. This will contain
all of the relevant header information for message delivery
nsFileSpec
*sendFileSpec,
- the file spec for the message being sent
PRBool
deleteSendFileOnCompletion,
- tell the back end if it should delete the file
upon successful completion
PRBool
digest_p,
- this is a flag that says that most of the documents
we are attaching are themselves messages, and so we should generate a multipart/digest
container instead of multipart/mixed. (It's a minor difference.)
nsMsgDeliverMode
mode,
- mode is the delivery mode. This can be set
for the various modes of delivery. These can include nsMsgDeliverNow, nsMsgQueueForLater,
nsMsgSave, nsMsgSaveAs, nsMsgSaveAsDraft, nsMsgSaveAsTemplate.
nsIMessage
*msgToReplace,
- if the delivery mode is set to nsMsgSaveAsDraft,
this is a pointer to the the nsIMessage object for the message that needs
to be replaced
nsIMsgSendListener
**aListenerArray) = 0;
- an array of listeners for the send operation.
this can be nsnull if you want to do the delivery operation "blind"
The SendWebPage method is a convenience function that will let
the caller send a web page by specifying a URI. NOTE: This can be any valid
URI so one can send local disk files by specifying a file:// URI.
NS_IMETHOD SendWebPage(
nsIMsgIdentity
*aUserIdentity,
- the user identity for the person doing the
send operation. This will be needed to determine the appropriate folder
for copy operations.
nsIMsgCompFields
*fields,
- the message composition fields. This will contain
all of the relevant header information for message delivery
nsIURI
*url,
- the URI of the message composition fields.
This will contain all of the relevant header information for message delivery
nsMsgDeliverMode
mode,
- mode is the delivery mode. This can be set
for the various modes of delivery (i.e. send later, drafts, templates or
send the message now)
nsIMsgSendListener
**aListenerArray) = 0;
- an array of listeners for the send operation.
this can be nsnull if you want to do the delivery operation "blind"
The AddListener/RemoveListener methods let the caller add and
remove listeners to the sending interface.
NS_IMETHOD AddListener(nsIMsgSendListener
*aListener) = 0;
NS_IMETHOD RemoveListener(nsIMsgSendListener
*aListener) = 0;
Sending
Listener Interfaces
The nsIMsgSendListener interface will let a caller keep track
of the progress and any status of a send operation. These are critical
for message delivery since message sending is asynchronous. It is the only
way to determine if the operation was successful or not. An important item
to note is the fact that this interface should also implement the nsIMsgCopyServiceListener
interface if it wants to be notified of the progress and completion of
the copy operation.
nsIMsgSendListener
The following describes the methods of the nsIMsgSendListener
interface:
The OnStartSending interface is called when the sending operation
has begun. This is called after messages creation has completed. If message
creation fails, the nsIMsgSend operation will return an NS_FAILED() return
code.
NS_IMETHOD OnStartSending(const
char *aMsgID,
- the message ID for the message being sent
PRUint32 aMsgSize) = 0;
- the total message size for the message being
sent
The OnProgress interface is called with progress notification
on the send operation.
NS_IMETHOD OnProgress(const char
*aMsgID,
- the message ID for the message being sent
PRUint32 aProgress,
- the progress so far
PRUint32 aProgressMax) = 0;
- the maximum progress (aProgress should be used
as a numerator and aProgressMax as a denominator for a message sent percentage)
The OnStatus gives the listener status updates for the current
operation.
NS_IMETHOD OnStatus(const char
*aMsgID,
- the message ID for the message being sent
const PRUnichar *aMsg) = 0;
- a message concerning the status of the send
operation
The OnStopSending interface is called when the sending operation
has completed. This will be called in the case of both success and failure.
NS_IMETHOD OnStopSending(const
char *aMsgID,
- the message ID for the message being sent
nsresult aStatus,
- the resulting status for the send operation
const PRUnichar *aMsg,
- a message concerning the status of the send
operation
nsIFileSpec *returnFileSpec) = 0;
- an nsIFileSpec which will specify the file
that was created (this is used if the dont_deliver_p
argument
is set to PR_TRUE)
nsIMsgCopyServiceListener
The nsIMsgCopyServiceListener interface will notify the implementor
or the progress and completion of the copy operation that follows successful
send operations.
The OnStartCopy interface is called when the copy operation has
begun.
NS_IMETHOD OnStartCopy(
nsISupports *listenerData) = 0;
- the nsISupports pointer passed in to the original
copy operation
The OnProgress interface is called with progress notification
for the copy operation.
NS_IMETHOD OnProgress(
PRUint32 aProgress,
- the progress so far
PRUint32 aProgressMax) = 0;
- the maximum progress (aProgress should be used
as a numerator and aProgressMax as a denominator for a message sent percentage)
nsISupports *listenerData) = 0;
- the nsISupports pointer passed in to the original
copy operation
The OnStopCopy interface is called when the copy operation has
completed. This will be called in the case of both success and failure.
NS_IMETHOD OnStopCopy(
nsresult aStatus,
- the resulting status for the send operation
nsISupports *listenerData) = 0;
- the nsISupports pointer passed in to the original
copy operation
Copy Operations
There are various copy operations that can result as a part of message
creation and delivery. These are all controlled by the caller in various
way. The following details the specific copy operations that can occur
in a message send call.
Copy to
Sent Folder
Copying to the "Sent" folder is controlled by a setting in the nsIMsgCompFields
interface. The SetFcc() and GetFcc() methods are used by the caller to
control if a message should be copied to the defined "Sent" folder if the
sending operation was successful. Currently, this pref is a "char *" which
is the specific name of the folder, but this will more than likely change
to a PRBool (boolean) preference. The determiniation of which folder is
the "Sent" folder for the user is done by a call to GetFoldersWithFlag()
and the message store will control this user defined preference. If the
setting for GetFcc() is set to true, the copy operation is automatically
performed after a successful send operation.
Drafts
Saving a message as a draft is controlled by the "nsMsgDeliverMode
mode" argument of the CreateAndSendMessage and SendMessageFile
methods.
If the caller passes in nsMsgSaveAsDraft,
the
file created or passed in will be stored as a draft in the user specified
"Drafts" folder.
Templates
Like Drafts, saving a message as a template is controlled by the "nsMsgDeliverMode
mode" argument of the CreateAndSendMessage and SendMessageFile
methods.
If the caller passes in nsMsgSaveAsTemplate,
the
file created or passed in will be stored as a draft in the user specified
"Templates" folder.
Send
Later
Developers also have the ability to do "Send Later" operations. This
will store messages in the user defined "Unsent Messages or Drafts" folder.
This simply does a save operation similar to Drafts and Templates. Send
Later operations are controlled by the "nsMsgDeliverMode
mode" argument of the CreateAndSendMessage and SendMessageFile
methods.
If the caller passes in nsMsgQueueForLater.
Sending
Unsent Messages
The back end has the ability to send all messages that are currently
stored in the user defined "Unsent Messages or Drafts" folder. (See Send
Later above) The nsIMsgSendLater is the interface that allows
the caller to send all of the files previously stored. The caller will
implement an nsIMsgSendLaterListener interface to monitor the progress
of the send operations.
The following describes the methods of the nsIMsgSendLater interface.
This method is performs the send operations asynchronously.
The SendUnsentMessages method will send all queued messages.
NS_IMETHOD SendUnsentMessages(nsIMsgIdentity
*identity,
- the user identity for the person doing the
send operation. This will be needed to determine the appropriate folder
for copy operations.
nsIMsgSendLaterListener **listenerArray) = 0;
- an array of listeners for the send operation.
this can be nsnull if you want to do the delivery operations "blind"
The AddListener & RemoveListener methods will add and remove
listeners from the nsIMsgSendLater object.
NS_IMETHOD AddListener(nsIMsgSendLaterListener
*aListener) = 0;
NS_IMETHOD RemoveListener(nsIMsgSendLaterListener
*aListener) = 0;
Sending
Unsent Messages Listener
The nsIMsgSendLaterListener interface will notify the implementor
of the progress and completion of the send later operations.
The OnStartSending interface is called when the send later operation
has begun.
NS_IMETHOD OnStartSending(
PRUint32 aTotalMessageCount) = 0;
- the total messages to be sent
The OnProgress interface is called with progress notification
of the send later operation.
NS_IMETHOD OnProgress(
PRUint32 aCurrentMessage,
- the current message being sent
PRUint32 aTotalMessage) = 0;
- the total messages to be sent
The OnStatus gives the listener status updates for the current
operation.
NS_IMETHOD OnStatus(
const PRUnichar *aMsg) = 0;
- the progress so far
The OnStopSending interface is called when the send later operation
has completed.
NS_IMETHOD OnStopSending(
nsresult aStatus,
- the resulting status for the send operation
const PRUnichar *aMsg,
- a status message
PRUint32 aTotalTried,
- the total messages that were attempted
PRUint32 aSuccessful) = 0;
- the number of successful messages
Quoting
Quoting a mail message is made possible via the nsIMsgQuote
interface. It is a simple interface that takes a consumer output stream
for the quoted data. The message will be output in HTML form and it is
up to the caller to handle plain text conversion.
The QuoteMessage method is the primary interface for message
quoting.
NS_IMETHOD QuoteMessage(
const PRUnichar *msgURI,
- the URI of the message to be quoted
nsIOutputStream *outStream) = 0;
- the consumer output stream for the quoted data
Sample
Programs
The mozilla/mailnews/compose/tests/
directory contains sample test programs for all of the above described
interfaces.
-
compose
- this program shows the use of the CreateAndSendMessage interface
(CreateAndSendMessage)
-
compose2
- this program shows the use of the CreateAndSendMessage interface
(SendMessageFile)
-
sendlater
- this program shows the use of the nsIMsgSendLater interface
-
sendpage
- this program shows the use of the CreateAndSendMessage interface
(SendWebPage)
Last modified: Tue Sep 28 23:17:57 PDT 1999
rhp@netscape.com
|