Skip to content

Commit dc9b8da

Browse files
committed
Update buffer posts.
1 parent f426f87 commit dc9b8da

File tree

1 file changed

+129
-0
lines changed

1 file changed

+129
-0
lines changed

src/pages/api/buffer_posts.ts

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
import { getCollection, getEntry } from "astro:content";
2+
import type { APIRoute } from "astro";
3+
4+
export const GET: APIRoute = async ({ params, request }) => {
5+
const limit = Infinity;
6+
const speakers = await getCollection("speakers");
7+
8+
const exclude = [
9+
"sebastian-ramirez",
10+
"savannah-ostrowski",
11+
"nerea-luis",
12+
"petr-baudis",
13+
"brett-cannon",
14+
];
15+
16+
const records: any[] = [];
17+
18+
const charLimits: Record<string, number> = {
19+
instagram: 2200,
20+
x: 280,
21+
linkedin: 3000,
22+
bsky: 300,
23+
fosstodon: 500,
24+
};
25+
26+
const message_template_full = ({
27+
name,
28+
talkTitle,
29+
affiliation,
30+
fallbackUrl,
31+
}: {
32+
name: string;
33+
talkTitle: string;
34+
affiliation: string | null;
35+
fallbackUrl: string;
36+
}) => `🚀 Exciting News: ${name} to Speak at EuroPython 2025!
37+
38+
I'm thrilled to announce that ${name}${affiliation ? `, renowned for their work at ${affiliation},` : ""} will be speaking at EuroPython 2025 about "${talkTitle}"!
39+
40+
🗓️ Event: EuroPython 2025
41+
🔗 Details & Registration: https://ep2025.europython.eu/
42+
👤 Speaker Profile: ${fallbackUrl}
43+
44+
#EuroPython2025 #Python #TechConference`;
45+
46+
const message_template_short = ({
47+
name,
48+
talkTitle,
49+
}: {
50+
name: string;
51+
talkTitle: string;
52+
}) =>
53+
`${name} is speaking at EuroPython 2025 about "${talkTitle}"! 🎤 https://ep2025.europython.eu/ #EuroPython2025`;
54+
55+
const trimToLimit = (text: string, limit: number) =>
56+
text.length <= limit ? text : text.slice(0, limit - 1) + "…";
57+
58+
for (const speaker of speakers) {
59+
if (records.length >= limit) break;
60+
if (exclude.includes(speaker.id)) continue;
61+
62+
const {
63+
name,
64+
twitter_url,
65+
linkedin_url,
66+
bluesky_url,
67+
mastodon_url,
68+
submissions,
69+
affiliation,
70+
} = speaker.data;
71+
72+
const sessions = await Promise.all(
73+
submissions.map((session) => getEntry("sessions", session.id))
74+
);
75+
76+
const validSessions = sessions.filter(
77+
(session) => session && session.data.title
78+
);
79+
if (validSessions.length === 0) continue;
80+
81+
const talkTitle = validSessions[0]?.data.title || "an exciting topic";
82+
83+
const speakerImage = `https://ep2025-buffer.ep-preview.click/media/social-${speaker.id}.png`;
84+
const fallbackUrl = `https://ep2025.europython.eu/speaker/${speaker.id}`;
85+
const links = {
86+
instagram: fallbackUrl,
87+
x: twitter_url ?? fallbackUrl,
88+
linkedin: linkedin_url ?? fallbackUrl,
89+
bsky: bluesky_url ?? fallbackUrl,
90+
fosstodon: mastodon_url ?? fallbackUrl,
91+
};
92+
93+
const generateMessage = (platform: string) => {
94+
const full = message_template_full({
95+
name,
96+
talkTitle,
97+
affiliation,
98+
fallbackUrl: links[platform],
99+
});
100+
const short = message_template_short({ name, talkTitle });
101+
const limit = charLimits[platform];
102+
103+
if (full.length <= limit) return full;
104+
if (short.length <= limit) return short;
105+
return trimToLimit(short, limit);
106+
};
107+
108+
const record = {
109+
name,
110+
image: speakerImage,
111+
channel: {
112+
instagram: generateMessage("instagram"),
113+
x: generateMessage("x"),
114+
linkedin: generateMessage("linkedin"),
115+
bsky: generateMessage("bsky"),
116+
fosstodon: generateMessage("fosstodon"),
117+
},
118+
};
119+
120+
records.push(record);
121+
}
122+
123+
return new Response(JSON.stringify(records, null, 2), {
124+
status: 200,
125+
headers: {
126+
"Content-Type": "application/json",
127+
},
128+
});
129+
};

0 commit comments

Comments
 (0)