Here is some code that I wrote for sending emails, cc, bcc, attachments, authentication, plain/html emails. Basically, I wrote it to help myself learn how to create the new PB Classes.
Sample code to call the Class
clsEmail.inc
Sample code to call the Class
Code:
#Compile Exe #Include "win32api.inc" #Include "clsEmail.inc" Function PBMain() As Long ' NOTES: ' The 'SendTo', 'CC', 'BCC' fields can be a one address or a ' semicolon(;) or comma(,) deliminated list of multiple addresses. ' SMTP only allows 100 recipients max at a time (per rfc821), therefore ' for large mailings you should break it into multiple emails. ' Multiple attachments can be sent by simply separating the file ' names with a semicolon or comma. ' You can use 'Plain' text emails or 'HTML' emails, or 'Both'. ' When sending "Both", the email client application will use whichever ' one it can render based on the user's settings. ' Default values for the following that are already set by the ' class (constructor). Change them here if you want a different value. ' e.g. ' cMail.ServerTimeOut = 60000 ' milliseconds ' default is 60000 ' cMail.LocalHost = "MySuperComputer" ' default is localhost ' cMail.CharSet = "us-ascii" ' default is iso-8859-1 ' cMail.MessageStyle = "both" ' default is Plain Dim cMail As EMailInterface cMail = Class "clsEmail" cMail.SMTPServer = "mysmtpxxxx.com" cMail.SendFrom = "[email protected]" cMail.SendTo = "[email protected]" cMail.CC = "[email protected]" cMail.BCC = "[email protected]" cMail.ReplyTo = "[email protected]" cMail.Subject = "test subject" cMail.EnableAuth = %TRUE cMail.AuthType = "AUTH LOGIN" cMail.AuthUsername = "[email protected]" cMail.AuthPassword = "mypassword" cMail.MessageStyle = "both" cMail.Attachments = "" ' eg. "myfilename.zip" ' Plain text email cMail.PlainMessage = "This is my test message." & $CrLf & _ "Line #2" & $CrLf & _ "Last line." ' HTML text email cMail.HTMLMessage = "<html>" & $CrLf & _ "<body>" & $CrLf & _ "<center><b>This Is a test!</b></center>" & $CrLf & _ "</body>" & $CrLf & _ "</html>" & $CrLf ' Send the actual email and deal with any error/message response. If cMail.SendMail Then MsgBox "Error sending E-mail! " & cMail.Response Else MsgBox "Email(s) sent okay." End If End Function
Code:
Class clsEmail Instance m_Server As String Instance m_From As String Instance m_ReplyTo As String Instance m_TO As String Instance m_CC As String Instance m_BCC As String Instance m_Subject As String Instance m_PlainMessage As String Instance m_HTMLMessage As String Instance m_Response As String Instance m_EnableAuth As Long Instance m_AuthType As String Instance m_AuthUsername As String Instance m_AuthPassword As String Instance m_Style As String Instance m_Timeout As Long Instance m_Attachments As String Instance m_LocalHost As String Instance m_CharSet As String '------------------------------------------------------------ ' Private Class methods '------------------------------------------------------------ '// '// Class Method Create() ' Constructor ' Initialize default properties m_Timeout = 60000 '(60 seconds) m_CharSet = "iso-8859-1" m_Style = "plain" Host Name To m_LocalHost End Method '// '// Class Method MimeEncode( ByVal sFileData As String ) As String Local lBlock, lcBlocks, lByte1, lByte2, lByte3, lIndex1, lIndex2, lIndex3, lIndex4 As Long Local pInput, pOutput, pTable As Byte Ptr Local sBase64, sResult, Pad As String sBase64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" 'Base64 table Pad = String$(2 - (Len(sFileData) - 1) Mod 3, "=") 'Calculate padding on Base64 stream lcBlocks = (Len(sFileData) + 2) \ 3 'Round up the length of the input If lcBlocks * 3 > Len(sFileData) Then 'data to a multiple of three sFileData = LSet$(sFileData, lcBlocks * 3 Using $Nul) End If sResult = Space$(lcBlocks * 4) 'Allocate space for output string pInput = StrPtr(sFileData) 'Set up pointers so we can treat pOutput = StrPtr(sResult) 'the data as byte streams pTable = StrPtr(sBase64) For lBlock = 1 To lcBlocks 'Loop through the input buffer lByte1 = @pInput : Incr pInput 'Get the next three binary data- lByte2 = @pInput : Incr pInput 'bytes to process lByte3 = @pInput : Incr pInput lIndex1 = lByte1 \ 4 'Translate 3 databytes to 4 Base64 lIndex2 = (lByte1 And 3) * 16 + lByte2 \ 16 'table indices lIndex3 = (lByte2 And 15) * 4 + lByte3 \ 64 lIndex4 = lByte3 And 63 @pOutput = @pTable[lIndex1] : Incr pOutput 'Use Base64 table to encode the @pOutput = @pTable[lIndex2] : Incr pOutput 'output string @pOutput = @pTable[lIndex3] : Incr pOutput @pOutput = @pTable[lIndex4] : Incr pOutput Next RSet Abs sResult = Pad 'Merge in the padding bytes Method = sResult End Method '// '// Class Method GetMailDateTime() As String ' Retrieve the current time and date to put in E-mail header format Local szFormat As Asciiz * 40 Local szTemp As Asciiz * 40 Local sResult As String Local t As SYSTEMTIME Local sUCTOffset As String Local tzi As TIME_ZONE_INFORMATION GetLocalTime t szFormat = "ddd',' dd MMM yyyy" GetDateFormat %LOCALE_USER_DEFAULT, 0, t, szFormat, szTemp, SizeOf(szTemp) sResult = szTemp szFormat = "HH':'mm':'ss" GetTimeFormat %LOCALE_USER_DEFAULT, 0, t, szFormat, szTemp, SizeOf(szTemp) Select Case GetTimeZoneInformation(tzi) Case %TIME_ZONE_ID_DAYLIGHT sUCTOffset = IIf$((tzi.bias + tzi.DaylightBias) <= 0, "+", "-") _ + Format$(Abs(tzi.bias + tzi.DaylightBias) \ 60, "00") _ + Format$(Abs(tzi.bias + tzi.DaylightBias) Mod 60, "00") Case %TIME_ZONE_ID_STANDARD sUCTOffset = IIf$((tzi.bias + tzi.StandardBias) <= 0, "+", "-") _ + Format$(Abs(tzi.bias + tzi.StandardBias) \ 60, "00") _ + Format$(Abs(tzi.bias + tzi.StandardBias) Mod 60, "00") Case Else sUCTOffset = "-0000" End Select Method = sResult & " " & szTemp & " " & sUCTOffset End Method '------------------------------------------------------------ ' End of Private Class methods '------------------------------------------------------------ '------------------------------------------------------------ ' Public Interface '------------------------------------------------------------ '// '// Interface EMailInterface: Inherit IUnknown Property Get SMTPServer() As String Property = m_Server End Property Property Set SMTPServer( ByVal sServerName As String ) m_Server = RTrim$(sServername) End Property Property Get SendFrom() As String Property = m_From End Property Property Set SendFrom( ByVal sRecipientFrom As String ) m_From = RTrim$(sRecipientFrom) End Property Property Get SendTo() As String Property = m_TO End Property Property Set SendTo( ByVal sRecipientTo As String ) m_TO = RTrim$(sRecipientTo) End Property Property Get CC() As String Property = m_CC End Property Property Set CC( ByVal sRecipientCC As String ) m_CC = RTrim$(sRecipientCC) End Property Property Get BCC() As String Property = m_BCC End Property Property Set BCC( ByVal sRecipientBCC As String ) m_BCC = RTrim$(sRecipientBCC) End Property Property Get ReplyTo() As String Property = m_ReplyTo End Property Property Set ReplyTo( ByVal sReplyTo As String ) m_ReplyTo = RTrim$(sReplyTo) End Property Property Get Subject() As String Property = m_Subject End Property Property Set Subject( ByVal sSubject As String ) m_Subject = sSubject End Property Property Get PlainMessage() As String Property = m_PlainMessage End Property Property Set PlainMessage( ByVal sPlainMessage As String ) m_PlainMessage = sPlainMessage End Property Property Get HTMLMessage() As String Property = m_HTMLMessage End Property Property Set HTMLMessage( ByVal sHTMLMessage As String ) m_HTMLMessage = sHTMLMessage End Property Property Get Response() As String Property = m_Response End Property Property Get EnableAuth() As Long Property = m_EnableAuth End Property Property Set EnableAuth( ByVal nEnableAuth As Long ) m_EnableAuth = nEnableAuth End Property Property Get AuthType() As String Property = m_AuthType End Property Property Set AuthType( ByVal sAuthType As String ) m_AuthType = RTrim$(sAuthType) End Property Property Get AuthUserName() As String Property = m_AuthUserName End Property Property Set AuthUserName( ByVal sAuthUserName As String ) m_AuthUserName = RTrim$(sAuthUserName) End Property Property Get AuthPassword() As String Property = m_AuthPassword End Property Property Set AuthPassword( ByVal sAuthPassword As String ) m_AuthPassword = RTrim$(sAuthPassword) End Property Property Get MessageStyle() As String Property = m_Style End Property Property Set MessageStyle( ByVal sMessageStyle As String ) m_Style = UCase$(RTrim$(sMessageStyle)) End Property Property Get ServerTimeout() As Long Property = m_Timeout End Property Property Set ServerTimeout( ByVal nServerTimeout As Long ) m_Timeout = nServerTimeout End Property Property Get Attachments() As String Property = m_Attachments End Property Property Set Attachments( ByVal sAttachments As String ) m_Attachments = RTrim$(sAttachments) End Property Property Get LocalHost() As String Property = m_LocalHost End Property Property Set LocalHost( ByVal sLocalHost As String ) m_LocalHost = RTrim$(sLocalHost) End Property Property Get CharSet() As String Property = m_CharSet End Property Property Set CharSet( ByVal sCharSet As String ) m_CharSet = RTrim$(sCharSet) End Property '// '// Method SendMail() As Long Local hTCP As Long Local y As Long Local f As Long Local z As Long Local NumLines As Long Local errcode As Long Local sTmp As String Local sBuffer As String Local sBoundary As String Local sAllRecipients As String Local NumAttachments As Long ' Make a unique file data boundary marker sBoundary = "Boundary." & Remove$(GuidTxt$(Guid$), Any "{-}") ' Connect to E-mail server (mailhost) hTCP = FreeFile Tcp Open "smtp" At m_Server As hTCP TimeOut m_Timeout m_Response = "Cannot connect to E-mail server: " & m_Server If Err Then GoTo SendError Tcp Line hTCP, m_Response If Left$(m_Response, 3) <> "220" Then GoTo SendError ' Get the local host name If RTrim$(m_LocalHost) = "" Then m_LocalHost = "localhost" ' Greet the mailhost Tcp Print hTCP, "HELO " & m_LocalHost Tcp Line hTCP, m_Response If Left$(m_Response, 3) <> "250" Then GoTo SendError ' Send authentication if required If m_EnableAuth Then Do While Not Eof(hTCP) Tcp Line hTCP, sBuffer errcode = Val(Left$(sBuffer, 3)) Loop Tcp Print hTCP, m_AuthType Do While Not Eof(hTCP) Tcp Line hTCP, sBuffer errcode = Val(Left$(sBuffer, 3)) Loop If errcode = 334 Then sTmp = Me.MimeEncode(m_AuthUsername) ' UserId (might be the same as the POP3 UserId) Tcp Print hTCP, sTmp Do While Not Eof(hTCP) Tcp Line hTCP, sBuffer errcode = Val(Left$(sBuffer, 3)) Loop If errcode = 334 Then sTmp = Me.MimeEncode(m_AuthPassword) ' Password (might be the same as the POP3 password) Tcp Print hTCP, sTmp Do While Not Eof(hTCP) Tcp Line hTCP, sBuffer errcode = Val(Left$(sBuffer, 3)) Loop End If End If End If ' Tell the mailhost who we are Tcp Print hTCP, "MAIL FROM:<" & m_From & ">" Tcp Line hTCP, m_Response If Left$(m_Response, 3) <> "250" Then GoTo SendError ' Tell the mailhost who the message is for ' There could be multiple recipients so iterate through ' the semicolon or comma deliminated list. The total RCPT ' list is the combination of the TO, CC, BCC lists. sAllRecipients = m_TO & ";" & m_CC & ";" & m_BCC NumLines = ParseCount(sAllRecipients, Any ";,") ReDim sArray(1 To NumLines) As String Parse sAllRecipients, sArray(), Any ";," For y = 1 To NumLines sTmp = RTrim$(sArray(y)) If Len(sTmp) Then Tcp Print hTCP, "RCPT TO:<" & sTmp & ">" Tcp Line hTCP, m_Response If Left$(m_Response, 3) <> "250" Then GoTo SendError End If Next ' Send the message Tcp Print hTCP, "DATA" Tcp Line hTCP, m_Response If Left$(m_Response, 3) <> "354" Then GoTo SendError ' The E-mail header Tcp Print hTCP, "Date: " & Me.GetMailDateTime Tcp Print hTCP, "From: " & m_From Tcp Print hTCP, "To: " & m_To If Len(m_ReplyTo) Then Tcp Print hTCP, "Reply-To: " & m_ReplyTo End If If Len(m_CC) Then Tcp Print hTCP, "Cc: " & m_CC End If ' Obviously we won't output the BCC list to the email Tcp Print hTCP, "Subject: " & m_Subject Tcp Print hTCP, "X-Mailer: pMailer Mail" Tcp Print hTCP, "MIME-Version: 1.0" Tcp Print hTCP, "Content-Type: multipart/mixed; boundary=" & $Dq & sBoundary & $Dq Tcp Print hTCP, "" ' Create a main E-mail body section for the Plain message. ' Break the message down into lines If (m_Style = "PLAIN") Or (m_Style = "BOTH") Then Tcp Print hTCP, "--" & sBoundary Tcp Print hTCP, "Content-Type: text/plain; charset=" & $Dq & m_CharSet & $Dq Tcp Print hTCP, "Content-Transfer-Encoding: 7bit" Tcp Print hTCP, "" ' Any crlf pairs or plain lf's will be replaced with cr's for easy parsing Replace $CrLf With $Cr In m_PlainMessage Replace $Lf With $Cr In m_PlainMessage NumLines = ParseCount( m_PlainMessage, $Cr ) ReDim sArray(1 To NumLines) As String Parse m_PlainMessage, sArray(), $Cr For y = 1 To NumLines Tcp Print hTCP, sArray(y) Next End If If (m_Style = "HTML") Or (m_Style = "BOTH") Then Tcp Print hTCP, "--" & sBoundary Tcp Print hTCP, "Content-Type: text/html; charset=" & $Dq & m_CharSet & $Dq Tcp Print hTCP, "Content-Transfer-Encoding: 7bit" Tcp Print hTCP, "" ' Any crlf pairs or plain lf's will be replaced with cr's for easy parsing Replace $CrLf With $Cr In m_HTMLMessage Replace $Lf With $Cr In m_HTMLMessage NumLines = ParseCount( m_HTMLMessage, $Cr ) ReDim sArray(1 To NumLines) As String Parse m_HTMLMessage, sArray(), $Cr For y = 1 To NumLines Tcp Print hTCP, sArray(y) Next End If ' Create the attachment body section If Len(m_Attachments) > 0 Then NumAttachments = ParseCount( m_Attachments, ";," ) ReDim sArray(1 To NumAttachments) As String Parse m_Attachments, sArray(), ";," For y = 1 To NumAttachments If Dir$(sArray(y)) = "" Then Iterate For f = FreeFile Open sArray(y) For Binary As #f Get$ #f, Lof(f), sBuffer Close #f ' Encode the file sBuffer = Me.MimeEncode( sBuffer ) Tcp Print hTCP, "--" & sBoundary Tcp Print hTCP, "Content-Type: application/octet-stream; name=" & $Dq & PathName$(NameX, sArray(y)) & $Dq Tcp Print hTCP, "Content-Transfer-Encoding: base64" Tcp Print hTCP, "" ' Write the encoded data in lines of 76 characters. Add an equality ' character if the last line is less than 76 bytes long For z = 1 To Len(sBuffer) Step 76 If Len(sBuffer) - z >= 76 Then Tcp Print hTCP, Mid$(sBuffer, z, 76) Else Tcp Print hTCP, Mid$(sBuffer, z) & "=" End If Next Next End If ' Send the terminating boundary marker Tcp Print hTCP, "--" & sBoundary & "--" ' Now finish the E-mail off as we're done sending the message Tcp Print hTCP, "." Tcp Line hTCP, m_Response If Left$(m_Response, 3) <> "250" Then GoTo SendError ' Say goodbye Tcp Print hTCP, "QUIT" Tcp Line hTCP, m_Response If Left$(m_Response, 3) <> "221" Then GoTo SendError Tcp Close hTCP Exit Method SendError: Method = %TRUE ' error occurred End Method End Interface '------------------------------------------------------------ ' End of Public Interface '------------------------------------------------------------ End Class
Comment