Handle quotes better

This commit is contained in:
dangered wolf 2022-07-14 17:23:25 -04:00
parent 824e44d4ed
commit 9f2162b53c
No known key found for this signature in database
GPG key ID: 41E4D37680ED8B58
4 changed files with 62 additions and 41 deletions

12
src/linkFixer.ts Normal file
View file

@ -0,0 +1,12 @@
export const linkFixer = (tweet: TweetPartial, text: string): string => {
// Replace t.co links with their full counterparts
if (typeof tweet.entities?.urls !== 'undefined') {
tweet.entities?.urls.forEach((url: TcoExpansion) => {
text = text.replace(url.url, url.expanded_url);
});
text = text.replace(/ ?https\:\/\/t\.co\/\w{10}/, '');
}
return text;
}

View file

@ -1,3 +1,15 @@
import { linkFixer } from "./linkFixer";
export const handleQuote = (quote: TweetPartial): string | null => { export const handleQuote = (quote: TweetPartial): string | null => {
return null; console.log('quote tweet: ', quote);
let str = `\n`
str += `↘️ Quoting ${quote.user?.name} (${quote.user?.screen_name}) `
str += '═'.repeat(Math.max(60 - str.length, 0))
str += ` \n\n`;
str += linkFixer(quote, quote.full_text);
return str;
}; };

View file

