Update response tuple handling for pushes
main{:ok, notif} or {:error, reason, notif} used in earlier versions has been replaced. In v1.1.0+, response information is now contained within a :response key on the notification struct itself.repository·main·Indexed 20 days ago
https://github.com/codedge-llc/pigeonAn Elixir library for sending push notifications to iOS (APNS), Android (FCM), and Amazon Android (ADM). It supports synchronous and asynchronous pushing, dynamic runtime dispatchers, and custom adapter implementation via Pigeon.Adapter. Features include built-in support for Pigeon.APNS, Pigeon.FCM (v1 API), and Pigeon.ADM, with comprehensive handling for service-specific authentication and error responses.
{:ok, notif} or {:error, reason, notif} used in earlier versions has been replaced. In v1.1.0+, response information is now contained within a :response key on the notification struct itself.Pigeon.Dispatcher documentation for implementation details.Pigeon.Adapter.When calling Pigeon.FCM.push/2, you can provide an optional anonymous function as the second argument to handle the response. This is useful for managing device registration lifecycles (e.g., removing invalid IDs) or handling authentication errors.
Common patterns include checking n.status and using helper functions like FCM.Notification.remove?(n) or FCM.Notification.retry?(n) to manage the registration list.
on_response = fn(n) ->
case n.status do
:success ->
bad_regids = FCM.Notification.remove?(n)
to_retry = FCM.Notification.retry?(n)
# Handle updated regids, remove bad ones, etc
:unauthorized ->
# Bad FCM key
error ->
# Some other error
end
end
data = %{message: "your message"}
n = Pigeon.FCM.Notification.new("your device token", data)
Pigeon.FCM.push(n, on_response: on_response)To send a notification, create a %Pigeon.FCM.Notification{} struct using Pigeon.FCM.Notification.new/2 and pass it to Pigeon.FCM.push/1.
Pushes are synchronous and return the notification struct with updated :status and :response keys. If :status is :success, the :response key will contain a keyword list of individual registration ID responses.
# 1. Create a notification packet
msg = %{"body" => "your message"}
n = Pigeon.FCM.Notification.new("your device registration ID", msg)
# 2. Send the packet
Pigeon.FCM.push(n)In Pigeon v2.0, you define a worker module using Pigeon.Dispatcher and supervise it in your application tree. You can pass configuration either via your application's config.exs or directly as arguments to the worker in the supervision tree.
config.exs# lib/your_app/apns.ex
defmodule YourApp.APNS do
use Pigeon.Dispatcher, otp_app: :your_app
endconfig.exs:# config.exs
config :your_app, YourApp.APNS,
adapter: Pigeon.APNS,
cert: File.read!("cert.pem"),
key: File.read!("key_unencrypted.pem"),
mode: :devdefmodule YourApp.Application do
use Application
def start(_type, _args) do
children = [YourApp.APNS]
opts = [strategy: :one_for_one, name: YourApp.Supervisor]
Supervisor.start_link(children, opts)
end
endYou can pass configuration directly when starting the child in the supervision tree:
defmodule YourApp.Application do
use Application
def start(_type, _args) do
children = [{YourApp.APNS, apns_opts()}]
opts = [strategy: :one_for_one, name: YourApp.Supervisor]
Supervisor.start_link(children, opts)
end
defp apns_opts do
[
adapter: Pigeon.APNS,
cert: File.read!("cert.pem"),
key: File.read!("key_unencrypted.pem"),
mode: :dev
]
end
endTo send a notification, first create a notification packet using Pigeon.ADM.Notification.new/2 with the device registration ID and the message payload. Then, pass that packet to Pigeon.ADM.push/1.
msg = %{ "body" => "your message" }
n = Pigeon.ADM.Notification.new("your device registration ID", msg)
Pigeon.ADM.push(n)To use Pigeon in your Elixir project, add it to your mix.exs dependencies. It is recommended to use the ~> 2.0 version constraint for compatibility with the v2 series.
def deps do
[
{:pigeon, "~> 2.0"}
]
endTo send a push notification, create a notification packet using Pigeon.APNS.Notification.new/3 and then pass it to Pigeon.APNS.push/2.
Note: The topic parameter is generally your app's bundle identifier.
Pushes are synchronous by default and return the notification struct with an updated :response key.
n = Pigeon.APNS.Notification.new("your message", "your device token", "your push topic (optional)")
Pigeon.APNS.push(n)In Pigeon v1.1.0 and later, pushes are synchronous by default for all services. If you require asynchronous functionality, you must pass an :on_response callback as an option to the push/2 function.
# Synchronous push (default)
Pigeon.push(notification, options)
# Asynchronous push
Pigeon.push(notification, [on_response: fn response -> ... end])To upgrade from version 1.6 to 2.0, you must update your dependencies and change how push workers are supervised and configured.
Update your mix.exs to use ~> 2.0 and remove the kadadbra dependency.
In v2.0, push workers are no longer started under Pigeon. Instead, you must define a module that uses Pigeon.Dispatcher and add it directly to your application's supervision tree.
Configuration is no longer handled via the :pigeon configuration key. Instead, configure your worker module directly under your application's name.
# mix.exs
[
{:pigeon, "~> 2.0"},
# Remove {:kadadbra, ~> 0.6.0}
]