-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathviralUpdate.ts
114 lines (105 loc) · 4.46 KB
/
viralUpdate.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
import { getTweet } from "@/utils/twitter/index";
import { getDeform } from "@/utils/deform/getDeformData";
import { type NextApiResponse, type NextApiRequest } from "next";
import { getPgAllocationCount } from "@/utils/pg/pgAllocationCount";
import { type RecipientScore, type NewPoints } from "@/types";
import { writeScoresToPg } from "@/utils/pg/processPgPoints";
import { processMultiPoints } from "@/utils/ceramic/processMultiPoints";
interface Response extends NextApiResponse {
status(code: number): Response;
send(data: Array<NewPoints> | undefined | { error: string }): void;
}
const DEFORM_VIRAL_FORM_ID = process.env.DEFORM_VIRAL_FORM_ID ?? "";
const X_PLATFORM_HANDLE = process.env.X_PLATFORM_HANDLE ?? "";
export default async function handler(_req: NextApiRequest, res: Response) {
try {
// fetch the DeForm data
const deformData = await getDeform(DEFORM_VIRAL_FORM_ID).then((data) => {
return data?.data;
});
const allocationData = await getPgAllocationCount("viral");
// failure mode for fetching DeForm data or allocation data
if (!deformData || !allocationData) {
return res.status(500).send({ error: "Internal Server Error" });
}
// first, see if there is a difference between the number of rows in the PG database and the number of rows in the DeForm database
const difference = deformData.length - allocationData.allocationCount;
const recipientScores = [] as Array<RecipientScore>;
// if there is a difference, then we need to update the Notion database
if (difference > 0) {
for (let i = 0; i < difference; i++) {
const newEntry = deformData[deformData.length - 1 - i];
const tweet = newEntry?.answers.find(
(answer) =>
answer.name === "Link to your original X post with 40+ likes.",
)?.value;
const user = newEntry?.answers.find(
(answer) =>
answer.name === "Connect your X account. - Twitter Username",
)?.value;
const wallet = newEntry?.answers.find(
(answer) =>
answer.name === "Connect your crypto wallet - Wallet Address",
)?.value;
if (
!tweet ||
typeof tweet !== "string" ||
!user ||
typeof user !== "string" ||
!wallet ||
typeof wallet !== "string"
) {
return res
.status(500)
.send({ error: "Unable to retrieve Tweet user input" });
}
const isValid = await getTweet(tweet);
if (!isValid) {
return res
.status(500)
.send({ error: "Unable to retrieve Tweet data" });
}
const { tweetData, likes, account } = isValid;
// perform checks
const isUser = account === user;
const likesAboveTwo = likes.meta.result_count > 2;
const mentionsPlatform =
tweetData.data.text.includes(X_PLATFORM_HANDLE);
// check to make sure allocationData.allocations does not already contain an entry for the recipint + context + subContext combination
const existingAllocation = allocationData.allocations.find(
(allocation) =>
allocation.recipient ===
`did:pkh:eip155:1:${wallet.toLowerCase()}` &&
allocation.context === "viral" &&
allocation.subContext === tweetData.data.text,
);
// if all checks pass, then we can add the entry to the returnEntries array
if (isUser && likesAboveTwo && mentionsPlatform && !existingAllocation) {
recipientScores.push({
recipient: `did:pkh:eip155:1:${wallet.toLowerCase()}`,
score: 750,
context: "viral",
subContext: tweetData.data.text,
});
}
// if the checks fail, still add the entry to the returnEntries array, but with a score of 0 to ensure the entry is recorded
else {
recipientScores.push({
recipient: `did:pkh:eip155:1:${wallet.toLowerCase()}`,
score: 0,
context: "viral",
});
}
}
}
// process and write the patches to Postgres
const pgResults = await writeScoresToPg(recipientScores);
console.log("Processed PG viral patches: ", pgResults);
// process and write the patches to Ceramic
const results = await processMultiPoints(recipientScores);
return res.status(200).json(results);
} catch (error) {
console.error(error);
res.status(500).send({ error: "Internal Server Error" });
}
}