Просмотр исходного кода

added welcome email

frontends/logic-flow
Maksim Pechnikov 3 лет назад
Родитель
Сommit
3edaecae96
12 измененных файлов: 212 добавлений и 30 удалений
  1. +1
    -0
      CHANGELOG.md
  2. +14
    -2
      config/config.exs
  3. +12
    -0
      docs/configuration/cheatsheet.md
  4. +17
    -0
      lib/pleroma/config/helpers.ex
  5. +17
    -0
      lib/pleroma/config/utils.ex
  6. +11
    -6
      lib/pleroma/emails/user_email.ex
  7. +20
    -1
      lib/pleroma/user.ex
  8. +68
    -0
      lib/pleroma/user/welcome_email.ex
  9. +27
    -14
      lib/pleroma/user/welcome_message.ex
  10. +1
    -0
      test/emails/user_email_test.exs
  11. +1
    -3
      test/tasks/config_test.exs
  12. +23
    -4
      test/user_test.exs

+ 1
- 0
CHANGELOG.md Просмотреть файл

@@ -64,6 +64,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Support pagination in emoji packs API (for packs and for files in pack)
- Support for viewing instances favicons next to posts and accounts
- Added Pleroma.Upload.Filter.Exiftool as an alternate EXIF stripping mechanism targeting GPS/location metadata.
- Configuration: Add `:welcome` setting for welcoming message to a newly registered users.

<details>
<summary>API Changes</summary>


+ 14
- 2
config/config.exs Просмотреть файл

@@ -225,8 +225,6 @@ config :pleroma, :instance,
autofollowed_nicknames: [],
max_pinned_statuses: 1,
attachment_links: false,
welcome_user_nickname: nil,
welcome_message: nil,
max_report_comment_size: 1000,
safe_dm_mentions: false,
healthcheck: false,
@@ -254,6 +252,20 @@ config :pleroma, :instance,
]
]

config :pleroma, :welcome,
direct_message: [
enabled: false,
sender_nickname: nil,
message: nil
],
email: [
enabled: false,
sender_nickname: nil,
subject: "Welcome to <%= instance_name %>",
html: "Welcome to <%= instance_name %>",
text: "Welcome to <%= instance_name %>"
]

