this repo has no description
at main 102 lines 3.0 kB view raw
1import { parseTapEvent, assureAdminAuth, RecordEvent } from "@atproto/tap"; 2import { and, eq } from "drizzle-orm"; 3import * as dev from "../../utils/types/lexicons/dev"; 4/** 5 * Handles incoming incoming tap events from tap 6 */ 7export default defineEventHandler(async (event) => { 8 const adminPassword = useRuntimeConfig(event).tapAdminPassword; 9 const headers = getRequestHeaders(event); 10 const authorization = headers.authorization; 11 if (!authorization || !adminPassword) { 12 console.error( 13 "Missing admin password or the request does not have an auth header", 14 ); 15 throw createError({ 16 statusCode: 401, 17 statusMessage: "Unauthorized", 18 }); 19 } 20 try { 21 assureAdminAuth(adminPassword, authorization); 22 } catch (error) { 23 console.error("Failed to authenticate adm¡n:", error); 24 throw createError({ 25 statusCode: 401, 26 statusMessage: "Unauthorized", 27 }); 28 } 29 30 const body = await readBody(event); 31 const tapEvent = parseTapEvent(body); 32 switch (tapEvent.type) { 33 case "identity": 34 //Just logging these for now 35 console.log( 36 `Identity event received: ${tapEvent.status} ${tapEvent.did}`, 37 ); 38 break; 39 case "record": 40 const recordEvent: RecordEvent = tapEvent; 41 const atUri = `at://${recordEvent.did}/${recordEvent.collection}/${recordEvent.rkey}`; 42 if (recordEvent.collection !== "dev.npmx.feed.like") { 43 console.log("Skipping event:", recordEvent); 44 break; 45 } 46 try { 47 await handleLikes(recordEvent, atUri); 48 } catch (error) { 49 console.log(recordEvent); 50 console.error("Failed to handle likes:", error); 51 } 52 53 break; 54 } 55 56 return {}; 57}); 58 59const handleLikes = async (recordEvent: RecordEvent, atUri: string) => { 60 switch (recordEvent.action) { 61 case "update": 62 case "create": 63 const likeRecord = dev.npmx.feed.like.$validate(recordEvent.record); 64 if (!likeRecord) { 65 console.log("Invalid like record:", recordEvent); 66 return; 67 } 68 const newLike: NewLike = { 69 atUri, 70 subjectRef: likeRecord.subjectRef, 71 did: recordEvent.did, 72 createdAt: new Date(likeRecord.createdAt), 73 }; 74 await db 75 .insert(likes) 76 .values(newLike) 77 .onConflictDoUpdate({ 78 target: likes.atUri, 79 set: { 80 atUri, 81 subjectRef: likeRecord.subjectRef, 82 did: recordEvent.did, 83 createdAt: new Date(likeRecord.createdAt), 84 }, 85 }); 86 if (recordEvent.live) { 87 console.log( 88 `a new like was ${recordEvent.action}d for ${likeRecord.subjectRef}`, 89 ); 90 } else { 91 console.log( 92 `like was ${recordEvent.action}d for ${likeRecord.subjectRef}`, 93 ); 94 } 95 96 break; 97 case "delete": 98 await db.delete(likes).where(and(eq(likes.atUri, atUri))); 99 console.log("like deleted"); 100 break; 101 } 102};