From 2fe49add34e3eff155398442499ed45c13f0cefb Mon Sep 17 00:00:00 2001 From: Jhefrey Sajot <70475641+jeepers3327@users.noreply.github.com> Date: Fri, 11 Jun 2021 18:56:51 +0800 Subject: [PATCH] Add support for Sendgrid unique arguments (#609) Closes https://github.com/thoughtbot/bamboo/issues/592 Adds support for Sendgrid unique arguments. It includes a `with_unique_args` helper function in the SendGridHelper. --- lib/bamboo/adapters/send_grid_adapter.ex | 9 +++++++ lib/bamboo/adapters/send_grid_helper.ex | 22 +++++++++++++++++ .../adapters/send_grid_adapter_test.exs | 19 +++++++++++++++ .../bamboo/adapters/send_grid_helper_test.exs | 24 +++++++++++++++++++ 4 files changed, 74 insertions(+) diff --git a/lib/bamboo/adapters/send_grid_adapter.ex b/lib/bamboo/adapters/send_grid_adapter.ex index 239df173..0164fb19 100644 --- a/lib/bamboo/adapters/send_grid_adapter.ex +++ b/lib/bamboo/adapters/send_grid_adapter.ex @@ -130,6 +130,7 @@ defmodule Bamboo.SendGridAdapter do |> put_bypass_list_management(email) |> put_google_analytics(email) |> put_ip_pool_name(email) + |> put_unique_args(email) end defp put_from(body, %Email{from: from}) do @@ -440,4 +441,12 @@ defmodule Bamboo.SendGridAdapter do do: Map.put(body, :ip_pool_name, ip_pool_name) defp put_ip_pool_name(body, _), do: body + + defp put_unique_args(body, %Email{private: %{unique_args: unique_args}}) + when is_map(unique_args) do + body + |> Map.put(:unique_args, unique_args) + end + + defp put_unique_args(body, _), do: body end diff --git a/lib/bamboo/adapters/send_grid_helper.ex b/lib/bamboo/adapters/send_grid_helper.ex index e82f756d..9402adc9 100644 --- a/lib/bamboo/adapters/send_grid_helper.ex +++ b/lib/bamboo/adapters/send_grid_helper.ex @@ -22,6 +22,7 @@ defmodule Bamboo.SendGridHelper do @allowed_google_analytics_utm_params ~w(utm_source utm_medium utm_campaign utm_term utm_content)a @send_at_field :sendgrid_send_at @ip_pool_name_field :ip_pool_name + @unique_args :unique_args @doc """ Specify the template for SendGrid to use for the context of the substitution @@ -294,4 +295,25 @@ defmodule Bamboo.SendGridHelper do email |> Email.put_private(@ip_pool_name_field, ip_pool_name) end + + @doc """ + A map of unique arguments for this email. This will override any existing unique arguments. + + ## Example + + email + |> with_unique_args(%{new_arg_1: "new arg 1", new_arg_2: "new arg 2"}) + """ + def with_unique_args(email, unique_args) when is_map(unique_args) do + unique_args = + Map.get(email.private, @unique_args, %{}) + |> Map.merge(unique_args) + + email + |> Email.put_private(@unique_args, unique_args) + end + + def with_unique_args(_email, _unique_args) do + raise "expected a map of unique arguments" + end end diff --git a/test/lib/bamboo/adapters/send_grid_adapter_test.exs b/test/lib/bamboo/adapters/send_grid_adapter_test.exs index ede9a6b7..9cd5cf85 100644 --- a/test/lib/bamboo/adapters/send_grid_adapter_test.exs +++ b/test/lib/bamboo/adapters/send_grid_adapter_test.exs @@ -628,6 +628,25 @@ defmodule Bamboo.SendGridAdapterTest do assert msg =~ ~r/'email' field/ end + test "deliver/2 correctly handles with_unique_args" do + email = new_email() + + unique_args = %{ + new_arg1: "new arg 1", + new_arg2: "new arg 2", + new_arg3: "new arg 3" + } + + email + |> Bamboo.SendGridHelper.with_unique_args(unique_args) + |> SendGridAdapter.deliver(@config) + + assert_receive {:fake_sendgrid, %{params: params}} + assert params["unique_args"]["new_arg1"] == "new arg 1" + assert params["unique_args"]["new_arg2"] == "new arg 2" + assert params["unique_args"]["new_arg3"] == "new arg 3" + end + test "deliver/2 will set sandbox mode correctly" do email = new_email() email |> SendGridAdapter.deliver(@config_with_sandbox_enabled) diff --git a/test/lib/bamboo/adapters/send_grid_helper_test.exs b/test/lib/bamboo/adapters/send_grid_helper_test.exs index 6a56dd3f..c817bbb1 100644 --- a/test/lib/bamboo/adapters/send_grid_helper_test.exs +++ b/test/lib/bamboo/adapters/send_grid_helper_test.exs @@ -207,4 +207,28 @@ defmodule Bamboo.SendGridHelperTest do email = email |> with_ip_pool_name(@ip_pool_name) assert email.private[:ip_pool_name] == @ip_pool_name end + + test "with_unique_args/2 merges multiple maps", %{email: email} do + email = + email + |> with_unique_args(%{new_arg_1: "new arg 1", new_arg_2: "new arg 2"}) + |> with_unique_args(%{new_arg_3: "new arg 3"}) + + assert map_size(email.private[:unique_args]) == 3 + end + + test "with_unique_args/2 overrides duplicate entries", %{email: email} do + email = + email + |> with_unique_args(%{new_arg_1: "new arg 1"}) + |> with_unique_args(%{new_arg_1: "latest new arg 1", new_arg_2: "new arg 2"}) + + assert map_size(email.private[:unique_args]) == 2 + end + + test "with_unique_args/2 raises on non-map parameter", %{email: email} do + assert_raise RuntimeError, fn -> + email |> with_unique_args(["new arg"]) + end + end end