Phoenix Elixir
Phoenix Elixir integration examples for Keplers Mail Service
Send emails using Phoenix Elixir with Keplers Mail Service REST API.
Installation
Add to your mix.exs:
defp deps do
[
{:httpoison, "~> 2.0"},
{:jason, "~> 1.4"}
]
endBasic Setup
# config/config.exs
import Config
config :your_app,
keplers_api_key: System.get_env("KEPLERS_API_KEY")REST API Integration
Basic Client
# lib/your_app/services/keplers_email_client.ex
defmodule YourApp.Services.KeplersEmailClient do
@base_url "https://api.keplars.com"
defstruct [:api_key, :base_url]
def new(api_key, base_url \\ @base_url) do
%__MODULE__{
api_key: api_key,
base_url: String.trim_trailing(base_url, "/")
}
end
def send_email(client, to, subject, body, is_html \\ false) do
make_request(client, "/api/v1/send-email/queue", %{
to: [to],
subject: subject,
body: body,
is_html: is_html
})
end
def send_instant_email(client, to, subject, body, is_html \\ false) do
make_request(client, "/api/v1/send-email/instant", %{
to: [to],
subject: subject,
body: body,
is_html: is_html
})
end
defp make_request(client, endpoint, payload) do
url = client.base_url <> endpoint
headers = [
{"Authorization", "Bearer #{client.api_key}"},
{"Content-Type", "application/json"}
]
case Jason.encode(payload) do
{:ok, json_payload} ->
case HTTPoison.post(url, json_payload, headers, timeout: 30_000) do
{:ok, %HTTPoison.Response{status_code: 200, body: body}} ->
case Jason.decode(body) do
{:ok, response} -> {:ok, response}
{:error, _} -> {:error, :invalid_json}
end
{:ok, %HTTPoison.Response{status_code: status_code, body: body}} ->
{:error, {:http_error, status_code, body}}
{:error, %HTTPoison.Error{reason: reason}} ->
{:error, {:request_failed, reason}}
end
{:error, _} ->
{:error, :invalid_payload}
end
end
endUsage Examples
# lib/your_app/services/email_service.ex
defmodule YourApp.Services.EmailService do
alias YourApp.Services.KeplersEmailClient
def client do
api_key = Application.get_env(:your_app, :keplers_api_key)
KeplersEmailClient.new(api_key)
end
def send_welcome_email(user_email, user_name) do
html_body = """
<h1>Welcome #{user_name}!</h1>
<p>Thank you for joining our platform.</p>
"""
case KeplersEmailClient.send_email(client(), user_email, "Welcome #{user_name}!", html_body, true) do
{:ok, response} ->
{:ok, response}
{:error, reason} ->
{:error, reason}
end
end
def send_verification_email(user_email, code) do
body = "Your verification code: #{code}"
case KeplersEmailClient.send_instant_email(client(), user_email, "Verify Your Email", body, false) do
{:ok, response} ->
{:ok, response}
{:error, reason} ->
{:error, reason}
end
end
endPhoenix Controller Integration
# lib/your_app_web/controllers/email_controller.ex
defmodule YourAppWeb.EmailController do
use YourAppWeb, :controller
alias YourApp.Services.EmailService
def send_welcome(conn, %{"email" => email, "name" => name}) do
case EmailService.send_welcome_email(email, name) do
{:ok, _response} ->
json(conn, %{success: true, message: "Welcome email sent successfully"})
{:error, reason} ->
conn
|> put_status(:internal_server_error)
|> json(%{success: false, error: "Failed to send email: #{inspect(reason)}"})
end
end
def send_verification(conn, %{"email" => email, "code" => code}) do
case EmailService.send_verification_email(email, code) do
{:ok, _response} ->
json(conn, %{success: true, message: "Verification email sent successfully"})
{:error, reason} ->
conn
|> put_status(:internal_server_error)
|> json(%{success: false, error: "Failed to send verification email: #{inspect(reason)}"})
end
end
endLiveView Integration
# lib/your_app_web/live/email_live.ex
defmodule YourAppWeb.EmailLive do
use YourAppWeb, :live_view
alias YourApp.Services.EmailService
def mount(_params, _session, socket) do
{:ok, assign(socket, email: "", name: "", loading: false, message: nil)}
end
def handle_event("send_email", %{"email" => email, "name" => name}, socket) do
socket = assign(socket, loading: true, message: nil)
case EmailService.send_welcome_email(email, name) do
{:ok, _response} ->
{:noreply, assign(socket, loading: false, message: "Email sent successfully!", email: "", name: "")}
{:error, _reason} ->
{:noreply, assign(socket, loading: false, message: "Failed to send email")}
end
end
def render(assigns) do
~H"""
<div class="max-w-md mx-auto mt-8">
<h1 class="text-2xl font-bold mb-4">Send Email</h1>
<form phx-submit="send_email" class="space-y-4">
<div>
<label for="email" class="block text-sm font-medium">Email</label>
<input type="email" id="email" name="email" value={@email} class="mt-1 block w-full rounded border" required />
</div>
<div>
<label for="name" class="block text-sm font-medium">Name</label>
<input type="text" id="name" name="name" value={@name} class="mt-1 block w-full rounded border" required />
</div>
<button type="submit" disabled={@loading} class="w-full bg-blue-500 text-white py-2 px-4 rounded disabled:opacity-50">
<%= if @loading, do: "Sending...", else: "Send Email" %>
</button>
</form>
<%= if @message do %>
<div class="mt-4 p-4 rounded bg-green-100 text-green-800">
<%= @message %>
</div>
<% end %>
</div>
"""
end
endPhoenix Context Integration
# lib/your_app/accounts.ex
defmodule YourApp.Accounts do
alias YourApp.Services.EmailService
def register_user(attrs) do
with {:ok, user} <- create_user(attrs),
{:ok, _response} <- EmailService.send_welcome_email(user.email, user.name) do
{:ok, user}
else
{:error, reason} -> {:error, reason}
end
end
def send_verification_code(user) do
code = generate_verification_code()
with {:ok, _response} <- EmailService.send_verification_email(user.email, code) do
{:ok, code}
else
{:error, reason} -> {:error, reason}
end
end
defp generate_verification_code do
:rand.uniform(900_000) + 100_000
|> Integer.to_string()
end
defp create_user(_attrs) do
# Your user creation logic here
{:ok, %{email: "[email protected]", name: "John Doe"}}
end
endGenServer Background Worker
# lib/your_app/workers/email_worker.ex
defmodule YourApp.Workers.EmailWorker do
use GenServer
alias YourApp.Services.EmailService
def start_link(opts) do
GenServer.start_link(__MODULE__, opts, name: __MODULE__)
end
def send_welcome_email_async(email, name) do
GenServer.cast(__MODULE__, {:send_welcome, email, name})
end
def init(_opts) do
{:ok, %{}}
end
def handle_cast({:send_welcome, email, name}, state) do
case EmailService.send_welcome_email(email, name) do
{:ok, _response} ->
IO.puts("Welcome email sent to #{email}")
{:error, reason} ->
IO.puts("Failed to send welcome email: #{inspect(reason)}")
end
{:noreply, state}
end
endRouter Configuration
# lib/your_app_web/router.ex
defmodule YourAppWeb.Router do
use YourAppWeb, :router
pipeline :api do
plug :accepts, ["json"]
end
scope "/api", YourAppWeb do
pipe_through :api
post "/emails/welcome", EmailController, :send_welcome
post "/emails/verification", EmailController, :send_verification
end
scope "/", YourAppWeb do
pipe_through :browser
live "/email", EmailLive, :index
end
endPhoenix Elixir provides robust email integration with Keplers Mail Service using HTTPoison for HTTP requests and built-in JSON handling.