WIP: Fix Twitter Cards
[akkoma] / lib / pleroma / web / metadata / twitter_card.ex
1 # Pleroma: A lightweight social networking server
2 # Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
3 # SPDX-License-Identifier: AGPL-3.0-only
4
5 defmodule Pleroma.Web.Metadata.Providers.TwitterCard do
6 alias Pleroma.User
7 alias Pleroma.Web.Metadata
8 alias Pleroma.Web.Metadata.Providers.Provider
9 alias Pleroma.Web.Metadata.Utils
10
11 @behaviour Provider
12
13 @impl Provider
14 def build_tags(%{
15 object: object,
16 user: user
17 }) do
18 attachments = build_attachments(object)
19 scrubbed_content = Utils.scrub_html_and_truncate(object)
20 # Zero width space
21 content =
22 if scrubbed_content != "" and scrubbed_content != "\u200B" do
23 "“" <> scrubbed_content <> "”"
24 else
25 ""
26 end
27
28 [
29 {:meta,
30 [
31 property: "twitter:title",
32 content: Utils.user_name_string(user)
33 ], []},
34 {:meta,
35 [
36 property: "twitter:description",
37 content: content
38 ], []}
39 ] ++
40 if attachments == [] or Metadata.activity_nsfw?(object) do
41 [
42 {:meta,
43 [property: "twitter:image", content: Utils.attachment_url(User.avatar_url(user))], []},
44 {:meta, [property: "twitter:card", content: "summary_large_image"], []}
45 ]
46 else
47 attachments
48 end
49 end
50
51 @impl Provider
52 def build_tags(%{user: user}) do
53 with truncated_bio = Utils.scrub_html_and_truncate(user.bio || "") do
54 [
55 {:meta,
56 [
57 property: "twitter:title",
58 content: Utils.user_name_string(user)
59 ], []},
60 {:meta, [property: "twitter:description", content: truncated_bio], []},
61 {:meta, [property: "twitter:image", content: Utils.attachment_url(User.avatar_url(user))],
62 []},
63 {:meta, [property: "twitter:card", content: "summary"], []}
64 ]
65 end
66 end
67
68 defp build_attachments(%{data: %{"attachment" => attachments}}) do
69 Enum.reduce(attachments, [], fn attachment, acc ->
70 rendered_tags =
71 Enum.reduce(attachment["url"], [], fn url, acc ->
72 content_type = url["mediaType"]
73
74 media_type =
75 Enum.find(["image", "audio", "video"], fn media_type ->
76 String.starts_with?(url["mediaType"], media_type)
77 end)
78
79 # TODO: Add additional properties to objects when we have the data available.
80 case media_type do
81 "audio" ->
82 [
83 {:meta, [property: "twitter:card", content: "player"], []},
84 {:meta, [property: "twitter:player", content: Utils.attachment_url(url["href"])],
85 []}
86 | acc
87 ]
88
89 "image" ->
90 [
91 {:meta, [property: "twitter:card", content: "summary_large_image"], []},
92 {:meta,
93 [
94 property: "twitter:player",
95 content:
96 Utils.attachment_url(
97 Pleroma.Uploaders.Uploader.preview_url(content_type, url["href"])
98 )
99 ], []}
100 | acc
101 ]
102
103 # TODO: Need the true width and height values here or Twitter renders an iFrame with a bad aspect ratio
104 "video" ->
105 [
106 {:meta, [property: "twitter:card", content: "player"], []},
107 {:meta, [property: "twitter:player", content: Utils.attachment_url(url["href"])],
108 []},
109 {:meta, [property: "twitter:player:width", content: "1280"], []},
110 {:meta, [property: "twitter:player:height", content: "720"], []}
111 | acc
112 ]
113
114 _ ->
115 acc
116 end
117 end)
118
119 acc ++ rendered_tags
120 end)
121 end
122 end