import { parseTapEvent, assureAdminAuth, RecordEvent } from "@atproto/tap"; import { and, eq } from "drizzle-orm"; import * as dev from "../../utils/types/lexicons/dev"; /** * Handles incoming incoming tap events from tap */ export default defineEventHandler(async (event) => { const adminPassword = useRuntimeConfig(event).tapAdminPassword; const headers = getRequestHeaders(event); const authorization = headers.authorization; if (!authorization || !adminPassword) { console.error( "Missing admin password or the request does not have an auth header", ); throw createError({ statusCode: 401, statusMessage: "Unauthorized", }); } try { assureAdminAuth(adminPassword, authorization); } catch (error) { console.error("Failed to authenticate adm¡n:", error); throw createError({ statusCode: 401, statusMessage: "Unauthorized", }); } const body = await readBody(event); const tapEvent = parseTapEvent(body); switch (tapEvent.type) { case "identity": //Just logging these for now console.log( `Identity event received: ${tapEvent.status} ${tapEvent.did}`, ); break; case "record": const recordEvent: RecordEvent = tapEvent; const atUri = `at://${recordEvent.did}/${recordEvent.collection}/${recordEvent.rkey}`; if (recordEvent.collection !== "dev.npmx.feed.like") { console.log("Skipping event:", recordEvent); break; } try { await handleLikes(recordEvent, atUri); } catch (error) { console.log(recordEvent); console.error("Failed to handle likes:", error); } break; } return {}; }); const handleLikes = async (recordEvent: RecordEvent, atUri: string) => { switch (recordEvent.action) { case "update": case "create": const likeRecord = dev.npmx.feed.like.$validate(recordEvent.record); if (!likeRecord) { console.log("Invalid like record:", recordEvent); return; } const newLike: NewLike = { atUri, subjectRef: likeRecord.subjectRef, did: recordEvent.did, createdAt: new Date(likeRecord.createdAt), }; await db .insert(likes) .values(newLike) .onConflictDoUpdate({ target: likes.atUri, set: { atUri, subjectRef: likeRecord.subjectRef, did: recordEvent.did, createdAt: new Date(likeRecord.createdAt), }, }); if (recordEvent.live) { console.log( `a new like was ${recordEvent.action}d for ${likeRecord.subjectRef}`, ); } else { console.log( `like was ${recordEvent.action}d for ${likeRecord.subjectRef}`, ); } break; case "delete": await db.delete(likes).where(and(eq(likes.atUri, atUri))); console.log("like deleted"); break; } };