Using Windows CDO COM, You Can Send E-mail Without Opening Your E-mail Program
In my last blog, I wrote a short script for extracting data from a Web page without using a Web browser (“Quick and Dirty Web Data Extraction Script“). As a demonstration, I showed how to quickly download and cull a daily horoscope from an astrology site for display in a MsgBox window. It occurred to me that rather than using a Hotkey each time I wanted to view my horoscope, I would prefer to receive it each morning in an e-mail. That way I could set up the script to run automatically and push the data to me at the same time every day. Plus, I can view an e-mail on any device (e.g. smartphone, tablet, or non-Windows computer) without any special programming. This requires sending an e-mail via an AutoHotkey script.
Commonly, AutoHotkey users employ the Run, Mailto: command when automating Windows e-mail. In conjunction with other AutoHotkey automation techniques (such as those discussed in the chapters in Section 8.1, “Windows Automation” of the book Jack’s Motley Assortment of AutoHotkey Tips), scripts can control virtually every aspect of e-mail processing. However, you do run into a few issues when using e-mail programs for sending an e-mail:
- You must load and navigate the program every time you want to send a message.
- After AutoHotkey loads the application, any additional automation must fit the specific program (i.e. Windows Mail, Outlook, Mozilla Thunderbird, Web-based mail programs, etc).
- With most e-mail apps, the Run, Mailto: command will not automatically send the e-mail. It merely opens your default e-mail program and loads the text into a new e-mail window.
- The process can be slow and cumbersome.
Wouldn’t be great if you could routinely send e-mail directly from an AutoHotkey script without using a Windows e-mail application? It just happens that you can!
Directly Sending E-mail from Windows
As part of the Component Object Model (COM) Microsoft offers a system called Collaboration Data Objects (CDO) which makes it possible to create and mail a message by sending a string of data directly to an e-mail server without any intervening e-mail software. By using this technique, we can write an AutoHotkey script which sends e-mail without using a client program normally associated with e-mail—whether desktop or Web-based.
I found a couple of AutoHotkey scripts in the AutoHotkey forums which send e-mail directly to your e-mail server for delivery to the destination e-mail address. After adding the parameters for my e-mail accounts, the scripts worked on both my Windows 10 computer and an old Vista laptop I have sitting in the corner. I also tested it with both Gmail and another e-mail server.
While I’ve done enough testing to ensure that it should function for most people, I don’t know that it will work for everyone. It’s quite possible that some e-mail providers won’t accept the input or other e-mail software may interfere. I haven’t had enough time to explore all the ins-and-outs.
Note: As with a number of the more advanced technique, I don’t fully comprehend what’s going on with this COM CDO method for sending an e-mail. I have a basic understanding of how the script works but not exactly what each enigmatic Windows command/function does. I can tell you how to get it working, but don’t ask me about its hidden mechanisms. I found explanations of COM CDO sparse and incomplete.
Send an E-mail from an AutoHotkey Script
To test your own e-mail set up, copy the following e-mail delivery script provided by shajul to an AutoHotkey script, make changes to the parameters shown in red, then save with the .ahk file extension:
: Web page for original script: ; https://autohotkey.com/board/topic/60813-cdo-com-email-delivery-ahk-l/ pmsg := ComObjCreate("CDO.Message") pmsg.From := """Mr Big"" <mrbig@gmail.com>" pmsg.To := "mrsmall@gmail.com" pmsg.BCC := "" ; Blind Carbon Copy, Invisable for all, same syntax as CC pmsg.CC := "" pmsg.Subject := "E-mail Test" pmsg.TextBody := "Test of sending e-mail directly from AutoHotkey." ;sAttach := ; "Path_Of_Attachment" ; can add multiple attachments ; the delimiter is | fields := Object() fields.smtpserver := "smtp.gmail.com" ; specify your SMTP server fields.smtpserverport := 465 ; 25 fields.smtpusessl := True ; False fields.sendusing := 2 ; cdoSendUsingPort fields.smtpauthenticate := 1 ; cdoBasic fields.sendusername := "mrbig@gmail.com" fields.sendpassword := "password" fields.smtpconnectiontimeout := 60 schema := "http://schemas.microsoft.com/cdo/configuration/" pfld := pmsg.Configuration.Fields For field,value in fields pfld.Item(schema . field) := value pfld.Update() Loop, Parse, sAttach, |, %A_Space%%A_Tab% pmsg.AddAttachment(A_LoopField) pmsg.Send()
Note: You can find a number of other scripts on the forum which serve the same purpose. Some of them use:
pmsg := COM_CreateObject("CDO.Message")
which you will need to change to:
pmsg := ComCreateObject("CDO.Message")
Not sure why they used COM_CreateObject(“CDO.Message”) in the first place. Probably, the function call from another scripting language.
Changes to the Script
Make the address script work by changing the designated parameters (in red) to your e-mail account settings. I could have provided a script which uses my credentials, but that would automatically give away my e-mail username and password. (No point in making it too easy for people to hack my e-mail.) In a coming blog, I plan to talk about techniques for hiding usernames and passwords.
From: E-mail Address
You can either provide the sending e-mail address in a plain vanilla format (“jackdunning@gmail.com“) or add a substitute alias (“Mr. Jack Dunning <jackdunning@gmail.com>“)—no need to add the extra double quotes to the alias as shown in the script above. At least in my tests, the e-mail address must match the account address, but you can change to the assigned alias in the e-mail (i.e. “Mr. Jack Dunning“).
The alias allows you to add proper identification to your e-mail. Without the extra text, the received e-mail defaults to displaying the address itself—which might appear quite cryptic to the person on the other end. Some people use an alias to spoof people into thinking they are someone else, but a person can always check the actual e-mail address for identification—if you can make any sense of it.
To: E-mail Address
The recipient e-mail address follows the same rules as the sending e-mail address except you can add multiple addresses by placing a semicolon ( ; ) between each. Any valid e-mail address should work.
E-mail Subject
You can either directly add the subject by placing it between quotes:
pmsg.Subject := "E-mail Test"
or place the text in a variable:
MySubject := "E-mail Test"
pmsg.Subject := MySubject
Using the second approach allows you to write an e-mail routine with accepts alternative input.
E-mail TextBody
As with the Subject line of the e-mail, you can substitute a variable for the text.
MyTextBody := "Test of sending e-mail directly from AutoHotkey."
pmsg.TextBody := MyTextBody
This makes for an easy solution to the daily horoscope e-mail problem. Rather than displaying the horoscope variable in a MsgBox, simply use it as the TextBody in this e-mail script.
SMTP Server
Every e-mail system uses an e-mail server for processing messages. The sending server name usually includes the abbreviation SMTP (Simple Mail Transfer Protocol):
fields.smtpserver := "smtp.gmail.com"
You can find your SMTP server name in your e-mail account setup parameters. Do not assume that the server name will include the e-mail address domain name.
Note: The SMTP server port 465 uses secure encryption similar to HTTPS:// Web pages. Even if your username and password appear in plain text in the AutoHotkey script, the system encrypts them for transmission to the e-mail server. In most cases, e-mail servers no longer accept e-mail over SMTP port 25 (no encryption). To avoid Spammers, the servers require authentication. If your e-mail account shows a different SMTP port, use that one.
E-mail Username
Insert the e-mail account username—generally the same as the From: e-mail address.
Password
Yes, you must include your e-mail password in order for the e-mail server to allow authorized access. Since it’s in plain text, anyone who has access to the script can read it. I understand any reluctance to provide it, but the technique won’t work without it. You can embed it in a variable, but when you create the variable the plain text will appear—unless you draw it from another data source. In the near future, I will discuss alternative approaches to keeping your password as safe as reasonably possible. (See “Username and Password Protection in AutoHotkey.”)
E-mail Success
Every e-mail server operates a little differently. It’s quite possible that some of them will not accept this type of automatic e-mail. Also, many place limits on how many e-mails you can send within a specific period of time. (This blocks people from sending an inordinate amount of Spam.) If you can’t get this script working for your AutoHotkey e-mail, then you may need to consult with your e-mail provider. Worst case, you can always set up a Gmail account just for use with AutoHotkey.
Next time, I’ll integrate this automatic e-mail technique with the Horoscope.ahk script from last time.
Click the Follow button at the top of the sidebar on the right of this page for e-mail notification of new blogs. (If you’re reading this on a tablet or your phone, then you must scroll all the way to the end of the blog—pass any comments—to find the Follow button.)
This post was proofread by Grammarly
(Any other mistakes are all mine.)
(Full disclosure: If you sign up for a free Grammarly account, I get 20¢. I use the spelling/grammar checking service all the time, but, then again, I write a lot more than most people. I recommend Grammarly because it works and it’s free.)
Hi Jack, thanks for this post.
My AHK Version is v1.1.23.05 and the script doesn´t work in my computer (server error).
I tested with a gmail account. When I change from “465 , 25” to “25 , 465” (I saw in the post you linked) the error takes more time to appears.
Should I update my AHK version to make it work?
Thanks for all your post about AKH.
LikeLike
I seriously doubt that your older version of AutoHotkey is the source of your problem—although it wouldn’t hurt to upgrade. The code I offered predates your version. More likely, you need to look closely at your credentials (username and password). Any misstep there and the server won’t respond. Also, I don’t think that Gmail will allow you to use the unsecured port 25. Gmail demands authentication to send e-mail.
LikeLike
[…] Web Data Extraction Script“) and send an e-mail directly from an AutoHotkey script (“How to Send E-mail Directly from an AutoHotkey Script“). This time I put them both together to demonstrate how to deliver a daily horoscope to […]
LikeLike
Hi. I am a newbie here. The above script works great, however , I want it to be able to send a file whose path is copied to clipboard. I tried writing %clipboard% in place of file path, but its not working. Am I missing something..?
LikeLike
To add attachments to the above code:
;sAttach := ; “Path_Of_Attachment” ; can add multiple attachments
; the delimiter is |
You must remove the comment semi-colon ( ; ) at the beginning of the line to make it work. If you use %clipboard% for the path and file name, do not include the quotation marks.
LikeLike
Thanks. Sorry for the late reply.
I finally got it working. In fact, I have modified it to send to particular recipients based on where the file is located. This script has been very useful for me. Thanks..!
LikeLike
!— GMX —
Hello Jack, hello everybody
I have tried many (meaningful) value sets for the parameters but I could not get this script to work with GMX (mail.gmx.net).
In case anybody succeeds with GMX , please drop me a note !
Kind regards, Hauke
LikeLike
Very nice. Is there any ErrorLevel, or a way to determine whether the Send succeeded or failed?
LikeLike
Could put it all in a function and then add “Try” to the Send(), to catch errors in sending.
Try pmsg.Send()
Catch, err
errMsg := “Problem: ” err.Extra
. “`nFile: ” err.File
. “`nLine: ” err.Line
. “`n ” err.What
. “`nError: ” err.Message
Return errMsg
LikeLike
For a function like sendEmail, you can then:
If sendEmail(….)
MsgBox, An error occurrred.
LikeLike
[…] more information about sending e-mail with AutoHotkey, see “How to Send E-mail Directly from an AutoHotkey Script.” If you run into problems, check the comments at the end of the page and reference […]
LikeLike
[…] How to Send E-mail Directly from an AutoHotkey Script May 10, 2019 […]
LikeLike