65.9K
CodeProject 正在变化。 阅读更多。
Home

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

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.60/5 (5投票s)

2002年12月23日

3分钟阅读

viewsIcon

127347

downloadIcon

968

一篇关于 SMTP 服务器事件的文章。

引言

本文介绍了 Microsoft SMTP 服务器中的 SMTP 传输事件。本文展示了如何编写简单的脚本以及如何安装这些脚本。本文还展示了如何将传入的电子邮件写入数据库以及如何用红色后续标记标记传入的电子邮件。

背景

最近,我被要求找出一种方法,让 Exchange 2000 用红色后续标记标记一些传入的电子邮件。我开始浏览 MSDN,发现了 SMTP 服务器事件。 我发现有两种类型的事件

  • 协议事件
  • 传输事件
本文将讨论传输事件。

当 SMTP 服务器收到电子邮件时,会发生传输事件。我想讨论的事件是 OnSubmission 事件,还有另外 2 个事件:OnPreCategorizeOnPostCategorizeOnTransportSubmission 事件与 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 日 - 文章创建
© . All rights reserved.