VBA – Send E-mail Using Mozilla Thunderbird

I have several clients that use Open Source Software for their Office applications (LibreOffice, OpenOffice, …) and as such do not have Outlook. In such cases, they typically use Mozilla’s Thunderbird e-mail client (which is a great e-mail applications by the way).

I have created some simple procedures in the past to send out e-mails using Thunderbird to suit their needs, but today I thought I’d try and emulate the procedure I long ago created for Outlook so as to have the versatile procedure possible. So below is what I came up with:

'---------------------------------------------------------------------------------------
' Procedure : TB_SendEmail
' Author    : Daniel Pineault, CARDA Consultants Inc.
' Website   : http://www.cardaconsultants.com
' Purpose   : Send e-mail using Mozilla Thunderbird e-mail client using VBA
' Copyright : The following is release as Attribution-ShareAlike 4.0 International
'             (CC BY-SA 4.0) - https://creativecommons.org/licenses/by-sa/4.0/
' Req'd Refs: Late Binding -> None required
' References: Requires a copy of OverwriteTxt() from https://www.devhut.net/vba-export-to-text-file/
'
' Input Variables:
' ~~~~~~~~~~~~~~~~
' vTo           : To Recipient email address string (semi-colon separated list)
' vSubject      : Text string to be used as the email subject line
' vBody         : Text string to be used as the email body (actual message)
' vBodyHTMLFile : HTML file to be used as a template for the message body
' vCC           : CC Recipient email address string (semi-colon separated list)
' vBCC          : BCC Recipient email address string (semi-colon separated list)
' vAttachments  : Single file -> fully qualified path and filename string
'                   Multiple files -> Array of attachment (complete file paths with
'                   filename and extensions)
' vAccount      : E-mail address of the account to use for sending the email,
'                   if no match is found it will use the default account
'
' Usage:
' ~~~~~~
' Start a Blank E-amil
'   Call TB_SendEmail()
' Simple E-mail
'   Call TB_SendEmail("abc@xyz.com", "My Subject", "My body.")
' Simple E-mail using HTML template file
'   Call TB_SendEmail("abc@xyz.com", "My Subject", , "C:/Temp/EmailMessage.html")
' Multiple Recipients
'   Call TB_SendEmail("abc@xyz.com;def@wuv.ca;", "My Subject", "My body.")
' Include CC Recipient
'   Call TB_SendEmail("abc@xyz.com;def@wuv.ca;", "My Subject", "My body.", , _
'                     "someone@somewhere.com")
' Single Attachment
'   Call TB_SendEmail("abc@xyz.com;def@wuv.ca;", "My Subject", "My body.", , _
'                     , , "C:\Temp\Book1.pdf")
' Multiple Attachments
'   Call TB_SendEmail("abc@xyz.com;def@wuv.ca;", "My Subject", "My body.", , _
'                     , , Array("C:\Temp\Book1.pdf", "C:\Temp\Desert.jpg"))
' Using a Specific Account to Send the E-mail From
'   Call TB_SendEmail("abc@xyz.com;def@wuv.ca;", "My Subject", "My body.", , _
'                      , , , "johny@nodomain.com")
'
' Revision History:
' Rev       Date(yyyy/mm/dd)        Description
' **************************************************************************************
' 1         2020-03-07              Initial Release
' 2         2020-03-14              Made all input variable optional for the greatest
'                                       flexibility.
' 3         2022-10-05              Added vBodyHTMLFile
'                                   Added sCmd length check to export to HTML file
'                                       when it exceeds the string length limit
'---------------------------------------------------------------------------------------
Public Sub TB_SendEmail(Optional vTo As Variant, _
                        Optional vSubject As Variant, _
                        Optional vBody As Variant, _
                        Optional vBodyHTMLFile As Variant, _
                        Optional vCC As Variant, _
                        Optional vBCC As Variant, _
                        Optional vAttachments As Variant, _
                        Optional vAccount As Variant)
