diff --git a/.gitignore b/.gitignore index d867ce5..677c0c1 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,6 @@ +/.idea/ +exfcm.iml + # The directory Mix will write compiled artifacts to. /_build @@ -58,4 +61,4 @@ flycheck_*.el /server/ # projectiles files -.projectile \ No newline at end of file +.projectile diff --git a/lib/exfcm/message.ex b/lib/exfcm/message.ex index 77d0afe..ed18b37 100644 --- a/lib/exfcm/message.ex +++ b/lib/exfcm/message.ex @@ -23,10 +23,13 @@ defmodule ExFCM.Message do defstruct to: "", notification: nil, data: nil @url Application.get_env(:exfcm, :fcm_url, "") + + @fcm_endpoint "https://fcm.googleapis.com/v1" + @messaging_scope "https://www.googleapis.com/auth/firebase.messaging" @server_key Application.get_env(:exfcm, :server_key, "") defmodule Notification do - defstruct title: nil, body: nil + defstruct title: nil, body: nil, sound: nil end @doc """ @@ -38,6 +41,15 @@ defmodule ExFCM.Message do %__MODULE__{message | notification: notification} end + @doc """ + Puts a Audible Notification inside message. It will be displayed in tray when app is in background. + """ + + def put_audible_notification(message \\ %__MODULE__{}, title, data, sound) do + notification = %Notification{ title: title, body: data, sound: sound} + %__MODULE__{message | notification: notification} + end + @doc """ Puts a data fieldd into sending json, if it's present the `onMessageReceived` callback will be called on client. """ @@ -67,8 +79,32 @@ defmodule ExFCM.Message do @doc """ Sends synchronous message. """ - def send(message) do + case :persistent_term.get(:exfcm_send_mode, :pending) do + :pending -> + case Application.get_env(:exfcm, :send_mode, :new) do + :new -> + :persistent_term.put(:exfcm_send_mode, :new) + send_new(message) + _ -> + :persistent_term.put(:exfcm_send_mode, :old) + send_old(message) + end + :new -> + send_new(message) + |> case do + x = {:ok, %{status_code: 200}} -> x + {:ok, x} -> + Logger.warning("FCM Error: #{inspect x, pretty: true}") + {:ok, x} + x -> x + end + _ -> + send_old(message) + end + end + + def send_old(message) do as_json = Poison.encode!(message) Logger.debug as_json HTTPoison.post(@url, @@ -77,4 +113,52 @@ defmodule ExFCM.Message do {"Content-Type", "application/json"}]) end + + def send_new(message) do + with {:ok, project} <- Goth.Config.get(:project_id), + {:ok, goth_token} <- Goth.Token.for_scope({:default, @messaging_scope}) do + + body = %{ + message: %{ + notification: %{ + title: message.notification.title, + body: message.notification.body, + }, + } + } + body = if String.starts_with?(message.to, "/topics/") do + body + |> put_in([:message, :topic], String.slice(message.to, 8..-1)) + else + body + |> put_in([:message, :token], message.to) + end + body = if (message.data) do + data = Enum.map(message.data, + fn + {k,v} when is_map(v) or is_list(v) or is_atom(v) or is_boolean(v) -> {k, Poison.encode!(v)} + {k,v} -> {k,v} + end + ) |> Map.new() + put_in(body, [:message, :data], data) + else + body + end + body = if (message.notification.sound) do + body + |> put_in([:message, :android], %{notification: %{sound: message.notification.sound}}) + |> put_in([:message, :apns], %{payload: %{aps: %{sound: message.notification.sound}}}) + else + body + end # end if + as_json = Poison.encode!(body) + #Logger.warning as_json + HTTPoison.post("#{@fcm_endpoint}/projects/#{project}/messages:send", + as_json, + [{ "Authorization", "Bearer " <> goth_token.token}, + {"Content-Type", "application/json"}]) + + end # end with + end # end def + end diff --git a/mix.exs b/mix.exs index 167a94b..c22fd2b 100644 --- a/mix.exs +++ b/mix.exs @@ -3,7 +3,7 @@ defmodule ExFCM.Mixfile do def project do [app: :exfcm, - version: "0.1.0", + version: "0.2.0", elixir: "~> 1.3", build_embedded: Mix.env == :prod, start_permanent: Mix.env == :prod, @@ -16,13 +16,17 @@ defmodule ExFCM.Mixfile do # # Type "mix help compile.app" for more information def application do - [applications: [:logger, :httpoison]] + [ + applications: [:logger, :httpoison], + extra_applications: [:poison,:goth], + ] end defp deps do [ {:httpoison, "~> 0.9.0"}, {:poison, ">= 0.0.0"}, + {:goth, "~> 1.4"}, {:ex_doc, ">= 0.0.0", only: :dev} ] end diff --git a/mix.lock b/mix.lock index 2f5e778..aa5d1d0 100644 --- a/mix.lock +++ b/mix.lock @@ -1,10 +1,22 @@ -%{"certifi": {:hex, :certifi, "0.4.0", "a7966efb868b179023618d29a407548f70c52466bf1849b9e8ebd0e34b7ea11f", [:rebar3], []}, - "earmark": {:hex, :earmark, "1.0.1", "2c2cd903bfdc3de3f189bd9a8d4569a075b88a8981ded9a0d95672f6e2b63141", [:mix], []}, - "ex_doc": {:hex, :ex_doc, "0.14.1", "bfed8d4e93c755e2b150be925ad2cfa6af7c3bfcacc3b609f45f6048c9d623d6", [:mix], [{:earmark, "~> 1.0", [hex: :earmark, optional: false]}]}, - "hackney": {:hex, :hackney, "1.6.1", "ddd22d42db2b50e6a155439c8811b8f6df61a4395de10509714ad2751c6da817", [:rebar3], [{:certifi, "0.4.0", [hex: :certifi, optional: false]}, {:idna, "1.2.0", [hex: :idna, optional: false]}, {:metrics, "1.0.1", [hex: :metrics, optional: false]}, {:mimerl, "1.0.2", [hex: :mimerl, optional: false]}, {:ssl_verify_fun, "1.1.0", [hex: :ssl_verify_fun, optional: false]}]}, - "httpoison": {:hex, :httpoison, "0.9.2", "a211a8e87403a043c41218e64df250d321f236ac57f786c6a0ccf3e9e817c819", [:mix], [{:hackney, "~> 1.6.0", [hex: :hackney, optional: false]}]}, - "idna": {:hex, :idna, "1.2.0", "ac62ee99da068f43c50dc69acf700e03a62a348360126260e87f2b54eced86b2", [:rebar3], []}, - "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], []}, - "mimerl": {:hex, :mimerl, "1.0.2", "993f9b0e084083405ed8252b99460c4f0563e41729ab42d9074fd5e52439be88", [:rebar3], []}, - "poison": {:hex, :poison, "3.0.0", "625ebd64d33ae2e65201c2c14d6c85c27cc8b68f2d0dd37828fde9c6920dd131", [:mix], []}, - "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.0", "edee20847c42e379bf91261db474ffbe373f8acb56e9079acb6038d4e0bf414f", [:rebar, :make], []}} +%{ + "certifi": {:hex, :certifi, "0.4.0", "a7966efb868b179023618d29a407548f70c52466bf1849b9e8ebd0e34b7ea11f", [:rebar3], [], "hexpm", "1cc233bee2d6990e7b0ff4c5824d7f401edda8a3cfad04d3328e35ad97de7611"}, + "earmark": {:hex, :earmark, "1.0.1", "2c2cd903bfdc3de3f189bd9a8d4569a075b88a8981ded9a0d95672f6e2b63141", [:mix], [], "hexpm", "db7b13d74a9edc54d3681762154d164d4a661cd27673cca80760344449877664"}, + "ex_doc": {:hex, :ex_doc, "0.14.1", "bfed8d4e93c755e2b150be925ad2cfa6af7c3bfcacc3b609f45f6048c9d623d6", [:mix], [{:earmark, "~> 1.0", [hex: :earmark, repo: "hexpm", optional: false]}], "hexpm", "492e576a7559c13e63944b8f22ae0299bca801cf6555e0df17a61e923b1b42af"}, + "finch": {:hex, :finch, "0.19.0", "c644641491ea854fc5c1bbaef36bfc764e3f08e7185e1f084e35e0672241b76d", [:mix], [{:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mint, "~> 1.6.2 or ~> 1.7", [hex: :mint, repo: "hexpm", optional: false]}, {:nimble_options, "~> 0.4 or ~> 1.0", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:nimble_pool, "~> 1.1", [hex: :nimble_pool, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "fc5324ce209125d1e2fa0fcd2634601c52a787aff1cd33ee833664a5af4ea2b6"}, + "goth": {:hex, :goth, "1.4.3", "80e86225ae174844e6a77b61982fafadfc715277db465e0956348d8bdd56b231", [:mix], [{:finch, "~> 0.17", [hex: :finch, repo: "hexpm", optional: false]}, {:jason, "~> 1.1", [hex: :jason, repo: "hexpm", optional: false]}, {:jose, "~> 1.11", [hex: :jose, repo: "hexpm", optional: false]}], "hexpm", "34e2012ed1af2fe2446083da60a988fd9829943d30e4447832646c3a6863a7e6"}, + "hackney": {:hex, :hackney, "1.6.1", "ddd22d42db2b50e6a155439c8811b8f6df61a4395de10509714ad2751c6da817", [:rebar3], [{:certifi, "0.4.0", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "1.2.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.0", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm", "bf0cf3f8a4bb588b14d20613a888c786655b2eb20255e328dd33f129b2d5b184"}, + "hpax": {:hex, :hpax, "1.0.0", "28dcf54509fe2152a3d040e4e3df5b265dcb6cb532029ecbacf4ce52caea3fd2", [:mix], [], "hexpm", "7f1314731d711e2ca5fdc7fd361296593fc2542570b3105595bb0bc6d0fad601"}, + "httpoison": {:hex, :httpoison, "0.9.2", "a211a8e87403a043c41218e64df250d321f236ac57f786c6a0ccf3e9e817c819", [:mix], [{:hackney, "~> 1.6.0", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm", "edccf20b43da7dabd2f9f2776edc9e18280c0655b2218f4b823900d0d622cbdc"}, + "idna": {:hex, :idna, "1.2.0", "ac62ee99da068f43c50dc69acf700e03a62a348360126260e87f2b54eced86b2", [:rebar3], [], "hexpm", "1d724cdafb66397e61774ead242c9b725de7033cde8ea98fa4a91e64ac5ef5b3"}, + "jason": {:hex, :jason, "1.4.4", "b9226785a9aa77b6857ca22832cffa5d5011a667207eb2a0ad56adb5db443b8a", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "c5eb0cab91f094599f94d55bc63409236a8ec69a21a67814529e8d5f6cc90b3b"}, + "jose": {:hex, :jose, "1.11.10", "a903f5227417bd2a08c8a00a0cbcc458118be84480955e8d251297a425723f83", [:mix, :rebar3], [], "hexpm", "0d6cd36ff8ba174db29148fc112b5842186b68a90ce9fc2b3ec3afe76593e614"}, + "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm", "69b09adddc4f74a40716ae54d140f93beb0fb8978d8636eaded0c31b6f099f16"}, + "mime": {:hex, :mime, "2.0.6", "8f18486773d9b15f95f4f4f1e39b710045fa1de891fada4516559967276e4dc2", [:mix], [], "hexpm", "c9945363a6b26d747389aac3643f8e0e09d30499a138ad64fe8fd1d13d9b153e"}, + "mimerl": {:hex, :mimerl, "1.0.2", "993f9b0e084083405ed8252b99460c4f0563e41729ab42d9074fd5e52439be88", [:rebar3], [], "hexpm", "7a4c8e1115a2732a67d7624e28cf6c9f30c66711a9e92928e745c255887ba465"}, + "mint": {:hex, :mint, "1.6.2", "af6d97a4051eee4f05b5500671d47c3a67dac7386045d87a904126fd4bbcea2e", [:mix], [{:castore, "~> 0.1.0 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:hpax, "~> 0.1.1 or ~> 0.2.0 or ~> 1.0", [hex: :hpax, repo: "hexpm", optional: false]}], "hexpm", "5ee441dffc1892f1ae59127f74afe8fd82fda6587794278d924e4d90ea3d63f9"}, + "nimble_options": {:hex, :nimble_options, "1.1.1", "e3a492d54d85fc3fd7c5baf411d9d2852922f66e69476317787a7b2bb000a61b", [:mix], [], "hexpm", "821b2470ca9442c4b6984882fe9bb0389371b8ddec4d45a9504f00a66f650b44"}, + "nimble_pool": {:hex, :nimble_pool, "1.1.0", "bf9c29fbdcba3564a8b800d1eeb5a3c58f36e1e11d7b7fb2e084a643f645f06b", [:mix], [], "hexpm", "af2e4e6b34197db81f7aad230c1118eac993acc0dae6bc83bac0126d4ae0813a"}, + "poison": {:hex, :poison, "3.0.0", "625ebd64d33ae2e65201c2c14d6c85c27cc8b68f2d0dd37828fde9c6920dd131", [:mix], [], "hexpm", "813db7909e9aa20b2f4d42692798beef7a430691b424d0e6b08f7cb11727c721"}, + "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.0", "edee20847c42e379bf91261db474ffbe373f8acb56e9079acb6038d4e0bf414f", [:make, :rebar], [], "hexpm", "6c0e0d857fdb031ba67b0a791202bee116bea2313db7b649839000847591ba1e"}, + "telemetry": {:hex, :telemetry, "1.3.0", "fedebbae410d715cf8e7062c96a1ef32ec22e764197f70cda73d82778d61e7a2", [:rebar3], [], "hexpm", "7015fc8919dbe63764f4b4b87a95b7c0996bd539e0d499be6ec9d7f3875b79e6"}, +}