Jump to content

Smtp Mailer That Supports Html And Attachments.


Jos
 Share

Recommended Posts

Optically beter to read/understood/diagnoze/learn/modify.

 

Edited by mLipok

Signature beginning:
Please remember: "AutoIt"..... *  Wondering who uses AutoIt and what it can be used for ? * Forum Rules *
ADO.au3 UDF * POP3.au3 UDF * XML.au3 UDF * IE on Windows 11 * How to ask ChatGPT for AutoIt Codefor other useful stuff click the following button:

Spoiler

Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind. 

My contribution (my own projects): * Debenu Quick PDF Library - UDF * Debenu PDF Viewer SDK - UDF * Acrobat Reader - ActiveX Viewer * UDF for PDFCreator v1.x.x * XZip - UDF * AppCompatFlags UDF * CrowdinAPI UDF * _WinMergeCompare2Files() * _JavaExceptionAdd() * _IsBeta() * Writing DPI Awareness App - workaround * _AutoIt_RequiredVersion() * Chilkatsoft.au3 UDF * TeamViewer.au3 UDF * JavaManagement UDF * VIES over SOAP * WinSCP UDF * GHAPI UDF - modest begining - comunication with GitHub REST APIErrorLog.au3 UDF - A logging Library * Include Dependency Tree (Tool for analyzing script relations) * Show_Macro_Values.au3 *

 

My contribution to others projects or UDF based on  others projects: * _sql.au3 UDF  * POP3.au3 UDF *  RTF Printer - UDF * XML.au3 UDF * ADO.au3 UDF SMTP Mailer UDF * Dual Monitor resolution detection * * 2GUI on Dual Monitor System * _SciLexer.au3 UDF * SciTE - Lexer for console pane

Useful links: * Forum Rules * Forum etiquette *  Forum Information and FAQs * How to post code on the forum * AutoIt Online Documentation * AutoIt Online Beta Documentation * SciTE4AutoIt3 getting started * Convert text blocks to AutoIt code * Games made in Autoit * Programming related sites * Polish AutoIt Tutorial * DllCall Code Generator * 

Wiki: Expand your knowledge - AutoIt Wiki * Collection of User Defined Functions * How to use HelpFile * Good coding practices in AutoIt * 

OpenOffice/LibreOffice/XLS Related: WriterDemo.au3 * XLS/MDB from scratch with ADOX

IE Related:  * How to use IE.au3  UDF with  AutoIt v3.3.14.x * Why isn't Autoit able to click a Javascript Dialog? * Clicking javascript button with no ID * IE document >> save as MHT file * IETab Switcher (by LarsJ ) * HTML Entities * _IEquerySelectorAll() (by uncommon) * IE in TaskSchedulerIE Embedded Control Versioning (use IE9+ and HTML5 in a GUI) * PDF Related:How to get reference to PDF object embeded in IE * IE on Windows 11

I encourage you to read: * Global Vars * Best Coding Practices * Please explain code used in Help file for several File functions * OOP-like approach in AutoIt * UDF-Spec Questions *  EXAMPLE: How To Catch ConsoleWrite() output to a file or to CMD *

I also encourage you to check awesome @trancexx code:  * Create COM objects from modules without any demand on user to register anything. * Another COM object registering stuffOnHungApp handlerAvoid "AutoIt Error" message box in unknown errors  * HTML editor

winhttp.au3 related : * https://www.autoitscript.com/forum/topic/206771-winhttpau3-download-problem-youre-speaking-plain-http-to-an-ssl-enabled-server-port/

"Homo sum; humani nil a me alienum puto" - Publius Terentius Afer
"Program are meant to be read by humans and only incidentally for computers and execute" - Donald Knuth, "The Art of Computer Programming"
:naughty:  :ranting:, be  :) and       \\//_.

Anticipating Errors :  "Any program that accepts data from a user must include code to validate that data before sending it to the data store. You cannot rely on the data store, ...., or even your programming language to notify you of problems. You must check every byte entered by your users, making sure that data is the correct type for its field and that required fields are not empty."

Signature last update: 2023-04-24

Link to comment
Share on other sites

  • Developers

Ok, so let's agree to disagree here. ;) 
I am fine with they it is and it compares easily now with the zillion examples out there that are coded in the way I have done it. :)

