2022-12-05 20:14:56 +00:00
|
|
|
// https://docs.joinmastodon.org/methods/notifications/#get-one
|
|
|
|
|
2023-01-11 15:45:07 +00:00
|
|
|
import type { Notification, NotificationsQueryResult } from 'wildebeest/backend/src/types/notification'
|
2022-12-05 20:14:56 +00:00
|
|
|
import { urlToHandle } from 'wildebeest/backend/src/utils/handle'
|
2023-02-03 10:13:46 +00:00
|
|
|
import { getActorById } from 'wildebeest/backend/src/activitypub/actors'
|
2022-12-05 20:14:56 +00:00
|
|
|
import { loadExternalMastodonAccount } from 'wildebeest/backend/src/mastodon/account'
|
|
|
|
import type { Person } from 'wildebeest/backend/src/activitypub/actors'
|
|
|
|
import type { Env } from 'wildebeest/backend/src/types/env'
|
|
|
|
import type { ContextData } from 'wildebeest/backend/src/types/context'
|
|
|
|
|
|
|
|
const headers = {
|
|
|
|
'content-type': 'application/json; charset=utf-8',
|
|
|
|
}
|
|
|
|
|
|
|
|
export const onRequest: PagesFunction<Env, any, ContextData> = async ({ data, request, env, params }) => {
|
|
|
|
const domain = new URL(request.url).hostname
|
|
|
|
return handleRequest(domain, params.id as string, env.DATABASE, data.connectedActor)
|
|
|
|
}
|
|
|
|
|
|
|
|
export async function handleRequest(
|
|
|
|
domain: string,
|
|
|
|
id: string,
|
|
|
|
db: D1Database,
|
|
|
|
connectedActor: Person
|
|
|
|
): Promise<Response> {
|
|
|
|
const query = `
|
|
|
|
SELECT
|
|
|
|
objects.*,
|
|
|
|
actor_notifications.type,
|
|
|
|
actor_notifications.actor_id,
|
|
|
|
actor_notifications.from_actor_id,
|
|
|
|
actor_notifications.cdate as notif_cdate,
|
|
|
|
actor_notifications.id as notif_id
|
|
|
|
FROM actor_notifications
|
2023-01-12 13:57:22 +00:00
|
|
|
LEFT JOIN objects ON objects.id=actor_notifications.object_id
|
2022-12-05 20:14:56 +00:00
|
|
|
WHERE actor_notifications.id=? AND actor_notifications.actor_id=?
|
|
|
|
`
|
|
|
|
|
2023-01-11 15:45:07 +00:00
|
|
|
const row = await db.prepare(query).bind(id, connectedActor.id.toString()).first<NotificationsQueryResult>()
|
2022-12-05 20:14:56 +00:00
|
|
|
|
|
|
|
const from_actor_id = new URL(row.from_actor_id)
|
2023-02-03 10:13:46 +00:00
|
|
|
const fromActor = await getActorById(db, from_actor_id)
|
2022-12-05 20:14:56 +00:00
|
|
|
if (!fromActor) {
|
|
|
|
throw new Error('unknown from actor')
|
|
|
|
}
|
|
|
|
|
|
|
|
const acct = urlToHandle(from_actor_id)
|
|
|
|
const fromAccount = await loadExternalMastodonAccount(acct, fromActor)
|
|
|
|
|
|
|
|
const out: Notification = {
|
|
|
|
id: row.notif_id.toString(),
|
|
|
|
type: row.type,
|
|
|
|
created_at: new Date(row.notif_cdate).toISOString(),
|
|
|
|
account: fromAccount,
|
|
|
|
}
|
|
|
|
|
|
|
|
if (row.type === 'mention' || row.type === 'favourite') {
|
|
|
|
const properties = JSON.parse(row.properties)
|
|
|
|
|
|
|
|
out.status = {
|
|
|
|
id: row.mastodon_id,
|
|
|
|
content: properties.content,
|
|
|
|
uri: row.id,
|
2023-01-17 16:16:29 +00:00
|
|
|
url: new URL('/statuses/' + row.mastodon_id, 'https://' + domain),
|
2022-12-05 20:14:56 +00:00
|
|
|
created_at: new Date(row.cdate).toISOString(),
|
|
|
|
|
|
|
|
emojis: [],
|
|
|
|
media_attachments: [],
|
|
|
|
tags: [],
|
|
|
|
mentions: [],
|
2023-02-16 16:58:03 +00:00
|
|
|
spoiler_text: properties.spoiler_text ?? '',
|
2022-12-05 20:14:56 +00:00
|
|
|
|
|
|
|
// TODO: a shortcut has been taked. We assume that the actor
|
|
|
|
// generating the notification also created the object. In practice
|
|
|
|
// likely true but not guarantee.
|
|
|
|
account: fromAccount,
|
|
|
|
|
|
|
|
// TODO: stub values
|
|
|
|
visibility: 'public',
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return new Response(JSON.stringify(out), { headers })
|
|
|
|
}
|