jamiedubs-roastcast.web.val.run
Readme

Farcaster action that summons a https://glif.app bot to roast the cast, using glif AI magic #farcaster #glif

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
// Farcaster action that summons @glif bot to roast the cast using AI magic
// Install URL: https://warpcast.com/~/add-cast-action?actionType=post&name=roastCast&icon=flame&postUrl=https%3A%2F%2Fjamiedubs-roastCast.web.val.run
import process from "node:process";
async function fetchCast({ fid, hash }: { fid: string; hash: string }) {
console.log("fetchCast", { fid, hash });
const res = await fetch(
`https://api.neynar.com/v2/farcaster/cast?identifier=${hash}&type=hash`,
{
method: "GET",
headers: {
accept: "application/json",
api_key: "NEYNAR_API_DOCS", // FIXME add my own API key pls
},
},
);
const json = await res.json();
const user = `@${json.cast.author.username} (${json.cast.author.display_name})`;
const message = json.cast.text;
return `${user}: ${message}`;
}
interface RunGlifResponse {
error?: string;
output?: string;
}
async function runGlif({ inputs }: { inputs: string[] }): Promise<RunGlifResponse> {
const id = "cluu91eda000cv8jd675qsrby" as const;
const body = { id, inputs };
const headers = {
Authorization: `Bearer ${process.env.GLIF_API_TOKEN}`,
};
const res = await fetch(`https://simple-api.glif.app`, {
method: "POST",
body: JSON.stringify(body),
headers,
});
if (res.status !== 200) {
const text = await res.text();
return { error: `${res.status} error from glif API: ${text}` };
}
const json = await res.json();
if (json?.error) return { error: json.error };
return json;
}
async function postCast({ text, replyToFid, replyToHash }: { text: string; replyToFid: string; replyToHash: string }) {
if (!process.env.FARCASTER_SIGNER_ID || !process.env.PINATA_JWT) {
throw new Error("missing required ENV vars");
}
const cast = {
signerId: process.env.FARCASTER_SIGNER_ID,
castAddBody: {
text,
parentCastId: {
fid: replyToFid,
hash: replyToHash,
},
},
};
const url = "https://api.pinata.cloud/v3/farcaster/casts";
const options = {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.PINATA_JWT}`,
"Content-Type": "application/json",
},
body: JSON.stringify(cast),
};
console.log("postCast fetching...", url, cast);
const res = await fetch(url, options);
let json;
try {
json = await res.json();
} catch (err) {
const { status, statusText, body } = err;
console.error("postCast error", { status, statusText, body });
process.exit(1);
}
console.log(JSON.stringify(json, null, 2));
return json;
}
async function runGlifAndPost({ inputs, cast }: { inputs: string[]; cast: { fid: string; hash: string } }) {
const glifRes = await runGlif({ inputs });
console.log({ glifRes });
const postRes = await postCast({ text: glifRes.output, replyToFid: cast.fid, replyToHash: cast.hash });
console.log({ postRes });
return glifRes;
}
export default async function(req: Request): Promise<Response> {
Val Town is a social website to write and deploy JavaScript.
Build APIs and schedule functions from your browser.
Comments
Nobody has commented on this val yet: be the first!
April 12, 2024