config :pleroma, :feed,
post_title: %{
max_length: 100,


+ 12
- 0
docs/configuration/cheatsheet.md Просмотреть файл

@@ -63,6 +63,18 @@ To add configuration to your config file, you can copy it from the base config.
* `external_user_synchronization`: Enabling following/followers counters synchronization for external users.
* `cleanup_attachments`: Remove attachments along with statuses. Does not affect duplicate files and attachments without status. Enabling this will increase load to database when deleting statuses on larger instances.

## Welcome
* `direct_message`: - welcome message sent as a direct message.
* `enabled`: Enables the send a direct message to a newly registered user. Defaults to `false`.
* `sender_nickname`: The nickname of the local user that sends the welcome message.
* `message`: A message that will be send to a newly registered users as a direct message.
* `email`: - welcome message sent as a email.
* `enabled`: Enables the send a welcome email to a newly registered user. Defaults to `false`.
* `sender_nickname`: The nickname of the local user that sends the welcome email.
* `subject`: A subject of welcome email.
* `html`: A html that will be send to a newly registered users as a email.
* `text`: A text that will be send to a newly registered users as a email.

## Message rewrite facility

### :mrf


+ 17
- 0
lib/pleroma/config/helpers.ex Просмотреть файл

@@ -0,0 +1,17 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only

defmodule Pleroma.Config.Helpers do
alias Pleroma.Config

def instance_name, do: Config.get([:instance, :name])

defp instance_notify_email do
Config.get([:instance, :notify_email]) || Config.get([:instance, :email])
end

def sender do
{instance_name(), instance_notify_email()}
end
end

+ 17
- 0
lib/pleroma/config/utils.ex Просмотреть файл

@@ -0,0 +1,17 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only

defmodule Pleroma.Config.Utils do
alias Pleroma.Config

def instance_name, do: Config.get([:instance, :name])

defp instance_notify_email do
Config.get([:instance, :notify_email]) || Config.get([:instance, :email])
end

def sender do
{instance_name(), instance_notify_email()}
end
end

+ 11
- 6
lib/pleroma/emails/user_email.ex Просмотреть файл

@@ -12,17 +12,22 @@ defmodule Pleroma.Emails.UserEmail do
alias Pleroma.Web.Endpoint
alias Pleroma.Web.Router

defp instance_name, do: Config.get([:instance, :name])

defp sender do
email = Config.get([:instance, :notify_email]) || Config.get([:instance, :email])
{instance_name(), email}
end
import Pleroma.Config.Helpers, only: [instance_name: 0, sender: 0]

defp recipient(email, nil), do: email
defp recipient(email, name), do: {name, email}
defp recipient(%User{} = user), do: recipient(user.email, user.name)

@spec welcome(User.t(), map()) :: Swoosh.Email.t()
def welcome(user, opts \\ %{}) do
new()
|> to(recipient(user))
|> from(Map.get(opts, :sender, sender()))
|> subject(Map.get(opts, :subject, "Welcome to #{instance_name()}!"))
|> html_body(Map.get(opts, :html, "Welcome to #{instance_name()}!"))
|> text_body(Map.get(opts, :text, "Welcome to #{instance_name()}!"))
end

def password_reset_email(user, token) when is_binary(token) do
password_reset_url = Router.Helpers.reset_password_url(Endpoint, :reset, token)



+ 20
- 1
lib/pleroma/user.ex Просмотреть файл

@@ -713,12 +713,31 @@ defmodule Pleroma.User do
def post_register_action(%User{} = user) do
with {:ok, user} <- autofollow_users(user),
{:ok, user} <- set_cache(user),
{:ok, _} <- User.WelcomeMessage.post_welcome_message_to_user(user),
{:ok, _} <- send_welcome_email(user),
{:ok, _} <- send_welcome_message(user),
{:ok, _} <- try_send_confirmation_email(user) do
{:ok, user}
end
end

def send_welcome_message(user) do
if User.WelcomeMessage.enabled?() do
User.WelcomeMessage.post_message(user)
{:ok, :enqueued}
else
{:ok, :noop}
end
end

def send_welcome_email(user) do
if User.WelcomeEmail.enabled?() do
User.WelcomeEmail.send_email(user)
{:ok, :enqueued}
else
{:ok, :noop}
end
end

def try_send_confirmation_email(%User{} = user) do
if user.confirmation_pending &&
Config.get([:instance, :account_activation_required]) do


+ 68
- 0
lib/pleroma/user/welcome_email.ex Просмотреть файл

@@ -0,0 +1,68 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only

defmodule Pleroma.User.WelcomeEmail do
@moduledoc """
The module represents the functions to send welcome email.
"""

alias Pleroma.Config
alias Pleroma.Emails
alias Pleroma.User

import Pleroma.Config.Utils, only: [instance_name: 0]

@spec enabled?() :: boolean()
def enabled?, do: Config.get([:welcome, :email, :enabled], false)

@spec send_email(User.t()) :: {:ok, Oban.Job.t()}
def send_email(%User{} = user) do
user
|> Emails.UserEmail.welcome(email_options(user))
|> Emails.Mailer.deliver_async()
end

defp email_options(user) do
bindings = [user: user, instance_name: instance_name()]

%{}
|> add_sender(Config.get([:welcome, :email, :sender_nickname], nil))
|> add_option(:subject, bindings)
|> add_option(:html, bindings)
|> add_option(:text, bindings)
end

defp add_option(opts, option, bindings) do
[:welcome, :email, option]
|> Config.get(nil)
|> eval_string(bindings)
|> merge_options(opts, option)
end

def add_sender(opts, nickname) do
nickname
|> fetch_sender()
|> merge_options(opts, :sender)
end

defp merge_options(nil, options, _option), do: options

defp merge_options(value, options, option) do
Map.merge(options, %{option => value})
end

defp fetch_sender(nickname) when is_binary(nickname) do
with %User{local: true} = user <- User.get_cached_by_nickname(nickname) do
{instance_name(), user.email}
else
_ -> nil
end
end

defp fetch_sender(_), do: nil

defp eval_string(nil, _), do: nil
defp eval_string("", _), do: nil
defp eval_string(str, bindings), do: EEx.eval_string(str, bindings)
end

+ 27
- 14
lib/pleroma/user/welcome_message.ex Просмотреть файл

@@ -3,32 +3,45 @@
# SPDX-License-Identifier: AGPL-3.0-only

defmodule Pleroma.User.WelcomeMessage do
alias Pleroma.Config
alias Pleroma.User
alias Pleroma.Web.CommonAPI

def post_welcome_message_to_user(user) do
with %User{} = sender_user <- welcome_user(),
message when is_binary(message) <- welcome_message() do
CommonAPI.post(sender_user, %{
@spec enabled?() :: boolean()
def enabled?, do: Config.get([:welcome, :direct_message, :enabled], false)

@spec post_message(User.t()) :: {:ok, Pleroma.Activity.t() | nil}
def post_message(user) do
[:welcome, :direct_message, :sender_nickname]
|> Config.get(nil)
|> fetch_sender()
|> do_post(user, welcome_message())
end

defp do_post(%User{} = sender, %User{nickname: nickname}, message)
when is_binary(message) do
CommonAPI.post(
sender,
%{
visibility: "direct",
status: "@#{user.nickname}\n#{message}"
})
else
_ -> {:ok, nil}
end
status: "@#{nickname}\n#{message}"
}
)
end

defp welcome_user do
with nickname when is_binary(nickname) <-
Pleroma.Config.get([:instance, :welcome_user_nickname]),
%User{local: true} = user <- User.get_cached_by_nickname(nickname) do
defp do_post(_sender, _recipient, _message), do: {:ok, nil}
defp fetch_sender(nickname) when is_binary(nickname) do
with %User{local: true} = user <- User.get_cached_by_nickname(nickname) do
user
else
_ -> nil
end
end

defp fetch_sender(_), do: nil

defp welcome_message do
Pleroma.Config.get([:instance, :welcome_message])
Config.get([:welcome, :direct_message, :message], nil)
end
end

+ 1
- 0
test/emails/user_email_test.exs Просмотреть файл

@@ -10,6 +10,7 @@ defmodule Pleroma.Emails.UserEmailTest do
alias Pleroma.Web.Router

import Pleroma.Factory
import Swoosh.TestAssertions

test "build password reset email" do
config = Pleroma.Config.get(:instance)


+ 1
- 3
test/tasks/config_test.exs Просмотреть файл

@@ -129,8 +129,6 @@ defmodule Mix.Tasks.Pleroma.ConfigTest do
autofollowed_nicknames: [],
max_pinned_statuses: 1,
attachment_links: false,
welcome_user_nickname: nil,
welcome_message: nil,
max_report_comment_size: 1000,
safe_dm_mentions: false,
healthcheck: false,
@@ -172,7 +170,7 @@ defmodule Mix.Tasks.Pleroma.ConfigTest do
end

assert file ==
"#{header}\n\nconfig :pleroma, :instance,\n name: \"Pleroma\",\n email: \"example@example.com\",\n notify_email: \"noreply@example.com\",\n description: \"A Pleroma instance, an alternative fediverse server\",\n limit: 5000,\n chat_limit: 5000,\n remote_limit: 100_000,\n upload_limit: 16_000_000,\n avatar_upload_limit: 2_000_000,\n background_upload_limit: 4_000_000,\n banner_upload_limit: 4_000_000,\n poll_limits: %{\n max_expiration: 31_536_000,\n max_option_chars: 200,\n max_options: 20,\n min_expiration: 0\n },\n registrations_open: true,\n federating: true,\n federation_incoming_replies_max_depth: 100,\n federation_reachability_timeout_days: 7,\n federation_publisher_modules: [Pleroma.Web.ActivityPub.Publisher],\n allow_relay: true,\n public: true,\n quarantined_instances: [],\n managed_config: true,\n static_dir: \"instance/static/\",\n allowed_post_formats: [\"text/plain\", \"text/html\", \"text/markdown\", \"text/bbcode\"],\n autofollowed_nicknames: [],\n max_pinned_statuses: 1,\n attachment_links: false,\n welcome_user_nickname: nil,\n welcome_message: nil,\n max_report_comment_size: 1000,\n safe_dm_mentions: false,\n healthcheck: false,\n remote_post_retention_days: 90,\n skip_thread_containment: true,\n limit_to_local_content: :unauthenticated,\n user_bio_length: 5000,\n user_name_length: 100,\n max_account_fields: 10,\n max_remote_account_fields: 20,\n account_field_name_length: 512,\n account_field_value_length: 2048,\n external_user_synchronization: true,\n extended_nickname_format: true,\n multi_factor_authentication: [\n totp: [digits: 6, period: 30],\n backup_codes: [number: 2, length: 6]\n ]\n"
"#{header}\n\nconfig :pleroma, :instance,\n name: \"Pleroma\",\n email: \"example@example.com\",\n notify_email: \"noreply@example.com\",\n description: \"A Pleroma instance, an alternative fediverse server\",\n limit: 5000,\n chat_limit: 5000,\n remote_limit: 100_000,\n upload_limit: 16_000_000,\n avatar_upload_limit: 2_000_000,\n background_upload_limit: 4_000_000,\n banner_upload_limit: 4_000_000,\n poll_limits: %{\n max_expiration: 31_536_000,\n max_option_chars: 200,\n max_options: 20,\n min_expiration: 0\n },\n registrations_open: true,\n federating: true,\n federation_incoming_replies_max_depth: 100,\n federation_reachability_timeout_days: 7,\n federation_publisher_modules: [Pleroma.Web.ActivityPub.Publisher],\n allow_relay: true,\n public: true,\n quarantined_instances: [],\n managed_config: true,\n static_dir: \"instance/static/\",\n allowed_post_formats: [\"text/plain\", \"text/html\", \"text/markdown\", \"text/bbcode\"],\n autofollowed_nicknames: [],\n max_pinned_statuses: 1,\n attachment_links: false,\n max_report_comment_size: 1000,\n safe_dm_mentions: false,\n healthcheck: false,\n remote_post_retention_days: 90,\n skip_thread_containment: true,\n limit_to_local_content: :unauthenticated,\n user_bio_length: 5000,\n user_name_length: 100,\n max_account_fields: 10,\n max_remote_account_fields: 20,\n account_field_name_length: 512,\n account_field_value_length: 2048,\n external_user_synchronization: true,\n extended_nickname_format: true,\n multi_factor_authentication: [\n totp: [digits: 6, period: 30],\n backup_codes: [number: 2, length: 6]\n ]\n"
end
end
end

+ 23
- 4
test/user_test.exs Просмотреть файл

@@ -17,6 +17,7 @@ defmodule Pleroma.UserTest do

import Pleroma.Factory
import ExUnit.CaptureLog
import Swoosh.TestAssertions

setup_all do
Tesla.Mock.mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end)
@@ -386,8 +387,8 @@ defmodule Pleroma.UserTest do
email: "email@example.com"
}
setup do: clear_config([:instance, :autofollowed_nicknames])
setup do: clear_config([:instance, :welcome_message])
setup do: clear_config([:instance, :welcome_user_nickname])
setup do: clear_config([:welcome])

