Replace api fallback domain with elongator

This commit is contained in:
dangered wolf 2023-04-09 18:04:36 -04:00
parent 9058326e0e
commit fc5bc49a85
No known key found for this signature in database
GPG key ID: 41E4D37680ED8B58
8 changed files with 37 additions and 26 deletions

View file

@ -13,4 +13,3 @@ SENTRY_DSN = ""
SENTRY_AUTH_TOKEN = "" SENTRY_AUTH_TOKEN = ""
SENTRY_ORG = "" SENTRY_ORG = ""
SENTRY_PROJECT = "" SENTRY_PROJECT = ""
API_FALLBACK_DOMAIN = "https://"

View file

@ -16,7 +16,6 @@
"REDIRECT_URL": "https://github.com/FixTweet/FixTweet", "REDIRECT_URL": "https://github.com/FixTweet/FixTweet",
"EMBED_URL": "https://github.com/FixTweet/FixTweet", "EMBED_URL": "https://github.com/FixTweet/FixTweet",
"RELEASE_NAME": "fixtweet-test", "RELEASE_NAME": "fixtweet-test",
"API_FALLBACK_DOMAIN": "",
"TEST": true "TEST": true
}, },
"testRegex": "/test/.*\\.test\\.ts$", "testRegex": "/test/.*\\.test\\.ts$",

View file

