defmodule Plausible.Workers.SendEmailReport do use Plausible.Repo use Oban.Worker, queue: :send_email_reports, max_attempts: 1 alias Plausible.Stats.Query alias Plausible.Stats.Clickhouse, as: Stats @impl Oban.Worker def perform(%Oban.Job{args: %{"interval" => "weekly", "site_id" => site_id}}) do site = Repo.get(Plausible.Site, site_id) |> Repo.preload(:weekly_report) today = Timex.now(site.timezone) |> DateTime.to_date() date = Timex.shift(today, weeks: -1) |> Timex.end_of_week() |> Date.to_iso8601() query = Query.from(site.timezone, %{"period" => "7d", "date" => date}) for email <- site.weekly_report.recipients do unsubscribe_link = PlausibleWeb.Endpoint.url() <> "/sites/#{URI.encode_www_form(site.domain)}/weekly-report/unsubscribe?email=#{email}" send_report(email, site, "Weekly", unsubscribe_link, query) end :ok end @impl Oban.Worker def perform(%Oban.Job{args: %{"interval" => "monthly", "site_id" => site_id}}) do site = Repo.get(Plausible.Site, site_id) |> Repo.preload(:monthly_report) last_month = Timex.now(site.timezone) |> Timex.shift(months: -1) |> Timex.beginning_of_month() query = Query.from(site.timezone, %{ "period" => "month", "date" => Timex.format!(last_month, "{ISOdate}") }) for email <- site.monthly_report.recipients do unsubscribe_link = PlausibleWeb.Endpoint.url() <> "/sites/#{URI.encode_www_form(site.domain)}/monthly-report/unsubscribe?email=#{email}" send_report(email, site, Timex.format!(last_month, "{Mfull}"), unsubscribe_link, query) end :ok end defp send_report(email, site, name, unsubscribe_link, query) do {pageviews, unique_visitors} = Stats.pageviews_and_visitors(site, query) {change_pageviews, change_visitors} = Stats.compare_pageviews_and_visitors(site, query, {pageviews, unique_visitors}) bounce_rate = Stats.bounce_rate(site, query) prev_bounce_rate = Stats.bounce_rate(site, Query.shift_back(query, site)) change_bounce_rate = if prev_bounce_rate > 0, do: bounce_rate - prev_bounce_rate referrers = Stats.top_sources(site, query, 5, 1, []) pages = Stats.top_pages(site, query, 5, 1, []) user = Plausible.Auth.find_user_by(email: email) login_link = user && Plausible.Sites.is_member?(user.id, site) template = PlausibleWeb.Email.weekly_report(email, site, unique_visitors: unique_visitors, change_visitors: change_visitors, pageviews: pageviews, change_pageviews: change_pageviews, bounce_rate: bounce_rate, change_bounce_rate: change_bounce_rate, referrers: referrers, unsubscribe_link: unsubscribe_link, login_link: login_link, pages: pages, query: query, name: name ) try do Plausible.Mailer.send_email(template) rescue _ -> nil end end end