test "it autofollows accounts that are set for it" do
user = insert(:user)
@@ -408,17 +409,35 @@ defmodule Pleroma.UserTest do

test "it sends a welcome message if it is set" do
welcome_user = insert(:user)
Pleroma.Config.put([:welcome, :direct_message, :enabled], true)
Pleroma.Config.put([:welcome, :direct_message, :sender_nickname], welcome_user.nickname)
Pleroma.Config.put([:welcome, :direct_message, :message], "Hello, this is a cool site")

Pleroma.Config.put([:welcome, :email, :enabled], true)
Pleroma.Config.put([:welcome, :email, :sender_nickname], welcome_user.nickname)

Pleroma.Config.put(
[:welcome, :email, :subject],
"Hello, welcome to cool site: <%= instance_name %>"
)

Pleroma.Config.put([:instance, :welcome_user_nickname], welcome_user.nickname)
Pleroma.Config.put([:instance, :welcome_message], "Hello, this is a cool site")
instance_name = Pleroma.Config.get([:instance, :name])

cng = User.register_changeset(%User{}, @full_user_data)
{:ok, registered_user} = User.register(cng)
ObanHelpers.perform_all()

activity = Repo.one(Pleroma.Activity)
assert registered_user.ap_id in activity.recipients
assert Object.normalize(activity).data["content"] =~ "cool site"
assert activity.actor == welcome_user.ap_id

assert_email_sent(
from: {instance_name, welcome_user.email},
to: {registered_user.name, registered_user.email},
subject: "Hello, welcome to cool site: #{instance_name}",
html_body: "Welcome to #{instance_name}"
)
end

setup do: clear_config([:instance, :account_activation_required])


Загрузка…
Отмена
Сохранить