ActivityPub work

This commit is contained in:
Jesse Wierzbinski 2024-03-03 14:45:21 -10:00
parent a9fb39f764
commit e05dca9fc1
No known key found for this signature in database
3 changed files with 229 additions and 0 deletions

View file

@ -76,3 +76,44 @@ export const emojiToLysand = (emoji: Emoji): LysandEmoji => {
alt: emoji.alt || undefined, alt: emoji.alt || undefined,
}; };
}; };
/**
* Converts the emoji to an ActivityPub object.
* @returns The ActivityPub object.
*/
export const emojiToActivityPub = (emoji: Emoji): any => {
// replace any with your ActivityPub Emoji type
return {
type: "Emoji",
name: `:${emoji.shortcode}:`,
updated: new Date().toISOString(),
icon: {
type: "Image",
url: emoji.url,
mediaType: emoji.content_type,
alt: emoji.alt || undefined,
},
};
};
export const addAPEmojiIfNotExists = async (apEmoji: any) => {
// replace any with your ActivityPub Emoji type
const existingEmoji = await client.emoji.findFirst({
where: {
shortcode: apEmoji.name.replace(/:/g, ""),
instance: null,
},
});
if (existingEmoji) return existingEmoji;
return await client.emoji.create({
data: {
shortcode: apEmoji.name.replace(/:/g, ""),
url: apEmoji.icon.url,
alt: apEmoji.icon.alt || null,
content_type: apEmoji.icon.mediaType,
visible_in_picker: true,
},
});
};

View file

@ -612,6 +612,53 @@ export const statusToAPI = async (
}; };
}; };
export const statusToActivityPub = async (
status: StatusWithRelations,
user?: UserWithRelations
): Promise<any> => {
// replace any with your ActivityPub type
return {
"@context": [
"https://www.w3.org/ns/activitystreams",
"https://mastodon.social/schemas/litepub-0.1.jsonld",
],
id: `${config.http.base_url}/users/${status.authorId}/statuses/${status.id}`,
type: "Note",
summary: status.spoilerText,
content: status.content,
published: new Date(status.createdAt).toISOString(),
url: `${config.http.base_url}/users/${status.authorId}/statuses/${status.id}`,
attributedTo: `${config.http.base_url}/users/${status.authorId}`,
to: ["https://www.w3.org/ns/activitystreams#Public"],
cc: [], // add recipients here
sensitive: status.sensitive,
attachment: (status.attachments ?? []).map(
a => attachmentToActivityPub(a) as ActivityPubAttachment // replace with your function
),
tag: [], // add tags here
replies: {
id: `${config.http.base_url}/users/${status.authorId}/statuses/${status.id}/replies`,
type: "Collection",
totalItems: status._count.replies,
},
likes: {
id: `${config.http.base_url}/users/${status.authorId}/statuses/${status.id}/likes`,
type: "Collection",
totalItems: status._count.likes,
},
shares: {
id: `${config.http.base_url}/users/${status.authorId}/statuses/${status.id}/shares`,
type: "Collection",
totalItems: status._count.reblogs,
},
inReplyTo: status.inReplyToPostId
? `${config.http.base_url}/users/${status.inReplyToPost?.authorId}/statuses/${status.inReplyToPostId}`
: null,
visibility: "public", // adjust as needed
// add more fields as needed
};
};
export const statusToLysand = (status: StatusWithRelations): Note => { export const statusToLysand = (status: StatusWithRelations): Note => {
return { return {
type: "Note", type: "Note",

141
types/activitypub.ts Normal file
View file

@ -0,0 +1,141 @@
export type APActivityPubContext =
| "https://www.w3.org/ns/activitystreams"
| {
ostatus: string;
atomUri: string;
inReplyToAtomUri: string;
conversation: string;
sensitive: string;
toot: string;
votersCount: string;
litepub: string;
directMessage: string;
};
export interface APActivityPubObject {
id: string;
type: string;
summary?: string;
inReplyTo?: string;
published: string;
url: string;
attributedTo: string;
to: string[];
cc: string[];
sensitive?: boolean;
atomUri: string;
inReplyToAtomUri?: string;
conversation: string;
content: string;
contentMap: Record<string, string>;
attachment: APActivityPubAttachment[];
tag: APTag[];
context?: string;
quoteUri?: string;
quoteUrl?: string;
source?: {
content: string;
mediaType: string;
};
}
export interface APActivityPubAttachment {
type?: string;
mediaType?: string;
url?: string;
name?: string;
}
export interface APActivityPubCollection {
id: string;
type: string;
first?: {
type: string;
next: string;
partOf: string;
items: any[]; // replace any with your item type
};
}
export interface APActivityPubNote extends APActivityPubObject {
type: "Note";
}
export interface APActivityPubActivity {
"@context": APActivityPubContext[];
id: string;
type: string;
actor: string;
published: string;
to: string[];
cc: string[];
object: APActivityPubNote;
}
export type APActorContext =
| "https://www.w3.org/ns/activitystreams"
| "https://w3id.org/security/v1"
| Record<
string,
| string
| { "@id": string; "@type": string }
| { "@container": string; "@id": string }
>;
export interface APActorPublicKey {
id: string;
owner: string;
publicKeyPem: string;
}
export interface APActorEndpoints {
sharedInbox: string;
}
export interface APActorIcon {
type: string;
mediaType: string;
url: string;
}
export interface APActor {
"@context": APActorContext[];
id: string;
type: string;
following: string;
followers: string;
inbox: string;
outbox: string;
featured: string;
featuredTags: string;
preferredUsername: string;
name: string;
summary: string;
url: string;
manuallyApprovesFollowers: boolean;
discoverable: boolean;
indexable: boolean;
published: string;
memorial: boolean;
devices: string;
publicKey: APActorPublicKey;
tag: APTag[];
attachment: APAttachment[];
endpoints: APActorEndpoints;
icon: APActorIcon;
}
export interface APTag {
type: string;
href: string;
name: string;
}
export interface APAttachment {
type: string;
mediaType: string;
url: string;
name?: string;
blurhash?: string;
description?: string;
}