AhaSend

E-mail versturen vanuit Phoenix met de native AhaSend-adapter voor Swoosh

Mark Kraakman
Mark Kraakman
Productupdate
Op deze pagina

Swoosh heeft nu een native AhaSend-adapter. Tot nu toe bereikten Elixir-ontwikkelaars AhaSend via SMTP of schreven ze hun eigen API-client. Nu is het een versiebump en drie regels configuratie:

# config/runtime.exs
config :my_app, MyApp.Mailer,
  adapter: Swoosh.Adapters.AhaSend,
  api_key: System.fetch_env!("AHASEND_API_KEY"),
  account_id: System.fetch_env!("AHASEND_ACCOUNT_ID")

Daarachter krijg je de volledige Management API: tags, tracking en retentie per bericht, inplannen, idempotency keys en een sandboxmodus voor integratietests.

Wat er veranderd is

Swoosh 1.27.0 voegde Swoosh.Adapters.AhaSend toe, bijgedragen via pull request #1177. De adapter praat rechtstreeks met de AhaSend v2 API, kiest het juiste endpoint voor de e-mail die je hebt opgebouwd en vertaalt de provider options van Swoosh naar de berichtvelden van de API. Iedere Swoosh vanaf 1.27 bevat hem, dus een verse mix phx.new heeft hem al aan boord.

Installatie in een Phoenix-project

Een gegenereerd Phoenix-project hangt al van Swoosh af; zorg dat het minimaal 1.27 is. Swoosh heeft daarnaast een HTTP-client nodig en werkt met Req, Finch of Hackney. Req is de eenvoudigste keuze voor een nieuw project.

defp deps do
  [
    {:swoosh, "~> 1.27"},
    {:req, "~> 0.5"}
  ]
end

Vertel Swoosh welke client het moet gebruiken en wijs de mailer in productie naar AhaSend. Houd de sleutel en het account-id buiten de repository: lees ze uit de omgeving in config/runtime.exs.

# config/config.exs
config :swoosh, :api_client, Swoosh.ApiClient.Req

# config/runtime.exs
if config_env() == :prod do
  config :my_app, MyApp.Mailer,
    adapter: Swoosh.Adapters.AhaSend,
    api_key: System.fetch_env!("AHASEND_API_KEY"),
    account_id: System.fetch_env!("AHASEND_ACCOUNT_ID")
end

Laat in development de Swoosh.Adapters.Local-adapter staan die Phoenix heeft gegenereerd, zodat e-mails in de mailboxpreview op /dev/mailbox belanden in plaats van in een echte inbox. Houd in test Swoosh.Adapters.Test; daardoor werkt assert_email_sent/1, en er is geen API-sleutel voor nodig.

De mailermodule is degene die Phoenix al heeft aangemaakt:

defmodule MyApp.Mailer do
  use Swoosh.Mailer, otp_app: :my_app
end

Maak aan de AhaSend-kant op de pagina API Keys van het dashboard een API-sleutel met alleen de scope messages:send:{jouw-domein} (of messages:send:all als hij vanaf ieder domein mag versturen), en voeg een verzenddomein toe met geverifieerde DNS-records. Dat is de hele installatie.

Een e-mail versturen

Aan het opbouwen van berichten verandert niets. Een wachtwoordreset uit de notifier van phx.gen.auth ziet er zo uit:

import Swoosh.Email

new()
|> to({user.name, user.email})
|> from({"MyApp", "[email protected]"})
|> subject("Reset je wachtwoord")
|> text_body("Gebruik deze link om je wachtwoord te resetten: #{url}")
|> put_provider_option(:tags, ["auth", "password-reset"])
|> put_provider_option(:idempotency_key, "reset-#{token_id}")
|> MyApp.Mailer.deliver()

De optie idempotency_key is de moeite waard om vanaf dag één te gebruiken. Hij wordt meegestuurd als de header Idempotency-Key, zodat dezelfde e-mail niet twee keer wordt bezorgd wanneer een Oban-job na een time-out opnieuw wordt uitgevoerd.

Wat de adapter voor je doet

AhaSend heeft een /messages-endpoint dat iedere ontvanger een eigen kopie bezorgt, en een /messages/conversation-endpoint dat één bericht verstuurt met de volledige To-, Cc- en Bcc-headers, zoals een mailclient dat doet. De adapter gebruikt het eerste als je e-mail geen Cc of Bcc heeft en het tweede als dat wel zo is, zodat ontvangers precies zien wat je bedoelde.

Provider options worden één op één vertaald naar de API. Naast tags en idempotency_key:

  • substitutions: een map met templatevariabelen die op onderwerp en inhoud worden toegepast.
  • tracking: overschrijf de accountinstelling per bericht, bijvoorbeeld %{open: true, click: false}.
  • retention: overschrijf hoe lang AhaSend metadata en inhoud bewaart, bijvoorbeeld %{metadata: 30, data: 7}, binnen de grenzen van je plan.
  • schedule: stel bezorging uit, bijvoorbeeld %{first_attempt: "2026-11-01T08:00:00Z"}.
  • sandbox en sandbox_result: accepteer en valideer het bericht zonder het te bezorgen, en simuleer deliver, bounce, defer, fail of suppress. Dit is bedoeld voor integratietests die de echte API moeten raken zonder mail te versturen; unittests blijven op de Test-adapter.

Waarom Phoenix-teams voor AhaSend kiezen

Phoenix is populair bij Europese teams die het belangrijk vinden waar hun data staat. AhaSend draait op bare metal die het zelf beheert in Europese datacenters, slaat je data op in Duitsland en Finland en is ISO 27001-gecertificeerd. Het gratis plan bevat 1.000 e-mails per maand, genoeg om een MVP te lanceren zonder creditcard. Daarboven begint Pro bij €9 per maand voor 25.000 e-mails en Max bij €72 voor 100.000, met verbruiksafhankelijk meerverbruik op beide.

Begin gratis met AhaSend