Jos

SciTE4AutoIt3 Full installer Download page   - Beta files       Read before posting     How to post scriptsource   Forum etiquette  Forum Rules 
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Link to comment
Share on other sites

  • Developers
On 11/8/2020 at 3:03 AM, Zedna said:

I know it's late, but anyway here it is:

$objEmail.Fields("urn:schemas:mailheader:x-mailer") = "My application Name or whatever else"

 

and here is the way how to set "code page" (here Czech) :

this is important when you have chars with diacritics (special non-english letters) in your email

$objEmail.BodyPart.ContentTransferEncoding = "8bit"
$objEmail.BodyPart.CharSet = "windows-1250"

 

Good info! Thanks for that and I have added this to the First post to share. :) 

Jos 

SciTE4AutoIt3 Full installer Download page   - Beta files       Read before posting     How to post scriptsource   Forum etiquette  Forum Rules 
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Link to comment
Share on other sites

In my scripts I use this another parameter:

$objEmail.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/smtpconnectiontimeout") = 60

 

https://docs.microsoft.com/en-us/previous-versions/office/developer/exchange-server-2003/ms873043(v=exchg.65)

Quote

The number of seconds that can elapse without a response from the SMTP service before the connection attempt is aborted.

 

So here I share this for you as another possible tip ...

Edited by Zedna
Link to comment
Share on other sites

  • Developers

Thanks...... Have you ever had the need to extent the timer from the default 30 seconds to 60?

SciTE4AutoIt3 Full installer Download page   - Beta files       Read before posting     How to post scriptsource   Forum etiquette  Forum Rules 
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Link to comment
Share on other sites

As per DOCS 30s is default only when Outlook Express is installed.

By this setting I tried to set smaller timeout than observed (bigger) real time/timeout when problems in connection to SMTP server.

You can change this value to smaller one.

This code is only as tip that such option is available ...

Link to comment
Share on other sites

  • Developers
5 minutes ago, Zedna said:

As per DOCS 30s is default only when Outlook Express is installed.

Nah ...   it states that 30 secs is the default, unless OE is installed at which time the timeout of OE is used:

5 minutes ago, Zedna said:

This code is only as tip that such option is available .

Quote

The default value for this field is 30 seconds.
If Microsoft Outlook Express is installed, then the value from the default account is used.

I know and do appreciate the sharing of this kind of information and honestly was just curious whether you have had any issues with that 30 sec timeout which made you have to add this option. ;)  

Edited by Jos

SciTE4AutoIt3 Full installer Download page   - Beta files       Read before posting     How to post scriptsource   Forum etiquette  Forum Rules 
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Link to comment
Share on other sites

  • 1 month later...

Awesome UDF :)

But I have a minor issue, can I use unicode characters in the sender name? I tried it but all I see is question marks in the received email.

EasyCodeIt - A cross-platform AutoIt implementation - Fund the development! (GitHub will double your donations for a limited time)

DcodingTheWeb Forum - Follow for updates and Join for discussion

Link to comment
Share on other sites

  • Developers
7 hours ago, TheDcoder said:

But I have a minor issue, can I use unicode characters in the sender name? I tried it but all I see is question marks in the received email.

Try adding this in your code to convert the name to utf-8 encoded base64:

$s_FromName = "Jos ąćę"                      ; name from who the email was sent
$s_Fromname = "=?utf-8?B?" & _Base64Encode(BinaryToString(StringToBinary($s_FromName,4),1)) & '?='


Func _Base64Encode($vInput)
    Local Const $CRYPT_STRING_BASE64 = 0x00000001
    Local Const $CRYPT_STRING_NOCRLF = 0x40000000

    $vInput = Binary($vInput)
    Local $tInput = DllStructCreate("byte[" & BinaryLen($vInput) & "]")
    DllStructSetData($tInput, 1, $vInput)

    Local $aCall = DllCall("Crypt32.dll", "bool", "CryptBinaryToStringA", _
            "struct*", $tInput, _
            "dword", DllStructGetSize($tInput), _
            "dword", $CRYPT_STRING_BASE64 + $CRYPT_STRING_NOCRLF , _
            "ptr", 0, _
            "dword*", 0)
    If @error Or Not $aCall[0] Then Return SetError(1, 0, "") ; error calculating the length of the needed buffer

    Local $tOut = DllStructCreate("char[" & $aCall[5] & "]")

    $aCall = DllCall("Crypt32.dll", "int", "CryptBinaryToStringA", _
            "struct*", $tInput, _
            "dword", DllStructGetSize($tInput), _
            "dword", $CRYPT_STRING_BASE64 + $CRYPT_STRING_NOCRLF, _
            "struct*", $tOut, _
            "dword*", DllStructGetSize($tOut))
    If @error Or Not $aCall[0] Then Return SetError(2, 0, ""); error encoding

    Return DllStructGetData($tOut, 1)
