Packages
pigeon
2.0.0-rc.0
2.0.1
2.0.0
2.0.0-rc.3
2.0.0-rc.2
2.0.0-rc.1
2.0.0-rc.0
1.6.3
1.6.2
1.6.1
1.6.0
1.5.1
1.5.0
1.4.0
1.3.2
1.3.1
1.3.0
1.2.4
1.2.3
1.2.2
1.2.1
1.2.0
1.1.6
1.1.5
1.1.4
1.1.3
1.1.2
1.1.1
1.1.0
1.1.0-rc.1
1.1.0-rc.0
1.0.4
1.0.3
1.0.2
1.0.1
1.0.0
0.13.1
0.13.0
0.12.1
0.12.0
0.11.0
0.10.3
0.10.2
0.10.1
0.10.0
0.9.1
0.9.0
0.8.0
0.7.0
0.6.0
0.5.2
0.5.1
0.5.0
0.4.1
0.4.0
0.3.0
0.2.0
0.1.0
iOS (APNS), Android (FCM), and Amazon Android (ADM) push notifications for Elixir.
Current section
Files
Jump to
Current section
Files
lib/pigeon/apns/notification.ex
defmodule Pigeon.APNS.Notification do
@moduledoc ~S"""
Defines APNS notification struct and constructor functions.
"""
defstruct __meta__: %Pigeon.Metadata{},
collapse_id: nil,
device_token: nil,
expiration: nil,
id: nil,
payload: %{"aps" => %{}},
priority: nil,
push_type: "alert",
topic: nil,
response: nil
@typedoc ~S"""
APNS notification
## Examples
%Pigeon.APNS.Notification{
__meta__: %Pigeon.Metadata{on_response: nil},
collapse_id: nil,
device_token: "device token",
expiration: nil,
id: nil, # Set on push response if nil
payload: %{"aps" => %{"alert" => "push message"}},
priority: nil,
push_type: "alert",
response: nil, # Set on push response
topic: "com.example.YourApp"
}
"""
@type t :: %__MODULE__{
__meta__: Pigeon.Metadata.t(),
collapse_id: String.t() | nil,
device_token: String.t() | nil,
expiration: non_neg_integer | nil,
id: String.t() | nil,
payload: %{String.t() => term},
priority: non_neg_integer | nil,
push_type: String.t() | nil,
response: response,
topic: String.t() | nil
}
@typedoc ~S"""
APNS push response
- nil - Push has not been sent yet.
- `:success` - Push was successfully sent.
- `t:Pigeon.APNS.Error.error_response/0` - Push attempted but
server responded with error.
- `:timeout` - Internal error. Push did not reach APNS servers.
"""
@type response :: nil | :success | error_response | :timeout
@type error_response ::
:bad_collapse_id
| :bad_device_token
| :bad_expiration_date
| :bad_message_id
| :bad_priority
| :bad_topic
| :device_token_not_for_topic
| :duplicate_headers
| :idle_timeout
| :invalid_push_type
| :missing_device_token
| :missing_topic
| :payload_empty
| :topic_disallowed
| :bad_certificate
| :bad_certificate_environment
| :expired_provider_token
| :forbidden
| :invalid_provider_token
| :missing_provider_token
| :bad_path
| :method_not_allowed
| :unregistered
| :payload_too_large
| :too_many_provider_token_updates
| :too_many_requests
| :internal_server_error
| :service_unavailable
| :shutdown
| :unknown_error
@doc """
Returns an `APNS.Notification` struct with given message, device token, and
topic (optional).
Push payload is constructed in the form of `%{"aps" => %{"alert" => msg}}`
## Examples
iex> Pigeon.APNS.Notification.new("push message", "device token")
%Pigeon.APNS.Notification{
__meta__: %Pigeon.Metadata{},
device_token: "device token",
expiration: nil,
priority: nil,
push_type: "alert",
id: nil,
payload: %{"aps" => %{"alert" => "push message"}},
topic: nil
}
"""
@spec new(String.t() | map, String.t(), String.t() | nil) :: t
def new(msg, token, topic \\ nil) do
%__MODULE__{
device_token: token,
payload: %{"aps" => %{"alert" => msg}},
topic: topic
}
end
@doc """
Returns an `APNS.Notification` struct with given message, device token,
topic, and message ID.
Push payload is constructed in the form of `%{"aps" => %{"alert" => msg}}`
## Examples
iex> Pigeon.APNS.Notification.new("push message", "device token", "topic", "id_1234")
%Pigeon.APNS.Notification{
collapse_id: nil,
device_token: "device token",
expiration: nil,
priority: nil,
push_type: "alert",
id: "id_1234",
payload: %{"aps" => %{"alert" => "push message"}},
topic: "topic"
}
"""
@spec new(String.t() | map, String.t(), String.t(), String.t()) :: t
def new(msg, token, topic, id) do
%__MODULE__{
device_token: token,
id: id,
payload: %{"aps" => %{"alert" => msg}},
topic: topic
}
end
@doc """
Updates `"alert"` key in push payload.
This is the alert message displayed on the device.
## Examples
iex> Pigeon.APNS.Notification.put_alert(%Pigeon.APNS.Notification{}, "push message")
%Pigeon.APNS.Notification{
payload: %{"aps" => %{"alert" => "push message"}}
}
"""
@spec put_alert(t, String.t() | map) :: t
def put_alert(notification, alert),
do: update_payload(notification, "alert", alert)
@doc """
Updates `"badge"` key in push payload.
This is the badge number displayed on the application.
## Examples
iex> Pigeon.APNS.Notification.put_badge(%Pigeon.APNS.Notification{}, 5)
%Pigeon.APNS.Notification{
payload: %{"aps" => %{"badge" => 5}}
}
"""
@spec put_badge(t, integer) :: t
def put_badge(notification, badge),
do: update_payload(notification, "badge", badge)
@doc """
Updates `"category"` key in push payload.
## Examples
iex> Pigeon.APNS.Notification.put_category(%Pigeon.APNS.Notification{}, "category")
%Pigeon.APNS.Notification{
payload: %{"aps" => %{"category" => "category"}}
}
"""
@spec put_category(t, String.t()) :: t
def put_category(notification, category),
do: update_payload(notification, "category", category)
@doc """
Sets `"content-available"` flag in push payload.
Used for silent notifications. When set, ensure `alert`, `badge`, and `sound` keys
are not configured.
## Examples
iex> Pigeon.APNS.Notification.put_content_available(%Pigeon.APNS.Notification{})
%Pigeon.APNS.Notification{
payload: %{"aps" => %{"content-available" => 1}}
}
"""
@spec put_content_available(t) :: t
def put_content_available(notification),
do: update_payload(notification, "content-available", 1)
@doc """
Puts custom data in push payload.
## Examples
iex> n = Pigeon.APNS.Notification.new("test message", "device token")
iex> Pigeon.APNS.Notification.put_custom(n, %{"custom-key" => 1234})
%Pigeon.APNS.Notification{
device_token: "device token",
payload: %{"aps" => %{"alert" => "test message"}, "custom-key" => 1234}
}
"""
@spec put_custom(t, %{String.t() => term}) :: t
def put_custom(notification, data) do
new_payload = Map.merge(notification.payload, data)
%{notification | payload: new_payload}
end
@doc """
Sets `"mutable-content"` flag in push payload.
Used for notification service extensions (such as displaying custom media).
## Examples
iex> Pigeon.APNS.Notification.put_mutable_content(%Pigeon.APNS.Notification{})
%Pigeon.APNS.Notification{
payload: %{"aps" => %{"mutable-content" => 1}}
}
"""
@spec put_mutable_content(t) :: t
def put_mutable_content(notification),
do: update_payload(notification, "mutable-content", 1)
@doc """
Updates `"sound"` key in push payload.
Used for custom notification sounds. Value should
be the name of the custom sound file in the application's binary.
## Examples
iex> Pigeon.APNS.Notification.put_sound(%Pigeon.APNS.Notification{}, "custom.aiff")
%Pigeon.APNS.Notification{
payload: %{"aps" => %{"sound" => "custom.aiff"}}
}
iex> Pigeon.APNS.Notification.put_sound(%Pigeon.APNS.Notification{}, %{
...> "critical" => 1,
...> "sound" => "default",
...> "volume" => 1.0
...> })
%Pigeon.APNS.Notification{
payload: %{
"aps" => %{
"sound" => %{
"critical" => 1,
"sound" => "default",
"volume" => 1.0
}
}
}
}
"""
@spec put_sound(t, String.t() | %{String.t() => term}) :: t
def put_sound(notification, sound),
do: update_payload(notification, "sound", sound)
@doc """
Updates `"target-content-id"` key in push payload.
Used for bringing a specific window forward.
## Examples
iex> Pigeon.APNS.Notification.put_target_content_id(%Pigeon.APNS.Notification{}, "example")
%Pigeon.APNS.Notification{
payload: %{"aps" => %{"target-content-id" => "example"}}
}
"""
@spec put_target_content_id(t, String.t()) :: t
def put_target_content_id(notification, id),
do: update_payload(notification, "target-content-id", id)
@doc """
Updates `"thread-id"` key in push payload.
Used for grouping related notifications.
## Examples
iex> Pigeon.APNS.Notification.put_thread_id(%Pigeon.APNS.Notification{}, "example")
%Pigeon.APNS.Notification{
payload: %{"aps" => %{"thread-id" => "example"}}
}
"""
@spec put_thread_id(t, String.t()) :: t
def put_thread_id(notification, id),
do: update_payload(notification, "thread-id", id)
defp update_payload(notification, key, value) do
new_aps =
notification.payload
|> Map.get("aps")
|> Map.put(key, value)
new_payload = Map.put(notification.payload, "aps", new_aps)
%{notification | payload: new_payload}
end
end