How to send email via Gmail using Erlang
21st Century Code WorksBest of Erlang - noreply@blogger.com (Benjamin Nortier) - May 19, 2009One of my pet projects, www.dayfindr.com, integrates with email to send notifications to users.
I use Google Apps for email infrastructure, so you need an SMTP client that supports TLS. At the time, I couldn’t find a simple Erlang SMTP client that could handle TLS, so I used a command-line SMTP client.
For my new pet project, for want of a better name temporarily called The Isabelle Project, I need to add some email functionality. This time I would prefer to use an Erlang solution with proper error handling and logging.
I looked at the SMTP protocol on Wikipedia, and it didn’t seem to difficult. Erlang’s built-in ssl module also seemed to support TLS. So, with a bit of trial and error, here’s the result:
-module(smtp).
-export([connect/0]).
connect() ->
{ok, Socket} = ssl:connect("smtp.gmail.com", 465, [{active, false}], 1000),
recv(Socket),
send(Socket, "HELO localhost"),
send(Socket, "AUTH LOGIN"),
send(Socket, binary_to_list(base64:encode("___@gmail.com"))),
send(Socket, binary_to_list(base64:encode("johngalt"))),
send(Socket, "MAIL FROM: <___@gmail.com>"),
send(Socket, "RCPT TO:<___@gmail.com>"),
send(Socket, "DATA"),
send_no_receive(Socket, "From: <___@gmail.com>"),
send_no_receive(Socket, "To: <___@gmail.com>"),
send_no_receive(Socket, "Date: Tue, 15 Jan 2008 16:02:43 +0000"),
send_no_receive(Socket, "Subject: Test message"),
send_no_receive(Socket, ""),
send_no_receive(Socket, "This is a test"),
send_no_receive(Socket, ""),
send(Socket, "."),
send(Socket, "QUIT"),
ssl:close(Socket).
send_no_receive(Socket, Data) ->
ssl:send(Socket, Data ++ "rn").
send(Socket, Data) ->
ssl:send(Socket, Data ++ "rn"),
recv(Socket).
recv(Socket) ->
case ssl:recv(Socket, 0, 1000) of
{ok, Return} -> io:format("~p~n", [Return]);
{error, Reason} -> io:format("ERROR: ~p~n", [Reason])
end.
And the output from the Erlang shell:
3> application:start(ssl).
ok
4> smtp:connect().
"220 mx.google.com ESMTP y37sm613282mug.19rn"
"250 mx.google.com at your servicern"
"334 VXNlcm5hbWU6rn"
"334 UGFzc3dvcmQ6rn"
"235 2.7.0 Acceptedrn"
"250 2.1.0 OK y37sm613282mug.19rn"
"250 2.1.5 OK y37sm613282mug.19rn"
"354 Go ahead y37sm613282mug.19rn"
"250 2.0.0 OK 1242683885 y37sm613282mug.19rn"
"221 2.0.0 closing connection y37sm613282mug.19rn"
ok
The only tricky bit is that for the AUTO LOGIN, the received text and the username and password you send is base-64 encoded. By default the connect is active=false, which means the responses are send to the creating process directly. Using passive mode requires explicit receiving of the response using ssl:recv/2
You’ll have to handle errors better if you use this in production, but the basic protocol is pretty straightforward…
Categories: Blogs 21st Century Code Works Best of Erlang
Comments
I use R13B & winXP
when I use the up,And the output from the Erlang shell:
1>application:start(ssl).
ok
2>smtp:connect().
***exception exit:no_ssl_server
What’s wrong coudle you tell me?
THX
@tt0786
You probably need to have open ssl. See this tutorial on CouchDB for more links and info.
http://www.hiveminds.co.uk/?p=35807
Posted by Carl McDade on 23 May 2009 at 09:38hi! just tried this code with .(JavaScript must be enabled to view this email address) set up as my address and recipient address (can it be different from gmail?) anyway i used my pwd instead of johngalt and it works til
220 mx.google.com ESMTP y37sm613282mug.19rn”
then i got an error: {error, timeout} any clues?
this topic rules!
Posted by necromoncer on 27 May 2009 at 18:34@necromoncer
Make sure to replace ++ “rn” by ++ “\r\n” in send and send_no_recv.
Posted by Dominique Boucher on 10 Jun 2009 at 14:31great!thanx a lot man!
Posted by necromoncer on 08 Jul 2009 at 13:18seeing erlang do some good job makes me happy, thanks a lot dude
gelinlik
yarış oyunları
Türkiye’nin en büyük anne -bebek & aile yaşam platformu e-bebek ve Anadolu Ulaşım’ın işbirliğinde 1 Eylül 2009 tarihinde başlatılan, “çağrı merkezinden bilet alanlara çocuk koltuğu sağlanması”na yönelik uygulamaya olan ilgi artarak devam ediyor.
1 Haziran 2010 tarihinde yürürlüğe giren, ülkemizde oto koltuğu kullanımını zorunlu hale getiren yasa ile birlikte, seyahatlerde çocuk oto koltuğuna yönelik taleplerde ciddi artış yaşandığına dikkati çeken çocuk oto koltuğu Genel Müdürü Halil Erdoğmuş, ilerleyen dönemde bu talebin daha da artacağını öngördüklerinin altını çiziyor. admin yeah toto :)
Posted by çocuk on 23 Jun 2010 at 21:57Do you acquisition Gmail so great, admirable and affected that you wish to handle all your email in it, pass4sure 640-816 not just letters you accept at your gmail address! It’s apparently simple to advanced your plan mail, pass4sure 640-822 for example, to your Gmail account, but the replies with your Gmail abode in band do not attending too good, pass4sure 350-030 do they.
Posted by Foana21 on 11 Feb 2011 at 09:02I really love using gmail thanks for the great code
passive niche profits
In case you had some problems with this code (such as closed socket error): add recv(Socket) after the send(Socket, “HELO localhost”) line. Gmail sends additional action complete status (250 code) that needs to be received before sending login and password.
All in all great piece of code, very helpful. With aforementioned fix still works after 2 years. Thanks!
Posted by gregorej on 06 Jun 2011 at 14:18
Add comment
Erlang on Twitter
» ingojaeckel (ingo jaeckel): Even more awesome, free Erlang resources http://t.co/blGINLJd
» DiTeam (Тимурка): @multybuq @ukhin руби хороший вариант :) можно даже без rails..попробуй erlang еще :)
» michelir5 (Micheli Gelatinous): @pharkmillups Still seeing it. I might just have to manually install it. The version of Erlang required by Riak is not current version in HB
» Angry_Lawyer (Tony Aldridge): @rvirding @saghul If Erlang kills you, does a supervisor automatically create a replacement of you?
» rvirding (Robert Virding): Softly I hope. RT @saghul: Slowly making progress… erlang is killing me.
» jsvd (João Duarte): RT @FrancescoC: Woot! RT @valdo404: Practical Erlang Programming at #QConLondon I want to go there
» saghul (Saúl Ibarra Corretgé): Slowly making progress… erlang is killing me.
» dlsspy (Dustin Sallings): @IbnFirnas heh. The erlang parts are still solid. The currently active alerting box is arm5, failed over from a pc that died one day.
» quercialwji2 (Quercia Quinn): @MikeSmooth_ABCs http://t.co/pPiIpTCx
» levicole (Levi Kennedy): @pharkmillups the homebrew version of erlang is the most recent version, and riak requires R14B I think.
Statistics
Number of aggregated posts: 10456
Number of comments: 1445
Most recent article: February 06, 2012
Latest comments
» simple smile on Scale means Skills: Very informative article. Pretty sure people would love to go to that place for shopping. Specially to those who are…
» simplesmile on 27 January 2012: Erlang Solutions embarks on an Erlang Embedded KTP: Your article will make the world better. Thanks again and good luck to you in your life. See you next time.simplesmile
» tandblekning easewhite on 08 February 2012: Erlang Express 3-day Course in San Francisco on 8 February: ncomprehensible to me now, but in general, the usefulness and significance is overwhelmingtandblekning easewhite