On Error GoTo Error_Handler
    Dim oWSHShell             As Object
    Dim sCmd                  As String
    Dim sCmdTemp              As String
    Dim att                   As Variant
    Dim sHTMLFile             As String
    
    TempVars!bUseHTMLFile = False
 
    sCmd = "thunderbird -compose """
    If IsMissing(vTo) = False Then
        sCmd = sCmd & "to='" & vTo & "',"
    End If
    If IsMissing(vSubject) = False Then
        sCmd = sCmd & "subject='" & vSubject & "',"
    End If
    If IsMissing(vBodyHTMLFile) = False Then
        sCmd = sCmd & "message='" & vBodyHTMLFile & "',"
    End If
    If IsMissing(vCC) = False Then
        sCmd = sCmd & "cc='" & vCC & "',"
    End If
    If IsMissing(vBCC) = False Then
        sCmd = sCmd & "bcc='" & vBCC & "',"
    End If
    If IsMissing(vAttachments) = False Then
        If IsArray(vAttachments) = False Then
            sCmd = sCmd & "attachment='" & vAttachments & "',"
        Else
            sCmd = sCmd & "attachment='"
            For Each att In vAttachments
                sCmd = sCmd & "" & att & ","
            Next att
            sCmd = Left(sCmd, Len(sCmd) - 1)
            sCmd = sCmd & "',"
        End If
    End If
    If IsMissing(vAccount) = False Then
        sCmd = sCmd & "from='" & vAccount & "',"
    End If
    sCmd = sCmd & "format=1,"    '1=html, 2=plain text

    'Ensure no HTML file has already been specified
    If IsMissing(vBodyHTMLFile) = True Then
        'Check the length of the command/body string and act accordingly
        If IsMissing(vBody) = False Then
            sCmdTemp = sCmd & "body='" & vBody & "',"
        End If
        If Len(sCmdTemp) <= (32767 - 100) Then
            'Normal
            sCmd = sCmd & "body='" & vBody & "',"
            Debug.Print "Use Command."
        Else
            'Use intermediary HTML File as the content exceeds the character limit
            TempVars!bUseHTMLFile = True
            sHTMLFile = Environ("TEMP") & "\TB_HTML.html"
            Call OverwriteTxt(sHTMLFile, vBody)
            
            sCmd = sCmd & "message='" & sHTMLFile & "',"
            Debug.Print "Use HTML file."
        End If
    End If
    
    Do While Right(sCmd, 1) = ","
        sCmd = Left(sCmd, Len(sCmd) - 1)
    Loop
    sCmd = sCmd & """"

    Set oWSHShell = CreateObject("WScript.Shell")
    oWSHShell.Run sCmd
 
Error_Handler_Exit:
    On Error Resume Next
    If Not oWSHShell Is Nothing Then Set oWSHShell = Nothing
    Exit Sub
 
Error_Handler:
    MsgBox "The following error has occurred" & vbCrLf & vbCrLf & _
        "Error Number: " & Err.Number & vbCrLf & _
        "Error Source: TB_SendEmail" & vbCrLf & _
        "Error Description: " & Err.Description & _
        Switch(Erl = 0, "", Erl <> 0, vbCrLf & "Line No: " & Erl) _
        , vbOKOnly + vbCritical, "An Error has Occurred!"
    Resume Error_Handler_Exit
End Sub

There truly isn’t very much to it. Simply go through the various arguments building up the command to be executes and then run the command using the WScript.Shell object.

Limitations

There are a couple things to be aware of when trying to automate Thunderbird.

Firstly, we are limited, in comparison to Outlook Automation that exposes everything, to being able to work with just a few e-mail properties (Subject, Body, To, CC, BCC, Attachments, …). Mozilla has made the most important properties available to us through the command line, but others such as Priority, Delivery Receipt, … are simply not accessible.

The other issue is that there is no way to automatically send the created e-mail by default. It will generate the e-mail, but not send it, the end-user will need to click the Send button themselves. That said, I have seen people use a ‘pause’ in their code and then SendKeys to automatically send the e-mail. As always, SendKeys is very unreliable and not something I put into production systems. I would instead use APIs to locate the e-mail window and click the button that way, but have never had the need as my users have always wanted to be able to review the e-mails before sending them.

Should you wish to use the SendKeys approach, here is an example of how it can be done. There is one important thing to note with the SendKeys approach, you need to add a small delay after sending the Thunderbird command to create the e-mail and the call to SendKeys as to allow Thunderbird to load and create the e-mail. Now in certain applications, such as Excel, you can simlply use Application.Wait, but since this isn’t universally available in all applications I have choosen to use the Sleep API so my code is the most versatile possible. Enough talk, here is the required code:

So, in the module header you need to add the following API declaration

#If VBA7 Then
    Public Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
#Else
    Public Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
#End If

and then use a function, such as:

'---------------------------------------------------------------------------------------
' Procedure : TB_SendEmail
' Author    : Daniel Pineault, CARDA Consultants Inc.
' Website   : http://www.cardaconsultants.com
' Purpose   : Send e-mail using Mozilla Thunderbird e-mail client using VBA
' Copyright : The following is release as Attribution-ShareAlike 4.0 International
'             (CC BY-SA 4.0) - https://creativecommons.org/licenses/by-sa/4.0/
' Req'd Refs: Late Binding -> None required
' References: Requires a copy of OverwriteTxt() from https://www.devhut.net/vba-export-to-text-file/
'
' Input Variables:
' ~~~~~~~~~~~~~~~~
' vTo           : To Recipient email address string (semi-colon separated list)
' vSubject      : Text string to be used as the email subject line
' vBody         : Text string to be used as the email body (actual message)
' vBodyHTMLFile : HTML file to be used as a template for the message body
' vCC           : CC Recipient email address string (semi-colon separated list)
' vBCC          : BCC Recipient email address string (semi-colon separated list)
' vAttachments  : Single file -> fully qualified path and filename string
'                   Multiple files -> Array of attachment (complete file paths with
'                   filename and extensions)
' vAccount      : E-mail address of the account to use for sending the email,
'                   if no match is found it will use the default account
'
' Usage:
' ~~~~~~
' Start a Blank E-amil
'   Call TB_SendEmail()
' Simple E-mail and Send it
'   Call TB_SendEmail("abc@xyz.com", "My Subject", "My body.", , , , , ,True)
' Simple E-mail using HTML template file
'   Call TB_SendEmail("abc@xyz.com", "My Subject", , "C:/Temp/EmailMessage.html")
' Multiple Recipients
'   Call TB_SendEmail("abc@xyz.com;def@wuv.ca;", "My Subject", "My body.")
' Include CC Recipient
'   Call TB_SendEmail("abc@xyz.com;def@wuv.ca;", "My Subject", "My body.", , _
'                     "someone@somewhere.com")
' Single Attachment
'   Call TB_SendEmail("abc@xyz.com;def@wuv.ca;", "My Subject", "My body.", , _
'                     , , "C:\Temp\Book1.pdf")
' Multiple Attachments
'   Call TB_SendEmail("abc@xyz.com;def@wuv.ca;", "My Subject", "My body.", , _
'                     , , Array("C:\Temp\Book1.pdf", "C:\Temp\Desert.jpg"))
' Using a Specific Account to Send the E-mail From
'   Call TB_SendEmail("abc@xyz.com;def@wuv.ca;", "My Subject", "My body.", , _
'                      , , , "joh2ny@nodomain.com")
'
' Revision History:
' Rev       Date(yyyy/mm/dd)        Description
' **************************************************************************************
' 1         2020-03-07              Initial Release
' 2         2020-03-14              Made all input variable optional for the greatest
'                                       flexibility.
' 3         2022-10-05              Added vBodyHTMLFile
'                                   Added sCmd length check to export to HTML file
'                                       when it exceeds the string length limit
'---------------------------------------------------------------------------------------
Public Sub TB_SendEmail(Optional vTo As Variant, _
                        Optional vSubject As Variant, _
                        Optional vBody As Variant, _
                        Optional vBodyHTMLFile As Variant, _
                        Optional vCC As Variant, _
                        Optional vBCC As Variant, _
                        Optional vAttachments As Variant, _
                        Optional vAccount As Variant, _
                        Optional bAutoSend As Boolean = False)
    Dim sExePath              As String
    Dim sCmd                  As String
    Dim sCmdTemp              As String
    Dim att                   As Variant
    Dim sHTMLFile             As String

    On Error Resume Next
    sExePath = CreateObject("WScript.Shell").RegRead("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\thunderbird.EXE\")
    If Err.Number <> 0 Then
        MsgBox "Unable to determine the Thunderbird.exe path." & vbCrLf & vbCrLf & _
               "Please ensure that Thunderbird is installed and try again." & vbCrLf & _
               "Otherwise contact your database developer for further assistance.", _
               vbCritical Or vbOKOnly, "Operation Aborted!"
        GoTo Error_Handler_Exit
    End If

    On Error GoTo Error_Handler
    sCmd = sExePath & " -compose """
    If IsMissing(vTo) = False Then
        sCmd = sCmd & "to='" & vTo & "',"
    End If
    If IsMissing(vSubject) = False Then
        sCmd = sCmd & "subject='" & vSubject & "',"
    End If
    If IsMissing(vBodyHTMLFile) = False Then
        sCmd = sCmd & "message='" & vBodyHTMLFile & "',"
    End If
    If IsMissing(vCC) = False Then
        sCmd = sCmd & "cc='" & vCC & "',"
    End If
    If IsMissing(vBCC) = False Then
        sCmd = sCmd & "bcc='" & vBCC & "',"
    End If
    If IsMissing(vAttachments) = False Then
        If IsArray(vAttachments) = False Then
            sCmd = sCmd & "attachment='" & vAttachments & "',"
        Else
            sCmd = sCmd & "attachment='"
            For Each att In vAttachments
                sCmd = sCmd & "" & att & ","
            Next att
            sCmd = Left(sCmd, Len(sCmd) - 1)
            sCmd = sCmd & "',"
        End If
    End If
    If IsMissing(vAccount) = False Then
        sCmd = sCmd & "from='" & vAccount & "',"
    End If
    sCmd = sCmd & "format=1,"    '1=html, 2=plain text
    
    'Ensure no HTML file has already been specified
    If IsMissing(vBodyHTMLFile) = True Then
        'Check the length of the command/body string and act accordingly
        If IsMissing(vBody) = False Then
            sCmdTemp = sCmd & "body='" & vBody & "',"
        End If
        If Len(sCmdTemp) <= (32767 - 100) Then
            'Normal
            sCmd = sCmd & "body='" & vBody & "',"
            Debug.Print "Use Command."
        Else
            'Use intermediary HTML File as the content exceeds the character limit
            TempVars!bUseHTMLFile = True
            sHTMLFile = Environ("TEMP") & "\TB_HTML.html"
            Call OverwriteTxt(sHTMLFile, vBody)
            
            sCmd = sCmd & "message='" & sHTMLFile & "',"
            Debug.Print "Use HTML file."
        End If
    End If
    
    Do While Right(sCmd, 1) = ","
        sCmd = Left(sCmd, Len(sCmd) - 1)
    Loop
    sCmd = sCmd & """"

    Call Shell(sCmd, vbNormalFocus)
    If bAutoSend = True Then
        Sleep (1000)    'Wait for TB to load and create the email
                        '     this value may need to be tweaked
'        SendKeys "^+{ENTER}", True
'        SendKeys "%fd", True
        SendKeys "^~", True
    End If

Error_Handler_Exit:
    On Error Resume Next
    Exit Sub

Error_Handler:
    MsgBox "The following error has occurred" & vbCrLf & vbCrLf & _
           "Error Number: " & Err.Number & vbCrLf & _
           "Error Source: TB_SendEmail" & vbCrLf & _
           "Error Description: " & Err.Description & _
           Switch(Erl = 0, "", Erl <> 0, vbCrLf & "Line No: " & Erl) _
           , vbOKOnly + vbCritical, "An Error has Occurred!"
    Resume Error_Handler_Exit
End Sub
Requirement(s)
Both versions of the function require a copy of my OverwriteTxt() function found at:

Other Resources

37 responses on “VBA – Send E-mail Using Mozilla Thunderbird

  1. Karol

    Is it possible to find a specific e-mail by the name of the e-mail title and reply to it using VBA.

    For example, I receive an email with the title “Subject 2020” from xxx@text.com. I would like to find the last e-mail with this title and sender and reply on it.

    1. Daniel Pineault Post author

      Here’s the basic concept

      Sub Outlook_FindEmails()
          Dim oOutlook              As Object
          Dim oNS                   As Object
          Dim oItems                As Object
          Dim oFilterItems          As Object
          Dim oFilterItem           As Object
          Dim sFilter               As String
          Dim bOutlookOpened        As Boolean
          Dim i                     As Long
          Const olFolderInbox = 6
      
          On Error Resume Next
          Set oOutlook = GetObject(, "Outlook.Application")    'Bind to existing instance of Outlook
          If Err.Number <> 0 Then    'Could not get instance of Outlook, so create a new one
              Err.Clear
              Set oOutlook = CreateObject("Outlook.Application")
              bOutlookOpened = False    'Outlook was not already running, we had to start it
          Else
              bOutlookOpened = True    'Outlook was already running
          End If
          On Error GoTo Error_Handler
          DoEvents
      
          Set oNS = oOutlook.GetNamespace("MAPI")
          Set oItems = oNS.GetDefaultFolder(olFolderInbox)
          'Apply a filter so we don't waste our time going through old stuff if we don't need to.
      '    sFilter = "@SQL=""http://schemas.microsoft.com/mapi/proptag/0x0037001f"" like '%e-transfer%'"
          'Subject Filter (like operator)
          sFilter = "@SQL=""urn:schemas:httpmail:subject"" like '%Subject 2020%'"
          sFilter = sFilter & " AND "
          'FROM Email Address Filter (exact match)
          sFilter = sFilter & """urn:schemas:httpmail:fromemail"" ci_phrasematch 'xxx@text.com'"
          Debug.Print sFilter
          Set oFilterItems = oItems.Items.Restrict(sFilter)
          oFilterItems.Sort "[SentOn]", True
          
          'List All Items
          Debug.Print oFilterItems.Count & " items found."
          'Iterate through each appt in our calendar
          For Each oFilterItem In oFilterItems
              If oFilterItem.Class = 43 Then
                  Debug.Print , oFilterItem.Subject, oFilterItem.SentOn, oFilterItem.SenderEmailAddress
              End If
          Next
          
          'Get Only the last item
          Debug.Print ""
          Debug.Print "The last e-mail was:"
          For Each oFilterItem In oFilterItems
              If oFilterItem.Class = 43 Then
                  Debug.Print , oFilterItem.Subject, oFilterItem.SentOn, oFilterItem.SenderEmailAddress
                  Exit For
              End If
          Next
      
          If bOutlookOpened = False Then    'Since we started Outlook, we should close it now that we're done
              oOutlook.Quit    'There seems to be a delay in this action taking place, but does eventually take place
          End If
      
      Error_Handler_Exit:
          On Error Resume Next
          Set oFilterItem = Nothing
          Set oFilterItems = Nothing
          Set oItems = Nothing
          Set oNS = Nothing
          Set oOutlook = Nothing
          Exit Sub
      
      Error_Handler:
          MsgBox "The following error has occured" & vbCrLf & vbCrLf & _
                 "Error Number: " & Err.Number & vbCrLf & _
                 "Error Source: Outlook_FindEmails" & vbCrLf & _
                 "Error Description: " & Err.Description & _
                 Switch(Erl = 0, "", Erl <> 0, vbCrLf & "Line No: " & Erl) _
                 , vbOKOnly + vbCritical, "An Error has Occured!"
          Resume Error_Handler_Exit
      End Sub

      Hope this helps. If you have further questions, you should post in a forum where you’ll get the support of multiple people.

      1. Elek

        Hi Daniel,

        It is possible to send mail from Excel via Thunderbird with the MailBody contain link line.

        Thanks,
        Elek

        1. Daniel Pineault Post author

          You should be able to use these functions in Excel without issue.

          Regarding mailbody, I’m not sure what you mean exactly as mailbody isn’t part of Thunderbird. If you look over some of the provided usage examples you can see the vBody input argument accepts plain text or HTML content. So if you wish to send a link, you need online build the proper HTML string that represents a link, such as:

          Link Text
  2. SB

    Wonderful! Thank you very much for this very accurate description!
    Is it possible to use a template already used in Thunderbird?
    Thank you for your help.

  3. Ray White

    Hi Daniel
    The first set of code works great.
    So I was going to try the Auto Send code.
    But when I enter this code in the module header the (( Alias “Sleep” )) disappears…. Why would it do that?
    Declare Sub Sleep Lib “kernel32” Alias “Sleep” (ByVal dwMilliseconds As Long)

    1. Daniel Pineault Post author

      Yes, I’ve seen the same behavior. If the alias is the same as the sub name, then VBA remove it as it is redundant. It doesn’t impact the code in any way. Nothing to worry about.

      1. Ray White

        Great Thanks Dan
        I did get it working and doing more testing on it now.
        One think I noticed is when it Auto sends the email that it puts
        it in the OutBox folder but does not send it, You have to right click
        on the Outbox folder in Thunderbird and tell it to Send Unsent messages.
        Any thought on that?

        1. Ray White

          Hi Dan
          I found out if you use :
          SendKeys “^+{ENTER}”, True ‘ This will send it to the Outbox and not send it until you tell it to.
          If you use : SendKeys “%fd”, True OR SendKeys “^~”, True
          Then it will send the email right then.
          Hope this helps someone..

          1. Claudio

            I tried what do you suggest. SendKeys “^+{ENTER}”, True will send the e-mail to the Outbox, but the other two sendkeys that you suggest open it but don’t send it. Any suggestion?

          2. Claudio

            Solved! The issued was that I had put the instructions directly in another macro. I solved creating a new module and calling it by the first one. Now the sendkeys SendKeys “^~”, True send the email right now.

          3. Claudio

            Sending email is solved! Now I am tryng to send a message and a PDF to Whatsup via vba. The first step is partially solved (I am able to open the chat and send a message but then I need to press enter personally :
            ActiveWorkbook.FollowHyperlink _
            Address:=”https://api.whatsapp.com/send?phone=” & numero & ” & testo”
            but I do not find how to send the PDF. Can you help me?
            Thanks

  4. Jörg Piesbergen

    I copied the Code, and it works flawless. Great, Daniel. Many Thanks.
    With your great piece of software I was able to replace Outlook (that doeas not support roaming profiles on a NAS) with Thunderbird (that in fact allow using roaming profiles)
    Best Regards from Switzerland…Jörg

  5. Kristy Roberts

    Hi Daniel, I am a VBS new born. It takes me a while to understand the code but I have made some progress using forums for assistance. However, the code is very complex for me to understand when, where and what I need.

    My issue: I have my code that runs several queries and drops them into 1 excel on separate tabs, the excel will open and then I select email as attachment and send the document that way. I’d like to be able to insert the code to call Thunderbird send the email with the attachment.
    Do I need to add all of the code you provided to have Thunderbird send the email as needed?
    I appreciate your assistance.
    Here is the code I mentioned above.

    Private Sub Command186_Click()

    DoCmd.TransferSpreadsheet acExport, _
    acSpreadsheetTypeExcel9, “License Applications T Corporate – Angel”, _
    “O:\Rep_Reports\Angel_Action_Items.xls”, , “Corporate T & TW”

    DoCmd.TransferSpreadsheet acExport, _
    acSpreadsheetTypeExcel9, “License Applications S Corporate – Angel”, _
    “O:\Rep_Reports\Angel_Action_Items.xls”, , “Corporate S”

    DoCmd.TransferSpreadsheet acExport, _
    acSpreadsheetTypeExcel9, “License Applications I Corporate – Angel”, _
    “O:\Rep_Reports\Angel_Action_Items.xls”, , “Corporate I & IW”

    DoCmd.TransferSpreadsheet acExport, _
    acSpreadsheetTypeExcel9, “License Applications P Corporate – Angel”, _
    “O:\Rep_Reports\Angel_Action_Items.xls”, , “Corporate P & PW”

    DoCmd.TransferSpreadsheet acExport, _
    acSpreadsheetTypeExcel9, “New License Issued Corporate – Angel”, _
    “O:\Rep_Reports\Angel_Action_Items.xls”, , “Corporate LCOD”

    Shell “Excel.EXE O:\Rep_Reports\Angel_Action_Items.xls”, vbNormalFocus
    End Sub

  6. Mike

    Thank you, thank you, thank you.
    Exactly what I need. Being an amateur VBAer, this saved me a ton of time.
    I probably given up as a lost cause if I were to try to come up with this on my own.

  7. Chas Mann

    Hi
    I have installed the code in an Access database, but when the code is run, Thunderbird wants to create a newsgroup and doesn’t get to populate the blank email which has appeared behind.

    I have a added a ‘From=’ parameter to the command being sent to Thunderbird, but that doesn’t inhibit it.
    Any ideas how I can remove the requirement to create a newsgroup?
    Thanks
    Charlie

    1. Daniel Pineault Post author

      I’ve never seen such behavior. Is Thunderbird configured with one account at least and functional? What version of Thunderbird are you running?

  8. Joji Mathew

    Hello Daniel,

    Greetings!

    I feel fortunate to have reached here as I’ve picked up a few very useful tips while browsing through this thread.

    I want to compose emails that Encodes the image in the HTML body as base64 content (so no attachment file). Of course, in thunderbird using Excel VBA.

    Thanks in advance for your help.
    Joji M

  9. Tobias

    Hello Daniel,
    thank you for this code.
    My question:
    Is it possible to customize/extend the code to attach even just an attachment to an already opened mail?

    Thanks already for your answer

  10. David

    Fantastic code. It works perfectly. The solution raises two questions:

    1) How is it possible for Windows to recognize the command (Thunderbird -compose… etc) if we do not indicate the full path (only the name of the executable)? I’m intrigued. Can you explain it, please?

    2) Do you know if is there a way to embed an image in the message content?

    Thank you so much for everything.

      1. David

        The closest approach I’ve found to embed an image in the body of the message is to pass the appropriate tag on the vBody parameter.:
        .

        Thunderbird will lock the loading of the image but by clicking on the Options button available in the warning that is displayed you can unlock it.

        1. Daniel Pineault Post author

          The easiest technique is to place your images on a public server and then simply use the img HTML tag.

          another approach, but I haven’t had time to test would be to read the file, encode it in base64 (you can do that using MSXML2.DOMDocument) and use that as the src

          When developing, you can use a tool such as https://codebeautify.org/base64-to-image-converter to validate that your base64 encoding is proper.

          1. David

            Yeah! That is! I confirm you that passing the image as a base64 string does the trick! Thank you so much again!

  11. Dr L D Howe

    The send keys option works. However, it doesn’t actually send the mail messages, but puts them in the outbox. It is then simply a question of right clicking the outbox and followed by clicking “Send Unsent Messages”. All the messages are then sent. I use the following routine to call you subroutine, which reads the date from an Excel Spreadsheet;

    Sub Auto_thunderbird()

    Dim Lastrow As Long
    Dim myemail As String
    Dim myrange As Range
    Dim mymessage As String
    Dim outmessage As String
    Dim mygreeting As String
    Dim mysubject As String
    Dim myfile As String
    Dim myAttachments As String
    Dim i As Long
    ‘ counts the number of rows in use
    Lastrow = Sheets(“Names”).Cells(Rows.Count, 1).End(xlUp).Row
    i = 1
    mymessage = Sheets(“Message”).Cells(2, 6) & Chr(10) & Chr(10) & Sheets(“Message”).Cells(2, 8) & Chr(10) & Chr(10) & Sheets(“Message”).Cells(2, 5)
    mysubject = Sheets(“Message”).Cells(2, 4)
    myfile = Sheets(“Message”).Cells(2, 3)
    myAttachments = “C:\Users\innov\Documents\” & myfile

    For Each myrange In Sheets(“Names”).Range(“A2:A” & Lastrow)

    myemail = myrange.Offset(0, 1).Value
    i = i + 1
    mygreeting = “Dear ” & Sheets(“Names”).Cells(i, 3) & Chr(10) & Chr(10)
    outmessage = mygreeting & mymessage

    Call TB_AutoEmail(myemail, mysubject, outmessage, , , myfile)

    Next myrange

    End Sub

  12. Daniel

    Hi Daniel,
    I have implemented the code but when adding more than one attachment, it uses the Path name as the attachment name instead of the file by itself. (Ex: “c:\\desktop/testfile.xlsx” and “testfile.xlsc”)

    Do you know if there is a way to make sure the files that get attached only show the file name?

  13. Gregory

    vBODY = “first_item” & ” ” & “second_item” in TB it looks like “first_item second_item”.
    Trunderbird change ” ” (few spaces) into ” ” (single space).
    Is there a way to send message with few spaces

  14. Radzhap

    Hi!
    Many thanks for the info, very helpfull!

    I have a question , I want to be able to change the subject of the letter every time, and change emails and subjects, let’s say there will be 3 different cells or columns where I insert info (email, message text, and email subject) and run the macro.

    Is it possible to make?

    Thanks!

  15. Peter

    It works fine for Thunderbird up to Version 115.0.1
    Now there ist the problem:
    Type: com.sun.star.lang.WrappedTargetRuntimeException
    Message: [automation bridge] unexpected exception in IUnknownWrapper::invoke ! Message :
    [automation bridge]: .