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
/** @jsxImportSource npm:hono@3/jsx */
import { render } from "https://deno.land/x/resvg_wasm/mod.ts";
import { Hono } from "npm:hono@3";
import satori from "npm:satori";
const app = new Hono();
async function renderImage(s: string, color: string) {
const fontArrayBuf = await fetch(
"https://cdn.jsdelivr.net/npm/roboto-font@0.1.0/fonts/Roboto/roboto-regular-webfont.ttf",
).then((res) => res.arrayBuffer());
const svg = await satori(
{
type: "div",
props: {
children: s,
style: {
display: "flex",
height: "100%",
width: "100%",
fontSize: "100px",
backgroundColor: "white",
color,
justifyContent: "center",
paddingTop: "120px",
},
},
},
{
width: 600,
height: 400,
fonts: [
{
name: "Roboto",
data: fontArrayBuf,
weight: 400,
style: "normal",
},
],
},
);
return await render(svg);
}
app.get("/satori", async (c) => {
const query = c.req.query("button");
let text = "Hello world!";
let color = "blue";
switch (query) {
case "1": {
text = "one!";
color = "red";
break;
}
case "2": {
text = "two";
color = "green";
break;
}
case "3": {
text = "three";
color = "chocolate";
break;
}
case "4": {
text = "four";
color = "purple";
break;
}
}
return c.body(await renderImage(text, color), 200, { "Content-Type": "image/png" });
});
app.get("/", (c) => {
return c.html(
<head>
<meta property="fc:frame" content="vNext" />
<meta
property="fc:frame:image"
content="https://nlnw-frame.web.val.run/satori"
/>
<meta property="fc:frame:button:1" content="Door 1" />
<meta property="fc:frame:button:2" content="Door 2" />
<meta property="fc:frame:button:3" content="Door 3" />
<meta property="fc:frame:button:4" content="Door 4" />
<meta property="of:accepts:xmtp" content="2024-02-01" />
</head>,
);
});
app.post("/", async (c) => {
const body = await c.req.json();
const buttonIndex = body.untrustedData.buttonIndex;
return c.html(
<head>
<meta property="fc:frame" content="vNext" />
<meta
property="fc:frame:image"
content={`https://nlnw-frame.web.val.run/satori?button=${buttonIndex}`}