forked from potsda.mn/mobilizon
1893d9f55b
Signed-off-by: Thomas Citharel <tcit@tcit.fr>
198 lines
5.5 KiB
Elixir
198 lines
5.5 KiB
Elixir
defmodule Mobilizon.Service.Activity.Comment do
|
|
@moduledoc """
|
|
Insert a comment activity
|
|
"""
|
|
alias Mobilizon.Actors.Actor
|
|
alias Mobilizon.{Discussions, Events}
|
|
alias Mobilizon.Discussions.Comment
|
|
alias Mobilizon.Events.Event
|
|
alias Mobilizon.Service.Activity
|
|
alias Mobilizon.Service.Workers.{ActivityBuilder, LegacyNotifierBuilder}
|
|
|
|
import Mobilizon.Service.Activity.Utils, only: [maybe_inserted_at: 0]
|
|
|
|
@behaviour Activity
|
|
|
|
@impl Activity
|
|
def insert_activity(comment, options \\ [])
|
|
|
|
def insert_activity(
|
|
%Comment{
|
|
actor_id: actor_id,
|
|
event_id: event_id
|
|
} = comment,
|
|
options
|
|
)
|
|
when not is_nil(actor_id) and not is_nil(event_id) do
|
|
with {:ok, %Event{} = event} <-
|
|
Events.get_event_with_preload(event_id) do
|
|
res =
|
|
[]
|
|
# Notify the actors mentionned
|
|
|> handle_notification(:mentionned, comment, event, options)
|
|
# Notify participants if there's a new announcement
|
|
|> handle_notification(:announcement, comment, event, options)
|
|
# Notify event organizer or group that there's new comments
|
|
|> handle_notification(:organizer, comment, event, options)
|
|
|
|
{:ok, res}
|
|
end
|
|
end
|
|
|
|
def insert_activity(_, _), do: {:ok, nil}
|
|
|
|
@impl Activity
|
|
def get_object(comment_id) do
|
|
Discussions.get_comment(comment_id)
|
|
end
|
|
|
|
@common_params %{
|
|
"type" => :comment,
|
|
"object_type" => :comment
|
|
}
|
|
|
|
@spec handle_notification(Keyword.t(), notification_type, Comment.t(), Event.t(), Keyword.t()) ::
|
|
Keyword.t()
|
|
defp handle_notification(global_res, function, comment, event, options) do
|
|
{:ok, res} = notify(function, comment, event, options)
|
|
Keyword.put(global_res, function, res)
|
|
end
|
|
|
|
@spec legacy_notifier_enqueue(map()) :: :ok
|
|
defp legacy_notifier_enqueue(args) do
|
|
LegacyNotifierBuilder.enqueue(
|
|
:legacy_notify,
|
|
@common_params |> Map.merge(maybe_inserted_at()) |> Map.merge(args)
|
|
)
|
|
end
|
|
|
|
@type notification_type :: :mentionned | :announcement | :organizer
|
|
|
|
# An actor is mentionned
|
|
@spec notify(notification_type(), Comment.t(), Event.t(), Keyword.t()) ::
|
|
{:ok, :enqueued} | {:ok, :skipped}
|
|
defp notify(
|
|
:mentionned,
|
|
%Comment{actor_id: actor_id, id: comment_id, mentions: mentions},
|
|
%Event{
|
|
uuid: uuid,
|
|
title: title
|
|
},
|
|
_options
|
|
)
|
|
when length(mentions) > 0 do
|
|
legacy_notifier_enqueue(%{
|
|
"subject" => :event_comment_mention,
|
|
"subject_params" => %{
|
|
event_uuid: uuid,
|
|
event_title: title
|
|
},
|
|
"author_id" => actor_id,
|
|
"object_id" => to_string(comment_id),
|
|
"mentions" => Enum.map(mentions, & &1.actor_id)
|
|
})
|
|
|
|
{:ok, :enqueued}
|
|
end
|
|
|
|
# An event has a new announcement, send it to the participants
|
|
defp notify(
|
|
:announcement,
|
|
%Comment{actor_id: actor_id, is_announcement: true, id: comment_id},
|
|
%Event{
|
|
id: event_id,
|
|
uuid: uuid,
|
|
title: title
|
|
},
|
|
_options
|
|
) do
|
|
legacy_notifier_enqueue(%{
|
|
"subject" => :participation_event_comment,
|
|
"subject_params" => %{
|
|
event_id: event_id,
|
|
event_uuid: uuid,
|
|
event_title: title
|
|
},
|
|
"author_id" => actor_id,
|
|
"object_id" => to_string(comment_id)
|
|
})
|
|
|
|
{:ok, :enqueued}
|
|
end
|
|
|
|
# A group event has a new comment, send it as an activity
|
|
defp notify(
|
|
:announcement,
|
|
%Comment{
|
|
actor_id: actor_id,
|
|
in_reply_to_comment_id: in_reply_to_comment_id,
|
|
id: comment_id
|
|
},
|
|
%Event{
|
|
uuid: uuid,
|
|
title: title,
|
|
attributed_to: %Actor{type: :Group, id: group_id}
|
|
},
|
|
options
|
|
) do
|
|
ActivityBuilder.enqueue(:build_activity, %{
|
|
"type" => "event",
|
|
"subject" => Keyword.fetch!(options, :subject),
|
|
"subject_params" => %{
|
|
event_title: title,
|
|
event_uuid: uuid,
|
|
comment_reply_to: !is_nil(in_reply_to_comment_id)
|
|
},
|
|
"group_id" => group_id,
|
|
"author_id" => actor_id,
|
|
"object_type" => "comment",
|
|
"object_id" => to_string(comment_id),
|
|
"inserted_at" => DateTime.utc_now()
|
|
})
|
|
|
|
{:ok, :enqueued}
|
|
end
|
|
|
|
# An event has a new comment, send it to the organizer
|
|
defp notify(
|
|
:organizer,
|
|
%Comment{
|
|
actor_id: actor_id,
|
|
in_reply_to_comment_id: in_reply_to_comment_id,
|
|
id: comment_id,
|
|
uuid: comment_uuid
|
|
} = comment,
|
|
%Event{
|
|
uuid: event_uuid,
|
|
title: title,
|
|
attributed_to: nil,
|
|
organizer_actor_id: organizer_actor_id
|
|
},
|
|
_options
|
|
)
|
|
when actor_id !== organizer_actor_id do
|
|
legacy_notifier_enqueue(%{
|
|
"subject" => :event_new_comment,
|
|
"subject_params" => %{
|
|
event_title: title,
|
|
event_uuid: event_uuid,
|
|
comment_reply_to: !is_nil(in_reply_to_comment_id),
|
|
comment_uuid: comment_uuid,
|
|
comment_reply_to_uuid: reply_to_comment_uuid(comment)
|
|
},
|
|
"author_id" => actor_id,
|
|
"object_id" => to_string(comment_id)
|
|
})
|
|
|
|
{:ok, :enqueued}
|
|
end
|
|
|
|
defp notify(_, _, _, _), do: {:ok, :skipped}
|
|
|
|
@spec reply_to_comment_uuid(Comment.t()) :: String.t() | nil
|
|
defp reply_to_comment_uuid(%Comment{in_reply_to_comment: %Comment{uuid: comment_reply_to_uuid}}),
|
|
do: comment_reply_to_uuid
|
|
|
|
defp reply_to_comment_uuid(%Comment{in_reply_to_comment: _}), do: nil
|
|
end
|