Skip to content

Taure/hikyaku

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

19 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Hikyaku

Email delivery library for Erlang — composable email builder with swappable adapter backends.

Features

  • Builder — functional, chainable email construction with address normalization
  • Attachments — from file path, binary data, or inline with content-id
  • Mailer — behaviour-based mailer modules with validation on delivery
  • Adapters — SMTP, SendGrid, Mailgun, Amazon SES, logger, and test
  • Content Types — automatic MIME type detection for attachments

Quick Start

Define a Mailer

-module(my_mailer).
-behaviour(hikyaku_mailer).

-export([config/0, deliver/1]).

config() ->
    #{
        adapter => hikyaku_adapter_smtp,
        relay => <<"smtp.example.com">>,
        port => 587,
        username => <<"user@example.com">>,
        password => <<"secret">>,
        tls => always
    }.

deliver(Email) ->
    hikyaku_mailer:deliver(?MODULE, Email).

Build & Send

-include_lib("hikyaku/include/hikyaku.hrl").

Email = hikyaku_email:new(),
Email1 = hikyaku_email:from(Email, {<<"Alice">>, <<"alice@example.com">>}),
Email2 = hikyaku_email:to(Email1, <<"bob@example.com">>),
Email3 = hikyaku_email:subject(Email2, <<"Hello!">>),
Email4 = hikyaku_email:text_body(Email3, <<"Hi Bob">>),
Email5 = hikyaku_email:html_body(Email4, <<"<b>Hi Bob</b>">>),

{ok, _} = my_mailer:deliver(Email5).

Addresses accept a binary (<<"bob@example.com">>), a {Name, Address} tuple, or a #hikyaku_address{} record.

Use to/2, cc/2, bcc/2 to append recipients, or put_to/2, put_cc/2, put_bcc/2 to replace the entire list.

Attachments

%% From file path (content type auto-detected)
Pdf = hikyaku_attachment:from_path(<<"/tmp/report.pdf">>),

%% From binary data
Csv = hikyaku_attachment:from_data(<<"data.csv">>, CsvBin),

%% Inline image with content-id
Logo = hikyaku_attachment:inline(<<"logo">>, <<"/tmp/logo.png">>),

Email6 = hikyaku_email:attachment(Email5, Pdf),
Email7 = hikyaku_email:attachment(Email6, Logo).

from_path/2 and from_data/3 accept an options map: #{content_type => binary(), filename => binary()}.

Adapters

Adapter Description Config
hikyaku_adapter_smtp SMTP via gen_smtp relay, port, username, password, ssl, tls
hikyaku_adapter_sendgrid SendGrid v3 API api_key, http_client
hikyaku_adapter_mailgun Mailgun Messages API api_key, domain, base_url, http_client
hikyaku_adapter_ses Amazon SES v2 API access_key, secret_key, region, http_client
hikyaku_adapter_logger Logs emails via logger level
hikyaku_adapter_test Sends to a process pid

Mailgun

config() ->
    #{
        adapter => hikyaku_adapter_mailgun,
        api_key => <<"key-xxx">>,
        domain => <<"mg.example.com">>,
        base_url => <<"https://api.eu.mailgun.net">>  %% optional, defaults to US region
    }.

Amazon SES

config() ->
    #{
        adapter => hikyaku_adapter_ses,
        access_key => <<"AKIA...">>,
        secret_key => <<"...">>,
        region => <<"us-east-1">>
    }.

SES uses the v2 JSON API for simple emails and automatically falls back to raw MIME encoding when attachments are present. Authentication uses AWS Signature V4 — no external dependencies required beyond OTP crypto.

Testing

-include_lib("hikyaku/include/hikyaku.hrl").
-include_lib("eunit/include/eunit.hrl").

-behaviour(hikyaku_mailer).

config() ->
    #{adapter => hikyaku_adapter_test, pid => self()}.

send_test() ->
    Email = hikyaku_email:to(
        hikyaku_email:from(
            hikyaku_email:subject(hikyaku_email:new(), <<"Test">>),
            <<"sender@test.com">>
        ),
        <<"recipient@test.com">>
    ),
    {ok, _} = hikyaku_mailer:deliver(?MODULE, Email),
    receive
        {hikyaku_email, Received} ->
            ?assertEqual(<<"Test">>, Received#hikyaku_email.subject)
    after 1000 ->
        error(timeout)
    end.

Requirements

  • Erlang/OTP 27+

About

Email delivery library for Erlang with swappable adapter backends

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors