From 676fab787146c907fd9419a50926f585cec95eaf Mon Sep 17 00:00:00 2001 From: Thomas Citharel Date: Wed, 13 Oct 2021 12:57:54 +0200 Subject: [PATCH] Embed json-ld metadata on events in emails Signed-off-by: Thomas Citharel --- lib/web/email/email.ex | 1 + lib/web/email/event.ex | 6 ++++ lib/web/email/participation.ex | 14 +++++++-- lib/web/templates/email/email.html.heex | 3 ++ lib/web/views/json_ld/object_view.ex | 39 ++++++++++++++++++++++++- 5 files changed, 60 insertions(+), 3 deletions(-) diff --git a/lib/web/email/email.ex b/lib/web/email/email.ex index c80bd854d..51782d06e 100644 --- a/lib/web/email/email.ex +++ b/lib/web/email/email.ex @@ -18,6 +18,7 @@ defmodule Mobilizon.Web.Email do |> put_header("Reply-To", Config.instance_email_reply_to()) |> maybe_put_date_header() |> maybe_put_message_id() + |> assign(:jsonLDMetadata, nil) |> assign(:instance_name, Config.instance_name()) |> put_html_layout({EmailView, "email.html"}) |> put_text_layout({EmailView, "email.text"}) diff --git a/lib/web/email/event.ex b/lib/web/email/event.ex index dd0a0b1c5..13a627d7c 100644 --- a/lib/web/email/event.ex +++ b/lib/web/email/event.ex @@ -47,6 +47,11 @@ defmodule Mobilizon.Web.Email.Event do title: old_event.title ) + json_ld = + "participation.json" + |> ObjectView.render(%{participant: %Participant{participant | event: event, actor: actor}}) + |> Jason.encode!() + Email.base_email(to: {Actor.display_name(actor), email}, subject: subject) |> assign(:locale, locale) |> assign(:event, event) @@ -54,6 +59,7 @@ defmodule Mobilizon.Web.Email.Event do |> assign(:changes, changes) |> assign(:subject, subject) |> assign(:timezone, timezone) + |> assign(:jsonLDMetadata, json_ld) |> Email.add_event_attachment(event) |> render(:event_updated) end diff --git a/lib/web/email/participation.ex b/lib/web/email/participation.ex index c363c1a9e..5b48205eb 100644 --- a/lib/web/email/participation.ex +++ b/lib/web/email/participation.ex @@ -8,11 +8,11 @@ defmodule Mobilizon.Web.Email.Participation do import Mobilizon.Web.Gettext alias Mobilizon.Actors.Actor - alias Mobilizon.Config + alias Mobilizon.{Config, Events, Users} alias Mobilizon.Events.{Event, Participant} - alias Mobilizon.Users alias Mobilizon.Users.User alias Mobilizon.Web.Email + alias Mobilizon.Web.JsonLD.ObjectView @doc """ Send participation emails to local user @@ -117,6 +117,7 @@ defmodule Mobilizon.Web.Email.Participation do |> assign(:locale, locale) |> assign(:event, event) |> assign(:subject, subject) + |> assign(:jsonLDMetadata, json_ld(participant)) |> Email.add_event_attachment(event) |> render(:event_participation_approved) end @@ -139,7 +140,16 @@ defmodule Mobilizon.Web.Email.Participation do Email.base_email(to: email, subject: subject) |> assign(:locale, locale) |> assign(:participant, participant) + |> assign(:jsonLDMetadata, json_ld(participant)) |> assign(:subject, subject) |> render(:anonymous_participation_confirmation) end + + defp json_ld(participant) do + event = Events.get_event_with_preload!(participant.event_id) + + "participation.json" + |> ObjectView.render(%{participant: %Participant{participant | event: event}}) + |> Jason.encode!() + end end diff --git a/lib/web/templates/email/email.html.heex b/lib/web/templates/email/email.html.heex index e7e34bf0b..e2248ca8d 100644 --- a/lib/web/templates/email/email.html.heex +++ b/lib/web/templates/email/email.html.heex @@ -41,6 +41,9 @@ /* ANDROID CENTER FIX */ div[style*="margin: 16px 0;"] { margin: 0 !important; } + <%= if @jsonLDMetadata do %> + + <% end %> diff --git a/lib/web/views/json_ld/object_view.ex b/lib/web/views/json_ld/object_view.ex index cc41e511b..f4de971fc 100644 --- a/lib/web/views/json_ld/object_view.ex +++ b/lib/web/views/json_ld/object_view.ex @@ -3,10 +3,11 @@ defmodule Mobilizon.Web.JsonLD.ObjectView do alias Mobilizon.Actors.Actor alias Mobilizon.Addresses.Address - alias Mobilizon.Events.Event + alias Mobilizon.Events.{Event, Participant, ParticipantRole} alias Mobilizon.Posts.Post alias Mobilizon.Web.Endpoint alias Mobilizon.Web.JsonLD.ObjectView + alias Mobilizon.Web.Router.Helpers, as: Routes @spec render(String.t(), map()) :: map() def render("group.json", %{group: %Actor{} = group}) do @@ -25,6 +26,13 @@ defmodule Mobilizon.Web.JsonLD.ObjectView do "name" => Actor.display_name(event.organizer_actor) } + organizer = + if event.organizer_actor.avatar do + Map.put(organizer, "image", event.organizer_actor.avatar.url) + else + organizer + end + json_ld = %{ "@context" => "https://schema.org", "@type" => "Event", @@ -94,6 +102,35 @@ defmodule Mobilizon.Web.JsonLD.ObjectView do } end + def render("participation.json", %{ + participant: %Participant{} = participant + }) do + res = %{ + "@context" => "http://schema.org", + "@type" => "EventReservation", + "underName" => %{ + "@type" => "Person", + "name" => participant.actor.name || participant.actor.preferred_username + }, + "reservationFor" => render("event.json", %{event: participant.event}), + "reservationStatus" => reservation_status(participant.role), + "modifiedTime" => participant.updated_at, + "modifyReservationUrl" => Routes.page_url(Endpoint, :event, participant.event.uuid) + } + + if participant.code do + Map.put(res, "reservationNumber", participant.code) + else + res + end + end + + @spec reservation_status(ParticipantRole.t()) :: String.t() + defp reservation_status(:rejected), do: "https://schema.org/ReservationCancelled" + defp reservation_status(:not_confirmed), do: "https://schema.org/ReservationPending" + defp reservation_status(:not_approved), do: "https://schema.org/ReservationHold" + defp reservation_status(_), do: "https://schema.org/ReservationConfirmed" + @spec render_location(map()) :: map() | nil defp render_location(%{physical_address: %Address{} = address}), do: render_one(address, ObjectView, "place.json", as: :address)