Reader: ESV chapter audio
Build and Push Docker Image / build-and-push (push) Failing after 19s

The Reader's player follows the translation on screen: ESV plays its own
recording via a server route that resolves the ESV API's audio redirect;
other translations keep the BSB narrators.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
nmemmertandClaude Sonnet 5.5 committed 2026-09-29 09:20:15 -04:00
1 parent e50a73d351
commit 3279dddae5
4 files changed
+51 -13

No files matched your search

+21
View File
@@ -59,6 +59,27 @@ export function registerBibleRoutes(app, requireAuth) {
})));
});
// ESV chapter audio (read by David Cochran Heath). The ESV API answers with a
// redirect to a public mp3; hand that URL to the browser's <audio> element.
app.get('/api/bible/ESV/audio/:book/:chapter', requireAuth, async (req, res) => {
const { book, chapter } = req.params;
const bookNum = BOOK_ORDER.indexOf(book.toUpperCase()) + 1;
if (!bookNum || !/^\d{1,3}$/.test(chapter)) return res.status(400).json({ error: 'Invalid book or chapter.' });
if (!process.env.ESV_API_KEY) return res.status(503).json({ error: 'ESV_API_KEY is not configured on the server.' });
const prefix = String(bookNum).padStart(2, '0') + String(Number(chapter)).padStart(3, '0');
try {
const upstream = await fetch(`https://api.esv.org/v3/passage/audio/?q=${prefix}001-${prefix}999`, {
headers: { Authorization: `Token ${process.env.ESV_API_KEY}` }, redirect: 'manual',
});
const url = upstream.headers.get('location');
if (upstream.status === 429) return res.status(429).json({ error: 'ESV rate limit reached. Try again in a minute.' });
if (!url) return res.status(502).json({ error: 'ESV audio is not available for this chapter.' });
res.json({ url });
} catch {
res.status(502).json({ error: 'Could not reach the ESV audio service.' });
}
});
app.get('/api/bible/:translation/:book/:chapter', requireAuth, async (req, res) => {
const translation = LICENSED_TRANSLATIONS[req.params.translation.toUpperCase()];
const { book, chapter } = req.params;