Packages

Strategy to send notifications through Pusher with Ravenx.

Current section

Files

Jump to
ravenx_pusher lib strategy pusher_strategy.ex
Raw

lib/strategy/pusher_strategy.ex

defmodule Ravenx.Strategy.Pusher do
@moduledoc """
RavenxPusher is a Strategy to send notifications through Pusher with Ravenx.
"""
@behaviour Ravenx.StrategyBehaviour
import Pusher, only: [trigger: 4, configure!: 5]
alias RavenxPusher.Push
@push_required [:data, :event, :channels]
@required_options [:host, :port, :app_id, :app_key, :secret]
@doc """
`call/2` Accepts a payload and an options map
an returns `{:ok, %Push{}}` if the notification
could be sent, `{:error, {:missing_config, error}}` in case
any required config fields are missing, or `{:error, {:pusher_error, %Push{}}}`
in case there was an error when sending the notification.
"""
@spec call(Ravenx.notif_payload(), Ravenx.notif_options()) ::
{:ok, Push.t()}
| {:error, {:missing_config, any}}
| {:error, {:pusher_error, Push.t()}}
def call(payload, opts \\ %{}) when is_map(payload) and is_map(opts) do
options = parse_options(opts)
%Push{}
|> parse_payload(payload)
|> send_push(options)
end
@spec send_push(payload :: map, options :: map) ::
{:ok, Push.t()}
| {:error, {:missing_config, any}}
| {:error, {:pusher_error, Push.t()}}
defp send_push(payload, opts)
for field <- @required_options do
defp send_push(_push, %{unquote(field) => f}) when f in [nil, ""] do
{:error, {:missing_config, unquote(field)}}
end
end
for field <- @push_required do
defp send_push(%Push{unquote(field) => f}, _opts) when f in [nil, ""] do
{:error, {:missing_field, unquote(field)}}
end
end
defp send_push(%Push{} = push, %{
host: host,
port: port,
app_id: aid,
app_key: akey,
secret: secret
}) do
configure!(host, port, aid, akey, secret)
case trigger(push.event, push.data, push.channels, push.socket_id) do
:ok -> {:ok, %{push | sent?: true}}
:error -> {:error, {:pusher_error, push}}
end
end
defp parse_payload(push, payload) do
push
|> add_to_push(:data, Map.get(payload, :data))
|> add_to_push(:event, Map.get(payload, :event))
|> add_to_push(:channels, get_channels(Map.get(payload, :channels)))
|> add_to_push(:socket_id, Map.get(payload, :socket_id))
end
defp parse_options(opts) do
%{}
|> add_to_options(:host, Map.get(opts, :host))
|> add_to_options(:port, Map.get(opts, :port))
|> add_to_options(:app_id, Map.get(opts, :app_id))
|> add_to_options(:app_key, Map.get(opts, :app_key))
|> add_to_options(:secret, Map.get(opts, :secret))
end
defp add_to_push(push, key, value), do: Map.put(push, key, value)
defp add_to_options(opts, key, value), do: Map.put(opts, key, value)
defp get_channels(nil), do: nil
defp get_channels(channels) when is_list(channels) and length(channels) > 0, do: channels
defp get_channels(channels) when is_binary(channels), do: [channels]
defp get_channels(_channels), do: nil
end