mirror of
https://github.com/plausible/analytics.git
synced 2024-12-23 17:44:43 +03:00
Migrate HTTPoison to Finch (#2054)
Signed-off-by: Manu S Ajith <neo@codingarena.in> Signed-off-by: Manu S Ajith <neo@codingarena.in>
This commit is contained in:
parent
5c83ea77de
commit
777c69b1d6
@ -44,7 +44,27 @@ defmodule Plausible.Application do
|
||||
config = Application.fetch_env!(:plausible, Plausible.Finch)
|
||||
|
||||
pool_config = %{
|
||||
:default => [size: config[:default_pool_size], count: config[:default_pool_count]]
|
||||
:default => [size: config[:default_pool_size], count: config[:default_pool_count]],
|
||||
"https://vendors.paddle.com" => [
|
||||
protocol: :http2,
|
||||
count: 50,
|
||||
conn_opts: [transport_opts: [timeout: 15_000]]
|
||||
],
|
||||
"https://www.googleapis.com" => [
|
||||
protocol: :http2,
|
||||
count: 200,
|
||||
conn_opts: [transport_opts: [timeout: 15_000]]
|
||||
],
|
||||
"https://analyticsreporting.googleapis.com" => [
|
||||
protocol: :http2,
|
||||
count: 200,
|
||||
conn_opts: [transport_opts: [timeout: 15_000]]
|
||||
],
|
||||
"https://icons.duckduckgo.com" => [
|
||||
protocol: :http2,
|
||||
count: 100,
|
||||
conn_opts: [transport_opts: [timeout: 15_000]]
|
||||
]
|
||||
}
|
||||
|
||||
sentry_dsn = Application.get_env(:sentry, :dsn)
|
||||
|
@ -1,4 +1,6 @@
|
||||
defmodule Plausible.Billing.PaddleApi do
|
||||
alias Plausible.HTTPClient
|
||||
|
||||
@update_endpoint "https://vendors.paddle.com/api/2.0/subscription/users/update"
|
||||
@get_endpoint "https://vendors.paddle.com/api/2.0/subscription/users"
|
||||
@headers [
|
||||
@ -21,10 +23,10 @@ defmodule Plausible.Billing.PaddleApi do
|
||||
}
|
||||
|
||||
{:ok, response} =
|
||||
HTTPoison.post(
|
||||
HTTPClient.post(
|
||||
vendors_domain() <> "/api/2.0/subscription/preview_update",
|
||||
Jason.encode!(params),
|
||||
@headers
|
||||
@headers,
|
||||
Jason.encode!(params)
|
||||
)
|
||||
|
||||
body = Jason.decode!(response.body)
|
||||
@ -50,7 +52,7 @@ defmodule Plausible.Billing.PaddleApi do
|
||||
quantity: 1
|
||||
})
|
||||
|
||||
{:ok, response} = HTTPoison.post(@update_endpoint, Jason.encode!(params), @headers)
|
||||
{:ok, response} = HTTPClient.post(@update_endpoint, @headers, Jason.encode!(params))
|
||||
body = Jason.decode!(response.body)
|
||||
|
||||
if body["success"] do
|
||||
@ -69,7 +71,7 @@ defmodule Plausible.Billing.PaddleApi do
|
||||
subscription_id: paddle_subscription_id
|
||||
}
|
||||
|
||||
{:ok, response} = HTTPoison.post(@get_endpoint, Jason.encode!(params), @headers)
|
||||
{:ok, response} = HTTPClient.post(@get_endpoint, @headers, Jason.encode!(params))
|
||||
body = Jason.decode!(response.body)
|
||||
|
||||
if body["success"] do
|
||||
@ -94,7 +96,7 @@ defmodule Plausible.Billing.PaddleApi do
|
||||
to: Timex.shift(Timex.today(), days: 1) |> Timex.format!("{YYYY}-{0M}-{0D}")
|
||||
}
|
||||
|
||||
case HTTPoison.post(invoices_endpoint(), Jason.encode!(params), @headers) do
|
||||
case HTTPClient.post(invoices_endpoint(), @headers, Jason.encode!(params)) do
|
||||
{:ok, response} ->
|
||||
body = Jason.decode!(response.body)
|
||||
|
||||
|
@ -1,4 +1,6 @@
|
||||
defmodule Plausible.Google.HTTP do
|
||||
alias Plausible.HTTPClient
|
||||
|
||||
@spec get_report(module(), Plausible.Google.ReportRequest.t()) ::
|
||||
{:ok, {[map()], String.t() | nil}} | {:error, any()}
|
||||
def get_report(http_client, %Plausible.Google.ReportRequest{} = report_request) do
|
||||
@ -58,31 +60,46 @@ defmodule Plausible.Google.HTTP do
|
||||
end
|
||||
|
||||
def list_sites(access_token) do
|
||||
"https://www.googleapis.com/webmasters/v3/sites"
|
||||
|> HTTPoison.get!("Content-Type": "application/json", Authorization: "Bearer #{access_token}")
|
||||
url = "https://www.googleapis.com/webmasters/v3/sites"
|
||||
headers = [{"Content-Type", "application/json"}, {"Authorization", "Bearer #{access_token}"}]
|
||||
|
||||
{:ok, response} = HTTPClient.get(url, headers)
|
||||
|
||||
response
|
||||
|> Map.get(:body)
|
||||
|> Jason.decode!()
|
||||
|> then(&{:ok, &1})
|
||||
end
|
||||
|
||||
def fetch_access_token(code) do
|
||||
"https://www.googleapis.com/oauth2/v4/token"
|
||||
|> HTTPoison.post!(
|
||||
"client_id=#{client_id()}&client_secret=#{client_secret()}&code=#{code}&grant_type=authorization_code&redirect_uri=#{redirect_uri()}",
|
||||
"Content-Type": "application/x-www-form-urlencoded"
|
||||
)
|
||||
url = "https://www.googleapis.com/oauth2/v4/token"
|
||||
headers = [{"Content-Type", "application/x-www-form-urlencoded"}]
|
||||
|
||||
params =
|
||||
"client_id=#{client_id()}&client_secret=#{client_secret()}&code=#{code}&grant_type=authorization_code&redirect_uri=#{redirect_uri()}"
|
||||
|
||||
{:ok, response} = HTTPClient.post(url, headers, params)
|
||||
|
||||
response
|
||||
|> Map.get(:body)
|
||||
|> Jason.decode!()
|
||||
end
|
||||
|
||||
def list_views_for_user(access_token) do
|
||||
"https://www.googleapis.com/analytics/v3/management/accounts/~all/webproperties/~all/profiles"
|
||||
|> HTTPoison.get!(Authorization: "Bearer #{access_token}")
|
||||
|> case do
|
||||
%{body: body, status_code: 200} ->
|
||||
url =
|
||||
"https://www.googleapis.com/analytics/v3/management/accounts/~all/webproperties/~all/profiles"
|
||||
|
||||
headers = [{"Authorization", "Bearer #{access_token}"}]
|
||||
|
||||
case HTTPClient.get(url, headers) do
|
||||
{:ok, %Finch.Response{body: body, status: 200}} ->
|
||||
{:ok, Jason.decode!(body)}
|
||||
|
||||
%{body: body} ->
|
||||
{:error, %Mint.TransportError{reason: reason}} ->
|
||||
Sentry.capture_message("Error fetching Google view ID", extra: inspect(reason))
|
||||
{:error, reason}
|
||||
|
||||
{:error, %Finch.Response{body: body}} ->
|
||||
Sentry.capture_message("Error fetching Google view ID", extra: Jason.decode!(body))
|
||||
{:error, body}
|
||||
end
|
||||
@ -108,27 +125,23 @@ defmodule Plausible.Google.HTTP do
|
||||
dimensionFilterGroups: filter_groups
|
||||
})
|
||||
|
||||
:post
|
||||
|> Finch.build(
|
||||
"https://www.googleapis.com/webmasters/v3/sites/#{property}/searchAnalytics/query",
|
||||
[{"Authorization", "Bearer #{access_token}"}],
|
||||
params
|
||||
)
|
||||
|> Finch.request(Plausible.Finch)
|
||||
|> case do
|
||||
{:ok, %{status: 200, body: body}} ->
|
||||
url = "https://www.googleapis.com/webmasters/v3/sites/#{property}/searchAnalytics/query"
|
||||
headers = [{"Authorization", "Bearer #{access_token}"}]
|
||||
|
||||
case HTTPClient.post(url, headers, params) do
|
||||
{:ok, %Finch.Response{body: body, status: 200}} ->
|
||||
{:ok, Jason.decode!(body)}
|
||||
|
||||
{:ok, %{status: 401, body: body}} ->
|
||||
{:ok, %Finch.Response{body: body, status: 401}} ->
|
||||
Sentry.capture_message("Error fetching Google queries", extra: Jason.decode!(body))
|
||||
{:error, :invalid_credentials}
|
||||
|
||||
{:ok, %{status: 403, body: body}} ->
|
||||
{:ok, %Finch.Response{body: body, status: 403}} ->
|
||||
body = Jason.decode!(body)
|
||||
Sentry.capture_message("Error fetching Google queries", extra: body)
|
||||
{:error, get_in(body, ["error", "message"])}
|
||||
|
||||
{:ok, %{body: body}} ->
|
||||
{:ok, %Finch.Response{body: body}} ->
|
||||
Sentry.capture_message("Error fetching Google queries", extra: Jason.decode!(body))
|
||||
{:error, :unknown}
|
||||
end
|
||||
@ -138,16 +151,17 @@ defmodule Plausible.Google.HTTP do
|
||||
defp property_base_url(url), do: url
|
||||
|
||||
def refresh_auth_token(refresh_token) do
|
||||
"https://www.googleapis.com/oauth2/v4/token"
|
||||
|> HTTPoison.post!(
|
||||
"client_id=#{client_id()}&client_secret=#{client_secret()}&refresh_token=#{refresh_token}&grant_type=refresh_token&redirect_uri=#{redirect_uri()}",
|
||||
"Content-Type": "application/x-www-form-urlencoded"
|
||||
)
|
||||
|> case do
|
||||
%{body: body, status_code: 200} ->
|
||||
url = "https://www.googleapis.com/oauth2/v4/token"
|
||||
headers = [{"Content-Type", "application/x-www-form-urlencoded"}]
|
||||
|
||||
params =
|
||||
"client_id=#{client_id()}&client_secret=#{client_secret()}&refresh_token=#{refresh_token}&grant_type=refresh_token&redirect_uri=#{redirect_uri()}"
|
||||
|
||||
case HTTPClient.post(url, headers, params) do
|
||||
{:ok, %Finch.Response{body: body, status: 200}} ->
|
||||
{:ok, Jason.decode!(body)}
|
||||
|
||||
%{body: body} ->
|
||||
{:error, %Finch.Response{body: body}} ->
|
||||
body
|
||||
|> Jason.decode!(body)
|
||||
|> Map.get("error")
|
||||
@ -175,15 +189,11 @@ defmodule Plausible.Google.HTTP do
|
||||
]
|
||||
})
|
||||
|
||||
"https://analyticsreporting.googleapis.com/v4/reports:batchGet"
|
||||
|> HTTPoison.post!(
|
||||
params,
|
||||
[Authorization: "Bearer #{access_token}"],
|
||||
timeout: 15_000,
|
||||
recv_timeout: 15_000
|
||||
)
|
||||
|> case do
|
||||
%{status_code: 200, body: body} ->
|
||||
url = "https://analyticsreporting.googleapis.com/v4/reports:batchGet"
|
||||
headers = [{"Authorization", "Bearer #{access_token}"}]
|
||||
|
||||
case HTTPClient.post(url, headers, params) do
|
||||
{:ok, %Finch.Response{body: body, status: 200}} ->
|
||||
report = List.first(Jason.decode!(body)["reports"])
|
||||
|
||||
date =
|
||||
@ -197,7 +207,7 @@ defmodule Plausible.Google.HTTP do
|
||||
|
||||
{:ok, date}
|
||||
|
||||
%{body: body} ->
|
||||
{:error, %Finch.Response{body: body}} ->
|
||||
Sentry.capture_message("Error fetching Google view ID", extra: Jason.decode!(body))
|
||||
{:error, body}
|
||||
end
|
||||
|
33
lib/plausible/http_client.ex
Normal file
33
lib/plausible/http_client.ex
Normal file
@ -0,0 +1,33 @@
|
||||
defmodule Plausible.HTTPClient do
|
||||
@moduledoc """
|
||||
HTTP Client built on top of Finch.
|
||||
"""
|
||||
|
||||
@doc """
|
||||
Make a POST request
|
||||
"""
|
||||
def post(url, headers \\ [], params \\ nil) do
|
||||
call(:post, url, headers, params)
|
||||
end
|
||||
|
||||
@doc """
|
||||
Make a GET request
|
||||
"""
|
||||
def get(url, headers \\ [], params \\ nil) do
|
||||
call(:get, url, headers, params)
|
||||
end
|
||||
|
||||
defp call(method, url, headers, params) do
|
||||
method
|
||||
|> build_request(url, headers, params)
|
||||
|> do_request
|
||||
end
|
||||
|
||||
defp build_request(method, url, headers, params) do
|
||||
Finch.build(method, url, headers, params)
|
||||
end
|
||||
|
||||
defp do_request(request) do
|
||||
Finch.request(request, Plausible.Finch)
|
||||
end
|
||||
end
|
@ -1,4 +1,6 @@
|
||||
defmodule PlausibleWeb.Captcha do
|
||||
alias Plausible.HTTPClient
|
||||
|
||||
@verify_endpoint "https://hcaptcha.com/siteverify"
|
||||
|
||||
def enabled? do
|
||||
@ -13,7 +15,11 @@ defmodule PlausibleWeb.Captcha do
|
||||
def verify(token) do
|
||||
if enabled?() do
|
||||
res =
|
||||
HTTPoison.post!(@verify_endpoint, {:form, [{"response", token}, {"secret", secret()}]})
|
||||
HTTPClient.post(
|
||||
@verify_endpoint,
|
||||
[],
|
||||
{:form, [{"response", token}, {"secret", secret()}]}
|
||||
)
|
||||
|
||||
json = Jason.decode!(res.body)
|
||||
json["success"]
|
||||
|
@ -1,5 +1,6 @@
|
||||
defmodule PlausibleWeb.Favicon do
|
||||
import Plug.Conn
|
||||
alias Plausible.HTTPClient
|
||||
|
||||
def init(_) do
|
||||
domains =
|
||||
@ -19,7 +20,7 @@ defmodule PlausibleWeb.Favicon do
|
||||
["favicon", "sources", source] ->
|
||||
clean_source = URI.decode_www_form(source)
|
||||
domain = Map.get(favicon_domains, clean_source, clean_source)
|
||||
res = HTTPoison.get!("https://icons.duckduckgo.com/ip3/#{domain}.ico")
|
||||
res = HTTPClient.get("https://icons.duckduckgo.com/ip3/#{domain}.ico")
|
||||
|
||||
conn =
|
||||
Enum.filter(res.headers, fn {key, _val} -> key != "Transfer-Encoding" end)
|
||||
|
Loading…
Reference in New Issue
Block a user