EndFunc

This seems to working for me.... maybe there is an other/simpler way, but this worked for me. :)

Jos

SciTE4AutoIt3 Full installer Download page   - Beta files       Read before posting     How to post scriptsource   Forum etiquette  Forum Rules 
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Link to comment
Share on other sites

  • Developers
19 hours ago, TheDcoder said:

Would the same technique also work for the message body?

Just add the 2 lines to the original UDF:

If StringInStr($as_Body, "<") And StringInStr($as_Body, ">") Then
        $objEmail.HTMLBody = $as_Body
        $objEmail.HTMLBodyPart.CharSet = "UTF-8"
    Else
        $objEmail.Textbody = $as_Body & @CRLF
        $objEmail.TextBodyPart.CharSet = "UTF-8"
    EndIf

Jos

SciTE4AutoIt3 Full installer Download page   - Beta files       Read before posting     How to post scriptsource   Forum etiquette  Forum Rules 
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Link to comment
Share on other sites

@Jos Awesome, maybe these changes should be merged into the UDF in the first post since AutoIt uses unicode strings anyway, what do you think?

EasyCodeIt - A cross-platform AutoIt implementation - Fund the development! (GitHub will double your donations for a limited time)

DcodingTheWeb Forum - Follow for updates and Join for discussion

Link to comment
Share on other sites

  • Developers

Agree, but first needs to be properly tested to see if everything keeps working and I haven't done that yet. 
So ...  input/feedback is welcome before doing so! :) 

My preference is to do this without adding an option and just default to these changes when they work also for regular text/names.

Jos

Edited by Jos

SciTE4AutoIt3 Full installer Download page   - Beta files       Read before posting     How to post scriptsource   Forum etiquette  Forum Rules 
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Link to comment
Share on other sites

6 minutes ago, Jos said:

So ...  input/feedback is welcome before doing so! :) 

I will report back after testing :)

7 minutes ago, Jos said:

My preference is to do this without adding an option

Same! It should be okay because UTF-8 is backward compatible with ASCII (which is what I think Windows is defaulting to).

EasyCodeIt - A cross-platform AutoIt implementation - Fund the development! (GitHub will double your donations for a limited time)

DcodingTheWeb Forum - Follow for updates and Join for discussion

Link to comment
Share on other sites

  • Developers

Please give this a try before I update the main page:

;
;##################################
; Include
;##################################
#include <file.au3>
;##################################
; Variables
;##################################
$SmtpServer = "MailServer"              ; address for the smtp-server to use - REQUIRED
$FromName = "Name"                      ; name from who the email was sent
$FromAddress = "your@Email.Address.com" ; address from where the mail should come
$ToAddress = "your@Email.Address.com"   ; destination address of the email - REQUIRED
$Subject = "Userinfo"                   ; subject from the email - can be anything you want it to be
$Body = ""                              ; the messagebody from the mail - can be left blank but then you get a blank mail
$AttachFiles = ""                       ; the file(s) you want to attach seperated with a ; (Semicolon) - leave blank if not needed
$CcAddress = "CCadress1@test.com"       ; address for cc - leave blank if not needed
$BccAddress = "BCCadress1@test.com"     ; address for bcc - leave blank if not needed
$Importance = "Normal"                  ; Send message priority: "High", "Normal", "Low"
$Username = "******"                    ; username for the account used from where the mail gets sent - REQUIRED
$Password = "********"                  ; password for the account used from where the mail gets sent - REQUIRED
$IPPort = 25                            ; port used for sending the mail
$ssl = 0                                ; enables/disables secure socket layer sending - put to 1 if using httpS
$tls = 0                                ; enables/disables TLS when required

