Allow returning page if transcript extraction failed

777b2518bdb0153f194db79fb651c558e196fc3d

Cohee <18619528+Cohee1207@users.noreply.github.com>

1 files changed, +67 -49Showing whitespace changes
src/endpoints/search.js+67 -49
@@ -22,59 +22,15 @@ const visitHeaders = {
2222 'Sec-Fetch-User': '?1',
2323};
2424
25-router.post('/serpapi', jsonParser, async (request, response) => {
26- try {
27- const key = readSecret(request.user.directories, SECRET_KEYS.SERPAPI);
28-
29- if (!key) {
30- console.log('No SerpApi key found');
31- return response.sendStatus(400);
32- }
33-
34- const { query } = request.body;
35- const result = await fetch(`https://serpapi.com/search.json?q=${encodeURIComponent(query)}&api_key=${key}`);
36-
37- console.log('SerpApi query', query);
38-
39- if (!result.ok) {
40- const text = await result.text();
41- console.log('SerpApi request failed', result.statusText, text);
42- return response.status(500).send(text);
43- }
44-
45- const data = await result.json();
46- return response.json(data);
47- } catch (error) {
48- console.log(error);
49- return response.sendStatus(500);
50- }
51-});
52-
5325/**
5426 * GetExtract the transcript of a YouTube video
55- * @copyright https://github.com/Kakulukian/youtube-transcript (MIT License)
27+ * @param {string} videoPageBody HTML of the video page
28+ * @param {string} lang Language code
29+ * @returns {Promise<string>} Transcript text
5630 */
57-router.post('/transcript', jsonParser, async (request, response) => {
31+async function extractTranscript(videoPageBody, lang) {
58- try {
5932 const he = require('he');
6033 const RE_XML_TRANSCRIPT = /<text start="([^"]*)" dur="([^"]*)">([^<]*)<\/text>/g;
61- const id = request.body.id;
62- const lang = request.body.lang;
63- const json = request.body.json;
64-
65- if (!id) {
66- console.log('Id is required for /transcript');
67- return response.sendStatus(400);
68- }
69-
70- const videoPageResponse = await fetch(`https://www.youtube.com/watch?v=${id}`, {
71- headers: {
72- ...(lang && { 'Accept-Language': lang }),
73- 'User-Agent': visitHeaders['User-Agent'],
74- },
75- });
76-
77- const videoPageBody = await videoPageResponse.text();
7834 const splittedHTML = videoPageBody.split('"captions":');
7935
8036 if (splittedHTML.length <= 1) {
@@ -129,11 +85,73 @@ router.post('/transcript', jsonParser, async (request, response) => {
12985 }));
13086 // The text is double-encoded
13187 const transcriptText = transcript.map((line) => he.decode(he.decode(line.text))).join(' ');
88+ return transcriptText;
89+}
90+
91+router.post('/serpapi', jsonParser, async (request, response) => {
92+ try {
93+ const key = readSecret(request.user.directories, SECRET_KEYS.SERPAPI);
94+
95+ if (!key) {
96+ console.log('No SerpApi key found');
97+ return response.sendStatus(400);
98+ }
99+
100+ const { query } = request.body;
101+ const result = await fetch(`https://serpapi.com/search.json?q=${encodeURIComponent(query)}&api_key=${key}`);
102+
103+ console.log('SerpApi query', query);
132104
105+ if (!result.ok) {
106+ const text = await result.text();
107+ console.log('SerpApi request failed', result.statusText, text);
108+ return response.status(500).send(text);
109+ }
110+
111+ const data = await result.json();
112+ return response.json(data);
113+ } catch (error) {
114+ console.log(error);
115+ return response.sendStatus(500);
116+ }
117+});
118+
119+/**
120+ * Get the transcript of a YouTube video
121+ * @copyright https://github.com/Kakulukian/youtube-transcript (MIT License)
122+ */
123+router.post('/transcript', jsonParser, async (request, response) => {
124+ try {
125+ const id = request.body.id;
126+ const lang = request.body.lang;
127+ const json = request.body.json;
128+
129+ if (!id) {
130+ console.log('Id is required for /transcript');
131+ return response.sendStatus(400);
132+ }
133+
134+ const videoPageResponse = await fetch(`https://www.youtube.com/watch?v=${id}`, {
135+ headers: {
136+ ...(lang && { 'Accept-Language': lang }),
137+ 'User-Agent': visitHeaders['User-Agent'],
138+ },
139+ });
140+
141+ const videoPageBody = await videoPageResponse.text();
142+
143+ try {
144+ const transcriptText = await extractTranscript(videoPageBody, lang);
133145 return json
134146 ? response.json({ transcript: transcriptText, html: videoPageBody })
135147 : response.send(transcriptText);
136148 } catch (error) {
149+ if (json) {
150+ return response.json({ html: videoPageBody, transcript: '' });
151+ }
152+ throw error;
153+ }
154+ } catch (error) {
137155 console.log(error);
138156 return response.sendStatus(500);
139157 }