File size: 3,398 Bytes
8da2481 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 | defmodule Plausible.Google.HTTP do
@moduledoc """
HTTP client implementation for Google APIs.
"""
require Logger
alias Plausible.HTTPClient
def list_sites(access_token) do
url = "#{api_url()}/webmasters/v3/sites"
headers = [{"Content-Type", "application/json"}, {"Authorization", "Bearer #{access_token}"}]
case HTTPClient.impl().get(url, headers) do
{:ok, %{body: body}} ->
{:ok, body}
{:error, %{reason: %{status: s}}} when s in [401, 403] ->
{:error, "google_auth_error"}
{:error, %{reason: %{body: %{"error" => error}}}} ->
{:error, error}
{:error, reason} ->
Logger.error("Google Analytics: failed to list sites: #{inspect(reason)}")
{:error, "failed_to_list_sites"}
end
end
def fetch_access_token!(code) do
url = "#{api_url()}/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.impl().post(url, headers, params)
response.body
end
def list_stats(access_token, property, date_range, pagination, search_console_filters) do
{limit, page} = pagination
params = %{
startDate: Date.to_iso8601(date_range.first),
endDate: Date.to_iso8601(date_range.last),
dimensions: ["query"],
rowLimit: limit,
startRow: page * limit,
dimensionFilterGroups: search_console_filters
}
url =
"#{api_url()}/webmasters/v3/sites/#{URI.encode_www_form(property)}/searchAnalytics/query"
headers = [{"Authorization", "Bearer #{access_token}"}]
case HTTPClient.impl().post(url, headers, params) do
{:ok, %Finch.Response{body: body, status: 200}} ->
{:ok, body}
{:error, %{reason: %Finch.Response{body: _body, status: status}}}
when status in [401, 403] ->
{:error, "google_auth_error"}
{:error, %{reason: %{body: %{"error" => error}}}} ->
{:error, error}
{:error, reason} ->
Logger.error("Google Search Console: failed to list stats: #{inspect(reason)}")
{:error, "failed_to_list_stats"}
end
end
def refresh_auth_token(refresh_token) do
url = "#{api_url()}/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.impl().post(url, headers, params) do
{:ok, %Finch.Response{body: body, status: 200}} ->
{:ok, body}
{:error, %{reason: %Finch.Response{body: %{"error" => error}, status: _non_http_200}}} ->
{:error, error}
{:error, %{reason: _} = e} ->
Sentry.capture_message("Error fetching Google queries", extra: %{error: inspect(e)})
{:error, :unknown_error}
end
end
defp config, do: Application.get_env(:plausible, :google)
defp client_id, do: Keyword.fetch!(config(), :client_id)
defp client_secret, do: Keyword.fetch!(config(), :client_secret)
defp api_url, do: Keyword.fetch!(config(), :api_url)
defp redirect_uri, do: PlausibleWeb.Endpoint.url() <> "/auth/google/callback"
end
|