;~ $SmtpServer = "smtp.gmail.com"       ; GMAIL address for the smtp-server to use - REQUIRED
;~ $IPPort=465                          ; GMAIL port used for sending the mail
;~ $ssl=1                               ; GMAIL enables/disables secure socket layer sending - put to 1 if using httpS
;~ $SmtpServer = "smtp.office365.com"   ; O365 address for the smtp-server to use - REQUIRED
;~ $IPPort=25                           ; O365 port used for sending the mail
;~ $ssl=1                               ; O365 enables/disables secure socket layer sending - put to 1 if using httpS
;~ SmtpServer = "smtp.mail.yahoo.com"   ; Yahoo address for the smtp-server to use - REQUIRED
;~ $IPPort = 465                        ; Yahoo port used for sending the mail
;~ $ssl = 1                             ; Yahoo enables/disables secure socket layer sending - put to 1 if using httpS

;##################################
; Script
;##################################
Global $oMyRet[2]
Global $oMyError = ObjEvent("AutoIt.Error", "MyErrFunc")
$rc = _INetSmtpMailCom($SmtpServer, $FromName, $FromAddress, $ToAddress, $Subject, $Body, $AttachFiles, $CcAddress, $BccAddress, $Importance, $Username, $Password, $IPPort, $ssl, $tls)
If @error Then
    MsgBox(0, "Error sending message", "Error code:" & @error & "  Description:" & $rc)
EndIf
;
; The UDF
Func _INetSmtpMailCom($s_SmtpServer, $s_FromName, $s_FromAddress, $s_ToAddress, $s_Subject = "", $as_Body = "", $s_AttachFiles = "", $s_CcAddress = "", $s_BccAddress = "", $s_Importance="Normal", $s_Username = "", $s_Password = "", $IPPort = 25, $ssl = 0, $tls = 0)
    Local $objEmail = ObjCreate("CDO.Message")
    ; convert the Fromname to UTF-8 basex64 to allow for UTF characters in the name
    If $s_FromName <> "" Then $s_FromName = "=?utf-8?B?" & _Base64Encode(BinaryToString(StringToBinary($s_FromName, 4), 1)) & '?='
    $objEmail.From = '"' & $s_FromName & '" <' & $s_FromAddress & '>'
    $objEmail.To = $s_ToAddress
    Local $i_Error = 0
    Local $i_Error_desciption = ""
    If $s_CcAddress <> "" Then $objEmail.Cc = $s_CcAddress
    If $s_BccAddress <> "" Then $objEmail.Bcc = $s_BccAddress
    $objEmail.Subject = $s_Subject
    If StringInStr($as_Body, "<") And StringInStr($as_Body, ">") Then
        $objEmail.HTMLBody = $as_Body
        $objEmail.HTMLBodyPart.CharSet = "UTF-8"
    Else
        $objEmail.Textbody = $as_Body & @CRLF
        $objEmail.TextBodyPart.CharSet = "UTF-8"
    EndIf
    If $s_AttachFiles <> "" Then
        Local $S_Files2Attach = StringSplit($s_AttachFiles, ";")
        For $x = 1 To $S_Files2Attach[0]
            $S_Files2Attach[$x] = _PathFull($S_Files2Attach[$x])