@ -155,25 +155,23 @@ export const statusAPI = async (
tweet = conversation?.globalObjects?.tweets?.[tweet.retweeted_status_id_str] || {}; tweet = conversation?.globalObjects?.tweets?.[tweet.retweeted_status_id_str] || {};
} }
/* Fallback for if Tweet did not load */ /* Fallback for if Tweet did not load (i.e. NSFW) */
if (typeof tweet.full_text === 'undefined') { if (typeof tweet.full_text === 'undefined') {
console.log('Invalid status, got tweet ', tweet, ' conversation ', conversation); console.log('Invalid status, got tweet ', tweet, ' conversation ', conversation);
/* We've got timeline instructions, so the Tweet is probably private */
if (conversation.timeline?.instructions?.length > 0) { if (conversation.timeline?.instructions?.length > 0) {
// Try request again with fallback this time /* Try again using elongator API proxy */
console.log('No Tweet was found, trying fallback in case of geo-restriction'); console.log('No Tweet was found, loading again from elongator');
conversation = await fetchConversation(status, event, true); conversation = await fetchConversation(status, event, true);
tweet = conversation?.globalObjects?.tweets?.[status] || {}; tweet = conversation?.globalObjects?.tweets?.[status] || {};
if (typeof tweet.full_text !== 'undefined') { if (typeof tweet.full_text !== 'undefined') {
console.log('Successfully loaded Tweet, requiring fallback'); console.log('Successfully loaded Tweet using elongator');
} } else if (
if (
typeof tweet.full_text === 'undefined' && typeof tweet.full_text === 'undefined' &&
conversation.timeline?.instructions?.length > 0 conversation.timeline?.instructions?.length > 0
) { ) {
console.log('Tweet could not be accessed with elongator, must be private/suspended');
return { code: 401, message: 'PRIVATE_TWEET' }; return { code: 401, message: 'PRIVATE_TWEET' };
} }
} else { } else {

View file

@ -15,7 +15,6 @@ export const Constants = {
API_DOCS_URL: `https://github.com/dangeredwolf/FixTweet/wiki/API-Home`, API_DOCS_URL: `https://github.com/dangeredwolf/FixTweet/wiki/API-Home`,
TWITTER_ROOT: 'https://twitter.com', TWITTER_ROOT: 'https://twitter.com',
TWITTER_API_ROOT: 'https://api.twitter.com', TWITTER_API_ROOT: 'https://api.twitter.com',
API_FALLBACK_DOMAIN: API_FALLBACK_DOMAIN,
BOT_UA_REGEX: 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, /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 */ /* 3 hours */

View file

@ -6,6 +6,7 @@ const API_ATTEMPTS = 16;
export const twitterFetch = async ( export const twitterFetch = async (
url: string, url: string,
event: FetchEvent, event: FetchEvent,
useElongator = false,
validateFunction: (response: unknown) => boolean validateFunction: (response: unknown) => boolean
): Promise<unknown> => { ): Promise<unknown> => {
let apiAttempts = 0; let apiAttempts = 0;
@ -84,14 +85,18 @@ export const twitterFetch = async (
This can effectively mean virtually unlimited (read) access to Twitter's API, This can effectively mean virtually unlimited (read) access to Twitter's API,
which is very funny. */ which is very funny. */
// if (useElongator) {
// activate = await TwitterProxy.fetch(guestTokenRequest.clone());
// } else {
activate = await fetch(guestTokenRequest.clone()); activate = await fetch(guestTokenRequest.clone());
// }
} }
/* Let's grab that guest_token so we can use it */ /* Let's grab that guest_token so we can use it */
let activateJson: { guest_token: string }; let activateJson: { guest_token: string };
try { try {
activateJson = (await activate.clone().json()) as { guest_token: string }; activateJson = (await activate?.clone().json()) as { guest_token: string };
} catch (e: unknown) { } catch (e: unknown) {
continue; continue;
} }
@ -117,11 +122,20 @@ export const twitterFetch = async (
let apiRequest; let apiRequest;
try { try {
if (useElongator && typeof TwitterProxy !== 'undefined') {
console.log('Fetching using elongator');
apiRequest = await TwitterProxy.fetch(url, {
method: 'GET',
headers: headers
});
} else {
apiRequest = await fetch(url, { apiRequest = await fetch(url, {
method: 'GET', method: 'GET',
headers: headers headers: headers
}); });
response = await apiRequest.json(); }
response = await apiRequest?.json();
} catch (e: unknown) { } catch (e: unknown) {
/* We'll usually only hit this if we get an invalid response from Twitter. /* We'll usually only hit this if we get an invalid response from Twitter.
It's uncommon, but it happens */ It's uncommon, but it happens */
@ -177,13 +191,12 @@ export const twitterFetch = async (
export const fetchConversation = async ( export const fetchConversation = async (
status: string, status: string,
event: FetchEvent, event: FetchEvent,
fallback = false useElongator = false
): Promise<TimelineBlobPartial> => { ): Promise<TimelineBlobPartial> => {
return (await twitterFetch( 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, event,
useElongator,
(_conversation: unknown) => { (_conversation: unknown) => {
const conversation = _conversation as TimelineBlobPartial; const conversation = _conversation as TimelineBlobPartial;
return !( return !(

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

@ -9,9 +9,10 @@ declare const EMBED_URL: string;
declare const REDIRECT_URL: string; declare const REDIRECT_URL: string;
declare const MOSAIC_DOMAIN_LIST: string; declare const MOSAIC_DOMAIN_LIST: string;
declare const API_HOST_LIST: string; declare const API_HOST_LIST: string;
declare const API_FALLBACK_DOMAIN: string;
declare const SENTRY_DSN: string; declare const SENTRY_DSN: string;
declare const RELEASE_NAME: string; declare const RELEASE_NAME: string;
declare const TEST: boolean | undefined; declare const TEST: boolean | undefined;
declare const TwitterProxy: { fetch: (input: RequestInfo<unknown, CfProperties<unknown>>, init?: RequestInit<RequestInitCfProperties> | undefined) => Promise<Response> };

View file

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

View file

@ -3,6 +3,9 @@ account_id = "[CLOUDFLARE_ACCOUNT_ID]"
main = "./dist/worker.js" main = "./dist/worker.js"
compatibility_date = "2022-08-17" compatibility_date = "2022-08-17"
send_metrics = false send_metrics = false
services = [
{ binding = "TwitterProxy", service = "elongator" }
]
[build] [build]
command = "npm run build" command = "npm run build"