|
Chapter 6: CDO Messaging
Chapter 6 CDO MessagingRemember when the fastest and easiest way to communicate with your coworkers in other offices and with colleagues at other companies was to pick up the telephone and call them? That wasn’t very long ago. Now, although the phone is still essential to doing business, e-mail has replaced it as our most important telecommunication link. Today when a phone system goes down, it’s a nuisance but not a disaster. (For that matter, many people now have cell phones.) However, when a messaging server goes down, the world seems to stop. Entire businesses come to their knees when e-mail isn’t working. People depend on this quick and easy form of communication for everything from handling standard business practices, such as invoice approvals, to providing the necessary link between international offices any time of the day.More and more applications have messaging integrated into them. To keep up with this increasing demand, Collaboration Data Objects (CDO) for Microsoft Exchange 2000 Server provides a robust set of classes and interfaces to develop rich messaging applications. This chapter explains the core techniques necessary to build the simplest application or the most complex solution. Sections include:
Overview of CDO MessagingMicrosoft Exchange 2000 Server and CDO support the Internet standards that specify how messages should be formatted for transmission across a network. By conforming to these standards, CDO for Microsoft Windows 2000 and CDO for Exchange can be used to build messaging solutions that function across a broad range of protocols, including Simple Mail Transfer Protocol (SMTP) and Network News Transfer Protocol (NNTP). The messages themselves are structured using Multipurpose Internet Mail Extensions (MIME), the currently accepted standard for messaging. This chapter focuses on MIME-formatted messages unless stated otherwise.MIME enables any client program to decode and display complex message bodies, such as those that contain HTML tags, rich text, and structured attachments. MIME is highly flexible and allows each piece of an electronic mail message to be managed independently of, or in relation to, the other parts without affecting the underlying format of the message.
CDO Messaging Classes and InterfacesWhen you use CDO to build message applications, you use the classes and interfaces found in the CDO for Exchange 2000 object library (Cdoex.dll). Messaging applications are not built with a single object and interface but involve a number of classes and interfaces. The more complex the application, the more classes you use to create it. However, some basics always apply.Predominant among these is the Message class. The Message class is the cornerstone of CDO messaging solutions. It can be either a message or a post, which is a message saved in a folder or posted to a newsgroup, and it is used to create new messages as well as to open and manipulate existing ones. The Message object has an extensive list of properties, but not all possible message fields are exposed as properties. The Message object also provides a Fields collection that you can use to access the schema properties that are not defined as CDO Message properties, including any custom properties. By using the methods of the Message object, you can send or post messages, reply to existing messages, and forward them to other recipients. You can address a message by using the properties of the Message object, but you must use the Addressee object to resolve addresses and eliminate ambiguous names. Figure 6.1 shows the Message object model. If you work with MIME messages, then you will also use the BodyParts collection. MIME messages are made up of pieces known as BodyPart objects. A BodyPart can, for example, be an attachment, the body text, or the header section. You can create and manage attachments by using the BodyPart object. In addition, you can use the ActiveX Data Objects (ADO) Stream object to save attachments or other BodyPart objects to disk. If you work with groups of messages, you will undoubtedly use the Configuration object. You use the Configuration object to define how to send or post a message. You can then apply that single configuration to all messages that your application sends, eliminating the need to configure each individual message. And, as with all CDO objects, the IDataSource interface handles the data swapping between the actual resource in the Microsoft Web Storage System and the copy of data in the CDO object.
Figure 6.1 The CDO Message object model
Dissecting a MIME MessageTo successfully build messaging applications by using CDO, you must understand how MIME messages are split into BodyPart objects. BodyPart objects have a media type property (BodyPart.ContentMediaType) that identifies what the BodyPart object contains. This section presents general information about media types. For a more detailed discussion of media types, see "Identifying the Media Type of a BodyPart Object" later in this chapter.One way to learn how messages are broken into BodyPart objects is to step through a few messaging scenarios. A simple example is a plain-text message that has an attachment. When you create a simple message that uses plain text in the body text, the entire Message object is considered to be a single BodyPart object (see Figure 6.2). The BodyPart contains all the information about the message, including header information and the body text of the message. The BodyPart for the message has a media type of "text/plain."
Figure 6.2 A plain-text message has only one BodyPart object and contains both the message header and the body text. When you add an attachment, for example, a Microsoft Word document, to that message, the entire structure of the message changes. The message no longer has a single BodyPart object but three BodyPart objects: one for the header information, one for the attachment, and one for the body text. The BodyPart object that represents the header information is considered the parent of the other two BodyPart objects, which constitute a BodyParts collection. The BodyPart object that represents the body text is still plain-text, so it has a media type of "text/plain." The attachment is a Word document, so the media type for that BodyPart object is "application/msword." Because the message BodyPart object contains BodyPart objects with different media types, the message header BodyPart has a media type of "multipart/mixed." Figure 6.3 shows how the message evolves from a single BodyPart object into three BodyPart objects.
Figure 6.3 A plain-text message with a Word document attachment has three BodyPart objects: one for the message header, one for the body text, and one for the file attachment. Another example is a message with HTML formatting in the body text. Because not every client is able to process HTML in messages, by default Exchange also generates a plain-text version of the content. In this message, the body text must be rendered in two different BodyPart objects: one BodyPart object that represents the HTML version with a media type of "text/HTML" and one BodyPart object that represents the plain-text version with a media type of "text/plain." Because the message can generate the body text using two different formats, the message header BodyPart object has a media type of "multipart/alternative." Figure 6.4 shows this type of message structure.
Figure 6.4 A message that uses both plain-text and HTML body text formats consists of three BodyPart objects: one for the message header, one for the plain-text format, and one for the HTML format. Let’s look at one last example: this time, you want to create a message with HTML formatting in the body text and a Word document attachment. Essentially, this example combines the first two examples. When you create a message with two possible formats for the body text, the message has the same structure as that shown in Figure 6.4. When you add the attachment, the message becomes rather complex. The message BodyPart contains a BodyParts collection that consists of another BodyParts collection for the body text formats and a BodyPart object for the file attachment. Because the message contains multiple media types, the message header BodyPart has a media type of "multipart/mixed." The BodyParts collection that represents the body formatting types has a media type of "multipart/alternative" and consists of a BodyPart object for the HTML format with a media type of "text/HTML" and a BodyPart object for the plain-text version with a media type of "text/plain." The BodyPart object that represents the attachment has a media type of "application/msword". Figure 6.5 shows this nested multipart message.
Figure 6.5 A message that uses alternative body text formatting and also includes a file attachment Although this might seem rather overwhelming, the good news is that CDO provides several properties and methods to make your interaction with BodyPart objects and BodyParts collection as painless as possible. For example, when you add an attachment, you do not have to add a BodyPart object to the message and set the media type. Instead, you can use the AddAttachment method, which does the dirty work for you.
Composing and Sending MessagesWhether you’re composing a simple message with plain text or a complex message that uses a Web page in the body and a persistent configuration, you need to know the basic techniques involved in composing and sending a message. If you understand the basics behind messaging with CDO, the more advanced tasks don’t seem so advanced.
Sending a Simple MessageWhen you send e-mail to someone by using a client application such as Microsoft Outlook Web Access, you create a new message, fill in some information, and then send it. Typically, you address the message to someone, specify the subject matter, and fill in the body with the message. When you send a message with CDO, you do the same thing. To send a simple message by using CDO, create a new Message object and then:
When you send e-mail using CDO, you must do one additional thing to successfully send the message. You must specify who is sending the e-mail. Client applications such as Outlook Web Access do this for you automatically, but you must set this information explicitly when using CDO. You can set the From property of a Message object to do this. Listing 6.1 shows how to successfully send a very simple e-mail message to two people. Listing 6.1. Send a simple message.
Public Sub CreateandSendMail() ' This sends a very simple message ' If you are using VBScript, use this With: ' With CreateObject("CDO.Message")
With New CDO.Message ' Indicate who is sending the message .From = "mindy@domain.com" ' Address the message .To = "denise@domain.com, aidan@domain.com" ' Set the subject matter .Subject = "Siberian Tigers" ' Fill in the body text using plain text formatting .TextBody = "Did you know there are estimated only " & _ "about 400 of these magnifcent creatures left in the wild?" ' Send the message .Send End With Debug.Print "Message sent." End Sub Addressing a MessageWhen you develop an application by using the Microsoft Outlook 2000 object model or earlier versions of CDO, you address a message by adding to a Recipients collection of the message. CDO does not use a Recipients collection. Instead, when using CDO, you address a message by setting the appropriate CDO properties or schema properties to the appropriate e-mail addresses. The term "recipient" is still used; however, it only defines the receiver of a message. It does not define an object in the CDO object model.
Specifying Who Is Sending the Message As mentioned earlier, you must specify who is sending the e-mail message to successfully send it. You can indicate the sender by setting the From property to the e-mail address of the person who is sending the message. If you set the From property to more than one address, the first address is used as the From address. If you do not indicate a sender, the code fails with a trappable error. For example, this sets the From property for a Message object:
msg.From = "mindy@domain.com"If you are sending multiple messages in the same application, you might want to specify a sender with a Configuration object instead of setting the From property on every Message object. By using a persistent Configuration object, you can define a sender with one object and then apply this Configuration to each message. For more information on using a Configuration object to set the sender information, see "Using a Persistent Configuration Object," later in this chapter. Specifying Who Is Receiving the Message To indicate who is receiving the message, set one or more of the properties listed in Table 6.1. You can set each property to a string value that consists of one or more e-mail addresses. Table 6.1 Standard address properties
If you are sending to more than one address, separate each address with a comma. This style of creating multiple recipients is different from that used by some e-mail clients, including Outlook. The following code sample addresses an e-mail message to several recipients:
msg.To = "denise@domain.com, aidan@domain.com" msg.CC = "robert@domain.com" msg.BCC = "peter@domain.com"CDO supports e-mail addresses in any address format defined by Internet standards. If you are sending a message within your organization, you can use the alias associated with an e-mail address. An alias is a shortcut name for the proper e-mail address and is often the portion of the e-mail address before the @ symbol. For example, an e-mail address of mindy@domain.com might have an alias of "mindy." Configuring for Replies In addition to setting the standard address properties for addressing a message, you can also set an alternative address for replies. Normally when you reply to an existing message, the replies go to the address specified in the From property. If you prefer to have replies sent to another address instead, set the ReplyTo property to that e-mail address. Replies then go to the ReplyTo address instead of to the From address. As with the From property, the ReplyTo property has an equivalent configuration schema property that can be set with a Configuration object instead of setting the ReplyTo property on every Message. By using a persistent Configuration object, you can define the address used for replies with a single Configuration object and then apply this Configuration to each message. For more information about using a Configuration object to set the sender information, see "Using a Persistent Configuration Object," later in this chapter.
Adding the Body TextYou can add the body text of a message several different ways. You can add text that uses plain-text formatting, HTML formatting, or MIME Encapsulation of Aggregate HTML Documents (MHTML) formatting. This section discusses how to use these three types of formatting in the body text of a message.Using Plain-Text Formatting If you want to add only simple text to the body of a message, set the TextBody property of a Message object to a text string. You can use the TextBody property to add text, but it does not allow you to specify special formatting, such as making some words bold or making bulleted lists. For example, the following code sample adds text to a Message object text body without using any special formatting:
msg.TextBody = _ "This is the main body text without any special formatting."If you want to format the text, you must use HTML to add the formatting features. Using HTML Formatting If you want to include formatting in the body text, you can use HTML formatting. With HTML, you can specify the font style, add bold or italic, or use bulleted lists. In fact, you can use just about any formatting available in HTML. To use HTML formatting in body text, you set the HTMLBody property to a legitimate HTML string. For example, the following code sample uses HTML formatting to create body text with a header, a rule, italic, and special font styles in the text:
msg.HTMLBody = _ "<H1>Check this out!</H1>" & _ "<HR><i>Look</i>" & _ " at this " & _ "<font color=red size=12>cool</font>" & _ " HTML message."When you create an HTML body, by default CDO also generates a plain-text version of the body text. The plain-text version of the body uses the same text as the HTML body but without any special HTML formatting. This ensures that clients unable to process HTML-formatted messages can still read the message. If you would rather not automatically generate a plain-text version of the body text, set the AutoGenerateTextBody property to False. Then, if you prefer to create a plain-text body, you can do so by setting the TextBody property to the value you want. For example, Listing 6.2 shows how to create a message with two different formats for the body text. Listing 6.2 Generate a message with both a text body and an HTML body.
Public Sub CreateSeparateTextandHTML() ' Use both an HTML and plain text ' version for body text formatting. ' If you are using VBScript, use this With: ' With CreateObject("CDO.Message")
With New CDO.Message .From = "mindy@domain.com" .To = "peter@domain.com" .Subject = _ "This message has two different body text versions" ' Generate body text for plain text viewers .TextBody = _ "You're missing out by not supporting HTML!" ' Generate body text for HTML capable viewers .HTMLBody = _ "<H1>Check this out!</H1>" & _ "<HR><i>Look</i>" & _ " at this " & _ "<font color=red size=12>cool</font>" & _ " HTML message." ' Send the message .Send End With Debug.Print "Message sent." End SubUsing MHTML Formatting Many e-mail clients, such as Outlook, can display HTML pages just like a Web browser does. To include all the HTML formatting, graphics, objects, and other elements contained in the Web page in the body of a message, you use MHTML formatting. MHTML is an Internet standard that defines the MIME structure that is used to send HTML content in message bodies along with those elements that are used in the Web page. To embed a Web page or portions of a Web page as body text, you use the CreateMHTMLBody method of a Message object. The CreateMHTMLBody method has one required parameter: the URL of the Web page must be embedded in the body of a Message object. For example, the following code sample fills the body of a message with the msdn.Microsoft.com/exchange developer center home page:
msg.CreateMHTMLBody "http://msdn.microsoft.com/exchange/"If the Web page contains support elements (such as sound files, style sheets, or graphics), they are included with the Web page and attached to the message as file attachments. Although this allows a recipient to view the Web page in its entirety, it also dramatically increases the size of a message in bytes. To avoid this increase in message size, you can use the optional argument Flags to indicate which elements to exclude. To define which elements to exclude, set the Flag parameter to one or more of the numeric constants from Table 6.2. Table 6.2 Constants for the Flags argument of the CreateMHTMLBody method
The following code sample once again embeds the microsoft.com home page in a message, but this time, suppresses the background sounds and objects:
msg.CreateMHTMLBody _ "http://msdn.microsoft.com/exchange/", _ cdoSuppressImages + cdoSuppressObjectsListing 6.3 shows how to embed a complete Web page into the body of an e-mail message while suppressing background sounds and objects used in the Web page. Listing 6.3 Embed a Web page in the body of an e-mail message.
Public Sub FillMessageBodywithWebPage() ' Creates a mail message with the Microsoft home page ' as the body text. Dim cnfg As CDO.Configuration ' Set the Sender information Set cnfg = New CDO.Configuration With cnfg .Fields(cdoSendEmailAddress) = "peter@domain.com" .Fields.Update End With ' Create the new message With New CDO.Message Set .Configuration = cnfg .To = "mindy@domain.com" .Subject = "This is a great web site." ' Embed the Microsoft home page into the body .CreateMHTMLBody _ "http://msdn.microsoft.com/exchange/" _ , cdoSuppressBGSounds + cdoSuppressObjects .Send End With ' Clean up Set cnfg = Nothing End SubFigure 6.6 shows the result of executing the code in Listing 6.3.
Figure 6.6 The CreateMHTMLBody method of a Message object lets you embed an entire Web page in the body of a message.
Adding AttachmentsYou often need to send files along with an e-mail message. To add an attachment, use the AddAttachment method of a Message object. The AddAttachment method is a shortcut to manually add a new BodyPart to a message and then set the necessary properties for that BodyPart to be an attachment. In case you need to manipulate the attachment further, the AddAttachment method returns a BodyPart object.To use the AddAttachment method, pass a string value with the path and file name to be attached. An attachment can be a file on a local or remote computer, a message in an Inbox, or even a Web page. Correct examples of using the AddAttachment method include:
msg.AddAttachment _ "D:\Sales Information\Latest Sales Data.xls" msg.AddAttachment _ "http://cyberserver/exchange/mindy/inbox/siberian%20tigers.eml" msg.AddAttachment _ "/index.html"If the attachment doesn’t exist, the code fails with a trappable error. Listing 6.4 shows how to attach a file to a message. If the file doesn’t exist, an error message is generated. Listing 6.4 Attach a file to a message.
Sub CreateMsgwithAttachment() ' Attempts to attach a file ' to a message. ' Turn on error handling On Error GoTo HandleErrors ' Create a new message With New CDO.Message .From = " mindy @domain.com" .To = "peter@domain.com" .Subject = "Message with attachments" .TextBody = "Can you see this?" ' Attempt to attach a file .AddAttachment "D:\somefile.xls" ' Send the message .Send End With Debug.Print "Message sent." ExitHere: Exit Sub HandleErrors: Dim strError As String ' Get the error number, description, and source strError = "Error #" & Err.Number & ": " _ & Err.Description ' Display the errors in a message box MsgBox strError Resume ExitHere End Sub Useful Schema Properties for MessagingWhen you create a new CDO Message object, you are creating a resource in a Web Storage System with a DAV:contentclass of urn:content-classes:message. The Web Storage System automatically associates a number of properties with the urn:content-classes:message content class, most of which are accessible through a CDO property. However, some of the most useful schema properties cannot be read or set through a CDO property. Table 6.3 lists these schema properties.Because a CDO object does not explicitly expose these properties, you must use the Fields property of a Message object to set them. You can pass either the schema property name or the CDO constant equivalent. After you set the appropriate properties, save the changes you made with the Fields.Update method. For example, the following code sample sets the importance level of the message to high:
Set msg = New CDO.Message msg.Fields(cdoImportance) = cdoHighTable 6.3 To retrieve these schema properties for a Message object, you must use the Fields collection.
1Not available.
Last Updated: Friday, July 6, 2001 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||