;~          ConsoleWrite('@@ Debug : $S_Files2Attach[$x] = ' & $S_Files2Attach[$x] & @LF & '>Error code: ' & @error & @LF) ;### Debug Console
            If FileExists($S_Files2Attach[$x]) Then
                ConsoleWrite('+> File attachment added: ' & $S_Files2Attach[$x] & @LF)
                $objEmail.AddAttachment($S_Files2Attach[$x])
            Else
                ConsoleWrite('!> File not found to attach: ' & $S_Files2Attach[$x] & @LF)
                SetError(1)
                Return 0
            EndIf
        Next
    EndIf
    $objEmail.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/sendusing") = 2
    $objEmail.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/smtpserver") = $s_SmtpServer
    If Number($IPPort) = 0 Then $IPPort = 25
    $objEmail.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/smtpserverport") = $IPPort
    ;Authenticated SMTP
    If $s_Username <> "" Then
        $objEmail.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/smtpauthenticate") = 1
        $objEmail.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/sendusername") = $s_Username
        $objEmail.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/sendpassword") = $s_Password
    EndIf
    ; Set security params
    If $ssl Then $objEmail.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/smtpusessl") = True
    If $tls Then $objEmail.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/sendtls") = True
    ;Update settings
    $objEmail.Configuration.Fields.Update
    ; Set Email Importance
    Switch $s_Importance
        Case "High"
            $objEmail.Fields.Item ("urn:schemas:mailheader:Importance") = "High"
        Case "Normal"
            $objEmail.Fields.Item ("urn:schemas:mailheader:Importance") = "Normal"
        Case "Low"
            $objEmail.Fields.Item ("urn:schemas:mailheader:Importance") = "Low"
    EndSwitch
    $objEmail.Fields.Update
    ; Sent the Message
    $objEmail.Send
    If @error Then
        SetError(2)
        Return $oMyRet[1]
    EndIf
    $objEmail=""
EndFunc   ;==>_INetSmtpMailCom
;
;
; Com Error Handler
Func MyErrFunc()
    $HexNumber = Hex($oMyError.number, 8)
    $oMyRet[0] = $HexNumber
    $oMyRet[1] = StringStripWS($oMyError.description, 3)
    ConsoleWrite("### COM Error !  Number: " & $HexNumber & "   ScriptLine: " & $oMyError.scriptline & "   Description:" & $oMyRet[1] & @LF)
    SetError(1); something to check for when this function returns
    Return
EndFunc   ;==>MyErrFunc

; Base64 UDF made by Trancexx https://www.autoitscript.com/forum/topic/84133-winhttp-functions/?do=findComment&comment=1260746
Func _Base64Encode($vInput)
    Local Const $CRYPT_STRING_BASE64 = 0x00000001
    Local Const $CRYPT_STRING_NOCRLF = 0x40000000

    $vInput = Binary($vInput)
    Local $tInput = DllStructCreate("byte[" & BinaryLen($vInput) & "]")
    DllStructSetData($tInput, 1, $vInput)

    Local $aCall = DllCall("Crypt32.dll", "bool", "CryptBinaryToStringA", _
            "struct*", $tInput, _
            "dword", DllStructGetSize($tInput), _
            "dword", $CRYPT_STRING_BASE64 + $CRYPT_STRING_NOCRLF , _
            "ptr", 0, _
            "dword*", 0)
    If @error Or Not $aCall[0] Then Return SetError(1, 0, "") ; error calculating the length of the needed buffer

    Local $tOut = DllStructCreate("char[" & $aCall[5] & "]")

    $aCall = DllCall("Crypt32.dll", "int", "CryptBinaryToStringA", _
            "struct*", $tInput, _
            "dword", DllStructGetSize($tInput), _
            "dword", $CRYPT_STRING_BASE64 + $CRYPT_STRING_NOCRLF, _
            "struct*", $tOut, _
            "dword*", DllStructGetSize($tOut))
    If @error Or Not $aCall[0] Then Return SetError(2, 0, ""); error encoding

    Return DllStructGetData($tOut, 1)
EndFunc

 

Jos

Edited by Jos

SciTE4AutoIt3 Full installer Download page   - Beta files       Read before posting     How to post scriptsource   Forum etiquette  Forum Rules 
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Link to comment
Share on other sites

  • Developers
21 hours ago, Jos said:

Please give this a try before I update the main page:

mmm..  great feedback so far ... 🤔

SciTE4AutoIt3 Full installer Download page   - Beta files       Read before posting     How to post scriptsource   Forum etiquette  Forum Rules 
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Link to comment
Share on other sites

@Jos Sorry, I haven't gotten back to that project yet (I am waiting for something), will give you some feedback as soon as I finish testing.

EasyCodeIt - A cross-platform AutoIt implementation - Fund the development! (GitHub will double your donations for a limited time)

DcodingTheWeb Forum - Follow for updates and Join for discussion

Link to comment
Share on other sites

  • 2 weeks later...
  • Developers

Guess the fair conclusion can only be that it wasn't that important after all.....

SciTE4AutoIt3 Full installer Download page   - Beta files       Read before posting     How to post scriptsource   Forum etiquette  Forum Rules 
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...