Current section

57 Versions

Jump to

Compare versions

6 files changed
+50 additions
-30 deletions
  @@ -5,12 +5,15 @@
5 5 HTTP2-compliant wrapper for sending iOS and Android push notifications.
6 6
7 7 ## Installation
8 - Add pigeon as a `mix.exs` dependency:
9 -
10 8 **Note: Pigeon's API will likely change until v1.0**
9 +
10 + Add pigeon and chatterbox as `mix.exs` dependencies:
11 11 ```elixir
12 12 def deps do
13 - [{:pigeon, "~> 0.8.0"}]
13 + [
14 + {:pigeon, "~> 0.8.0"},
15 + {:chatterbox, github: "joedevivo/chatterbox"}
16 + ]
14 17 end
15 18 ```
16 19
  @@ -91,7 +94,7 @@ or
91 94
92 95 2. Create a notification packet. **Note: Your push topic is generally the app's bundle identifier.**
93 96 ```elixir
94 - n = Pigeon.APNS.Notification.new("your message", "your device token", "your push topic")
97 + n = Pigeon.APNS.Notification.new("your message", "your device token", "your push topic (optional)")
95 98 ```
96 99
97 100
  @@ -104,6 +107,7 @@ or
104 107 The contents of `payload` is what will be received on the iOS device. If updating this field directly, use strings for your keys. It is recommended to use the convenience functions defined in *Notifications with Custom Data*. `expiration` is a UNIX epoch date in seconds (UTC). Passing a value of `0` expires the notification immediately and Apple will not attempt to redeliver it.
105 108 ```elixir
106 109 %Pigeon.APNS.Notification{
110 + id: nil,
107 111 device_token: nil,
108 112 topic: nil,
109 113 expiration: nil,
  @@ -141,6 +145,7 @@ Notifications can contain additional information in `payload`. (e.g. setting bad
141 145 |> put_badge(5)
142 146 |> put_sound("default")
143 147 |> put_content_available
148 + |> put_mutable_content
144 149 |> put_category("category")
145 150 ```
  @@ -21,4 +21,4 @@
21 21 {<<"name">>,<<"httpoison">>},
22 22 {<<"optional">>,false},
23 23 {<<"requirement">>,<<"~> 0.7">>}]]}.
24 - {<<"version">>,<<"0.8.0">>}.
24 + {<<"version">>,<<"0.9.0">>}.
  @@ -95,9 +95,9 @@ defmodule Pigeon.APNSWorker do
95 95 req_headers = [
96 96 {":method", "POST"},
97 97 {":path", "/3/device/#{notification.device_token}"},
98 - {"apns-topic", notification.topic},
99 98 {"content-length", "#{byte_size(json)}"}]
100 99 |> put_apns_id(notification)
100 + |> put_apns_topic(notification)
101 101
102 102 :h2_client.send_request(socket, req_headers, json)
103 103 new_q = Map.put(queue, "#{stream_id}", {notification, on_response})
  @@ -112,9 +112,16 @@ defmodule Pigeon.APNSWorker do
112 112 end
113 113 end
114 114
115 + defp put_apns_topic(headers, notification) do
116 + case notification.topic do
117 + nil -> headers
118 + topic -> headers ++ [{"apns-topic", topic}]
119 + end
120 + end
121 +
115 122 defp parse_error(data) do
116 123 {:ok, response} = Poison.decode(data)
117 - response["reason"] |> Mix.Utils.underscore |> String.to_atom
124 + response["reason"] |> Macro.underscore |> String.to_existing_atom
118 125 end
119 126
120 127 defp log_error(reason, notification) do
  @@ -18,37 +18,43 @@ defmodule Pigeon.GCM do
18 18 @spec push(Pigeon.GCM.Notification) :: none
19 19 def push(notification) do
20 20 gcm_key = Application.get_env(:pigeon, :gcm_key)
21 - requests =
22 - notification.registration_id
23 - |> chunk_registration_ids
24 - |> encode_requests(notification.payload)
25 -
26 - response = fn({_reg_ids, payload}) ->
27 - HTTPoison.post(gcm_uri, payload, gcm_headers(gcm_key))
28 - end
29 -
30 - for r <- requests, do: Task.async(fn -> response.(r) end)
31 - :ok
21 + do_push(notification, %{gcm_key: gcm_key})
32 22 end
33 23
34 24 @doc """
35 25 Sends a push over GCM and executes function on success/failure.
36 26 """
37 27 @spec push(Pigeon.GCM.Notification, (() -> none)) :: none
38 - def push(notification, on_response) do
28 + def push(notification, on_response) when is_function(on_response) do
39 29 gcm_key = Application.get_env(:pigeon, :gcm_key)
30 + do_push(notification, %{gcm_key: gcm_key}, on_response)
31 + end
32 +
33 + def push(notification, config, on_response \\ nil) do
34 + do_push(notification, config, on_response)
35 + end
36 +
37 + defp do_push(notification, %{gcm_key: gcm_key}, on_response \\ nil) do
40 38 requests =
41 39 notification.registration_id
42 40 |> chunk_registration_ids
43 41 |> encode_requests(notification.payload)
44 42
45 - response = fn({reg_ids, payload}) ->
46 - {:ok, %HTTPoison.Response{status_code: status, body: body}} =
47 - HTTPoison.post(gcm_uri, payload, gcm_headers(gcm_key))
43 + response =
44 + case on_response do
45 + nil ->
46 + fn({_reg_ids, payload}) ->
47 + HTTPoison.post(gcm_uri, payload, gcm_headers(gcm_key))
48 + end
49 + _ ->
50 + fn({reg_ids, payload}) ->
51 + {:ok, %HTTPoison.Response{status_code: status, body: body}} =
52 + HTTPoison.post(gcm_uri, payload, gcm_headers(gcm_key))
48 53
49 - notification = %{ notification | registration_id: reg_ids }
50 - process_response(status, body, notification, on_response)
51 - end
54 + notification = %{ notification | registration_id: reg_ids }
55 + process_response(status, body, notification, on_response)
56 + end
57 + end
52 58 for r <- requests, do: Task.async(fn -> response.(r) end)
53 59 :ok
54 60 end
  @@ -125,7 +131,7 @@ defmodule Pigeon.GCM do
125 131 if is_nil(error) do
126 132 parse_success(result)
127 133 else
128 - error_atom = error |> Mix.Utils.underscore |> String.to_atom
134 + error_atom = error |> Macro.underscore |> String.to_existing_atom
129 135 {:error, error_atom}
130 136 end
131 137 end
  @@ -21,7 +21,7 @@ defmodule Pigeon.APNS.Notification do
21 21 """
22 22 defstruct device_token: nil, payload: %{"aps" => %{}}, expiration: nil, topic: nil, id: nil
23 23
24 - def new(msg, token, topic) do
24 + def new(msg, token, topic \\ nil) do
25 25 %Pigeon.APNS.Notification{
26 26 device_token: token,
27 27 topic: topic,
  @@ -48,6 +48,8 @@ defmodule Pigeon.APNS.Notification do
48 48
49 49 def put_category(notification, category), do: update_payload(notification, "category", category)
50 50
51 + def put_mutable_content(notification), do: update_payload(notification, "mutable-content", 1)
52 +
51 53 defp update_payload(notification, key, value) do
52 54 new_aps =
53 55 notification.payload
Loading more files…