Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
ukutaht committed May 7, 2024
1 parent 62138e0 commit 2e193c4
Show file tree
Hide file tree
Showing 5 changed files with 460 additions and 38 deletions.
92 changes: 91 additions & 1 deletion lib/plausible/google/api.ex
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ defmodule Plausible.Google.API do
alias Plausible.Google.HTTP

require Logger
import Plausible.Stats.Base, only: [page_regex: 1]

@search_console_scope URI.encode_www_form(
"email https://www.googleapis.com/auth/webmasters.readonly"
Expand Down Expand Up @@ -76,19 +77,24 @@ defmodule Plausible.Google.API do
def fetch_stats(site, %{filters: %{} = filters, date_range: date_range}, limit) do
with site <- Plausible.Repo.preload(site, :google_auth),
{:ok, access_token} <- maybe_refresh_token(site.google_auth),
{:ok, search_console_filters} <-
get_search_console_filters(site.google_auth.property, filters),
{:ok, stats} <-
HTTP.list_stats(
access_token,
site.google_auth.property,
date_range,
limit,
filters["page"]
search_console_filters
) do
stats
|> Map.get("rows", [])
|> Enum.filter(fn row -> row["clicks"] > 0 end)
|> Enum.map(fn row -> %{name: row["keys"], visitors: round(row["clicks"])} end)
|> then(&{:ok, &1})
else
# Show empty report to user with message about not being able to get keyword data for this set of filters
:bad_filters -> raise "FILTERS ARE BAD"
end
end

Expand Down Expand Up @@ -142,6 +148,90 @@ defmodule Plausible.Google.API do
Timex.before?(expires_at, thirty_seconds_ago)
end

defp get_search_console_filters(property, plausible_filters) do
plausible_filters = Map.drop(plausible_filters, ["visit:source"])

search_console_filters =
Enum.reduce_while(plausible_filters, [], fn plausible_filter, search_console_filters ->
case transform_filter(property, plausible_filter) do
:err -> {:halt, :bad_filters}
search_console_filter -> {:cont, [search_console_filter | search_console_filters]}
end
end)

case search_console_filters do
:bad_filters -> :bad_filters
filters when is_list(filters) -> {:ok, [%{filters: filters}]}
end
|> IO.inspect()
end

defp transform_filter(property, {"event:page", filter}) do
transform_filter(property, {"visit:entry_page", filter})
end

defp transform_filter(property, {"visit:entry_page", {:is, page}}) when is_binary(page) do
%{dimension: "page", expression: property_url(property, page)}
end

defp transform_filter(property, {"visit:entry_page", {:member, pages}}) when is_list(pages) do
expression =
Enum.map(pages, fn page -> property_url(property, Regex.escape(page)) end) |> Enum.join("|")

%{dimension: "page", operator: "includingRegex", expression: expression}
end

defp transform_filter(property, {"visit:entry_page", {:matches, page}}) when is_binary(page) do
page = page_regex(property_url(property, page))
%{dimension: "page", operator: "includingRegex", expression: page}
end

defp transform_filter(property, {"visit:entry_page", {:matches_member, pages}})
when is_list(pages) do
expression = Enum.map(pages, fn page -> page_regex(page) end) |> Enum.join("|")
%{dimension: "page", operator: "includingRegex", expression: expression}
end

defp transform_filter(_property, {"visit:screen", {:is, device}}) when is_binary(device) do
%{dimension: "device", expression: search_console_device(device)}
end

defp transform_filter(_property, {"visit:screen", {:is, device}}) when is_binary(device) do
%{dimension: "device", expression: search_console_device(device)}
end

defp transform_filter(_property, {"visit:screen", {:member, devices}}) when is_list(devices) do
expression = devices |> Enum.join("|")
%{dimension: "device", operator: "includingRegex", expression: expression}
end

defp transform_filter(_property, {"visit:country", {:is, country}}) when is_binary(country) do
%{dimension: "country", expression: search_console_country(country)}
end

defp transform_filter(_property, {"visit:country", {:member, countries}})
when is_list(countries) do
expression = Enum.map(countries, &search_console_country/1) |> Enum.join("|")
%{dimension: "country", operator: "includingRegex", expression: expression}
end

defp transform_filter(_, filter) do
IO.inspect(filter)
:err
end

defp property_url("sc-domain:" <> domain, page), do: "https://" <> domain <> page
defp property_url(url, page), do: url <> page

defp search_console_device("Desktop"), do: "DESKTOP"
defp search_console_device("Mobile"), do: "MOBILE"
defp search_console_device("Tablet"), do: "TABLET"

defp search_console_country(alpha_2) do
country = Location.Country.get_country(alpha_2)
country.alpha_3
end

defp client_id() do
Keyword.fetch!(Application.get_env(:plausible, :google), :client_id)
end
Expand Down
21 changes: 5 additions & 16 deletions lib/plausible/google/http.ex
Original file line number Diff line number Diff line change
Expand Up @@ -39,26 +39,18 @@ defmodule Plausible.Google.HTTP do
response.body
end

def list_stats(access_token, property, date_range, limit, page \\ nil) do
property = URI.encode_www_form(property)

filter_groups =
if page do
url = property_base_url(property)
[%{filters: [%{dimension: "page", expression: "https://#{url}#{page}"}]}]
else
%{}
end

def list_stats(access_token, property, date_range, limit, filters) do
params = %{
startDate: Date.to_iso8601(date_range.first),
endDate: Date.to_iso8601(date_range.last),
dimensions: ["query"],
rowLimit: limit,
dimensionFilterGroups: filter_groups
dimensionFilterGroups: filters
}

url = "#{api_url()}/webmasters/v3/sites/#{property}/searchAnalytics/query"
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
Expand All @@ -78,9 +70,6 @@ defmodule Plausible.Google.HTTP do
end
end

defp property_base_url("sc-domain:" <> domain), do: "https://" <> domain
defp property_base_url(url), do: url

def refresh_auth_token(refresh_token) do
url = "#{api_url()}/oauth2/v4/token"
headers = [{"content-type", "application/x-www-form-urlencoded"}]
Expand Down

0 comments on commit 2e193c4

Please sign in to comment.