From 13e13f6315f232d750aed03667379422c7371a52 Mon Sep 17 00:00:00 2001 From: "bhan@slab.com" Date: Thu, 26 May 2022 00:26:06 +0800 Subject: [PATCH] Support Algolia Insight Events --- lib/algolia.ex | 32 ++++++++++++++++++++++++-------- mix.exs | 4 ++-- mix.lock | 31 ++++++++++++++++--------------- test/algolia_test.exs | 30 ++++++++++++++++++++++++++++++ 4 files changed, 72 insertions(+), 25 deletions(-) diff --git a/lib/algolia.ex b/lib/algolia.ex index 647da6a..68a1527 100644 --- a/lib/algolia.ex +++ b/lib/algolia.ex @@ -42,7 +42,9 @@ defmodule Algolia do defp host(:read, 0), do: "#{application_id()}-dsn.algolia.net" defp host(:write, 0), do: "#{application_id()}.algolia.net" - defp host(_read_or_write, curr_retry) when curr_retry <= 3, + defp host(:insights, _curr_retry), do: "insights.algolia.io" + + defp host(_subdomain_hint, curr_retry) when curr_retry <= 3, do: "#{application_id()}-#{curr_retry}.algolianet.com" @doc """ @@ -146,14 +148,14 @@ defmodule Algolia do send_request(:read, %{method: :post, path: path, body: body}) end - defp send_request(read_or_write, request, curr_retry \\ 0) + defp send_request(subdomain_hint, request, curr_retry \\ 0) - defp send_request(_read_or_write, _request, 4) do + defp send_request(_subdomain_hint, _request, 4) do {:error, "Unable to connect to Algolia"} end - defp send_request(read_or_write, request, curr_retry) do - url = request_url(read_or_write, curr_retry, request[:path]) + defp send_request(subdomain_hint, request, curr_retry) do + url = request_url(subdomain_hint, curr_retry, request[:path]) headers = request_headers(request[:options] || []) body = request[:body] || "" @@ -173,13 +175,13 @@ defmodule Algolia do {:error, code, response} _ -> - send_request(read_or_write, request, curr_retry + 1) + send_request(subdomain_hint, request, curr_retry + 1) end end - defp request_url(read_or_write, retry, path) do + defp request_url(subdomain_hint, retry, path) do "https://" - |> Path.join(host(read_or_write, retry)) + |> Path.join(host(subdomain_hint, retry)) |> Path.join(path) end @@ -568,4 +570,18 @@ defmodule Algolia do def wait(response = {:ok, _}), do: wait(response, 1000) def wait(response = {:error, _}), do: response def wait(response), do: response + + @doc """ + Push events to the Insights REST API. + Corresponds to https://www.algolia.com/doc/rest-api/insights/#push-events + `events` should be a List of Maps, each Map having the fields described in the link above + """ + def push_events(events) do + body = Jason.encode!(%{"events" => events}) + + send_request( + :insights, + %{method: :post, path: "1/events", body: body} + ) + end end diff --git a/mix.exs b/mix.exs index ea4bec3..bfab5b8 100644 --- a/mix.exs +++ b/mix.exs @@ -27,8 +27,8 @@ defmodule Algolia.Mixfile do defp deps do [ - {:hackney, "~> 1.9 or ~> 1.10"}, - {:jason, "~> 1.0"}, + {:hackney, "1.17.4"}, + {:jason, "1.2.2"}, # Docs {:ex_doc, "~> 0.19", only: :dev}, {:inch_ex, ">= 0.0.0", only: :dev} diff --git a/mix.lock b/mix.lock index b48dea7..cc650d0 100644 --- a/mix.lock +++ b/mix.lock @@ -1,17 +1,18 @@ %{ - "certifi": {:hex, :certifi, "2.0.0", "a0c0e475107135f76b8c1d5bc7efb33cd3815cb3cf3dea7aefdd174dabead064", [:rebar3], [], "hexpm"}, - "earmark": {:hex, :earmark, "1.3.0", "17f0c38eaafb4800f746b457313af4b2442a8c2405b49c645768680f900be603", [:mix], [], "hexpm"}, - "ex_doc": {:hex, :ex_doc, "0.19.1", "519bb9c19526ca51d326c060cb1778d4a9056b190086a8c6c115828eaccea6cf", [:mix], [{:earmark, "~> 1.1", [hex: :earmark, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.7", [hex: :makeup_elixir, repo: "hexpm", optional: false]}], "hexpm"}, - "hackney": {:hex, :hackney, "1.9.0", "51c506afc0a365868469dcfc79a9d0b94d896ec741cfd5bd338f49a5ec515bfe", [: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"}, - "idna": {:hex, :idna, "5.1.0", "d72b4effeb324ad5da3cab1767cb16b17939004e789d8c0ad5b70f3cea20c89a", [:rebar3], [{:unicode_util_compat, "0.3.1", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm"}, - "inch_ex": {:hex, :inch_ex, "0.5.6", "418357418a553baa6d04eccd1b44171936817db61f4c0840112b420b8e378e67", [:mix], [{:poison, "~> 1.5 or ~> 2.0 or ~> 3.0", [hex: :poison, repo: "hexpm", optional: false]}], "hexpm"}, - "jason": {:hex, :jason, "1.0.0", "0f7cfa9bdb23fed721ec05419bcee2b2c21a77e926bce0deda029b5adc716fe2", [:mix], [{:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm"}, - "makeup": {:hex, :makeup, "0.5.5", "9e08dfc45280c5684d771ad58159f718a7b5788596099bdfb0284597d368a882", [:mix], [{:nimble_parsec, "~> 0.4", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm"}, - "makeup_elixir": {:hex, :makeup_elixir, "0.10.0", "0f09c2ddf352887a956d84f8f7e702111122ca32fbbc84c2f0569b8b65cbf7fa", [:mix], [{:makeup, "~> 0.5.5", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm"}, - "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm"}, - "mimerl": {:hex, :mimerl, "1.0.2", "993f9b0e084083405ed8252b99460c4f0563e41729ab42d9074fd5e52439be88", [:rebar3], [], "hexpm"}, - "nimble_parsec": {:hex, :nimble_parsec, "0.4.0", "ee261bb53214943679422be70f1658fff573c5d0b0a1ecd0f18738944f818efe", [:mix], [], "hexpm"}, - "poison": {:hex, :poison, "3.1.0", "d9eb636610e096f86f25d9a46f35a9facac35609a7591b3be3326e99a0484665", [:mix], [], "hexpm"}, - "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.1", "28a4d65b7f59893bc2c7de786dec1e1555bd742d336043fe644ae956c3497fbe", [:make, :rebar], [], "hexpm"}, - "unicode_util_compat": {:hex, :unicode_util_compat, "0.3.1", "a1f612a7b512638634a603c8f401892afbf99b8ce93a45041f8aaca99cadb85e", [:rebar3], [], "hexpm"}, + "certifi": {:hex, :certifi, "2.6.1", "dbab8e5e155a0763eea978c913ca280a6b544bfa115633fa20249c3d396d9493", [:rebar3], [], "hexpm", "524c97b4991b3849dd5c17a631223896272c6b0af446778ba4675a1dff53bb7e"}, + "earmark": {:hex, :earmark, "1.3.0", "17f0c38eaafb4800f746b457313af4b2442a8c2405b49c645768680f900be603", [:mix], [], "hexpm", "f8b8820099caf0d5e72ae6482d2b0da96f213cbbe2b5b2191a37966e119eaa27"}, + "ex_doc": {:hex, :ex_doc, "0.19.1", "519bb9c19526ca51d326c060cb1778d4a9056b190086a8c6c115828eaccea6cf", [:mix], [{:earmark, "~> 1.1", [hex: :earmark, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.7", [hex: :makeup_elixir, repo: "hexpm", optional: false]}], "hexpm", "dc87f778d8260da0189a622f62790f6202af72f2f3dee6e78d91a18dd2fcd137"}, + "hackney": {:hex, :hackney, "1.17.4", "99da4674592504d3fb0cfef0db84c3ba02b4508bae2dff8c0108baa0d6e0977c", [:rebar3], [{:certifi, "~>2.6.1", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "~>6.1.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "~>1.0.0", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "~>1.1", [hex: :mimerl, repo: "hexpm", optional: false]}, {:parse_trans, "3.3.1", [hex: :parse_trans, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "~>1.1.0", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}, {:unicode_util_compat, "~>0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "de16ff4996556c8548d512f4dbe22dd58a587bf3332e7fd362430a7ef3986b16"}, + "idna": {:hex, :idna, "6.1.1", "8a63070e9f7d0c62eb9d9fcb360a7de382448200fbbd1b106cc96d3d8099df8d", [:rebar3], [{:unicode_util_compat, "~>0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "92376eb7894412ed19ac475e4a86f7b413c1b9fbb5bd16dccd57934157944cea"}, + "inch_ex": {:hex, :inch_ex, "0.5.6", "418357418a553baa6d04eccd1b44171936817db61f4c0840112b420b8e378e67", [:mix], [{:poison, "~> 1.5 or ~> 2.0 or ~> 3.0", [hex: :poison, repo: "hexpm", optional: false]}], "hexpm", "7123ca0450686a61416a06cd38e26af18fd0f8c1cff5214770a957c6e0724338"}, + "jason": {:hex, :jason, "1.2.2", "ba43e3f2709fd1aa1dce90aaabfd039d000469c05c56f0b8e31978e03fa39052", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "18a228f5f0058ee183f29f9eae0805c6e59d61c3b006760668d8d18ff0d12179"}, + "makeup": {:hex, :makeup, "0.5.5", "9e08dfc45280c5684d771ad58159f718a7b5788596099bdfb0284597d368a882", [:mix], [{:nimble_parsec, "~> 0.4", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "d7152ff93f2eac07905f510dfa03397134345ba4673a00fbf7119bab98632940"}, + "makeup_elixir": {:hex, :makeup_elixir, "0.10.0", "0f09c2ddf352887a956d84f8f7e702111122ca32fbbc84c2f0569b8b65cbf7fa", [:mix], [{:makeup, "~> 0.5.5", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "4a36dd2d0d5c5f98d95b3f410d7071cd661d5af310472229dd0e92161f168a44"}, + "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm", "69b09adddc4f74a40716ae54d140f93beb0fb8978d8636eaded0c31b6f099f16"}, + "mimerl": {:hex, :mimerl, "1.2.0", "67e2d3f571088d5cfd3e550c383094b47159f3eee8ffa08e64106cdf5e981be3", [:rebar3], [], "hexpm", "f278585650aa581986264638ebf698f8bb19df297f66ad91b18910dfc6e19323"}, + "nimble_parsec": {:hex, :nimble_parsec, "0.4.0", "ee261bb53214943679422be70f1658fff573c5d0b0a1ecd0f18738944f818efe", [:mix], [], "hexpm", "ebb595e19456a72786db6dcd370d320350cb624f0b6203fcc7e23161d49b0ffb"}, + "parse_trans": {:hex, :parse_trans, "3.3.1", "16328ab840cc09919bd10dab29e431da3af9e9e7e7e6f0089dd5a2d2820011d8", [:rebar3], [], "hexpm", "07cd9577885f56362d414e8c4c4e6bdf10d43a8767abb92d24cbe8b24c54888b"}, + "poison": {:hex, :poison, "3.1.0", "d9eb636610e096f86f25d9a46f35a9facac35609a7591b3be3326e99a0484665", [:mix], [], "hexpm", "fec8660eb7733ee4117b85f55799fd3833eb769a6df71ccf8903e8dc5447cfce"}, + "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.6", "cf344f5692c82d2cd7554f5ec8fd961548d4fd09e7d22f5b62482e5aeaebd4b0", [:make, :mix, :rebar3], [], "hexpm", "bdb0d2471f453c88ff3908e7686f86f9be327d065cc1ec16fa4540197ea04680"}, + "unicode_util_compat": {:hex, :unicode_util_compat, "0.7.0", "bc84380c9ab48177092f43ac89e4dfa2c6d62b40b8bd132b1059ecc7232f9a78", [:rebar3], [], "hexpm", "25eee6d67df61960cf6a794239566599b09e17e668d3700247bc498638152521"}, } diff --git a/test/algolia_test.exs b/test/algolia_test.exs index 103191f..7b651c5 100644 --- a/test/algolia_test.exs +++ b/test/algolia_test.exs @@ -370,4 +370,34 @@ defmodule AlgoliaTest do %{"index" => "test", "query_headers" => headers} = log assert headers =~ ~r/X-Forwarded-For: 1\.2\.3\.4/ end + + test "push_events is successful" do + events = [ + %{ + "eventType" => "click", + "eventName" => "Product Clicked", + "index" => "products", + "userToken" => "user-123456", + "objectIDs" => ["9780545139700", "9780439784542"], + "queryID" => "43b15df305339e827f0ac0bdc5ebcaa7", + "positions" => [7, 6] + }, + %{ + "eventType" => "view", + "eventName" => "Product Detail Page Viewed", + "index" => "products", + "userToken" => "user-123456", + "objectIDs" => ["9780545139700", "9780439784542"] + }, + %{ + "eventType" => "conversion", + "eventName" => "Product Purchased", + "index" => "products", + "userToken" => "user-123456", + "objectIDs" => ["9780545139700", "9780439784542"], + "queryID" => "43b15df305339e827f0ac0bdc5ebcaa7" + } + ] + assert {:ok, _} = push_events(events) + end end