|
| 1 | +import { bold, hyperlink } from '@discordjs/builders'; |
| 2 | +import type { Response } from 'polka'; |
| 3 | +import { EMOJI_ID_GUIDE } from '../util/constants.js'; |
| 4 | +import { findRelevantDocsSection } from '../util/discordDocs.js'; |
| 5 | +import { noCodeLines, resolveResourceFromGuideUrl } from '../util/djsguide.js'; |
| 6 | +import { prepareResponse } from '../util/respond.js'; |
| 7 | +import { truncate } from '../util/truncate.js'; |
| 8 | + |
| 9 | +type GuideCacheEntry = { |
| 10 | + page: string; |
| 11 | + timestamp: number; |
| 12 | +}; |
| 13 | + |
| 14 | +const cache = new Map<string, GuideCacheEntry>(); |
| 15 | + |
| 16 | +async function getPage(url: string) { |
| 17 | + const cacheEntry = cache.get(url); |
| 18 | + |
| 19 | + if (cacheEntry && cacheEntry.timestamp < Date.now() - 1_000 * 60 * 60) { |
| 20 | + return cacheEntry.page; |
| 21 | + } |
| 22 | + |
| 23 | + const page = await fetch(url).then(async (res) => res.text()); |
| 24 | + cache.set(url, { page, timestamp: Date.now() }); |
| 25 | + |
| 26 | + return page; |
| 27 | +} |
| 28 | + |
| 29 | +export async function oramaResponse(res: Response, resultUrl: string, user?: string, ephemeral?: boolean) { |
| 30 | + const parsed = resolveResourceFromGuideUrl(resultUrl); |
| 31 | + const contentParts: string[] = []; |
| 32 | + |
| 33 | + const docsContents = await getPage(parsed.githubUrl); |
| 34 | + const section = findRelevantDocsSection(parsed.anchor ? `#${parsed.anchor}` : parsed.endpoint ?? '', docsContents); |
| 35 | + |
| 36 | + if (section) { |
| 37 | + const title = section.heading?.label ?? parsed.endpoint ?? 'No Title'; |
| 38 | + contentParts.push(`<:guide:${EMOJI_ID_GUIDE}> ${bold(title)}`); |
| 39 | + } |
| 40 | + |
| 41 | + const relevantLines = noCodeLines(section?.lines ?? []); |
| 42 | + if (relevantLines.length) { |
| 43 | + contentParts.push(truncate(relevantLines.join(' '), 300)); |
| 44 | + } |
| 45 | + |
| 46 | + contentParts.push(hyperlink('read more', parsed.guideUrl)); |
| 47 | + |
| 48 | + prepareResponse(res, contentParts.join('\n'), { |
| 49 | + ephemeral, |
| 50 | + suggestion: user ? { userId: user, kind: 'guide' } : undefined, |
| 51 | + }); |
| 52 | + return res; |
| 53 | +} |
0 commit comments