this repo has no description
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};