pop3mail v0.1.3 Pop3mail
Download email from the inbox and store them (including attachments) in a subdirectory per email.
Reads incoming mail via the POP3 protocol, using an Erlang Epop client with SSL support. Decodes multipart content, quoted-printables, base64 and encoded-words. The module also contains functions to perform only the decoding, giving you the choice to do retrieval and storage with your own functions.
Summary
Functions
Commandline interface for downloading email and storing them on disk
Decode multipart, base64 and quoted-printable text. Returned is a list of Pop3mail.Part structs
Decode multipart, base64 and quoted-printable text. Returned is a list of Pop3mail.Part structs
Decode raw message file (mostly an .eml file) and store result on disk
Decode a text with encoded words as defined in RFC 2047. Returns a list with tuples of charset name and binary content
Download emails from the inbox and store them (including attachments) in a subdirectory per email
Lookup header in header list retrieved via epop
Functions
Commandline interface for downloading email and storing them on disk.
Examples
Download maximum 2 emails from the email account and also save the raw undecoded message.
$ pop3mail_downloader --max=2 --raw --username=hendrik.lorentz@gmail.com --password=secret --output=mailbox
or
iex(1)> Pop3mail.cli(["--max=2", "--raw", "--username=hendrik.lorentz@gmail.com", "--password=secret", "--output=mailbox"])
info: 297 emails, 57.643.477 bytes total.
info: Process mail 1: Mon, 13 Oct 2015 18:34:07 +0200
info: message1.txt
info: message1.html
info: Solution Skolem problem.docx
info: Process mail 2: Mon, 13 Oct 2015 19:38:14 +0200
info: message1.iso-8859-1.txt
info: message2.iso-8859-1.html
{:ok, 297}
Print the usage text. It has a long explanation of all the parameters.
$ pop3mail_downloader --help
or
iex(1)> Pop3mail.cli(["--help"])
usage: ...
Decode multipart, base64 and quoted-printable text. Returned is a list of Pop3mail.Part structs.
Example
Decode message with nested multipart content.
iex(1)> message = """
...(1)> Il s'agit d'un message à parties multiples au format MIME.
...(1)>
...(1)> ------=_NextPart_000_0004_01D0C782.71A41900
...(1)> Content-Type: multipart/alternative;
...(1)> \tboundary="----=_NextPart_001_0005_01D0C782.71A8D3F0"
...(1)>
...(1)>
...(1)> ------=_NextPart_001_0005_01D0C782.71A8D3F0
...(1)> Content-Type: text/plain;
...(1)> \tcharset="iso-8859-1"
...(1)> Content-Transfer-Encoding: quoted-printable
...(1)>
...(1)> No problem, the reception will be open until 19.30 tomorrow.
...(1)>
...(1)> T=E9l: 555
...(1)>
...(1)> =20
...(1)>
...(1)>
...(1)> ------=_NextPart_001_0005_01D0C782.71A8D3F0
...(1)> Content-Type: text/html;
...(1)> \tcharset="iso-8859-1"
...(1)> Content-Transfer-Encoding: quoted-printable
...(1)>
...(1)> <META HTTP-EQUIV=3D"Content-Type" CONTENT=3D"text/html; =
...(1)> charset=3Diso-8859-1">
...(1)> <html><head><title>hoi</title></head>
...(1)> <body lang=3DFR link=3Dblue vlink=3Dpurple>
...(1)> <div class=3DSection1>
...(1)>
...(1)> <p>
...(1)> No problem, the reception will be open until 19.30 =
...(1)> tomorrow.</p>
...(1)>
...(1)> </div>
...(1)> </body>
...(1)> </html>
...(1)>
...(1)> ------=_NextPart_001_0005_01D0C782.71A8D3F0--
...(1)>
...(1)> ------=_NextPart_000_0004_01D0C782.71A41900
...(1)> Content-Type: image/gif;
...(1)> \tname="image001.gif"
...(1)> Content-Transfer-Encoding: base64
...(1)> Content-ID: <image001.gif@01D0C782.711C2450>
...(1)>
...(1)> R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7
...(1)>
...(1)> ------=_NextPart_000_0004_01D0C782.71A41900--
...(1)>
...(1)> """
...(2)> message |> String.replace("\n", "\r\n") |> Pop3mail.decode_body("multipart/related; boundary=\"----=_NextPart_000_0004_01D0C782.71A41900\"", "bit7", "")
[%Pop3mail.Part{boundary: "----=_NextPart_001_0005_01D0C782.71A8D3F0",
charset: "iso-8859-1",
content: <<78, 111, 32, 112, 114, 111, 98, 108, 101, 109, 44, 32, 116, 104, 101, 32, 114, 101, 99, 101, 112, 116, 105, 111, 110, 32, 119, 105, 108, 108, 32, 98, 101, 32, 111, 112, 101, 110, 32, 117, 110, 116, 105, 108, 32, 49, ...>>,
content_id: "", filename: "", filename_charset: "us-ascii", index: 1,
inline: nil, media_type: "text/plain", path: "related/alternative"},
%Pop3mail.Part{boundary: "----=_NextPart_001_0005_01D0C782.71A8D3F0",
charset: "iso-8859-1",
content: "<META HTTP-EQUIV=\"Content-Type\" CONTENT=\"text/html; charset=iso-8859-1\">\r\n<html><head><title>hoi</title></head>\r\n<body lang=FR link=blue vlink=purple>\r\n<div class=Section1>\r\n\r\n<p>\r\nNo problem, the reception will be open until 19.30 tomorrow.</p>\r\n\r\n</div>\r\n</body>\r\n</html>\r\n",
content_id: "", filename: "", filename_charset: "us-ascii", index: 2,
inline: nil, media_type: "text/html", path: "related/alternative"},
%Pop3mail.Part{boundary: "----=_NextPart_000_0004_01D0C782.71A41900",
charset: "us-ascii",
content: <<71, 73, 70, 56, 57, 97, 1, 0, 1, 0, 128, 0, 0, 0, 0, 0, 255, 255, 255, 33, 249, 4, 1, 0, 0, 0, 0, 44, 0, 0, 0, 0, 1, 0, 1, 0, 0, 2, 1, 68, 0, 59>>,
content_id: "<image001.gif@01D0C782.711C2450>", filename: "image001.gif",
filename_charset: "us-ascii", index: 2, inline: nil, media_type: "image/gif",
path: "related"}]
Decode multipart, base64 and quoted-printable text. Returned is a list of Pop3mail.Part structs.
Example
Retrieve email via epop_client and decode body and close the connection.
iex(1)> # notice that you must use single quotes here
iex(2)> {:ok, client} = :epop_client.connect('user@gmail.com', 'password', [{:addr, 'pop.gmail.com'},{:port,995},:ssl])
iex(3)> :epop_client.stat(client)
iex(4)> {:ok, mail_content} = :epop_client.retrieve(client, 1)
iex(5)> {:message, header_list, body_char_list } = :epop_message.parse(mail_content)
iex(6)> Pop3mail.decode_body_char_list(header_list, body_char_list)
[%Pop3mail.Part{boundary: "--_com.android.email_1191110031918720",
charset: "utf-8",
content: "
Please give me write access for the forum and possibly the wiki.
TIA “,
content_id: "", filename: "", filename_charset: "us-ascii", index: 1,
inline: nil, media_type: "text/plain", path: "alternative"},
%Pop3mail.Part{boundary: "--_com.android.email_1191110031918720",
charset: "utf-8",
content: "<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"></head><body ><div><br></div><div>Please give me write access for the forum and possibly the wiki.</div><div><br></div><div>TIA</div><div><br></div></body></html>",
content_id: "", filename: "", filename_charset: "us-ascii", index: 2,
inline: nil, media_type: "text/html", path: "alternative"}]
iex(7)> :epop_client.quit(client)
Decode raw message file (mostly an .eml file) and store result on disk.
Returns a list with file storage results.
Example
Decode simple.eml and write result in the testoutput directory.
iex(1)> Pop3mail.decode_raw_file("test/pop3mail/fixtures/simple.eml", "testoutput")
info: Process mail 1: Thu, 4 Sep 2014 19:23:15 +0200
info: message1.iso-8859-1.txt
[ok: "testoutput/20140904_192315_Re_appointment/header.Marie.txt",
ok: "testoutput/20140904_192315_Re_appointment/message1.iso-8859-1.txt"]
Decode a text with encoded words as defined in RFC 2047. Returns a list with tuples of charset name and binary content.
Encoded words can occur in email headers (Subject, From, To) and for filenames in multipart content.
Examples
Russian subject
iex> Pop3mail.decode_word("=?koi8-r?Q?Fwd:_=E4=CF=CD=C1=DB=CE=C5=C5_=DA=C1=C4=C1=CE=C9=C5_?=")
[{"koi8-r",
<<70, 119, 100, 58, 32, 228, 207, 205, 193, 219, 206, 197, 197, 32, 218, 193, 196, 193, 206, 201, 197, 32>>}]
French (Réception) and ascii text email address
iex(1)> Pop3mail.decode_words("=?iso-8859-1?Q?R=E9ception_Fayence?= <reception.fayence@acme.com>")
[{"iso-8859-1",
<<82, 233, 99, 101, 112, 116, 105, 111, 110, 32, 70, 97, 121, 101, 110, 99, 101>>},
{"us-ascii", " <reception.fayence@acme.com>"}]
Chinese
iex(1)> Pop3mail.decode_words("chinese")
[{"us-ascii", "chinese"}]
Download emails from the inbox and store them (including attachments) in a subdirectory per email.
Parameters must be supplied in a string-keyed map:
delete
- delete email after downloading. Default: false. Notice that Gmail ignores the delete and instead uses the Gmail account settings.delivered
- true/false. Skip emails with/without Delivered-To header. If you moved an email from your sent box to your inbox it will not have the Delivered-To header. Default: don’t skipmax
- maximum number of emails to download. Default: unlimitedoutput
- output directory. Default: inboxpassword
- email account password.port
- pop3 server port. Default: 995raw
- also save the unprocessed mail in a file called ‘raw.eml’. Usefull feature for error diagnostics.server
- pop3 server address. Default: pop.gmail.comssl
- true/false. Turn on/off Secure Socket Layer. Default: trueusername
- email account name. Gmail users can precede the name with ‘recent:’ to get the last 30 days mail, even if it has already been downloaded elsewhere.
Example
Download maximum 2 emails from the email account and also save the raw undecoded message.
iex(1)> Pop3mail.download(%{"max" => 2, "raw" => true, "username" => "hendrik.lorentz@gmail.com", "password" => "secret", "output" => "mailbox"})
Lookup header in header list retrieved via epop.
Example
Retrieve email via epop_client and lookup headers ‘Data’, ‘Subject’ and ‘From’ and close the connection.
iex(1)> # notice that you must use single quotes here
iex(2)> {:ok, client} = :epop_client.connect('user@gmail.com', 'password', [{:addr, 'pop.gmail.com'},{:port,995},:ssl])
iex(3)> :epop_client.stat(client)
iex(4)> {:ok, mail_content} = :epop_client.retrieve(client, 1)
iex(5)> {:message, header_list, body_char_list } = :epop_message.parse(mail_content)
iex(6)> Pop3mail.header_lookup(header_list, "Subject")
"Solution Skolem problem"
iex(7)> Pop3mail.header_lookup(header_list, "From")
"Hendrik Lorentz <hendrik.lorentz@gmail.com>"
iex(8)> Pop3mail.header_lookup(header_list, "Date")
"Thu, 11 Jun 2015 18:05:26 +0000 (UTC)"
iex(9)> :epop_client.quit(client)