diff --git a/config/config.exs b/config/config.exs index d05d96b8..ea312dde 100644 --- a/config/config.exs +++ b/config/config.exs @@ -50,11 +50,15 @@ config :logger, :console, # Use Jason for JSON parsing in Phoenix config :phoenix, :json_library, Jason +# Use Finch and Tesla for HTTP client +config :tesla, :adapter, {Tesla.Adapter.Finch, name: Tilex.Finch} + # Provide reasonable default for configuration options config :tilex, :page_size, 5 config :tilex, :auth_controller, AuthController config :tilex, :slack_notifier, Tilex.Notifications.Notifiers.Slack config :tilex, :twitter_notifier, Tilex.Notifications.Notifiers.Twitter +config :tilex, :webhook_notifier, Tilex.Notifications.Notifiers.Webhook config :tilex, :organization_name, System.get_env("ORGANIZATION_NAME") config :tilex, :canonical_domain, System.get_env("CANONICAL_DOMAIN") config :tilex, :default_twitter_handle, System.get_env("DEFAULT_TWITTER_HANDLE") diff --git a/config/runtime.exs b/config/runtime.exs index 496e86ae..bc0722b3 100644 --- a/config/runtime.exs +++ b/config/runtime.exs @@ -82,4 +82,6 @@ if config_env() == :prod do # config :swoosh, :api_client, Swoosh.ApiClient.Hackney # # See https://hexdocs.pm/swoosh/Swoosh.html#module-installation for details. + + config :tilex, webhook_url: System.get_env("WEBHOOK_URL") end diff --git a/config/test.exs b/config/test.exs index a2d4ae4f..0637e0c5 100644 --- a/config/test.exs +++ b/config/test.exs @@ -39,9 +39,11 @@ config :tilex, :hosted_domain, "hashrocket.com" config :tilex, :auth_controller, Test.AuthController config :tilex, :slack_notifier, Test.Notifications.Notifiers.Slack config :tilex, :twitter_notifier, Test.Notifications.Notifiers.Twitter +config :tilex, :webhook_notifier, Test.Notifications.Notifiers.Webhook config :tilex, :date_time_module, Tilex.DateTimeMock config :tilex, :date_display_tz, "America/Chicago" config :tilex, :slack_endpoint, "https://slack.test.com/abc/123" +config :tilex, :webhook_url, "https://example.com/webhook" config :httpoison, timeout: 6000 diff --git a/lib/test/notifications/notifiers/webhook.ex b/lib/test/notifications/notifiers/webhook.ex new file mode 100644 index 00000000..18a28377 --- /dev/null +++ b/lib/test/notifications/notifiers/webhook.ex @@ -0,0 +1,15 @@ +defmodule Test.Notifications.Notifiers.Webhook do + use Tilex.Notifications.Notifier + + def handle_post_created(_post, _developer, _channel, _url) do + :ok + end + + def handle_post_liked(_post, _developer, _url) do + :ok + end + + def handle_page_views_report(_report) do + :ok + end +end diff --git a/lib/tilex/application.ex b/lib/tilex/application.ex index cdf2c1ed..68e17077 100644 --- a/lib/tilex/application.ex +++ b/lib/tilex/application.ex @@ -15,7 +15,8 @@ defmodule Tilex.Application do {Cachex, name: :tilex_cache}, Tilex.Notifications, Tilex.RateLimiter, - Tilex.Notifications.NotifiersSupervisor + Tilex.Notifications.NotifiersSupervisor, + {Finch, name: Tilex.Finch} ] :telemetry.attach( diff --git a/lib/tilex/create_post_webhook.ex b/lib/tilex/create_post_webhook.ex new file mode 100644 index 00000000..85c2b885 --- /dev/null +++ b/lib/tilex/create_post_webhook.ex @@ -0,0 +1,26 @@ +defmodule Tilex.CreatePostWebhook do + alias Tilex.Blog.Developer + + def call(post, developer, channel, url) do + if webhook_url() do + body = %{ + til: %{ + title: post.title, + developer_name: Developer.twitter_handle(developer), + channel: channel.twitter_hashtag, + post_url: url + } + } + + Tesla.post(webhook_url(), Jason.encode!(body), + headers: [{"content-type", "application/json"}] + ) + |> case do + {:ok, %Tesla.Env{status: 200}} -> :ok + env -> {:error, env} + end + end + end + + defp webhook_url, do: Application.get_env(:tilex, :webhook_url) +end diff --git a/lib/tilex/notifications/notifiers/webhook.ex b/lib/tilex/notifications/notifiers/webhook.ex new file mode 100644 index 00000000..5f79c63f --- /dev/null +++ b/lib/tilex/notifications/notifiers/webhook.ex @@ -0,0 +1,17 @@ +defmodule Tilex.Notifications.Notifiers.Webhook do + use Tilex.Notifications.Notifier + + alias Tilex.CreatePostWebhook + + def handle_post_created(post, developer, channel, url) do + CreatPostWebhook.call(post, developer, channel, url) + end + + def handle_post_liked(_post, _dev, _url) do + :ok + end + + def handle_page_views_report(_report) do + :ok + end +end diff --git a/lib/tilex/notifications/notifiers_supervisor.ex b/lib/tilex/notifications/notifiers_supervisor.ex index 99aecac2..5e7d3eb2 100644 --- a/lib/tilex/notifications/notifiers_supervisor.ex +++ b/lib/tilex/notifications/notifiers_supervisor.ex @@ -12,10 +12,12 @@ defmodule Tilex.Notifications.NotifiersSupervisor do def children do [ slack_notifier(), - twitter_notifier() + twitter_notifier(), + webhook_notifier() ] end defp slack_notifier, do: Application.get_env(:tilex, :slack_notifier) defp twitter_notifier, do: Application.get_env(:tilex, :twitter_notifier) + defp webhook_notifier, do: Application.get_env(:tilex, :webhook_notifier) end diff --git a/mix.exs b/mix.exs index 16bbb239..4e1680d3 100644 --- a/mix.exs +++ b/mix.exs @@ -41,6 +41,7 @@ defmodule Tilex.Mixfile do {:ecto_sql, "~> 3.6"}, {:esbuild, "~> 0.4", runtime: Mix.env() == :dev}, {:extwitter, "~> 0.13"}, + {:finch, "~> 0.14"}, {:floki, "~>0.34"}, {:gettext, "~> 0.18"}, {:guardian, "~> 2.0"}, @@ -61,6 +62,7 @@ defmodule Tilex.Mixfile do {:swoosh, "~> 1.3"}, {:telemetry_metrics, "~> 0.6"}, {:telemetry_poller, "~> 1.0"}, + {:tesla, "~> 1.4"}, {:timex, "~> 3.1"}, {:tzdata, "~> 1.1.0"}, {:ueberauth_google, "~> 0.5"}, diff --git a/mix.lock b/mix.lock index 7b5b934a..b8438a20 100644 --- a/mix.lock +++ b/mix.lock @@ -25,10 +25,12 @@ "expo": {:hex, :expo, "0.1.0", "d4e932bdad052c374118e312e35280f1919ac13881cb3ac07a209a54d0c81dd8", [:mix], [], "hexpm", "c22c536021c56de058aaeedeabb4744eb5d48137bacf8c29f04d25b6c6bbbf45"}, "extwitter": {:hex, :extwitter, "0.14.0", "5e15c5ea5e6a09baaf03fd5da6de1431eeeca0ef05a9c0f6cc62872e5b8816ed", [:mix], [{:jason, "~> 1.1", [hex: :jason, repo: "hexpm", optional: false]}, {:oauther, "~> 1.3", [hex: :oauther, repo: "hexpm", optional: false]}], "hexpm", "5e9bbb491531317062df42ab56ccb8368addb00931b0785c8a5e1d652813b0a8"}, "file_system": {:hex, :file_system, "0.2.10", "fb082005a9cd1711c05b5248710f8826b02d7d1784e7c3451f9c1231d4fc162d", [:mix], [], "hexpm", "41195edbfb562a593726eda3b3e8b103a309b733ad25f3d642ba49696bf715dc"}, + "finch": {:hex, :finch, "0.14.0", "619bfdee18fc135190bf590356c4bf5d5f71f916adb12aec94caa3fa9267a4bc", [:mix], [{:castore, "~> 0.1", [hex: :castore, repo: "hexpm", optional: false]}, {:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mint, "~> 1.3", [hex: :mint, repo: "hexpm", optional: false]}, {:nimble_options, "~> 0.4", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:nimble_pool, "~> 0.2.6", [hex: :nimble_pool, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "5459acaf18c4fdb47a8c22fb3baff5d8173106217c8e56c5ba0b93e66501a8dd"}, "floki": {:hex, :floki, "0.34.0", "002d0cc194b48794d74711731db004fafeb328fe676976f160685262d43706a8", [:mix], [], "hexpm", "9c3a9f43f40dde00332a589bd9d389b90c1f518aef500364d00636acc5ebc99c"}, "gettext": {:hex, :gettext, "0.21.0", "15bbceb20b317b706a8041061a08e858b5a189654128618b53746bf36c84352b", [:mix], [{:expo, "~> 0.1.0", [hex: :expo, repo: "hexpm", optional: false]}], "hexpm", "04a66db4103b6d1d18f92240bb2c73167b517229316b7bef84e4eebbfb2f14f6"}, "guardian": {:hex, :guardian, "2.3.1", "2b2d78dc399a7df182d739ddc0e566d88723299bfac20be36255e2d052fd215d", [:mix], [{:jose, "~> 1.8", [hex: :jose, repo: "hexpm", optional: false]}, {:plug, "~> 1.3.3 or ~> 1.4", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "bbe241f9ca1b09fad916ad42d6049d2600bbc688aba5b3c4a6c82592a54274c3"}, "hackney": {:hex, :hackney, "1.18.1", "f48bf88f521f2a229fc7bae88cf4f85adc9cd9bcf23b5dc8eb6a1788c662c4f6", [:rebar3], [{:certifi, "~> 2.9.0", [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", "a4ecdaff44297e9b5894ae499e9a070ea1888c84afdd1fd9b7b2bc384950128e"}, + "hpax": {:hex, :hpax, "0.1.2", "09a75600d9d8bbd064cdd741f21fc06fc1f4cf3d0fcc335e5aa19be1a7235c84", [:mix], [], "hexpm", "2c87843d5a23f5f16748ebe77969880e29809580efdaccd615cd3bed628a8c13"}, "html_sanitize_ex": {:hex, :html_sanitize_ex, "1.4.2", "c479398b6de798c03eb5d04a0a9a9159d73508f83f6590a00b8eacba3619cf4c", [:mix], [{:mochiweb, "~> 2.15", [hex: :mochiweb, repo: "hexpm", optional: false]}], "hexpm", "aef6c28585d06a9109ad591507e508854c5559561f950bbaea773900dd369b0e"}, "httpoison": {:hex, :httpoison, "1.8.2", "9eb9c63ae289296a544842ef816a85d881d4a31f518a0fec089aaa744beae290", [:mix], [{:hackney, "~> 1.17", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm", "2bb350d26972e30c96e2ca74a1aaf8293d61d0742ff17f01e0279fef11599921"}, "idna": {:hex, :idna, "6.1.1", "8a63070e9f7d0c62eb9d9fcb360a7de382448200fbbd1b106cc96d3d8099df8d", [:rebar3], [{:unicode_util_compat, "~> 0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "92376eb7894412ed19ac475e4a86f7b413c1b9fbb5bd16dccd57934157944cea"}, @@ -38,7 +40,10 @@ "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm", "69b09adddc4f74a40716ae54d140f93beb0fb8978d8636eaded0c31b6f099f16"}, "mime": {:hex, :mime, "2.0.3", "3676436d3d1f7b81b5a2d2bd8405f412c677558c81b1c92be58c00562bb59095", [:mix], [], "hexpm", "27a30bf0db44d25eecba73755acf4068cbfe26a4372f9eb3e4ea3a45956bff6b"}, "mimerl": {:hex, :mimerl, "1.2.0", "67e2d3f571088d5cfd3e550c383094b47159f3eee8ffa08e64106cdf5e981be3", [:rebar3], [], "hexpm", "f278585650aa581986264638ebf698f8bb19df297f66ad91b18910dfc6e19323"}, + "mint": {:hex, :mint, "1.4.2", "50330223429a6e1260b2ca5415f69b0ab086141bc76dc2fbf34d7c389a6675b2", [:mix], [{:castore, "~> 0.1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:hpax, "~> 0.1.1", [hex: :hpax, repo: "hexpm", optional: false]}], "hexpm", "ce75a5bbcc59b4d7d8d70f8b2fc284b1751ffb35c7b6a6302b5192f8ab4ddd80"}, "mochiweb": {:hex, :mochiweb, "2.22.0", "f104d6747c01a330c38613561977e565b788b9170055c5241ac9dd6e4617cba5", [:rebar3], [], "hexpm", "cbbd1fd315d283c576d1c8a13e0738f6dafb63dc840611249608697502a07655"}, + "nimble_options": {:hex, :nimble_options, "0.5.2", "42703307b924880f8c08d97719da7472673391905f528259915782bb346e0a1b", [:mix], [], "hexpm", "4da7f904b915fd71db549bcdc25f8d56f378ef7ae07dc1d372cbe72ba950dce0"}, + "nimble_pool": {:hex, :nimble_pool, "0.2.6", "91f2f4c357da4c4a0a548286c84a3a28004f68f05609b4534526871a22053cde", [:mix], [], "hexpm", "1c715055095d3f2705c4e236c18b618420a35490da94149ff8b580a2144f653f"}, "oauth2": {:hex, :oauth2, "2.1.0", "beb657f393814a3a7a8a15bd5e5776ecae341fd344df425342a3b6f1904c2989", [:mix], [{:tesla, "~> 1.5", [hex: :tesla, repo: "hexpm", optional: false]}], "hexpm", "8ac07f85b3307dd1acfeb0ec852f64161b22f57d0ce0c15e616a1dfc8ebe2b41"}, "oauther": {:git, "https://github.com/tobstarr/oauther.git", "e81fc6588e52eeaf41cdf51ed9d968da46b0b67d", [branch: "master"]}, "optimus": {:hex, :optimus, "0.3.0", "72754d1a06bab7b4b7f59b05622e442e5ab7909b9db5d8b01dc3d2792559fa9e", [:mix], [], "hexpm", "d0d026fdf068e461e1173c463ea2da15e109942135aa4e2490dd2dc9ef05946c"},