[ANN] letters - simple client abstractions for sending emails over SMTP

Hi all,

Earlier today I’ve published the first release of letters. This library aims to provide simple to use client library for sending emails over SMTP using lwt for async execution.

It is build on top of mrmime and colombe. While these libraries are very capable, they aren’t that simple to use, letters is trying to fill that gap. Anyway, big thanks for the authors of these projects for doing the heavy lifting.

As this library is still in its early stage, I believe I will break the API with first few releases. Luckily the API is quite simple so following these changes should be quite easy.

To make this library awesome, any feedback or feature request is welcome. I’ll try to address them as quickly as I can.

I hope I’ve managed to scratch someone else’s itch too, enjoy.
– Miko

8 Likes

This looks great, exactly what I was looking for a while back (ended up sending email using Mailgun’s REST API which felt a bit silly because email has a perfectly good protocol dedicated to it). Only smalll suggestion I can think of is that it might be nice to have a default certificates directory.

Hi @roddy,

thanks for the feedback. This is already on my list of planned features. Only thing is that, I haven’t really found a sensible way to discover this default location correctly. In most of the Linux distros, it seems to be /etc/ssl/certs and this is what I’m thinking to use as a default value until finding proper mechanism. If you happen to know way to get this using pkg-config or any other mechanism, it would greatly help.

Btw, my initial 0.1.0 release had a mistake in the packaging and it did not work correctly when using dune. Yesterday I published a bugfix release 0.1.1 to fix this issue.

I was looking into how Python’s smtplib does it, seems like ultimately uses OpenSSL’s SSL_CTX_load_verify_locations function. Unfortunately it seems like it might be difficult to use that here; it sets a default location for the context used by SSL rather than actually returning a location. This page has a huge amount of detail on the subject.

thanks, that looks a good starting point to find out the right location. Originally I was thinking about to check some Debian/Ubuntu packages that depend on ca-certificates package (and additionally what Alpine Linux has). Then a have a look how they check where things are installed or do they hard code things. I also had in mind to check if OpenSSL provides something for this purpose. Best would be if I could use pkg-config to read this information at build time.

I’m somewhat in the dark on the underlying libraries here, but for example if Python’s using OpenSSL, then a client built to that library wouldn’t normally wouldn’t trouble itself over certificates, just to open an encrypted connection, would it? Or anyway, mine doesn’t, just calls SSL_CTX_new(TLS_client_method()), and that works for port 465.

Yes, that’s quite true, but I haven’t been able to find easy way to replicate the same behaviour when using ocaml-tls. When using for example cURL it checks OpenSSL configs and pulls CA certificate bundle information from there and then uses this to verify the connection, I suppose this is pretty much build-in functionality of OpenSSL and maybe using ocaml-ssl would simplify this, but would be nice if I can use pure OCaml implementation for secure connections.

Anyway, I have two tickets in the backlog regarding this topic:


Looking at Readme, I have no idea how to use your library to send an email.

I haven’t put much effort on it yet as the release is initial one and the API is expected to change with next release. If you’re interested, master branch has a simple test that should work as an example.

Hopefully with next release the API is more sensible and if I find enough time, I can add some documentation with the code.