diff --git a/config/config.exs b/config/config.exs
index b0036fff0..53ea76dd3 100644
--- a/config/config.exs
+++ b/config/config.exs
@@ -502,7 +502,11 @@
mailer: 10,
transmogrifier: 20,
scheduled_activities: 10,
- background: 5
+ background: 5,
+ new_users_digest: 1
+ ],
+ crontab: [
+ {"0 0 * * *", Pleroma.Workers.NewUsersDigestWorker}
]
config :pleroma, :workers,
diff --git a/lib/pleroma/emails/new_users_digest_email.ex b/lib/pleroma/emails/new_users_digest_email.ex
new file mode 100644
index 000000000..21096a744
--- /dev/null
+++ b/lib/pleroma/emails/new_users_digest_email.ex
@@ -0,0 +1,36 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2019 Pleroma Authors
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Emails.NewUsersDigestEmail do
+ use Phoenix.Swoosh, view: Pleroma.Web.EmailView, layout: {Pleroma.Web.LayoutView, :email_styled}
+
+ defp instance_notify_email do
+ Pleroma.Config.get([:instance, :notify_email]) || Pleroma.Config.get([:instance, :email])
+ end
+
+ def new_users(to, users_and_statuses) do
+ instance_name = Pleroma.Config.get([:instance, :name])
+ styling = Pleroma.Config.get([Pleroma.Emails.UserEmail, :styling])
+ logo = Pleroma.Config.get([Pleroma.Emails.UserEmail, :logo])
+
+ logo_path =
+ if is_nil(logo) do
+ Path.join(:code.priv_dir(:pleroma), "static/static/logo.png")
+ else
+ Path.join(Pleroma.Config.get([:instance, :static_dir]), logo)
+ end
+
+ new()
+ |> to({to.name, to.email})
+ |> from({instance_name, instance_notify_email()})
+ |> subject("#{instance_name} New Users")
+ |> render_body("new_users_digest.html", %{
+ title: "New Users",
+ users_and_statuses: users_and_statuses,
+ instance: instance_name,
+ styling: styling
+ })
+ |> attachment(Swoosh.Attachment.new(logo_path, filename: "logo.png", type: :inline))
+ end
+end
diff --git a/lib/pleroma/web/templates/email/new_users_digest.html.eex b/lib/pleroma/web/templates/email/new_users_digest.html.eex
new file mode 100644
index 000000000..40d9b8381
--- /dev/null
+++ b/lib/pleroma/web/templates/email/new_users_digest.html.eex
@@ -0,0 +1,158 @@
+<%= for {user, total_statuses, latest_status} <- @users_and_statuses do %>
+ <%# user card START %>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
<%= user.name %>
+
<%= link "@" <> user.nickname, style: "color: #{@styling.link_color};text-decoration: none;", to: admin_user_url(user) %>
+
Total: <%= total_statuses %>
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <%# user card END %>
+
+ <%= if latest_status do %>
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <%= raw latest_status.object.data["content"] %>
+
+
+
+
+
+
<%= format_date latest_status.object.data["published"] %>
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <% end %>
+ <%# divider start %>
+
+
+ <%# divider end %>
+ <%# user card END %>
+<% end %>
diff --git a/lib/pleroma/web/templates/layout/email_styled.html.eex b/lib/pleroma/web/templates/layout/email_styled.html.eex
new file mode 100644
index 000000000..295d2bba0
--- /dev/null
+++ b/lib/pleroma/web/templates/layout/email_styled.html.eex
@@ -0,0 +1,193 @@
+
+
+
+
+
+
+
+
+
+
+
+ <%= @email.subject %><
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <%# header %>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <%# title %>
+ <%= if @title do %>
+
+ <% end %>
+ <%= render @view_module, @view_template, assigns %>
+
+ |
+
+
+
+
+
+
+
diff --git a/lib/pleroma/web/views/email_view.ex b/lib/pleroma/web/views/email_view.ex
index b506a234b..6b0fbe61e 100644
--- a/lib/pleroma/web/views/email_view.ex
+++ b/lib/pleroma/web/views/email_view.ex
@@ -12,4 +12,8 @@ def format_date(date) when is_binary(date) do
|> Timex.parse!("{ISO:Extended:Z}")
|> Timex.format!("{Mshort} {D}, {YYYY} {h24}:{m}")
end
+
+ def admin_user_url(%{id: id}) do
+ Pleroma.Web.Endpoint.url() <> "/pleroma/admin/#/users/" <> id
+ end
end
diff --git a/lib/pleroma/workers/new_users_digest_worker.ex b/lib/pleroma/workers/new_users_digest_worker.ex
new file mode 100644
index 000000000..24cc6bdf3
--- /dev/null
+++ b/lib/pleroma/workers/new_users_digest_worker.ex
@@ -0,0 +1,56 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2019 Pleroma Authors
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Workers.NewUsersDigestWorker do
+ alias Pleroma.User
+ alias Pleroma.Repo
+ alias Pleroma.Activity
+
+ import Ecto.Query
+
+ use Pleroma.Workers.WorkerHelper, queue: "new_users_digest"
+
+ @impl Oban.Worker
+ def perform(_args, _job) do
+ today = NaiveDateTime.utc_now() |> Timex.beginning_of_day()
+
+ a_day_ago =
+ today
+ |> Timex.shift(days: -1)
+ |> Timex.beginning_of_day()
+
+ users_and_statuses =
+ %{
+ local: true,
+ order_by: :inserted_at
+ }
+ |> User.Query.build()
+ |> where([u], u.inserted_at >= ^a_day_ago and u.inserted_at < ^today)
+ |> Repo.all()
+ |> Enum.map(fn user ->
+ latest_status =
+ Activity
+ |> Activity.Queries.by_actor(user.ap_id)
+ |> Activity.Queries.by_type("Create")
+ |> Activity.with_preloaded_object()
+ |> order_by(desc: :inserted_at)
+ |> limit(1)
+ |> Repo.one()
+
+ total_statuses =
+ Activity
+ |> Activity.Queries.by_actor(user.ap_id)
+ |> Activity.Queries.by_type("Create")
+ |> Repo.aggregate(:count, :id)
+
+ {user, total_statuses, latest_status}
+ end)
+
+ %{is_admin: true}
+ |> User.Query.build()
+ |> Repo.all()
+ |> Enum.map(&Pleroma.Emails.NewUsersDigestEmail.new_users(&1, users_and_statuses))
+ |> Enum.each(&Pleroma.Emails.Mailer.deliver/1)
+ end
+end
diff --git a/test/workers/cron/new_users_digest_worker_test.exs b/test/workers/cron/new_users_digest_worker_test.exs
new file mode 100644
index 000000000..7892a7809
--- /dev/null
+++ b/test/workers/cron/new_users_digest_worker_test.exs
@@ -0,0 +1,32 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2019 Pleroma Authors
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Workers.Cron.NewUsersDigestWorkerTest do
+ use Pleroma.DataCase
+ import Pleroma.Factory
+
+ alias Pleroma.Workers.NewUsersDigestWorker
+ alias Pleroma.Tests.ObanHelpers
+ alias Pleroma.Web.CommonAPI
+
+ test "it sends new users digest emails" do
+ yesterday = NaiveDateTime.utc_now() |> Timex.shift(days: -1)
+ admin = insert(:user, %{is_admin: true})
+ user = insert(:user, %{inserted_at: yesterday})
+ user2 = insert(:user, %{inserted_at: yesterday})
+ CommonAPI.post(user, %{"status" => "cofe"})
+
+ NewUsersDigestWorker.perform(nil, nil)
+ ObanHelpers.perform_all()
+
+ assert_received {:email, email}
+ assert email.to == [{admin.name, admin.email}]
+ assert email.subject == "#{Pleroma.Config.get([:instance, :name])} New Users"
+
+ refute email.html_body =~ admin.nickname
+ assert email.html_body =~ user.nickname
+ assert email.html_body =~ user2.nickname
+ assert email.html_body =~ "cofe"
+ end
+end