Sending an e-mail is possible with the Phobos wrapper of cURL. cURL is a network client library which lets us work with a variety of tasks involving URL, including downloading files through HTTP, uploading files with FTP, and sending e-mail.
cURL is most likely already installed on Posix systems and is installed automatically by the dmd
Windows installer. However, you may need to ensure you have the 32-bit library installed if you are building 32-bit binaries or the 64-bit library if you are building 64-bit binaries. To change the type of binary you are building, pass –m32
or –m64
to dmd
.
As std.net.curl
is a part of Phobos, you do not need to download any additional D libraries to send a basic e-mail with it.
Let's send a basic e-mail by executing the following steps:
std.net.curl
.smtp://localhost
or smtps://smtp.gmail.com:465
. SMTP is a reference counted struct, so do not use the new keyword.smtp.setAuthentication
with your username and password if you need to log in to your mail server.smtp.mailTo(array_of_recipients);
. This array should include all e-mail addresses that will receive the message, including people in the To list, the Cc list, and the Bcc list of recipients.smtp.mailFrom = "your_email_address"
. The mailFrom
value should not include your name.smtp.message
to the message string, including e-mail headers separated from the body by a blank line.smtp.perform()
to send the e-mail.curl
library with pragma(lib)
or the –L
option to dmd
.The code is as follows:
import std.net.curl; pragma(lib, "curl"); void main() { auto smtp = SMTP("smtp://localhost"); smtp.mailTo(["[email protected]"]); smtp.mailFrom = "[email protected]"; smtp.message = "Subject: Hello! From: Your Name <[email protected]> Content-Type: text/plain; charset=UTF-8 Hey there."; smtp.perform(); }
If you change the e-mail addresses and mail server to the ones you can actually use, that will send an e-mail with a subject line of Hello!
and body text of Hey there
.
There are two common ways for applications to initiate an e-mail: to ask a Simple Mail Transfer Protocol (SMTP) server to relay it for them or to call a local application (often sendmail
) to send it for them. Phobos has support for both: it can call a local application with std.process
or it can talk to a mail relay server with std.net.curl
, which is what we did here.
The std.net.curl.SMTP
module is a fairly low-level wrapper around the cURL library's functionality. To use it well, you need to manage the e-mail headers yourself and manage some protocol details such as building the array of all the mailTo
recipients and putting a plain e-mail address in the mailFrom
property. These properties are separate from the e-mail headers the end user sees. std.net.curl
will not parse headers in the message body, nor will it add recipient headers from the properties.
As a result, the mailTo
property must contain all recipients, including the To
, Cc
, and Bcc
lists. Additionally, the corresponding e-mail headers should be present in the message. Similarly, mailFrom
should contain your e-mail address while the From:
header in the message should also be present and include your name for display to the user.
A Content-Type
header should also be present. E-mails will typically work without these components, but may not appear correctly on the recipient's computer.
The std.net.curl
module also supports username and password-based SMTP authentication and the STARTTLS
features often used by e-mail providers. To add your username and password, use setAuthentication
. To use SSL or TLS, use the smtps://
protocol in the SMTP constructor as well as the appropriate port for your mail server (typically 465 or 587; check with your provider to be sure). It is written after a colon that follows the server name, for example, smtps://yourserver.com:465
.
After constructing the message, a call to smtp.perform()
will connect to the server and send the message. It may throw an exception saying it lost the connection to peer. This is most often caused by bad authentication information or an invalid recipient e-mail address. Be sure that your username is correct and you are sending to valid recipients; check that all addresses in the mailTo
array are well formed. The std.net.email
module has a helper function to validate that e-mail addresses are well-formed. You can also check that they have non-zero length and no extra white space.
Finally, to compile the program, we must add libcurl
to the linker command. The easiest way to do this is to write pragma(lib, "curl")
in your main file. You may also pass curl.lib
to dmd
on Windows or –L-lcurl
to dmd
on Posix systems.
Creating and parsing e-mails can be a complex task due to the need to handle various character encoding rules, message headers, and the Multipurpose Internet Mail Extensions (MIME) standard for attachments, alternative bodies, and more.
From my Github repository, you can download my email.d
file. The email.d
file includes a EmailMessage
class that permits you to build an e-mail message out of a property list and helper methods without worrying about the specific message format. Once the message is ready, you can call message.send()
to send it via std.net.curl.SMTP
. My email.d
file depends on htmltotext.d
, dom.d
, and characterencodings.d
to automatically convert HTML e-mails to a plain text alternative and parse incoming e-mails with different character sets.
3.133.127.37