Ep13 publish, MLX whisper, voicemail system, hero redesign, massive topic expansion
- Switch whisper transcription from faster-whisper (CPU) to lightning-whisper-mlx (GPU) - Fix word_timestamps hanging, use ffprobe for accurate duration - Add Cloudflare Pages Worker for SignalWire voicemail fallback when server offline - Add voicemail sync on startup, delete tracking, save feature - Add /feed RSS proxy to _worker.js (was broken by worker taking over routing) - Redesign website hero section: ghost buttons, compact phone, plain text links - Rewrite caller prompts for faster point-getting and host-following - Expand TOPIC_CALLIN from ~250 to 547 entries across 34 categories - Add new categories: biology, psychology, engineering, math, geology, animals, work, money, books, movies, relationships, health, language, true crime, drunk/high/unhinged callers - Remove bad Inworld voices (Pixie, Dominus), reduce repeat caller frequency - Add audio monitor device routing, uvicorn --reload-dir fix - Publish episode 13 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
64
website/_worker.js
Normal file
64
website/_worker.js
Normal file
@@ -0,0 +1,64 @@
|
||||
const VOICEMAIL_XML = `<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Response>
|
||||
<Say voice="woman">Luke at the Roost is off the air right now. Leave a message after the beep and we may play it on the next show!</Say>
|
||||
<Record maxLength="120" action="https://radioshow.macneilmediagroup.com/api/signalwire/voicemail-complete" playBeep="true" />
|
||||
<Say voice="woman">Thank you for calling. Goodbye!</Say>
|
||||
<Hangup/>
|
||||
</Response>`;
|
||||
|
||||
export default {
|
||||
async fetch(request, env) {
|
||||
const url = new URL(request.url);
|
||||
|
||||
if (url.pathname === "/api/signalwire/voice") {
|
||||
try {
|
||||
const body = await request.text();
|
||||
const resp = await fetch("https://radioshow.macneilmediagroup.com/api/signalwire/voice", {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
||||
body: body,
|
||||
signal: AbortSignal.timeout(5000),
|
||||
});
|
||||
|
||||
if (resp.ok) {
|
||||
return new Response(await resp.text(), {
|
||||
status: 200,
|
||||
headers: { "Content-Type": "application/xml" },
|
||||
});
|
||||
}
|
||||
} catch (e) {
|
||||
// Server unreachable or timed out
|
||||
}
|
||||
|
||||
return new Response(VOICEMAIL_XML, {
|
||||
status: 200,
|
||||
headers: { "Content-Type": "application/xml" },
|
||||
});
|
||||
}
|
||||
|
||||
// RSS feed proxy
|
||||
if (url.pathname === "/feed") {
|
||||
try {
|
||||
const resp = await fetch("https://podcast.macneilmediagroup.com/@LukeAtTheRoost/feed.xml", {
|
||||
signal: AbortSignal.timeout(8000),
|
||||
});
|
||||
if (resp.ok) {
|
||||
return new Response(await resp.text(), {
|
||||
status: 200,
|
||||
headers: {
|
||||
"Content-Type": "application/xml",
|
||||
"Access-Control-Allow-Origin": "*",
|
||||
"Cache-Control": "public, max-age=300",
|
||||
},
|
||||
});
|
||||
}
|
||||
} catch (e) {
|
||||
// Castopod unreachable
|
||||
}
|
||||
return new Response("Feed unavailable", { status: 502 });
|
||||
}
|
||||
|
||||
// All other requests — serve static assets
|
||||
return env.ASSETS.fetch(request);
|
||||
},
|
||||
};
|
||||
Reference in New Issue
Block a user