Need help with pigeon?
Click the “chat” button below for chat support from the developer who created it, or find similar developers for support.

About the developer

codedge-llc
458 Stars 90 Forks MIT License 234 Commits 15 Opened issues

Description

iOS and Android push notifications for Elixir

Services available

!
?

Need anything else?

Contributors list

logo

HTTP2-compliant wrapper for sending iOS and Android push notifications.

Build Status Coverage Status Hex.pm Hex.pm

Installation

Add pigeon and kadabra as

mix.exs
dependencies:
def deps do
  [
    {:pigeon, "~> 1.5.1"},
    {:kadabra, "~> 0.4.4"}
  ]
end

Quickstart Guides

Apple iOS (APNS)

  1. Add a default worker config to your mix config. See the detailed docs for setting up your certificate and key.
   config :pigeon, :apns,
     apns_default: %{
       cert: "cert.pem",
       key: "key_unencrypted.pem",
       mode: :dev
     }

This config sets up a default connection to APNS servers.

cert
and
key
can be any of the following:
  • Static file path
  • Full-text string of the file contents
  • {:my_app, "certs/cert.pem"}
    (indicates path relative to the
    priv
    folder of the given application)

Alternatively, you can use token based authentication:

   config :pigeon, :apns,
     apns_default: %{
       key: "AuthKey.p8",
       key_identifier: "ABC1234567",
       team_id: "DEF8901234",
       mode: :dev
     }
  • :key
    - Created and downloaded via your developer account. Like
    :cert
    this can be a file path, file contents string or tuple
  • :key_identifier
    - The 10-character key identifier associated with
    :key
    , obtained from your developer account
  • :team_id
    - Your 10-character Team ID, obtained from your developer account
  1. Create a notification packet. Note: Your push topic is generally the app's bundle identifier.
   iex> n = Pigeon.APNS.Notification.new("your message", "your device token", "your push topic (optional)")
  1. Send the packet. Pushes are synchronous and return the notification with an updated
    :response
    key.
   iex> Pigeon.APNS.push(n)
   %Pigeon.APNS.Notification{device_token: "your device token",
    expiration: nil, id: "963B9FDA-EA60-E869-AAB5-9C88C8E7396B",
    payload: %{"aps" => %{"alert" => "your message"}}, response: :success,
    topic: "your push topic"}

Add an :on_response callback for async pushes.

iex> Pigeon.APNS.push(n, on_response: fn(x) -> IO.inspect(x) end) :ok

Additional documentation: APNS (Apple iOS)

Android (FCM)

Looking for GCM? Try

v0.13
or earlier.
  1. Add a default worker config to your mix config.
   config :pigeon, :fcm,
     fcm_default: %{
       key: "your_fcm_key_here"
     }
  1. Create a notification packet. FCM notifications support
   iex> msg = %{ "body" => "your message" }
   iex> n = Pigeon.FCM.Notification.new("your device registration ID", msg)
  1. Send the packet. Pushes are synchronous and return the notification with updated
    :status
    and
    :response
    keys. If
    :status
    is success,
    :response
    will contain a keyword list of individual registration ID responses.
   iex> Pigeon.FCM.push(n)
   %Pigeon.FCM.Notification{message_id: "0:1512580747839227%8911a9178911a917",
    payload: %{"notification" => %{"body" => "your message"}}, priority: :normal,
    registration_id: "your device registration ID",
    response: [success: "your device registration ID"],
    status: :success}

Add an :on_response callback for async pushes.

iex> Pigeon.FCM.push(n, on_response: fn(x) -> IO.inspect(x) end) :ok

Additional documentation: FCM (Android)

Amazon Android (ADM)

  1. Add a default worker config to your mix config.
   config :pigeon, :adm,
     adm_default: %{
       client_id: "your_oauth2_client_id_here",
       client_secret: "your_oauth2_client_secret_here"
     }
  1. Create a notification packet.
   iex> msg = %{ "body" => "your message" }
   iex> n = Pigeon.ADM.Notification.new("your device registration ID", msg)
  1. Send the packet.
   iex> Pigeon.ADM.push(n)
   %Pigeon.ADM.Notification{consolidation_key: nil,
    expires_after: 604800, md5: "M13RuG4uDWqajseQcCiyiw==",
    payload: %{"data" => %{"body" => "your message"}},
    registration_id: "your device registration ID",
    response: :success, updated_registration_id: nil}

Add an :on_response callback for async pushes.

iex> Pigeon.ADM.push(n, on_response: fn(x) -> IO.inspect(x) end) :ok

Additional documentation: ADM (Amazon Android)

Startup Configuration of Push Workers

Workers may be specified at application startup by creating a module containing functions that return zero or more configuration structures appropriate to the push service being enabled.

Specify these in your

config.exs
as:
config :pigeon, workers: [
  {YourApp.Pigeon, :apns_config},
  {YourApp.Pigeon, :fcm_config},
  {YourApp.Pigeon, :adm_config}
]

These should be implemented as:

defmodule YourApp.Pigeon do
  @moduledoc false

@push_mode if(Mix.env() == :production, do: :prod, else: :dev)

def apns_config do Pigeon.APNS.ConfigParser.parse( key: System.get_env("APNS_KEY"), key_identifier: System.get_env("APNS_KEY_ID"), team_id: System.get_env("APNS_TEAM_ID"), mode: @push_mode, name: :apns_default ) end

def fcm_config do Pigeon.FCM.Config.new(name: :fcm_default, key: System.get_env("FCM_SERVER_KEY")) end end

If your startup configuration requires reading your configuration from a database or using another dependency that needs a database, startup is a little more complex.

  1. Modify your
    mix.exs
    to not start
    pigeon
    by default:
   def deps do
     [
       {:pigeon, "~> 1.3.1", runtime: false},
       {:kadabra, "~> 0.4.4"},
       {:ecto, "~> 2.0 or ~> 3.0"}
     ]
   end
  1. Modify
    config.exs
    to specify a single worker function:
   config :pigeon, workers: [{YourApp.Pigeon, :config}]
  1. Modify your main application to start
    pigeon
    after your
    Repo
    has been started under your application’s supervision tree:
   def start(_type, _args) do
     children = [
       YourApp.Repo,
     ]

 opts = [strategy: :one_for_one, name: YourApp.Supervisor]

 with {:ok, sup} 
  1. Implement your database query as part of your Pigeon module:
   defmodule YourApp.Pigeon do
     @moduledoc false

 alias YourApp.{PushApplication, Repo}

 def config_workers do
   PushApplication
   |> Repo.all()
   |> Enum.map(&build_config/1)
 end

 defp build_config(%{type: "apns"} = config)
   Pigeon.APNS.ConfigParser.parse(
     key: config.key,
     key_identifier: config.key_identifier,
     team_id: config.team_id,
     mode: config.mode,
     name: Atom.to_string(config.name) # This is bad, but keep it simple!
   )
 end

 defp build_config(%{type: "fcm"} = config) do
   Pigeon.FCM.Config.new(
     name: Atom.to_string(config.name),
     key: config.key
   )
 end

end

We use cookies. If you continue to browse the site, you agree to the use of cookies. For more information on our use of cookies please see our Privacy Policy.