POP3 client library for Erlang. It is derived from the original “epop” Erlang package which includes both a POP server and client.
epop author: Torbjörn Törnkvist when working at Software Engineering Research Center, SERC, in Melbourne
Documentation
Note that the proposed standards RFC 2449 (Pipelining), RFC 1734/5034 (AUTH), RFC 2595 (STLS), RFC 1082 (XTND) are NOT supported.
Changes
2023-11-29 Nico Hoogervorst - v1.4, Erlang / OTP 26 upgrade. Pass on cacerts to ssl:connect.
'ssl' parameter can now be false, true, list with ssl:connect options, or
a ssl:connect compatible function. A cacertfile can be passed in the ssl list.
2019-05-21 Nico Hoogervorst - v1.3.1, Replaced obsolete functions; string:tokens, string:str, string:substr, string:cspan.
2019-01-26 Nico Hoogervorst - v1.3, added line-by-line/streaming interface. Added NOOP. Stricter byte-stuffing. eunit tests.
2018-11-09 Nico Hoogervorst - v1.2, case-insensitive header lookup. Added erlpop as package 'pop3client' in hex.pm
2017-06-13 Nico Hoogervorst - Added 'bin_retrieve' get binary data instead of character list to reduce memory consumption
2016-08-05 Nico Hoogervorst - Erlang V8.0.2 / OTP 19 upgrade
2013-04-18 Erik Søe Sørensen - Add an email address parser 'epop_address' (RFC5322)
2013-04-17 Erik Søe Sørensen - Erlang/OTP 15 upgrade, "TOP" fix; rebarify
2013-01-31 Wes James - update ssl start command to current erlang api
2009-10-06 Harish Mallipeddi - Added `epop_message` to parse retrieved email messages.
2008-09-10 Harish Mallipeddi - Added SSL support (epop_client can be now be used with services like GMail which require SSL).License
Erlang public license is deprecated in June 2015 and replaced with Apache 2.0 license
Usage Erlang
rebar3 compile
erl -pa ./_build/default/lib/pop3client/ebin
1> User = "yourname@gmail.com".
2> {ok, Connection} = epop_client:connect(User, "yourpassword",
2> [ {addr, "pop.gmail.com"}, {port, 995}, {user, User}, ssl ] ).
3> {ok, {TotalCount, TotalSize}} = epop_client:stat(Connection).
4> {ok, TopContent} = epop_client:top(Connection, 1, 20).
5> {message, HeaderList, Body} = epop_message:parse(TopContent).
6> {ok, MailContent} = epop_client:bin_retrieve(Connection, 1).
7> {message, BinHeaderList, BinBody} = epop_message:bin_parse(MailContent).
8> {ok, Date} = epop_message:find_header(BinHeaderList, <<"Date">>).
9> epop_client:quit(Connection).NOTE: It’s important to call epop_client:quit/1 at the end, as it’s responsible for closing (tcp/tls) socket.
The retrieval of an email can also be done line-by-line using retrieve_start, retrieve_next, retrieve_after. Always call the retrieve_after when ready.
erl -pa ./_build/default/lib/pop3client/ebin
1> {ok, Acc} = epop_client:retrieve_start(Connection, 1).
2> {HaltOrNewLine, NewAcc} = epop_client:retrieve_next(Acc).
3> ok = epop_client:retrieve_after(NewAcc).Address list parser, like RFC 5322
erl -pa ./_build/default/lib/pop3client/ebin
1> {ok, AddressList} = epop_address:parse_list("\"hendrik\" <h.lorentz@gmail.com>, philipp <philipp.reis@telephon.de>").
{ok,[{{"h.lorentz","gmail.com"},"hendrik"},
{{"philipp.reis","telephon.de"},"philipp"}]}
2> {ok,[Group]} = epop_address:parse_list("Managing Partners:ben@example.com,carol@example.com;").
{ok,[{group,"Managing Partners",
[{{"ben","example.com"},[]},{{"carol","example.com"},[]}]}]}
3> epop_address:expand_groups([Group]).
[{{"ben","example.com"},[]},{{"carol","example.com"},[]}]Usage Elixir
Specially note how easy it is to create an Elixir stream
iex -S mix
iex(1)> user = 'yourname@gmail.com'
iex(2)> {ok, connection} = :epop_client.connect(user, 'yourpassword',
...(2)> [ {:addr, 'pop.gmail.com'}, {:port, 995}, {:user, user}, :ssl] )
iex(3)> {:ok, {total_count, total_size}} = :epop_client.stat(connection)
iex(4)> # read headers and 20 lines of the body of the first email
iex(5)> {:ok, mail_content} = :epop_client.top(connection, 1, 20)
iex(6)> # separate headers and body
iex(7)> {:message, header_list, body} = :epop_message.parse(mail_content)
iex(8)> # create lazy stream resource for the first email
iex(9)> mail1stream = apply(Stream, :resource, :epop_client.retrieve_resource_functions(connection, 1))
iex(10)> # read from the stream. Example:
iex(11)> mail1stream |> Enum.find(fn(val) -> String.contains?(val, "Waldo") end) |> String.trim
iex(12)> # use the stream again and it will read the whole mail again. Now write to file:
iex(13)> output_file = File.stream!("mail1.eml", [:write, :delayed_write])
iex(14)> mail1stream |> Enum.into(output_file)
iex(15)> :epop_client.quit(connection)NOTE: It’s important to call epop_client:quit/1 at the end, as it’s responsible for closing (tcp/tls) socket.
escript example for downloading emails
wget -q https://raw.github.com/nico-amsterdam/erlpop/master/pop3client_downloader
escript pop3client_downloader --help
escript pop3client_downloader
escript pop3client_downloader --username yourname@gmail.com --password yourpassword --max 10 --output myinbox