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
// WIP reddit embed static
/** @jsxImportSource https://esm.sh/react */
import { encode as base64Encode } from "https://deno.land/std@0.177.0/encoding/base64.ts";
import { renderToStaticMarkup } from "https://esm.sh/react-dom/server";
const CLIENT_ID = Deno.env.get("REDDIT_CLIENT_ID");
const CLIENT_SECRET = Deno.env.get("REDDIT_SECRET");
function Embed(props) {
// TODO: use the correct video URL and add placeholder background image
const vid = props.secure_media?.reddit_video?.fallback_url;
return (
<body
style={{
margin: 0,
fontFamily: "system-ui, sans-serif",
}}
>
{vid && (
<>
<video
controls
width="896"
style={{
maxWidth: "100%",
}}
>
<source src={vid} />
</video>
</>
)}
<div
style={{
display: "flex",
alignItems: "center",
justifyContent: "space-between",
padding: "8px 0",
fontSize: 12,
}}
>
<div>{props.title}</div>
<div>
<a
href={`https://reddit.com${props.permalink}`}
target="_blank"
rel="noreferrer"
style={{
color: "inherit",
}}
>
{props.ups} upvotes on Reddit
</a>
</div>
</div>
</body>
);
}
export default async function main(req: Request): Promise<Response> {
const url = new URL(req.url);
const id = url.searchParams.get("id");
const sub = url.searchParams.get("sub");
if (!sub || !id) {
return Response.json({ message: "Requires post id & sub params" });
}
const token = await getRedditAccessToken();
const res = await fetchPost(token, sub, id);
const data = res[0]?.data?.children[0]?.data;
const html = renderToStaticMarkup(<Embed {...data} />);
return new Response(html, {
headers: {
"Content-Type": "text/html",
},
});
}
async function getRedditAccessToken() {
const authString = base64Encode(`${CLIENT_ID}:${CLIENT_SECRET}`);
const tokenResponse = await fetch("https://www.reddit.com/api/v1/access_token", {
method: "POST",
headers: {
"Authorization": `Basic ${authString}`,
"Content-Type": "application/x-www-form-urlencoded",
},
body: "grant_type=client_credentials",
});
const tokenData = await tokenResponse.json();
return tokenData.access_token;
}
async function fetchPost(token: string, subreddit: string, postId: string) {
const response = await fetch(`https://oauth.reddit.com/r/${subreddit}/comments/${postId}/.json`, {
headers: {
"Authorization": `Bearer ${token}`,
"User-Agent": "ValTownScript/1.0",
},