Pop3 Class
Read email from a mailbox over POP3, with TLS by default and structured message parsing.
Pop3 connects to a POP3 server over implicit TLS (port 995) by default, authenticates, and parses each fetched message into a hash with subject, from, to, date, text/HTML bodies, and attachment metadata.
Pop3.new(host, user, password, opts?)
Pop3.new(host, user, password, opts?)
Connects and authenticates, returning a client instance.
Parameters
host : String — POP3 server hostnameuser : String — Mailbox usernamepassword : String — Password or app passwordopts : Hash? — port (default 995), tls (default true)mail = Pop3.new("pop.gmail.com", "me@gmail.com", "app-password")
# Plaintext on a custom port (e.g. a local test server)
mail = Pop3.new("127.0.0.1", "user", "pass", { "port": 110, "tls": false })
Gmail / 2FA accounts: use an App Password, not your normal password, and enable POP access in your account settings.
Instance Methods
mail.stat() — returns { "count": Int, "size": Int } (message count and total octets).mail.list() — returns an array of { "id": Int, "size": Int }.mail.fetch(id) — returns a parsed message hash (see below).mail.fetch_all() — returns an array of parsed message hashes (capped at 200; raise via SOLI_POP3_MAX_MESSAGES).mail.delete(id) — marks a message for deletion; returns true.mail.quit() — commits deletions and closes the connection; returns true.Message Hash
Each fetched message is a hash. from is a single {name, address} hash (or null); to is an array of them. Missing headers/bodies are null.
{
"id": 1,
"size": 2048,
"subject": "Hello from Alice",
"from": { "name": "Alice", "address": "alice@example.com" },
"to": [ { "name": "Bob", "address": "bob@example.com" } ],
"date": "2026-06-01T10:00:00Z",
"text_body": "Hi Bob, ...",
"html_body": "<p>Hi Bob, ...</p>",
"attachments": [ { "name": "report.pdf", "content_type": "application/pdf", "size": 51200 } ],
"raw": "From: Alice ..." # full RFC822 source
}
Complete Example
mail = Pop3.new("pop.gmail.com", "me@gmail.com", "app-password")
print("You have #{mail.stat()["count"]} messages")
for msg in mail.fetch_all()
print("#{msg["date"]} — #{msg["from"]["address"]}: #{msg["subject"]}")
for attachment in msg["attachments"]
print(" attachment: #{attachment["name"]} (#{attachment["content_type"]})")
end
end
mail.quit()