@ -24,15 +24,13 @@ String.prototype.format = function (options: any) {
const router = Router(); const router = Router();
const statusRequest = async (request: any) => { const statusRequest = async (request: any) => {
const { handle, id, mediaNumber } = request.params; const { id, mediaNumber } = request.params;
const url = new URL(request.url); const url = new URL(request.url);
const userAgent = request.headers.get('User-Agent'); const userAgent = request.headers.get('User-Agent');
if (userAgent.match(/bot/gi) !== null) { if (userAgent.match(/bot/gi) !== null) {
return new Response(await handleStatus(handle, id, parseInt(mediaNumber || 1)), { return new Response(await handleStatus(id, parseInt(mediaNumber || 1)), {
headers: { headers: Constants.RESPONSE_HEADERS,
'content-type': 'text/html;charset=UTF-8'
},
status: 200 status: 200
}); });
} else { } else {
@ -48,7 +46,7 @@ router.get('/:handle/statuses/:id/photo/:mediaNumber', statusRequest);
router.get('/:handle/statuses/:id/video/:mediaNumber', statusRequest); router.get('/:handle/statuses/:id/video/:mediaNumber', statusRequest);
router.get('/owoembed', async (request: any) => { router.get('/owoembed', async (request: any) => {
console.log('THE OWOEMBED HAS BEEN ACCESSED!!!!!!!!!'); console.log('oembed hit!');
const { searchParams } = new URL(request.url); const { searchParams } = new URL(request.url);
let text = searchParams.get('text') || 'Twitter'; let text = searchParams.get('text') || 'Twitter';
@ -57,7 +55,7 @@ router.get('/owoembed', async (request: any) => {
const test = { const test = {
author_name: decodeURIComponent(text), author_name: decodeURIComponent(text),
author_url: `https://twitter.com/${encodeURIComponent( author_url: `${Constants.TWITTER_ROOT}/${encodeURIComponent(
author author
)}/status/${encodeURIComponent(status)}`, )}/status/${encodeURIComponent(status)}`,
provider_name: Constants.BRANDING_NAME, provider_name: Constants.BRANDING_NAME,
@ -67,9 +65,7 @@ router.get('/owoembed', async (request: any) => {
version: '1.0' version: '1.0'
}; };
return new Response(JSON.stringify(test), { return new Response(JSON.stringify(test), {
headers: { headers: Constants.RESPONSE_HEADERS,
'content-type': 'application/json'
},
status: 200 status: 200
}); });
}); });

View file

@ -1,12 +1,12 @@
import { Constants } from './constants'; import { Constants } from './constants';
import { fetchUsingGuest } from './fetch'; import { fetchUsingGuest } from './fetch';
import { Html } from './html'; import { Html } from './html';
import { linkFixer } from './linkFixer';
import { colorFromPalette } from './palette'; import { colorFromPalette } from './palette';
import { renderPoll } from './poll'; import { renderPoll } from './poll';
import { handleQuote } from './quote'; import { handleQuote } from './quote';
export const handleStatus = async ( export const handleStatus = async (
handle: string,
status: string, status: string,
mediaNumber?: number mediaNumber?: number
): Promise<string> => { ): Promise<string> => {
@ -51,35 +51,45 @@ export const handleStatus = async (
const screenName = user?.screen_name || ''; const screenName = user?.screen_name || '';
const name = user?.name || ''; const name = user?.name || '';
const mediaList = Array.from( let mediaList = Array.from(
tweet.extended_entities?.media || tweet.entities?.media || [] tweet.extended_entities?.media || tweet.entities?.media || []
); );
let authorText = 'Twitter'; let authorText = 'Twitter';
// This is used to chop off the end if it's like pic.twitter.com or something
if (tweet.display_text_range) {
const [start, end] = tweet.display_text_range;
// We ignore start because it cuts off reply handles
// text = text.substring(0, end + 1);
}
if (tweet.card) { if (tweet.card) {
text += await renderPoll(tweet.card); text += await renderPoll(tweet.card);
} }
// Replace t.co links with their full counterparts text = linkFixer(tweet, text);
if (typeof tweet.entities?.urls !== 'undefined') {
tweet.entities?.urls.forEach((url: TcoExpansion) => { let quoteTweetMaybe =
text = text.replace(url.url, url.expanded_url); conversation.globalObjects?.tweets?.[tweet.quoted_status_id_str || '0'] || null;
});
text = text.replace(/ ?https\:\/\/t\.co\/\w{10}/, ''); if (quoteTweetMaybe) {
quoteTweetMaybe.user = conversation?.globalObjects?.users?.[quoteTweetMaybe.user_id_str] || {};
const quoteText = handleQuote(quoteTweetMaybe);
console.log('quoteText', quoteText);
if (quoteText) {
text += `\n${quoteText}`;
}
if (mediaList.length === 0 && (quoteTweetMaybe.extended_entities?.media?.length || quoteTweetMaybe.entities?.media?.length || 0) > 0) {
console.log('No media in main tweet, maybe we have some media in the quote tweet?');
mediaList = Array.from(
quoteTweetMaybe.extended_entities?.media ||
quoteTweetMaybe.entities?.media ||
[]
);
console.log('updated mediaList', mediaList)
}
} }
if ( if (mediaList.length === 0) {
typeof tweet.extended_entities?.media === 'undefined' && console.log('Media unavailable');
typeof tweet.entities?.media === 'undefined'
) {
let palette = user?.profile_image_extensions_media_color?.palette; let palette = user?.profile_image_extensions_media_color?.palette;
let colorOverride: string = Constants.DEFAULT_COLOR; let colorOverride: string = Constants.DEFAULT_COLOR;
@ -101,6 +111,7 @@ export const handleStatus = async (
`<meta content="${text}" property="og:description"/>` `<meta content="${text}" property="og:description"/>`
); );
} else { } else {
console.log('Media available');
let firstMedia = mediaList[0]; let firstMedia = mediaList[0];
let palette = firstMedia?.ext_media_color?.palette; let palette = firstMedia?.ext_media_color?.palette;
@ -186,16 +197,6 @@ export const handleStatus = async (
); );
} }
let quoteTweetMaybe =
conversation.globalObjects?.tweets?.[tweet.quoted_status_id_str || '0'] || null;
if (quoteTweetMaybe) {
const quoteText = handleQuote(quoteTweetMaybe);
if (quoteText) {
}
}
/* Special reply handling if authorText is not overriden */ /* Special reply handling if authorText is not overriden */
if (tweet.in_reply_to_screen_name && authorText === 'Twitter') { if (tweet.in_reply_to_screen_name && authorText === 'Twitter') {
authorText = `↪ Replying to @${tweet.in_reply_to_screen_name}`; authorText = `↪ Replying to @${tweet.in_reply_to_screen_name}`;
@ -204,7 +205,7 @@ export const handleStatus = async (
/* The additional oembed is pulled by Discord to enable improved embeds. /* The additional oembed is pulled by Discord to enable improved embeds.
Telegram does not use this. */ Telegram does not use this. */
headers.push( headers.push(
`<link rel="alternate" href="/owoembed?text=${encodeURIComponent( `<link rel="alternate" href="${Constants.HOST_URL}/owoembed?text=${encodeURIComponent(
authorText authorText
)}&status=${encodeURIComponent(status)}&author=${encodeURIComponent( )}&status=${encodeURIComponent(status)}&author=${encodeURIComponent(
user?.screen_name || '' user?.screen_name || ''