Attempt to implement API fallback proxy

This commit is contained in:
dangered wolf 2023-04-06 17:49:41 -04:00
parent 3b9edfe3ee
commit 57620d3004
No known key found for this signature in database
GPG key ID: 41E4D37680ED8B58
6 changed files with 36 additions and 18 deletions

View file

@ -12,4 +12,5 @@ EMBED_URL = "https://github.com/FixTweet/FixTweet"
SENTRY_DSN = ""
SENTRY_AUTH_TOKEN = ""
SENTRY_ORG = ""
SENTRY_PROJECT = ""
SENTRY_PROJECT = ""
API_FALLBACK_DOMAIN = ""

View file

@ -154,21 +154,35 @@ export const statusAPI = async (
/* We've got timeline instructions, so the Tweet is probably private */
if (conversation.timeline?.instructions?.length > 0) {
return { code: 401, message: 'PRIVATE_TWEET' };
}
// Try request again with fallback this time
console.log('No Tweet was found, trying fallback in case of geo-restriction');
const conversationFallback = await fetchConversation(status, event, true);
tweet = conversationFallback?.globalObjects?.tweets?.[status] || {};
/* {"errors":[{"code":34,"message":"Sorry, that page does not exist."}]} */
if (conversation.errors?.[0]?.code === 34) {
return { code: 404, message: 'NOT_FOUND' };
}
if (typeof tweet.full_text !== 'undefined') {
console.log('Successfully loaded Tweet, requiring fallback');
}
/* Tweets object is completely missing, smells like API failure */
if (typeof conversation?.globalObjects?.tweets === 'undefined') {
if (
typeof tweet.full_text === 'undefined' &&
conversation.timeline?.instructions?.length > 0
) {
return { code: 401, message: 'PRIVATE_TWEET' };
}
} else {
/* {"errors":[{"code":34,"message":"Sorry, that page does not exist."}]} */
if (conversation.errors?.[0]?.code === 34) {
return { code: 404, message: 'NOT_FOUND' };
}
/* Tweets object is completely missing, smells like API failure */
if (typeof conversation?.globalObjects?.tweets === 'undefined') {
return { code: 500, message: 'API_FAIL' };
}
/* If we have no idea what happened then just return API error */
return { code: 500, message: 'API_FAIL' };
}
/* If we have no idea what happened then just return API error */
return { code: 500, message: 'API_FAIL' };
}
/* Creating the response objects */

View file

@ -15,6 +15,7 @@ export const Constants = {
API_DOCS_URL: `https://github.com/dangeredwolf/FixTweet/wiki/API-Home`,
TWITTER_ROOT: 'https://twitter.com',
TWITTER_API_ROOT: 'https://api.twitter.com',
API_FALLBACK_DOMAIN: API_FALLBACK_DOMAIN,
BOT_UA_REGEX:
/bot|facebook|embed|got|firefox\/92|firefox\/38|curl|wget|go-http|yahoo|generator|whatsapp|preview|link|proxy|vkshare|images|analyzer|index|crawl|spider|python|cfnetwork|node/gi,
/* 3 hours */

View file

@ -113,9 +113,6 @@ export const twitterFetch = async (
headers['x-twitter-active-user'] = 'yes';
headers['x-guest-token'] = guestToken;
/* We pretend to be the Twitter Web App as closely as possible,
so we use twitter.com/i/api/2 instead of api.twitter.com/2.
We probably don't have to do this at all. But hey, better to be consistent with Twitter Web App. */
let response: unknown;
let apiRequest;
@ -179,10 +176,13 @@ export const twitterFetch = async (
export const fetchConversation = async (
status: string,
event: FetchEvent
event: FetchEvent,
fallback = false
): Promise<TimelineBlobPartial> => {
return (await twitterFetch(
`${Constants.TWITTER_API_ROOT}/2/timeline/conversation/${status}.json?${Constants.GUEST_FETCH_PARAMETERS}`,
`${
fallback ? Constants.API_FALLBACK_DOMAIN : Constants.TWITTER_API_ROOT
}/2/timeline/conversation/${status}.json?${Constants.GUEST_FETCH_PARAMETERS}`,
event,
(_conversation: unknown) => {
const conversation = _conversation as TimelineBlobPartial;

1
src/types/env.d.ts vendored
View file

@ -9,6 +9,7 @@ declare const EMBED_URL: string;
declare const REDIRECT_URL: string;
declare const MOSAIC_DOMAIN_LIST: string;
declare const API_HOST_LIST: string;
declare const API_FALLBACK_DOMAIN: string;
declare const SENTRY_DSN: string;
declare const RELEASE_NAME: string;

View file

@ -29,7 +29,8 @@ let envVariables = [
'API_HOST_LIST',
'SENTRY_DSN',
'DEPRECATED_DOMAIN_LIST',
'DEPRECATED_DOMAIN_EPOCH'
'DEPRECATED_DOMAIN_EPOCH',
'API_FALLBACK_DOMAIN'
];
let plugins = [