From 54631f5c2a0d4a10a9a8cf310c502704546fea7b Mon Sep 17 00:00:00 2001 From: vulet Date: Mon, 7 Jun 2021 15:30:40 +0800 Subject: [PATCH] refactor(invidious/nitter): add instance fallback. chore(readme): update instances. --- commands/invidious.js | 29 +++++++++++++++++------------ commands/nitter.js | 27 ++++++++++++++++----------- config.example.js | 4 +++- 3 files changed, 36 insertions(+), 24 deletions(-) diff --git a/commands/invidious.js b/commands/invidious.js index c1fe773..0b49329 100644 --- a/commands/invidious.js +++ b/commands/invidious.js @@ -6,8 +6,10 @@ const headers = ({ domain, userAgent }) => ({ const invidious = async (instance, url) => { const req = await instance({ method: 'GET', url }); if (req.statusText !== 'OK') throw req; + const { headers } = instance.defaults; const video = JSON.parse(req.data); return { + url: headers['Host'], name: video.title, date: video.publishedText, description: video.descriptionHtml, @@ -18,8 +20,8 @@ const invidious = async (instance, url) => { }; }; -const card = (video, base, path) => -`${video.name}
` + +const card = (video, path) => +`${video.name}
` + ((video.description.length > 300) ? `${video.description.substr(0, 300)}…` : ``)+ ((video.description === '

') ? `No description.`: ``)+ ((video.description.length < 300 && video.description !== '

') ? `${video.description}` : ``)+ @@ -29,16 +31,19 @@ const card = (video, base, path) => `
(${video.date})

`; -const run = async (roomId, userInput) => { - const instance = axios.create({ - baseURL: `https://${config.invidious.domain}/api/v1/videos/`, - headers: headers(config.invidious), - transformResponse: [], - timeout: 10 * 1000, - }); - const video = await invidious(instance, userInput); - return await matrixClient.sendHtmlNotice(roomId, '', card(video, `https://${config.invidious.domain}`, userInput)); -}; + const getInstance = config => + axios.create({ + baseURL: `https://${config.domain}/api/v1/videos`, + headers: headers(config), + transformResponse: [], + timeout: 10 * 1000, + }); + + const run = async (roomId, userInput) => { + const video = await invidious(getInstance(config.invidious), userInput) + .catch(_ => invidious(getInstance(Object.assign(config.invidious, { domain: config.invidious.fallback })), userInput)); + return matrixClient.sendHtmlNotice(roomId, '', card(video, userInput)); + }; exports.runQuery = async (roomId, event, userInput) => { try { diff --git a/commands/nitter.js b/commands/nitter.js index 823272d..aa470e6 100644 --- a/commands/nitter.js +++ b/commands/nitter.js @@ -15,7 +15,9 @@ const nitter = async (instance, url) => { const quote = tweet.querySelector('.tweet-body > .quote'); const isReply = tweet.querySelector('.tweet-body > .replying-to'); const replies = document.querySelectorAll('.main-thread > .before-tweet > .timeline-item'); + const { defaults } = instance; return { + url: defaults.baseURL, text: tweet.querySelector('.tweet-body > .tweet-content').innerHTML, date: tweet.querySelector('.tweet-body > .tweet-published').textContent, name: tweet.querySelector('.tweet-body > div .fullname').textContent, @@ -38,27 +40,30 @@ const nitter = async (instance, url) => { }; }; -const card = (tweet, base, check, path) => -`${tweet.name} ` + +const card = (tweet, check, path) => +`${tweet.name} ` + (tweet.check ? `${check} ` : '') + -`${tweet.date} ` + +`${tweet.date} ` + `🗨️ ${tweet.stats.replies} ` + `🔁 ${tweet.stats.retweets} ` + `❤️ ${tweet.stats.favorites} ` + `
${tweet.text.replace('\n', '
')}
` + (tweet.hasAttachments ? '
This tweet has attached media.
' : '') + -(tweet.isReply ? tweet.isReply === 'unavailable' ? '
Replied Tweet is unavailable
' : `
Replied Tweet
${tweet.isReply.text.replace('\n', '
')}
` : '') + -(tweet.quote ? `
Quoted Tweet
${tweet.quote.text.replace('\n', '
')}
` : ''); +(tweet.isReply ? tweet.isReply === 'unavailable' ? '
Replied Tweet is unavailable
' : `
Replied Tweet
${tweet.isReply.text.replace('\n', '
')}
` : '') + +(tweet.quote ? `
Quoted Tweet
${tweet.quote.text.replace('\n', '
')}
` : ''); -const run = async (roomId, userInput) => { - const instance = axios.create({ - baseURL: `https://${config.nitter.domain}`, - headers: headers(config.nitter), +const getInstance = config => + axios.create({ + baseURL: `https://${config.domain}`, + headers: headers(config), transformResponse: [], timeout: 10 * 1000, }); - const tweet = await nitter(instance, userInput); - return await matrixClient.sendHtmlNotice(roomId, '', card(tweet, `https://${config.nitter.domain}`, config.nitter.check, userInput)); + +const run = async (roomId, userInput) => { + const tweet = await nitter(getInstance(config.nitter), userInput) + .catch(_ => nitter(getInstance(Object.assign(config.nitter, { domain: config.nitter.fallback })), userInput)); + return matrixClient.sendHtmlNotice(roomId, '', card(tweet, config.nitter.check, userInput)); }; exports.runQuery = async (roomId, event, userInput) => { diff --git a/config.example.js b/config.example.js index ebc4c85..a216d7d 100644 --- a/config.example.js +++ b/config.example.js @@ -24,12 +24,14 @@ module.exports = { }, nitter: { domain: 'nitter.fdn.fr', + fallback: 'nitter.snopyta.org', userAgent: 'Mozilla/4.0 (compatible; Beep Boop)', - domains: [ 'nitter.net', 'www.nitter.net', 'twitter.com', 'www.twitter.com', 'mobile.twitter.com', 'm.twitter.com', 'nitter.fdn.fr' ], + domains: [ 'nitter.snopyta.org', 'nitter.net', 'www.nitter.net', 'twitter.com', 'www.twitter.com', 'mobile.twitter.com', 'm.twitter.com', 'nitter.fdn.fr' ], check: '(✅)' }, invidious: { domain: 'invidious.fdn.fr', + fallback: 'invidious.snopyta.org', userAgent: 'Mozilla/4.0 (compatible; Beep Boop)', domains: [ 'invidious.snopyta.org', 'invidious.xyz', 'youtube.com', 'www.youtube.com', 'youtu.be', 'm.youtube.com', 'invidious.fdn.fr' ] }