Sending HTML mail via SMTP part 3

Jake Howlett, 14 April 2002

Category: Java; Keywords: SMTP Mail Socket HTML

In the last article I showed all the code required to send a mail in HTML format. All very well but it's not what we really want to actually start using in our applications. What we want is a more powerful way of using the code in the agent. Wouldn't it be nice if we could simply supply any URL and the agent uses this as the source of the HTML for the mail. Well we can. This means that we can use the power of Domino forms and views to build the HTML and then send this in the mail. It doesn't have to be a Domino URL - we can use any location as long as the server has access to read form it.

Another change I've made to the sample database is to add a scheduled agent. We can now create documents in the database from any other database and wait for the agent to do the sending for us. This approach means that the Mail Database is a central location for sending formatted mail from all our applications.


Sending mail from any URL:

The code in the last article to send a message was simply:


msg.sendMessage( sFromTrue, sFromShow, vToTrue, sToShow, sSubject, vBody );

The only change required to send the HTML from a URL is:

msg.sendMessage( sFromTrue, sFromShow, vToTrue, sToShow, sSubject, vURL );

Notice that the last parameter has changed. In the first we sent a Vector object containing each line of the HTML. In the second we send a URL object. The actual code in the Java Script Library has two methods with the same name - "sendMessage". Java knows which one to use depending on the type of the arguments passed to it. This is known as Overloading and is very useful in circumstances like these.

So, in our agent that calls the sendMessage method, we need a line of code like the following to build a URL object:

URL vURL = new URL ( vNotesDocument.getItemValueString("URL") );

Then in the code that builds the mail we can use this to open an inputstream and loop through each line of the source and write it to the mail. The code for this is simpler than you might expect:

String inputLine;
BufferedReader in = new BufferedReader( new InputStreamReader( vURL.openStream( ) ) );

while ( ( inputLine = in.readLine( ) ) != null ) {
 sendText ( inputLine );
}
in.close();

As an example I used the agent to send all the HTML from the URL of the view called "URLs" in the sample database. Here's what it looks like in the browser:

image


Somewhat surprisingly, this doesn't look all that different when the client reading the mail happens to be Notes. Note however that is has ignored the stylesheet and the background logo image. Apart from that is laid out as we'd expect and all the links work.

image


As I mentioned in part 2 of this article, the Outlook client is a lot more reliable as it actually uses Internet Explorer to render the content of the mail. As you can see in the shot below it looks exactly the same as in the browser. In fact the only difference is that the Outlook preview-pane doesn't allow any JavaScript. That means anything like window.open and document.write is useless. Worth keeping in mind.

image


Hope this is enough to convince you of how powerful an application this can be. Using forms and views there is almost no limit to the content and format of the pages that you send. Just imagine how impressed the boss will be when they get a mail listing the latest content on the intranet, all nicely formatted with corporate logos and colours.

Sending mail from other applications:

To make this in to a truly useful application we need the ability to use it from all our other applications. To do this I've added a third form called "SendAUT". This has all the fields required to use either the URL or HTML methods. Using the following LotusScript we can create a document in the HTML Mail database from anywhere else and then wait for the agent to pick it up when it's next due to run.

Dim vDocSession As NotesSession
Dim vDocDatabase As NotesDatabase
Dim vMailDatabase As New NotesDatabase ("", "")

Call vMailDatabase.Open( "epsdomsvr01", "apps/htmlmail12.nsf" )

if ( Not vMailDatabase Is Nothing ) Then
Set vMailDocument = vMailDatabase.CreateDocument
vMailDocument.Form = "SendAUT"
vMailDocument.From = "jhowlett@EITS"
vMailDocument.FromShow = "Jake Howlett <jhowlett@EITS>"
vMailDocument.SendTo = "developerone@EITS,developertwo@EITS"
vMailDocument.ToShow = "All Developers <$developers@EITS>"
vMailDocument.Subject = "Homepage as been updated. Here is a copy.."
vMailDocument.URL = "http://www.codestore.net/A55692/store.nsf"
vMailDocument.ComputeWithForm

vMailDocument.Save True, True
End If

When the agent opens this document it knows that it needs to use the overloaded method that sends a URL as the final paramater because there is a value in the field called "URL". If you wanted to use the method of adding all the HTML to the mail yourself then, instead of adding a value to the "URL" field, you add all the HTML, line by line, the field called "Body":

Dim vBodyItem As NotesItem
Set vBodyItem = vMailDocument.GetFirstItem( "Body" )
Call item.AppendToTextList( "<html>" )
Call item.AppendToTextList( "<body>" )
Call item.AppendToTextList( "<h1>" )
Call item.AppendToTextList( "hello in big letters" )
Call item.AppendToTextList( "</h1>" )
Call item.AppendToTextList( "</body>" )
Call item.AppendToTextList( "</html>" )

This adds lines of HTML to the item called "Body" which is of type multi-value. This is then passed in to the method as the vector object that we saw earlier.

Room for improvement:

What would be nice when you add a document from another application is to be kept updated as to when and if it is sent. Errors can occur while trying to send mails and it would be useful to have a set number of retries at sending it before somebody is made aware of its failure.

As I mentioned in the first article in this series we have to use valid SMTP addresses when sending the mail. Getting hold of these is fairly easy if the user enters a Domino user name and you get the code to find their short name and domain combination. This won't work in a mixed environment of Exchange and Domino though. The ideal solution is to use LDAP to find the SMTP address of any given name.

Any ideas or requests that you might have - let me know...

Noteworthy:

Something worth noting is that the way this works can be dictated by the server on which the agent runs. If the server doesn't have access outside the firewall then you will have problems specifying internet addresses in the URL field.

If the server tries to open a page that it doesn't have access to and an error message is returned then this is what will get mailed to the recipients. Not nice. Worth checking this first.

<<< Part 1
<<< Part 2
Part 3