SMTP 服务器传输事件 - 简单脚本






3.60/5 (5投票s)
2002年12月23日
3分钟阅读

127347

968
一篇关于 SMTP 服务器事件的文章。
引言
本文介绍了 Microsoft SMTP 服务器中的 SMTP 传输事件。本文展示了如何编写简单的脚本以及如何安装这些脚本。本文还展示了如何将传入的电子邮件写入数据库以及如何用红色后续标记标记传入的电子邮件。
背景
最近,我被要求找出一种方法,让 Exchange 2000 用红色后续标记标记一些传入的电子邮件。我开始浏览 MSDN,发现了 SMTP 服务器事件。 我发现有两种类型的事件
- 协议事件
- 传输事件
当 SMTP 服务器收到电子邮件时,会发生传输事件。我想讨论的事件是 OnSubmission
事件,还有另外 2 个事件:OnPreCategorize
和 OnPostCategorize
。OnTransportSubmission
事件与 Windows 2000 的 CDO OnArrival
事件相同。OnTransportSubmission
事件使用以下原型调用
Sub ISMTPOnArrival_OnArrival(ByVal Msg, EventStatus)
一个 CDO MailMsg
对象被传递到子例程中,通过它我们可以完全访问服务器正在处理的电子邮件。 因此,添加红色后续标记的完整代码将是
On Error Resume Next
Const cdoRunNextSink = 0
Sub ISMTPOnArrival_OnArrival(ByVal Msg, EventStatus)
On Error Resume Next
Set Flds = Msg.Fields
With Flds
.Item("urn:schemas:httpmail:messageflag") = True
.Item("urn:schemas:mailheader:x-message-flag") = True
.Update
End With
' save changes to the mail
Msg.Datasource.Save
' continue with the next event sink
EventStatus = cdoRunNextSink
End Sub
在另一个项目中,我们想自动将退回的电子邮件添加到我们的数据库中,执行此操作的代码如下所示
On Error Resume Next
Const cdoRunNextSink = 0
Const adCmdStoredProc = &H0004
Const adVarChar = 200
Const adWChar = 130
Const adParamInput = &H0001
Sub ISMTPOnArrival_OnArrival(ByVal Msg, EventStatus)
On Error Resume Next
Dim objConnection, objCommand, strConnection, intLen
Dim strBody, strToEmail, strFromEmail, strSubject
strToEmail = Msg.To
strFromEmail = Msg.From
strSubject = Msg.Subject
strBody = Msg.TextBody
If strBody <> "" Then
intLen = Len(strBody) + 1
Else
intLen = 1
End If
strConnection = _
"Provider=SQLOLEDB;SERVER=localhost;Initial Catalog=databasename;User ID=;Password=;"
Set objConnection = CreateObject("ADODB.Connection")
Set objCommand = CreateObject("ADODB.Command")
Call objConnection.Open(strConnection)
objCommand.ActiveConnection = objConnection
objCommand.CommandType = adCmdStoredProc
objCommand.CommandText = "spAddBouncedEmail"
objCommand.Parameters.Append objCommand.CreateParameter("ToEmail", adVarChar, _
adParamInput, 255, strToEmail)
objCommand.Parameters.Append objCommand.CreateParameter("FromEmail", adVarChar, _
adParamInput, 255, strFromEmail)
objCommand.Parameters.Append objCommand.CreateParameter("Subject", adVarChar, _
adParamInput, 255, strSubject)
objCommand.Parameters.Append objCommand.CreateParameter("Body", adWChar, _
adParamInput, intLen, strBody & " ")
objCommand.Execute
' continue with the next event sink
EventStatus = cdoRunNextSink
End Sub
使用代码
微软非常友好地为我们提供了一个 VB 脚本,可以帮助我们安装脚本,它被称为 smtpreg.vbs
安装脚本
cscript smtpreg.vbs /add 1 onarrival BouncedEmail CDO.SS_SMTPOnArrivalSink "rcpt to=*@somewhere.com;rcpt to=*@somewhere.net"这会添加一个名为 BouncedEmail 的 onarrival 事件,其入口点为
ISMTPOnArrival_OnArrival
,该事件将应用于所有匹配 '*@somewhere.com' 和 '*@somewhere.net' 的收件人。
现在我们需要告诉服务器要运行哪个脚本
cscript smtpreg.vbs /setprop 1 onarrival BouncedEmail Sink ScriptName "path_to_scriptfile"这只是设置 BouncedEmail 事件的属性,告诉它脚本的位置。
卸载是一个简单的过程
cscript smtpreg.vbs /remove 1 onarrival BouncedEmail
关注点
在实现红色后续标记时,我遇到了一个有趣的问题。 客户希望传入的电子邮件被标记为后续以及发送到某个地址的内部电子邮件。 起初,这对内部地址不起作用,这是因为 Outlook 使用 MAPI 与 Exchange 通信,而不是 SMTP。 微软发布了这篇 KB 文章解释了这个问题。解决方法非常混乱,它涉及添加一个新的虚拟 SMTP 服务器并从其中退回电子邮件,这会使事件触发,因为它从 Outlook 到 Exchange 作为 MAPI,然后从 Exchange 到虚拟 SMTP 服务器,然后再返回到 Exchange。
我希望这篇简单的文章能引起一些思考。 我可能会提到你可以编写自己的 COM 插件来执行相同的功能,当然这些插件会提供更好的性能。 我不想在需求量非常大的服务器上运行这些 VB 脚本,你可能会注意到一些性能问题。 但是,我使用这些技术的项目没有遇到任何此类问题。
一些与 SMTP 传输事件相关的有趣链接
历史
- 2002 年 12 月 20 日 - 文章创建