SMTP Tutorial

Go to the tutorial main page.

The Allegro CL :smtp module allows Lisp programs to talk with SMTP servers. The :smtp module is documented in imap.htm, at The SMTP interface (used for sending mail).

To use it, we first require the :smtp module and use the package:

cl-user(2): (require :smtp)
; Fast loading /acl/acl70/src/imap/smtp.fasl
;   Fast loading /acl/acl70/src/sasl/sasl.fasl
;     Fast loading /acl/acl70/src/code/osi.fasl
;     Fast loading /acl/acl70/src/code/rc4.fasl
;     Fast loading /acl/acl70/src/code/hmac.fasl
;       Fast loading /acl/acl70/src/code/sha1.fasl
;     Fast loading /acl/acl70/src/code/iodefs.fasl
;       Fast loading /acl/acl70/src/code/iordefs.fasl
t
cl-user(3): (use-package :net.post-office)
t
cl-user(4): 

Quick Start

Now, let's send a quick letter we compose on the fly, using send-letter. Replace <server> with a SMTP mail server, and replace <sender>, <recipient>, and <other> with appropriate email addresses (they can all be your own, for example).

cl-user(4): (send-letter "<server>"    ; the mail server
			 "<sender>"    ; from
			 "<recipient>" ; to
			 "this is the body of the message"
			 :cc (list "<sender>" <other>")
			 :subject "Test message")
; Fast loading /acl/acl70/src/code/acldns.fasl
nil
cl-user(5): 

The four required arguments are strings the first naming the server, the second the sender, the third the recipient (if more than one, a list of strings), and the fourth the message. We are also specifying a subject and Cc'ing to the sender and <other>. To give a concrete example, at Franz Inc, the server is smtp.franz.com, and doe and jane are email accounts. When in the Franz network, this call send a message from doe to doe, Cc'ing jane:

cl-user(4): (send-letter "smtp.franz.com"
			 "doe"
			 "doe"
			 "this is the body of the message"
			 :cc "jane"
			 :subject "Test message")
nil
cl-user(5): 

Now when <sender>, <recipient>, and <other> (in the template example) or doe and jane (in the concrete example) check their email, they should see mail. Here is what doe should see:

Date: Mon, 14 Feb 2005 15:41:05 -0800
From: doe
To: doe
Cc: jane
Subject: Test message

this is the body of the message

The above message creates an envelope (headers) for you. That is, you give the send-letter function a set of arguments and it constructs the envelope for you. If you want to create your own envelope, you can use send-smtp:

cl-user(1): (setq p (socket:make-socket :connect :passive))
#<multivalent stream socket waiting for connection at */40225 @ #x71b808ca>
cl-user(2): 
cl-user(6): (send-smtp
	     "smtp.franz.com"
	     "doe"
	     "jane"
	     "From: M...e 
To: Y....ou 
Subject: this is a test message

This is the body
")
nil
cl-user(7): 

The message jane receives 1s:

Date: Mon, 14 Feb 2005 15:44:21 -0800
From: "M...e" 
To: "Y....ou" 
Subject: this is a test message

This is the body

If you are going to create your own envelope, we recommend that you follow the specification for doing so. This is a good starting point to find RFC 821: http://www.google.com/search?q=rfc821.

Some SMTP servers require authentication. To communicate with them, you should either use the send-smtp-auth function, or the login and password keywords to send-letter.

Sometimes you want to test an email address before you send mail to it. The test-email-address function does its best to verify email addresses (but as noted below, conditions can make it return incorrect information):

cl-user(7): (test-email-address "[email protected]") ;; should not exist
nil
cl-user(8): (test-email-address "[email protected]") ;; should exist
t
cl-user(9): (test-email-address "[email protected]") ;; should not exist
nil
cl-user(10): 
cl-user(4): 

test-email-address checks the email address by contacting the mail server in the given domain, and if it exists it asks the mail server if the given user is valid. For this, we use the SMTP VRFY command. Since some mail servers do not implement VRFY we return t if VRFY does not work. nil means that this address is bad or we cannot make contact with the mail server, which could of course be a transient problem.

Again, the :smtp module is documented in imap.htm, at The SMTP interface (used for sending mail).

Go to the tutorial main page.