defmodule Pigeon do
@moduledoc """
HTTP2-compliant wrapper for sending iOS and Android push notifications.
"""
use Application
require Logger
import Supervisor.Spec
alias Pigeon.{ADM, APNS, FCM}
alias Pigeon.Http2.Client
@doc false
def start(_type, _args) do
Client.default().start()
opts = [strategy: :one_for_one, name: :pigeon]
Supervisor.start_link(workers(), opts)
end
defp workers do
[
adm_workers(),
apns_workers(),
fcm_workers(),
env_workers(),
apns_token_agent(),
task_supervisors()
]
|> List.flatten()
end
defp apns_token_agent do
[worker(APNS.Token, [%{}], restart: :permanent, shutdown: 5_000)]
end
defp task_supervisors do
[supervisor(Task.Supervisor, [[name: Pigeon.Tasks]])]
end
defp env_workers do
case Application.get_env(:pigeon, :workers) do
nil ->
[]
workers ->
Enum.flat_map(workers, fn {mod, fun} ->
mod
|> apply(fun, [])
|> List.wrap()
|> Enum.map(&worker/1)
|> Enum.filter(& &1)
end)
end
end
defp worker(%ADM.Config{} = config) do
worker(ADM.Worker, [config], id: config.name, restart: :temporary)
end
defp worker(config) do
worker(Pigeon.Worker, [config], id: config.name, restart: :temporary)
end
defp adm_workers do
workers_for(:adm, &ADM.Config.new/1, Pigeon.ADM.Worker)
end
defp apns_workers do
workers_for(:apns, &APNS.ConfigParser.parse/1, Pigeon.Worker)
end
defp fcm_workers do
workers_for(:fcm, &FCM.Config.new/1, Pigeon.Worker)
end
defp workers_for(name, config_fn, mod) do
case Application.get_env(:pigeon, name) do
nil ->
[]
workers ->
Enum.map(workers, fn {worker_name, _config} ->
config = config_fn.(worker_name)
worker(mod, [config], id: config.name, restart: :temporary)
end)
end
end
@doc """
Returns the configured JSON encoding library for Pigeon.
To customize the JSON library, include the following in your config/config.exs:
config :pigeon, :json_library, Jason
"""
@spec json_library :: module
def json_library do
Application.get_env(:pigeon, :json_library, Poison)
end
@doc false
def start_connection(state) do
opts = [restart: :temporary, id: :erlang.make_ref()]
spec = worker(Pigeon.Connection, [state], opts)
Supervisor.start_child(:pigeon, spec)
end
def debug_log?, do: Application.get_env(:pigeon, :debug_log, false)
end