From 594a0acb2716cfe34c9243e9b5515309232edd73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20S=C5=82ota?= Date: Mon, 24 Jun 2019 14:49:04 +0200 Subject: [PATCH] Add Pushy (pushy.me) support --- config/prod.exs | 17 +++++++++++++-- lib/mongoose_push/api.ex | 3 +++ lib/mongoose_push/api/v1.ex | 2 +- lib/mongoose_push/api/v2.ex | 2 +- lib/mongoose_push/application.ex | 5 +++-- lib/mongoose_push/pools.ex | 6 ++++++ lib/mongoose_push/service/fcm.ex | 2 ++ lib/mongoose_push/service/pushy.ex | 34 ++++++++++++++++++++++++++++++ mix.exs | 4 ++-- mix.lock | 4 ++-- 10 files changed, 69 insertions(+), 10 deletions(-) create mode 100644 lib/mongoose_push/service/pushy.ex diff --git a/config/prod.exs b/config/prod.exs index c90efaf4..d192f205 100644 --- a/config/prod.exs +++ b/config/prod.exs @@ -17,11 +17,15 @@ config :maru, MongoosePush.Router, config :mongoose_push, loglevel: {:system, :atom, "PUSH_LOGLEVEL", :info} + +config :mongoose_push, pushy_enabled: + {:system, :boolean, "PUSH_PUSHY_ENABLED", false} + config :mongoose_push, fcm_enabled: - {:system, :boolean, "PUSH_FCM_ENABLED", true} + {:system, :boolean, "PUSH_FCM_ENABLED", false} config :mongoose_push, apns_enabled: - {:system, :boolean, "PUSH_APNS_ENABLED", true} + {:system, :boolean, "PUSH_APNS_ENABLED", false} config :mongoose_push, fcm: [ default: [ @@ -32,6 +36,15 @@ config :mongoose_push, fcm: [ ] ] +config :mongoose_push, pushy: [ + default: [ + endpoint: {:system, :string, "PUSH_PUSHY_ENDPOINT", nil}, + key: {:system, :string, "PUSH_PUSHY_APP_KEY", "fake_app_key"}, + pool_size: {:system, :integer, "PUSH_PUSHY_POOL_SIZE", 100}, + mode: :prod, + ] +] + config :mongoose_push, apns: [ dev: [ endpoint: {:system, :string, "PUSH_APNS_DEV_ENDPOINT", nil}, diff --git a/lib/mongoose_push/api.ex b/lib/mongoose_push/api.ex index d713203e..7cc9b7a6 100644 --- a/lib/mongoose_push/api.ex +++ b/lib/mongoose_push/api.ex @@ -16,6 +16,9 @@ defmodule MongoosePush.API do {500, %{:details => reason}} end end + def to_status({:error, reason}) when is_binary(reason) do + {400, reason} + end def to_status({:error, _reason}) do {500, nil} end diff --git a/lib/mongoose_push/api/v1.ex b/lib/mongoose_push/api/v1.ex index bbbdad40..95b9c0e9 100644 --- a/lib/mongoose_push/api/v1.ex +++ b/lib/mongoose_push/api/v1.ex @@ -10,7 +10,7 @@ defmodule MongoosePush.API.V1 do parsers: [:urlencoded, :json, :multipart] params do - requires :service, type: Atom, values: [:fcm, :apns] + requires :service, type: Atom, values: [:fcm, :apns, :pushy] requires :body, type: String requires :title, type: String optional :badge, type: Integer diff --git a/lib/mongoose_push/api/v2.ex b/lib/mongoose_push/api/v2.ex index bd1f8c25..418a1625 100644 --- a/lib/mongoose_push/api/v2.ex +++ b/lib/mongoose_push/api/v2.ex @@ -10,7 +10,7 @@ defmodule MongoosePush.API.V2 do parsers: [:urlencoded, :json, :multipart] params do - requires :service, type: Atom, values: [:fcm, :apns] + requires :service, type: Atom, values: [:fcm, :apns, :pushy] optional :mode, type: Atom, values: [:prod, :dev] optional :priority, type: Atom, values: [:normal, :high] optional :time_to_live, type: Integer diff --git a/lib/mongoose_push/application.ex b/lib/mongoose_push/application.ex index b6eeef55..93077bf0 100644 --- a/lib/mongoose_push/application.ex +++ b/lib/mongoose_push/application.ex @@ -43,7 +43,8 @@ defmodule MongoosePush.Application do def services do [ fcm: MongoosePush.Service.FCM, - apns: MongoosePush.Service.APNS + apns: MongoosePush.Service.APNS, + pushy: MongoosePush.Service.Pushy ] end @@ -68,7 +69,7 @@ defmodule MongoosePush.Application do case service do :apns -> [:cert, :key] - :fcm -> + _ -> [] end config diff --git a/lib/mongoose_push/pools.ex b/lib/mongoose_push/pools.ex index c41d37cc..b1a1b347 100644 --- a/lib/mongoose_push/pools.ex +++ b/lib/mongoose_push/pools.ex @@ -24,6 +24,12 @@ defmodule MongoosePush.Pools do Enum.map(config, &(elem(&1, 0))) end + @spec pools_by_mode(MongoosePush.service, MongoosePush.mode) :: list(atom) + def pools_by_mode(:pushy = service, _mode) do + config = pools_config(service) + Enum.map(config, &(elem(&1, 0))) + end + def pools_by_mode(:apns = service, mode) do config = pools_config(service) diff --git a/lib/mongoose_push/service/fcm.ex b/lib/mongoose_push/service/fcm.ex index bec9b7f5..0e9f58c5 100644 --- a/lib/mongoose_push/service/fcm.ex +++ b/lib/mongoose_push/service/fcm.ex @@ -26,6 +26,8 @@ defmodule MongoosePush.Service.FCM do |> Enum.reduce(%{}, fn(field, map) -> Map.put(map, field, alert[field]) end) + |> Enum.filter(fn({_, value}) -> value != nil end) + |> Map.new() Notification.new(device_id, msg, request[:data]) |> Notification.put_priority(@priority_mapping[request[:priority]]) diff --git a/lib/mongoose_push/service/pushy.ex b/lib/mongoose_push/service/pushy.ex new file mode 100644 index 00000000..b1bed414 --- /dev/null +++ b/lib/mongoose_push/service/pushy.ex @@ -0,0 +1,34 @@ +defmodule MongoosePush.Service.Pushy do + @moduledoc """ + Pushy service provider implementation. + """ + + @behaviour MongoosePush.Service + alias MongoosePush.Pools + require Logger + + @spec prepare_notification(String.t(), MongoosePush.request) :: + Service.notification + def prepare_notification(device_id, request) do + MongoosePush.Service.FCM.prepare_notification(device_id, request) + end + + @spec push(Service.notification(), String.t(), atom(), Service.options()) :: + :ok | {:error, term} + def push(notification, device_id, worker, opts \\ []) do + MongoosePush.Service.FCM.push(notification, device_id, worker, opts) + end + + @spec workers({atom, Keyword.t()} | nil) :: list(Supervisor.Spec.spec()) + def workers(nil), do: [] + def workers({pool_name, pool_config}) do + Logger.info ~s"Starting Pushy pool with API key #{pool_config[:key]}" + pool_size = pool_config[:pool_size] + Enum.map(1..pool_size, fn(id) -> + worker_name = Pools.worker_name(:pushy, pool_name, id) + Supervisor.Spec.worker(Pigeon.PushyWorker, + [worker_name, pool_config], [id: worker_name]) + end) + end + +end diff --git a/mix.exs b/mix.exs index cc1e19ea..e1ec974b 100644 --- a/mix.exs +++ b/mix.exs @@ -25,7 +25,7 @@ defmodule MongoosePush.Mixfile do defp deps do [ - {:pigeon, github: "rslota/pigeon", ref: "2860eee35b58e2d8674f805f1151f57b9faeca21"}, + {:pigeon, github: "rslota/pigeon", ref: "fa7fa5e"}, {:chatterbox, github: "joedevivo/chatterbox", ref: "ff0c2e0", override: true}, {:maru, github: "rslota/maru", ref: "54fc038", override: true}, @@ -51,7 +51,7 @@ defmodule MongoosePush.Mixfile do # Until eproxus/meck #fcc551e3 is in a release, we need to use master version # to include this commit (fixes mocking in Erlang 20.x + Elixir 1.5.x) {:meck, github: "eproxus/meck", override: true}, - {:httpoison, "~> 0.13"}, + {:httpoison, "~> 1.4"}, {:excoveralls, "~> 0.7", only: :test}, {:dialyxir, "~> 0.4", only: [:dev, :test], runtime: false}, {:credo, "~> 0.5", only: [:dev, :test]}, diff --git a/mix.lock b/mix.lock index 36043dcd..c1da0fda 100644 --- a/mix.lock +++ b/mix.lock @@ -21,7 +21,7 @@ "goldrush": {:hex, :goldrush, "0.1.9", "f06e5d5f1277da5c413e84d5a2924174182fb108dabb39d5ec548b27424cd106", [:rebar3], [], "hexpm"}, "hackney": {:hex, :hackney, "1.11.0", "4951ee019df102492dabba66a09e305f61919a8a183a7860236c0fde586134b6", [:rebar3], [{:certifi, "2.0.0", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "5.1.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "1.0.1", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "1.0.2", [hex: :mimerl, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "1.1.1", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm"}, "hpack": {:git, "https://github.com/joedevivo/hpack.git", "6b58b6231e9b6ab83096715120578976f72f4f7c", [tag: "0.2.3"]}, - "httpoison": {:hex, :httpoison, "0.13.0", "bfaf44d9f133a6599886720f3937a7699466d23bb0cd7a88b6ba011f53c6f562", [:mix], [{:hackney, "~> 1.8", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm"}, + "httpoison": {:hex, :httpoison, "1.5.1", "0f55b5b673b03c5c327dac7015a67cb571b99b631acc0bc1b0b98dcd6b9f2104", [:mix], [{:hackney, "~> 1.8", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm"}, "hut": {:hex, :hut, "1.2.0", "0089df0faa2827c605bbada88153f24fff5ea7a4be32ecf0250a7fdc2719cafb", [:"erlang.mk", :rebar, :rebar3], [], "hexpm"}, "idna": {:hex, :idna, "5.1.0", "d72b4effeb324ad5da3cab1767cb16b17939004e789d8c0ad5b70f3cea20c89a", [:rebar3], [{:unicode_util_compat, "0.3.1", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm"}, "jason": {:hex, :jason, "1.0.0", "0f7cfa9bdb23fed721ec05419bcee2b2c21a77e926bce0deda029b5adc716fe2", [:mix], [{:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm"}, @@ -37,7 +37,7 @@ "mix_docker": {:hex, :mix_docker, "0.5.0", "c7ad34008c43d4a949d69721f39c4d2a2afc509c179926a683117ea8dff8af59", [:mix], [{:distillery, "~> 1.2", [hex: :distillery, repo: "hexpm", optional: false]}], "hexpm"}, "mock": {:hex, :mock, "0.3.1", "994f00150f79a0ea50dc9d86134cd9ebd0d177ad60bd04d1e46336cdfdb98ff9", [:mix], [{:meck, "~> 0.8.8", [hex: :meck, repo: "hexpm", optional: false]}], "hexpm"}, "parse_trans": {:hex, :parse_trans, "3.1.0", "1bad3b959941cc53ffd6f4769a5d2666f9cdf179b2d62826636497d3fbad9ec0", [:rebar3], [], "hexpm"}, - "pigeon": {:git, "https://github.com/rslota/pigeon.git", "2860eee35b58e2d8674f805f1151f57b9faeca21", [ref: "2860eee35b58e2d8674f805f1151f57b9faeca21"]}, + "pigeon": {:git, "https://github.com/rslota/pigeon.git", "fa7fa5e8686477c1ce19a7592bf4f13d994bc0f2", [ref: "fa7fa5e"]}, "plug": {:hex, :plug, "1.5.0", "224b25b4039bedc1eac149fb52ed456770b9678bbf0349cdd810460e1e09195b", [:mix], [{:cowboy, "~> 1.0.1 or ~> 1.1 or ~> 2.1", [hex: :cowboy, repo: "hexpm", optional: true]}, {:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}], "hexpm"}, "pobox": {:hex, :pobox, "1.0.4", "e695bc3b2b547dd6c8e5a19cb743396e6670e306ad3ff498844738f9418bd686", [:rebar3], [], "hexpm"}, "poison": {:hex, :poison, "3.1.0", "d9eb636610e096f86f25d9a46f35a9facac35609a7591b3be3326e99a0484665", [:mix], [], "hexpm"},