Send Notes mail from an XML call
As you can see in the errorCatch line, I named this agent “doSendMessage” so you will need to customize this for your purposes. For the purposes of brevity I will not go into detail for each line, but rely on my REM comments to explain what each section is.
Sub Initialize
On Error Goto errorCatch
Dim s As New NotesSession
Dim domParser As NotesDOMParser
Dim nodeDoc As NotesDOMDocumentNode,nodeNode As NotesDOMElementNode
Dim nodeResults As NotesDomElementNode
Dim dbThis As NotesDatabase
Dim docCtx As NotesDocument
Dim streamOut As NotesStream
Dim strInput As String, strIpAddress As String
' set defaults
Set dbThis = s.CurrentDatabase
Set docCtx = s.DocumentContext
Set domParser = s.CreateDOMParser
Set nodeDoc = domParser.Document
Set streamOut = s.CreateStream
bSuccess = False
strIpAddress = docCtx.Remote_Addr(0)
If Not setArrayDefaults Then ' initialize arrays default values
Goto createDomResults ' strOut is set within setArrayDefaults
End If
strInput = docCtx.Request_Content(0) ' grab POST data
If Not isAuthenticated(s, strInput) Then ' does the request have a valid user/pass?
Goto createDomResults ' strOut is set within isAuthenticated
End If
If Not getParams(s, strInput) Then ' grab parameters from POST data
Goto createDomResults ' strOut is set within getParams and/or sub-function
End If
If Not doMail(s, dbThis, strIpAddress) Then ' send the mail
Goto createDomResults ' strOut is set within doMail function
End If
bSuccess = True
createDomResults:
Set nodeNode = setDefaultDom(nodeDoc) ' create a response wrapper
Call domParser.setOutput(streamOut) ' to get xml doc we need to output to a notesStream
Call domParser.Serialize ' xml doc contents into stream
Print {content-type:text/xml; charset=utf-8} 'REQUIRED
Print {< ?xml version="1.0" encoding="UTF-8"?>} + streamOut.ReadText
Exit Sub
errorCatch:
strOut = “Error in doSendMessage:init in line: ” & Erl() & ” error$: ” & Error$
bSuccess = False
Exit Sub
End Sub
So we setup some of our arrays, grab the request_content text (the xml), check for authentication, grab the parameters from the xml and send the message. If everything is successful, we can then send a response back to the requesting client and everyone is happy! So let’s look into some of these functions. First is the setArrayDefaults function which does what it is named for.
Function setArrayDefaults() As Boolean
' function to initialize arrays with default values
setArrayDefaults = False
On Error Goto errorCatch
arrParams(0) = "sendto"
arrParams(1) = "copyto"
arrParams(2) = "blindcopyto"
arrParams(3) = "subject"
arrParams(4) = "message_body"
arrparams(5) = "from"
arrParams(6) = "attachments"
setArrayDefaults = True
Exit Function
errorCatch:
strOut = "Error in doSendMessage:setArrayDefaults in line: " & Erl() & " error$: " & Error$
bSuccess = False
Exit Function
End Function
The arrParams array is the node names of the parameters we want from the XML stream. So if this goes off without a hitch, we move onto the isAuthenticated function which checks the username and password combination that comes in with the request. For the sake of our example, our authentication method is to take a username and pass it through the LotusScript “HashPassword” method of the NotesSession class. So the password is the username hashed. Our function will extract the proper nodes from thhe XML stream and compare the hashed username to the password included.
Function isAuthenticated(s As NotesSession, strInput As String) As Boolean
' function to determine validity of user/pass combo
On Error Goto errorCatch
Dim domParser As NotesDOMParser
Dim nodeDoc As NotesDOMDocumentNode
Dim nodeList As NotesDOMNodeList
Dim nodeNode As NotesDOMElementNode
Dim authName As String, authPass As String
Set domParser = s.CreateDOMParser
Call domParser.parse(strInput)
Set nodeDoc = domParser.Document
isAuthenticated = False
strOut = "not a valid username / password pair"
Set nodeList = nodeDoc.GetElementsByTagName("auth_name") ' grab list of user name nodes
If nodeList.NumberOfEntries > 0 Then ' if we have one
Set nodeNode = nodeList.GetItem(1) ' grab the actual node
If nodeNode.HasChildNodes Then ' check to see if it has values
authName = nodeNode.FirstChild.NodeValue ' grab value
Else
Exit Function ' we have a node with no values
End If
Else
Exit Function ' we do not have a username node
End If
' rinse and repeat with auth_pass
Set nodeList = nodeDoc.GetElementsByTagName("auth_pass")
If nodeList.NumberOfEntries > 0 Then
Set nodeNode = nodeList.GetItem(1)
If nodeNode.HasChildNodes Then
authPass = nodeNode.FirstChild.NodeValue
Else
Exit Function
End If
Else
Messagebox "no auth pass"
Exit Function
End If
' to get a username and password combo, session.hashpassword method
If s.VerifyPassword(authName, authPass) Then ' verify username and password
isAuthenticated = True
strOut = ""
End If
Exit Function
errorCatch:
strOut = "Error in doMessageSend:isAuthenticated in line: " & Erl() & " error$: " & Error$
isAuthenticated = False
Exit Function
End Function
So there you have it, our first extraction of a value(s) from our XML stream. I do to want to go into too much detail on using an XML parser, hopefully my REM comments will help fill in any of the gaps. In my example, I am using the DOM parser which puts the entire XML tree into memory before extracting values, but you could also use the SAX parser.
March 30th, 2006 at 3:30 am
Hi there. Came across this article via codestore http://www.codestore.info/store.nsf/unid/BLOG-20060329, via Johan Känngård http://johankanngard.net/2005/12/13/sending-html-mails-via-lotusscript/ then you!
We have a PC on our network, that is used to run an Excel program, the Excel file is then emailed to various users (they should really stick it in a central repository etc…). The sending user could log into their Web Access mail file, but as an interesting exercise, I would like to give this a go. I keep getting a 404 error when trying to download your sample database.
Great site, interesting articles.
Nick