How To Send Emails From An Erlang Web Application

Do you want to quickly be able to send an email from your Erlang web application to one or more email addresses?

In this post I will show you an easy two steps method to achieve that goal:

  1. We are going to make our Ubuntu box (See how to install Erlang on Ubutntu) capable of sending emails to the outside world … and only that, nothing more (no mailbox configuration, spam assassin, etc …).
  2. Write an Erlang function responsible for building the message and sending it.

Step 1 – Install Postfix

Pre-requisite:
In the case you want to setup a dedicated server,  you will need to:

  • Associate a valid domain name with it (beebole.com in our example)
  • Install ‘Bind9′, the domain name server
  • Configure it

I invite you to read the section ‘Bind9′ at the end of this post for further information.

First, we are going to install Postfix and the mail utilities.

For that, just go to the command prompt of your Ubuntu server and type:

sudo apt-get install postfix mailutils

You will then face a post-installation screen (Note that you can always re-configure Postfix by using the following command : sudo dpkg-reconfigure postfix ).

In the case of a ‘Dedicated server’:

Choose ‘Internet’ and fill in your mail domain.  Just go with the default value for the rest.

Next, by editing the mailname config file (This file – /etc/mailname – is Debian specific and must be in a fully qualified domain name form, FQDN), we will tell our system what is the correct domain name for email addresses.  This name must be a valid domain name (MX record in the Bind9 section).

sudo vi /etc/mailname

Modify the domain name with your own:

mail.beebole.com

In the case of a ‘Home Station’:

Choose ‘Internet with smarthost’ and enter the relayhost info (= smarthost = the smtp of your ASP), i.e. relay.myasp.com

sudo vi /etc/mailname
relay.myasp.com

Now we need to refresh the Postfix configuration (we don’t need to restart the process with sudo /etc/postfix restart):

sudo postfix reload

Done? Great, we are ready now to check our setup!

An easy way to test it is to directly send an email. In this example, we are going to send a message titled “hello” to the address foo@mail.com with “hello me” as the body text.

Here are two examples, one in HTML, the other one in text format:

HTML:

echo "<strong>hello</strong> me" | mail -a "Content-type: text/html;" -s "hello" foo@mail.com

TEXT:

echo -e "hello n me" | mail -a "Content-type: text/plain" -s "hello" foo@mail.com

Just change the email address in the example by your own email address and check if you have received anything.

The answer is yes ? Congratulations, the first step is a success: you can send emails.

If it doesn’t work, have a look at your mail log file located in /var/log/mail.log (don’t forget to check your junk box … you never know).

Step 2 – Erlang Function

Here is the Erlang function responsible for sending emails using the ‘cmd’ function of the ‘os’ module.

This function issues a normal bash command. As simple as it is.

-module(mymailer).

-compile(export_all).

%% Destination: list of binaries
%% [<<"marc.liesen@example.net">>, <<"john.helbo@exmple.org">>, ...]
%%
%% Subject: binary
%% <<"A mail example">>
%%
%% Body: binary
%% <<"Once upon a time ... ">>
%%
%% ContentType: binary
%% <<"text/html">>

send(Destination, Subject, Body, ContentType) ->
D = string:join( lists:map( fun(Addr) -> binary_to_list(Addr) end, Destination ), " " ),
S = io_lib:format("~p",[binary_to_list(Subject)]),
B = io_lib:format("~p",[binary_to_list(Body)]),
CT = binary_to_list(ContentType),
os:cmd("echo " ++ B ++ " | mail -a "Content-type: " ++ CT ++ ";" -s " ++ S ++ " " ++ D).

Depending on how you have designed your web application (look at our video tutorial), you can call this function from within your web app. For example, you can call it like this:

mymailer:send([<<"foo@mail.org">>, <<"bar@mail.org">>], <<"hello">>, <<"Hello guys">>, <<"text/html">>)

At this point, I have to comment something. As you may have noticed, the function is accepting binaries as arguments.

When I started to learn Erlang, I knew that the language was playing with strings in a different way (list of integers). I also knew that the language was juggling with binaries pretty well.

So I decided to forget everything about strings and to keep going with binaries as long as possible. As soon as a request hits the server, mochijson parses the data into a binaries Erlang structure.

I can ensure you that you can do a lot with binaries … even applying regular expressions to it (have a look at this module, which provide you with functions for regular expression matching for strings and binaries).

Basically, the send function joins all the ‘stringified’ (hum … ‘listified’ should be more accurate) addresses, subject, body and the content type into one string, representing the command line we have just seen in the step ‘ONE’, and launch it with the ‘cmd’ function.

That’s it.

In the next post, I’ll use the os:cmd again, but this time to launch an ImageMagick script in order to create a CAPTCHA on the fly for your Erlang web application.

Bind9

Pre-requisite: You have a dedicated server and you just have associated your brand new domain name with that box (normally it takes around 24-48 hours to propagate this new association).

First, we start by installing the Domain Name System server:

sudo apt-get install bind9

Secondly, we configure it by adding a new zone in the named.conf.local file.

In this example host.dedicated.com is your server and beebole.com the domain you have associated with it.

sudo vi /etc/bind/named.conf.local
zone "beebole.com" {
type master;
file "/etc/bind/db.beebole.com";
};
sudo vi db.beebole.com
$TTL 3h
@ IN SOA host.dedicated.com. www.beebole.com. (
2008082501
8H
2H
1W
1D )

@ IN NS host.dedicted.com.
@ IN NS ns.dedicated.com.
@ IN MX 10 mail.beebole.com.
ns.dedicated.com. IN A 213.187.31.195
host.dedicated.com. IN A 91.120.121.95
www IN A 91.120.121.95
mail IN A 91.120.121.95
*.beebole.com. IN CNAME www.beebole.com.

sudo /etc/init.d/bind9 restart

Links

Comments are closed.