Add activitypub.ex

This commit is contained in:
Mirai Kumiko 2025-06-02 17:31:39 +02:00
parent 40a9e0e961
commit 5b0427ad59
Signed by: miraikumiko
GPG key ID: 3F178B1B5E0CB278

84
lib/nulla/activitypub.ex Normal file
View file

@ -0,0 +1,84 @@
defmodule Nulla.ActivityPub do
@spec context() :: list()
defp context do
[
"https://www.w3.org/ns/activitystreams",
"https://w3id.org/security/v1",
Jason.OrderedObject.new(
manuallyApprovesFollowers: "as:manuallyApprovesFollowers",
toot: "http://joinmastodon.org/ns#",
featured: %{"@id" => "toot:featured", "@type" => "@id"},
featuredTags: %{"@id" => "toot:featuredTags", "@type" => "@id"},
alsoKnownAs: %{"@id" => "as:alsoKnownAs", "@type" => "@id"},
movedTo: %{"@id" => "as:movedTo", "@type" => "@id"},
schema: "http://schema.org#",
PropertyValue: "schema:PropertyValue",
value: "schema:value",
discoverable: "toot:discoverable",
suspended: "toot:suspended",
memorial: "toot:memorial",
indexable: "toot:indexable",
attributionDomains: %{"@id" => "toot:attributionDomains", "@type" => "@id"},
Hashtag: "as:Hashtag",
focalPoint: %{"@container" => "@list", "@id" => "toot:focalPoint"}
)
]
end
@spec ap_user(String.t(), Nulla.Users.User.t()) :: Jason.OrderedObject.t()
def ap_user(domain, user) do
Jason.OrderedObject.new([
"@context": context(),
id: "https://#{domain}/@#{user.username}",
type: "Person",
following: "https://#{domain}/@#{user.username}/following",
followers: "https://#{domain}/@#{user.username}/followers",
inbox: "https://#{domain}/@#{user.username}/inbox",
outbox: "https://#{domain}/@#{user.username}/outbox",
featured: "https://#{domain}/@#{user.username}/collections/featured",
preferredUsername: user.username,
name: user.realname,
summary: user.bio,
url: "https://#{domain}/@#{user.username}",
manuallyApprovesFollowers: user.follow_approval,
discoverable: user.is_discoverable,
indexable: user.is_indexable,
published: DateTime.to_iso8601(user.inserted_at),
memorial: user.is_memorial,
publicKey: Jason.OrderedObject.new(
id: "https://#{domain}/@#{user.username}#main-key",
owner: "https://#{domain}/@#{user.username}",
publicKeyPem: user.public_key
),
tag: Enum.map(user.tags, fn tag ->
Jason.OrderedObject.new(
type: "Hashtag",
href: "https://#{domain}/tags/#{tag}",
name: "##{tag}"
)
end),
attachment: Enum.map(user.fields, fn {name, value} ->
Jason.OrderedObject.new(
type: "PropertyValue",
name: name,
value: value
)
end),
endpoints: Jason.OrderedObject.new(
sharedInbox: "https://#{domain}/inbox"
),
icon: Jason.OrderedObject.new(
type: "Image",
mediaType: MIME.from_path(user.avatar),
url: "https://#{domain}#{user.avatar}"
),
image: Jason.OrderedObject.new(
type: "Image",
mediaType: MIME.from_path(user.banner),
url: "https://#{domain}#{user.banner}"
),
"vcard:bday": user.birthday,
"vcard:Address": user.location
])
end
end