Advertisement
Guest User

CSendMail.cls

a guest
Jan 12th, 2018
215
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. Option Explicit
  2.  
  3. '
  4. ' CSendMail.cls - wraps CDO allowing to send email messages
  5. '                 using an SMTP server; supports attachments
  6. '                 and HTML emails
  7. '
  8.  
  9.  
  10. ' SMTP authentication modes
  11. Public Enum enAuthMode
  12.   amAnonymous = 0             ' anonymous
  13.  amBasic = 1                 ' basic (standard)
  14.  amNTLM = 2                  ' NTLM (only supported by Exchange)
  15. End Enum
  16.  
  17. ' return receipt flags
  18. Public Enum enReceiptFlags
  19.   rfDefault = 0               ' use defaults
  20.  rfNever = 1                 ' no receipt/notification
  21.  rfFailure = 2               ' failure notification
  22.  rfSuccess = 4               ' success notification
  23.  rfDelay = 8                 ' delay notification
  24.  rfAll = 14                  ' all notifications
  25. End Enum
  26.  
  27. ' HTML body type
  28. Public Enum enHtmlBodyType
  29.   htNone = 0                  ' no HTML body
  30.  htHTML = 1                  ' HTML body from string
  31.  htURL = 2                   ' HTML body from URL
  32.  htFile = 3                  ' HTML body from file
  33. End Enum
  34.  
  35. ' events
  36. Public Event Failure(ByVal lNum As Long, ByVal sMsg As String, ByVal sInfo As String)
  37. Public Event Warning(ByVal sMsg As String)
  38. Public Event Notice(ByVal sMsg As String)
  39.  
  40. ' internal constants
  41. Private Const DEFAULT_SERVER As String = "localhost"
  42. Private Const DEFAULT_PORT As Long = 0
  43. Private Const DEFAULT_TIMEOUT As Long = 30
  44. Private Const FILE_URL As String = "file://"
  45. Private Const MSG_HEADERS As String = "urn:schemas:mailheader:"
  46. Private Const CDO_CONFIG As String = "http://schemas.microsoft.com/cdo/configuration/"
  47. Private Const SMTP_PORT As Long = 25
  48. Private Const SMTP_SSL_PORT As Long = 465
  49. Private Const SMTP_SEND_MODE As Long = 2 ' cdoSendUsingPort
  50.  
  51. ' server configuration
  52. Private msServer    As String     ' SMTP server name or IP
  53. Private mlPort      As Long       ' SMTP server port
  54. Private mlTimeOut   As Long       ' server connection timeout
  55. Private mbUseSSL    As Boolean    ' True = use SSL (not TLS!)
  56. Private mnAuthMode  As enAuthMode ' authentication mode
  57. Private msUser      As String     ' user name for auth
  58. Private msPass      As String     ' password for auth
  59.  
  60. ' last error data
  61. Private mlErrNum    As Long       ' last error number
  62. Private msErrMsg    As String     ' last error description
  63. Private msErrInfo   As String     ' additional error informations
  64.  
  65. ' CDO configuration
  66. Private mbReconfig  As Boolean    ' True if CDO reconfig is needed
  67. Private mobjCDOcfg  As Object     ' object containing the CDO config
  68.  
  69. ' other stuff
  70. Private objFSO      As Object     ' object used to access the filesystem
  71.  
  72. ' ================================================================
  73. ' CLASS INSTANCE
  74. ' ================================================================
  75.  
  76. ' constructor
  77. Private Sub Class_Initialize()
  78.   On Local Error Resume Next
  79.   mbReconfig = True
  80.   msServer = DEFAULT_SERVER
  81.   mlPort = DEFAULT_PORT
  82.   mlTimeOut = DEFAULT_TIMEOUT
  83.   mbUseSSL = False
  84.   mnAuthMode = amAnonymous
  85.   msUser = ""
  86.   msPass = ""
  87.   SetError 0, "", ""
  88.   Err.Clear
  89.   Set objFSO = CreateObject("Scripting.FileSystemObject")
  90.   If Err.Number <> 0 Then
  91.     SetError Err.Number, Err.Description, "Initialize"
  92.   End If
  93. End Sub
  94.  
  95. ' destructor
  96. Private Sub Class_Terminate()
  97.   Set mobjCDOcfg = Nothing
  98.   Set objFSO = Nothing
  99. End Sub
  100.  
  101. ' ================================================================
  102. ' PUBLIC PROPERTIES
  103. ' ================================================================
  104.  
  105. ' server name or IP
  106. Public Property Let Server(ByVal sServer As String)
  107.   msServer = Trim(sServer)
  108.   If Len(msServer) < 1 Then
  109.     msServer = DEFAULT_SERVER
  110.   End If
  111.   mbReconfig = True
  112. End Property
  113.  
  114. ' port number, 0=autoconfig
  115. Public Property Let Port(ByVal lPort As Long)
  116.   mlPort = lPort
  117.   If (mlPort < 1) Or (mlPort > 65535) Then
  118.     mlPort = DEFAULT_PORT
  119.   End If
  120.   mbReconfig = True
  121. End Property
  122.  
  123. ' connection timeout
  124. Public Property Let ConnTimeOut(ByVal lTimeOut As Long)
  125.   mlTimeOut = lTimeOut
  126.   If mlTimeOut < 0 Then
  127.     mlTimeOut = DEFAULT_TIMEOUT
  128.   End If
  129.   mbReconfig = True
  130. End Property
  131.  
  132. ' true to use SSL (not TLS, CDO doesn't support it)
  133. Public Property Let UseSSL(ByVal bYesNo As Boolean)
  134.   mbUseSSL = bYesNo
  135.   mbReconfig = True
  136. End Property
  137.  
  138. ' authentication mode
  139. Public Property Let AuthMode(ByVal nMode As enAuthMode)
  140.   mnAuthMode = nMode
  141.   mbReconfig = True
  142. End Property
  143.  
  144. ' user name
  145. Public Property Let User(ByVal sUser As String)
  146.   msUser = Trim(sUser)
  147.   mbReconfig = True
  148. End Property
  149.  
  150. ' password
  151. Public Property Let Password(ByVal sPassword As String)
  152.   msPass = Trim(sPassword)
  153.   mbReconfig = True
  154. End Property
  155.  
  156. ' last error number
  157. Public Property Get ErrNum() As Long
  158.   ErrNum = mlErrNum
  159. End Property
  160.  
  161. ' last error message
  162. Public Property Get ErrMsg() As String
  163.   ErrMsg = msErrMsg
  164. End Property
  165.  
  166. ' last error informations
  167. Public Property Get ErrInfo() As String
  168.   ErrInfo = msErrInfo
  169. End Property
  170.  
  171. ' ================================================================
  172. ' PUBLIC METHODS
  173. ' ================================================================
  174.  
  175. ' send an email message
  176. Public Function SendMail(ByVal sFrom As String, _
  177.                          ByVal sTo As String, _
  178.                          ByVal sCc As String, _
  179.                          ByVal sBCc As String, _
  180.                          ByVal sSubject As String, _
  181.                          ByVal sTextBody As String, _
  182.                          Optional ByVal nReceipt As enReceiptFlags = rfDefault, _
  183.                          Optional ByVal nHtmlType As enHtmlBodyType = htNone, _
  184.                          Optional ByVal sHtmlData As String = "", _
  185.                          Optional ByVal colAttach As Collection _
  186.                          ) As Boolean
  187.   Dim objMsg As Object
  188.   Dim sConf As String, sFile As String, sURL As String
  189.   Dim vItem As Variant
  190.   Dim bResult As Boolean
  191.  
  192.   ' init
  193.  bResult = False
  194.   SendMail = bResult
  195.   SetError 0, "", ""
  196.  
  197.  
  198.   ' check if the config needs to be initialized
  199.  ' this is done once so that sending multiple
  200.  ' mail messages will be faster, the config is
  201.  ' only recreated if some propery is changed
  202.  If Not InitConfig() Then
  203.     Exit Function
  204.   End If
  205.  
  206.   On Local Error GoTo Catch
  207.  
  208.   ' perform some sanity checks and raise
  209.  ' warning in case of missing parameters
  210.  If Len(Trim(sFrom)) = 0 Then
  211.     RaiseEvent Warning("No sender address")
  212.   End If
  213.   sConf = Trim(sTo) & Trim(sCc) & Trim(sBCc)
  214.   If Len(sConf) = 0 Then
  215.     RaiseEvent Warning("No recipient address")
  216.   End If
  217.   If Len(Trim(sSubject)) < 1 Then
  218.     RaiseEvent Warning("Empty subject")
  219.   End If
  220.   If Len(Trim(sTextBody)) < 1 Then
  221.     RaiseEvent Warning("Empty text body")
  222.     If nHtmlType <> htNone Then
  223.       sTextBody = vbCrLf & "Please use an HTML capable e-mail reader" & vbCrLf
  224.     End If
  225.   End If
  226.  
  227.   ' create the new email message
  228.  RaiseEvent Notice("Creating a new e-mail message")
  229.   Set objMsg = CreateObject("CDO.Message")
  230.   With objMsg
  231.     Set .Configuration = mobjCDOcfg
  232.     ' base infos
  233.    .From = sFrom
  234.     .To = sTo
  235.     .Cc = sCc
  236.     .BCc = sBCc
  237.     .Subject = sSubject
  238.     .TextBody = sTextBody
  239.     ' handle HTML body (if any)
  240.    If nHtmlType <> htNone Then
  241.       Select Case nHtmlType
  242.         Case htHTML
  243.           ' straight HTML code string
  244.          .HTMLBody = sHtmlData
  245.         Case Else
  246.           sURL = sHtmlData
  247.           If nHtmlType = htFile Then
  248.             sFile = GetFileName(sURL)
  249.             If Len(sFile) > 0 Then
  250.               ' file://x:/path/name/file.xyz
  251.              sURL = FILE_URL & Replace(sFile, "\", "/")
  252.             Else
  253.               RaiseEvent Warning("HTML file not found: " & sURL)
  254.               sURL = ""
  255.             End If
  256.           End If
  257.           If Len(sURL) > 0 Then
  258.             RaiseEvent Notice("Creating HTML body from " & sURL)
  259.             .CreateMHTMLBody sURL
  260.           End If
  261.       End Select
  262.     End If
  263.     ' Add attachments (if any)
  264.    If Not IsMissing(colAttach) Then
  265.       If Not colAttach Is Nothing Then
  266.         For Each vItem In colAttach
  267.           sFile = Trim(vItem)
  268.           If Len(sFile) > 0 Then
  269.             sFile = GetFileName(sFile)
  270.             If Len(sFile) > 0 Then
  271.               RaiseEvent Notice("Adding attachment " & sFile)
  272.               .Addattachment sFile
  273.             Else
  274.               RaiseEvent Warning("Attachment not found: " & vItem)
  275.             End If
  276.           End If
  277.         Next
  278.       End If
  279.     End If
  280.     ' Return receipts / notify
  281.    If (nReceipt <> rfNever) And (nReceipt <> rfDefault) Then
  282.       sConf = MSG_HEADERS
  283.       .Fields(sConf & "disposition-notification-to") = sFrom
  284.       .Fields(sConf & "return-receipt-to") = sFrom
  285.     End If
  286.     .DSNOptions = nReceipt
  287.     .Fields.Update
  288.   End With
  289.  
  290.   ' send the message
  291.  RaiseEvent Notice("Sending the e-mail message")
  292.   objMsg.Send
  293.   bResult = True
  294.   RaiseEvent Notice("E-mail message successfully sent")
  295.  
  296. BailOut:
  297.   ' common exit
  298.  Set objMsg = Nothing
  299.   SendMail = bResult
  300.   Exit Function
  301.  
  302. Catch:
  303.   ' got an error
  304.  SetError Err.Number, Err.Description, "CDO message"
  305.   bResult = False
  306.   Resume BailOut
  307. End Function
  308.  
  309. ' ================================================================
  310. ' PRIVATE CODE
  311. ' ================================================================
  312.  
  313. ' initialize the CDO configuration
  314. Private Function InitConfig() As Boolean
  315.   Dim sConf As String
  316.   Dim objFlds As Object
  317.   Dim bResult As Boolean
  318.  
  319.   ' need to reconfigure the CDO ?
  320.  If mbReconfig = False Then
  321.     InitConfig = True
  322.     Exit Function
  323.   End If
  324.  
  325.   On Local Error GoTo Catch
  326.  
  327.   ' initialize, notice how the server port is automatically
  328.  ' selected (if set to 0) according to the SSL flag
  329.  bResult = False
  330.   If mlPort = DEFAULT_PORT Then
  331.     If mbUseSSL Then
  332.       mlPort = SMTP_SSL_PORT  ' SMTP over SSL
  333.    Else
  334.       mlPort = SMTP_PORT      ' standard SMTP
  335.    End If
  336.   End If
  337.  
  338.  
  339.   RaiseEvent Notice("Configuring SMTP server " & msServer & ":" & mlPort)
  340.  
  341.   ' instance the configuration object
  342.  Set mobjCDOcfg = Nothing
  343.   Set mobjCDOcfg = CreateObject("CDO.Configuration")
  344.  
  345.   ' set configuration
  346.  sConf = CDO_CONFIG
  347.   Set objFlds = mobjCDOcfg.Fields
  348.   With objFlds
  349.     .Item(sConf & "sendusing") = SMTP_SEND_MODE
  350.     .Item(sConf & "smtpserver") = msServer
  351.     .Item(sConf & "smtpusessl") = IIf(mbUseSSL, 1, 0)
  352.     .Item(sConf & "smtpserverport") = mlPort
  353.     .Item(sConf & "smtpconnectiontimeout") = mlTimeOut
  354.     .Item(sConf & "smtpauthenticate") = mnAuthMode
  355.     If mnAuthMode = amAnonymous Then
  356.       ' no authentication
  357.      .Item(sConf & "sendusername") = ""
  358.       .Item(sConf & "sendpassword") = ""
  359.     Else
  360.       ' use authentication
  361.      .Item(sConf & "sendusername") = msUser
  362.       .Item(sConf & "sendpassword") = msPass
  363.       If (Len(msUser) < 1) Or (Len(msPass) < 1) Then
  364.         RaiseEvent Warning("Empty Username or Password")
  365.       End If
  366.     End If
  367.     .Update
  368.   End With
  369.  
  370.   ' all ok
  371.  RaiseEvent Notice("Configuration complete")
  372.   mbReconfig = False
  373.   bResult = True
  374.  
  375. BailOut:
  376.   ' common exit
  377.  Set objFlds = Nothing
  378.   InitConfig = bResult
  379.   Exit Function
  380.  
  381. Catch:
  382.   ' got an error
  383.  SetError Err.Number, Err.Description, "CDO configuration"
  384.   bResult = False
  385.   Resume BailOut
  386. End Function
  387.  
  388. ' store and signal an error
  389. Private Sub SetError(ByVal lNum As Long, _
  390.                      ByVal sMsg As String, _
  391.                      ByVal sInfo As String)
  392.   mlErrNum = lNum
  393.   msErrMsg = sMsg
  394.   msErrInfo = sInfo
  395.   If lNum <> 0 Then
  396.     msErrMsg = Trim(Replace(msErrMsg, vbCrLf, " "))
  397.     RaiseEvent Failure(mlErrNum, msErrMsg, msErrInfo)
  398.   End If
  399. End Sub
  400.  
  401. ' get the full pathname for a given file
  402. Function GetFileName(ByVal sPathName As String) As String
  403.   Dim fi As Object
  404.   Dim sFullName As String
  405.  
  406.   On Local Error Resume Next
  407.   GetFileName = ""
  408.   If Not objFSO.FileExists(sPathName) Then
  409.     Exit Function
  410.   End If
  411.   Set fi = objFSO.GetFile(sPathName)
  412.   sFullName = fi.Path
  413.  
  414.   Set fi = Nothing
  415.   GetFileName = sFullName
  416. End Function
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement