Thomas Rizzo, Product Manager
Microsoft Corporation
September 1997
Click to copy the Expense Reporting sample for this technical article.
Editor's note Part 1 of this article has been adapted from the Microsoft® Exchange Event Scripting Agent documentation. The full Microsoft Exchange Event Scripting Agent documentation can be found in the MSDN Library (SDK Documentation, Platform SDK).
Developers are in store for a real treat this year with the introduction of Microsoft Exchange Server version 5.5. Exchange Server 5.5 introduces a slew of new developer technologies, including ADSI/LDAPv3 support, version 1.2 of the Collaboration Data Objects library (CDO), and the subject of this article, the Exchange Scripting Agent.
The Microsoft Exchange Server Scripting Agent lets you use server-side scripts that run as a result of events occurring in folders. Such triggering events include timer events and actions such as posting, editing, or deleting a message. They can take place in private folders (mailboxes) or public folders. You need sufficient folder permissions to install and enable event-driven folder scripts.
You can write these scripts in Microsoft Visual Basic® Scripting Edition (VBScript), JScript™, or other supported scripting languages, and you can use Microsoft Visual Studio™ (specifically the Microsoft Developer Studio IDE) as your script editor. Script debugging support is provided via the Microsoft Script Debugger (part of Microsoft Internet Information Server version 4.0 or Microsoft Internet Explorer version 4.0).
You can also create custom agents with programming languages such as Visual Basic, Microsoft Visual C++®, Java, or any other language that supports Component Object Model (COM). However, this topic is beyond the scope of this introductory article. For more details, see "Advanced Topics: Custom Agents" in the Microsoft Exchange Event Scripting Agent documentation.
Figure 1. Microsoft Exchange architecture
The Exchange Event Scripting Agent is built on the Exchange architecture. The following elements make up the core architecture of the Exchange Scripting Agent:
The Exchange Scripting Agent can handle four different events. The first three events involve creating, deleting, and editing a message: Folder_OnMessageCreated, Folder_OnMessageDeleted, and Message_OnChanged. For example, you can write an agent that sends an e-mail notification to users when a new appointment is added into a public calendar. The final event is a timer event: Folder_OnTimer. The timer event can be scheduled so that it runs hourly, daily, or weekly. A tickler is an example of a timer event. The system could remind people that certain tasks are due for a project.
The Microsoft Exchange Event Service passes the following intrinsic objects when your script is run:
The easiest way to explain how the Exchange Scripting Agent works is to provide a sample. The Expense Reporting sample allows users to enter expenses from a Web page. Once submitted, an agent checks the total of the expense report and either approves the report automatically if it is under a certain amount of money, $5,000 in this case, or looks up the submitter's manager in the Exchange directory and routes it to this person for approval. This agent handles the message-creation event.
The second agent reroutes all expense reports that have not been approved after an hour to the current approving manager's manager, again by looking up that person dynamically in the Exchange directory. The second agent handles a timer event that is fired every hour.
A quick look at samples of code from the "Process New Expense Report" agent will demonstrate how we were able to easily create and apply this agent to the Exchange Public folder.
The following code demonstrates how to handle the Folder_OnMessageCreated event. The other events, Folder_OnMessageDeleted, Message_OnChanged, and Folder_OnTimer, have similar syntax. This particular subroutine retrieves specific information about the event through GetEventDetails and then calls CheckTotal, which is shown below. Both of these scripts are written in VBScript.
' DESCRIPTION: This event is fired when a new message is added to the folder.
' CheckTotal checks the total of the expense report and routes accordingly.
Public Sub Folder_OnMessageCreated
On Error Resume Next
GetEventDetails
If Err.Number = 0 Then
CheckTotal
Else
Script.Response = "GetEventDetails Failed"
End If
End Sub
The CheckTotal subroutine checks the total of a new expense report and calls methods from the Exchange CDO library to look up the submitter's manager and send a message if the total is more than $5,000. The following code illustrates how to call some of these methods:
Private Sub CheckTotal
Dim msgResponse
Dim iMsgCount
On Error Resume Next
Dim msgManager
Dim UsersManager
Dim currentuser
Dim currentapprover
iMsgCount = fldrTarget.Messages.Count
If Err.Number = 0 Then
set ExpTotal = msgTarget.Fields("Total")
Set msgResponse = fldrOutbox.Messages.Add
If ExpTotal > 5000 then
msgResponse.Subject = "The Total was " & ExpTotal
msgResponse.Text = "This Expense Report has been routed to your Manager"
set msgManager = fldrOutbox.Messages.Add 'Message to Manager
'Find the sender of the expense report
set currentuser = msgTarget.Sender
'Find that person's manager in the directory
set UsersManager = currentuser.Manager
currentapprover = UsersManager.Name
'Get the spaces out since we're emailing a URL
currentapprover = Replace(currentapprover," ","+")
msgManager.Subject = "Approval Required for Expense Report!"
msgManager.Text = currentuser.name & " has submitted an expense report for " & ExpTotal & ". Please review it at http://localhost/expense/approve.asp?entryid=" & msgTarget.ID & "&Approver=" & CurrentApprover
msgManager.Recipients.Add "","",1,UsersManager.ID
msgManager.Recipients.Resolve(False)
msgManager.Send
'Update the status of the expense report
msgTarget.Fields("Status") = "Awaiting Approval from" & UsersManager.Name
msgTarget.Fields("StatusInt") = 2 'Awaiting Approval
'Put in the database the current approver's name
msgTarget.Fields.Add "Approver",8,UsersManager.Name
msgTarget.Update
Else 'Expense Report < 5000
. . . . . 'Automatically approve the expense report
End Sub
</SCRIPT>
From the example above, you can easily see how developers like yourselves can take advantage of the Exchange Event Scripting Agent to implement custom tracking and routing applications. The Exchange Event Scripting Agent makes it easy to add scripts or custom COM objects to events inside of Exchange Server.
Interested in learning more? Be sure to download the full Expense Reporting sample application from the MSDN Online Web site. More information on both the Exchange Scripting Agent and Exchange Collaboration Data Objects Library can be found at http://www.microsoft.com/exchange/.