mirror of
https://github.com/CompeyDev/fxtwitter-docker.git
synced 2025-04-05 10:30:55 +01:00
Add error handling for private tweets, 404s
This commit is contained in:
parent
c45814c092
commit
5fbe0be3bf
4 changed files with 69 additions and 13 deletions
|
@ -62,7 +62,7 @@ export const fetchUsingGuest = async (status: string): Promise<TimelineBlobParti
|
||||||
)
|
)
|
||||||
).json()) as TimelineBlobPartial;
|
).json()) as TimelineBlobPartial;
|
||||||
|
|
||||||
if (typeof conversation.globalObjects === 'undefined') {
|
if (typeof conversation.globalObjects === 'undefined' && typeof conversation.errors === 'undefined') {
|
||||||
console.log('Failed to fetch conversation, got', conversation);
|
console.log('Failed to fetch conversation, got', conversation);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,16 @@ import { handleQuote } from './quote';
|
||||||
import { sanitizeText } from './utils';
|
import { sanitizeText } from './utils';
|
||||||
import { Strings } from './strings';
|
import { Strings } from './strings';
|
||||||
|
|
||||||
|
export const returnError = (error: string) => {
|
||||||
|
return Strings.BASE_HTML.format({
|
||||||
|
lang: '',
|
||||||
|
headers: [
|
||||||
|
`<meta content="${Constants.BRANDING_NAME}" property="og:title"/>`,
|
||||||
|
`<meta content="${error}" property="og:description"/>`
|
||||||
|
].join('')
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
export const handleStatus = async (
|
export const handleStatus = async (
|
||||||
status: string,
|
status: string,
|
||||||
mediaNumber?: number,
|
mediaNumber?: number,
|
||||||
|
@ -34,18 +44,27 @@ export const handleStatus = async (
|
||||||
|
|
||||||
/* Fallback for if Tweet did not load */
|
/* Fallback for if Tweet did not load */
|
||||||
if (typeof tweet.full_text === 'undefined') {
|
if (typeof tweet.full_text === 'undefined') {
|
||||||
headers.push(
|
|
||||||
`<meta content="Twitter" property="og:title"/>`,
|
|
||||||
`<meta content="Tweet failed to load :(" property="og:description"/>`
|
|
||||||
);
|
|
||||||
|
|
||||||
console.log('Invalid status, got tweet ', tweet, ' conversation ', conversation);
|
console.log('Invalid status, got tweet ', tweet, ' conversation ', conversation);
|
||||||
|
|
||||||
return Strings.BASE_HTML.format({
|
console.log('instructions', conversation.timeline?.instructions.length);
|
||||||
lang: '',
|
|
||||||
headers: headers.join(''),
|
/* We've got timeline instructions, so the Tweet is probably private */
|
||||||
tweet: JSON.stringify(tweet)
|
if (conversation.timeline?.instructions?.length > 0) {
|
||||||
});
|
return returnError(Strings.ERROR_PRIVATE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* {"errors":[{"code":34,"message":"Sorry, that page does not exist."}]} */
|
||||||
|
if (conversation.errors?.[0]?.code === 34) {
|
||||||
|
return returnError(Strings.ERROR_TWEET_NOT_FOUND);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Tweets object is completely missing, smells like API failure */
|
||||||
|
if (typeof conversation?.globalObjects?.tweets === 'undefined') {
|
||||||
|
return returnError(Strings.ERROR_API_FAIL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If we have no idea what happened then just return API error */
|
||||||
|
return returnError(Strings.ERROR_API_FAIL);
|
||||||
}
|
}
|
||||||
|
|
||||||
let text = tweet.full_text;
|
let text = tweet.full_text;
|
||||||
|
@ -57,7 +76,7 @@ export const handleStatus = async (
|
||||||
tweet.extended_entities?.media || tweet.entities?.media || []
|
tweet.extended_entities?.media || tweet.entities?.media || []
|
||||||
);
|
);
|
||||||
|
|
||||||
let authorText = 'Twitter';
|
let authorText = Strings.DEFAULT_AUTHOR_TEXT;
|
||||||
|
|
||||||
text = linkFixer(tweet, text);
|
text = linkFixer(tweet, text);
|
||||||
|
|
||||||
|
@ -117,6 +136,7 @@ export const handleStatus = async (
|
||||||
headers.push(
|
headers.push(
|
||||||
`<meta content="${colorOverride}" property="theme-color"/>`,
|
`<meta content="${colorOverride}" property="theme-color"/>`,
|
||||||
`<meta property="og:site_name" content="${Constants.BRANDING_NAME}"/>`,
|
`<meta property="og:site_name" content="${Constants.BRANDING_NAME}"/>`,
|
||||||
|
// Use a slightly higher resolution image for profile pics
|
||||||
`<meta property="og:image" content="${user?.profile_image_url_https.replace(
|
`<meta property="og:image" content="${user?.profile_image_url_https.replace(
|
||||||
'_normal',
|
'_normal',
|
||||||
'_200x200'
|
'_200x200'
|
||||||
|
|
|
@ -34,5 +34,9 @@ export const Strings = {
|
||||||
███ A better Tweet embedding service
|
███ A better Tweet embedding service
|
||||||
███ by @dangeredwolf, et al.
|
███ by @dangeredwolf, et al.
|
||||||
-->
|
-->
|
||||||
<head>{headers}</head>`
|
<head>{headers}</head>`,
|
||||||
|
DEFAULT_AUTHOR_TEXT: 'Twitter',
|
||||||
|
ERROR_API_FAIL: 'Tweet failed to load due to an API error :(',
|
||||||
|
ERROR_PRIVATE: `I can't embed media from private accounts, sorry about that :(`,
|
||||||
|
ERROR_TWEET_NOT_FOUND: `Sorry, that Tweet doesn't exist :(`
|
||||||
};
|
};
|
||||||
|
|
|
@ -3,6 +3,34 @@
|
||||||
Note that a lot of these are not actually complete types. Many unused values may be missing.
|
Note that a lot of these are not actually complete types. Many unused values may be missing.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
type TimelineContent = {
|
||||||
|
item?: {
|
||||||
|
content?: {
|
||||||
|
tombstone?: {
|
||||||
|
timestoneInfo: {
|
||||||
|
richText: {
|
||||||
|
text: string;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type TimelineInstruction = {
|
||||||
|
addEntries?: {
|
||||||
|
entries: {
|
||||||
|
content: TimelineContent,
|
||||||
|
entryId: string
|
||||||
|
}[]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type TwitterAPIError = {
|
||||||
|
code: number;
|
||||||
|
message: string;
|
||||||
|
}
|
||||||
|
|
||||||
type TimelineBlobPartial = {
|
type TimelineBlobPartial = {
|
||||||
globalObjects: {
|
globalObjects: {
|
||||||
tweets: {
|
tweets: {
|
||||||
|
@ -12,6 +40,10 @@ type TimelineBlobPartial = {
|
||||||
[userId: string]: UserPartial;
|
[userId: string]: UserPartial;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
timeline: {
|
||||||
|
instructions: TimelineInstruction[]
|
||||||
|
},
|
||||||
|
errors?: TwitterAPIError[]
|
||||||
};
|
};
|
||||||
|
|
||||||
type TweetMediaSize = {
|
type TweetMediaSize = {
|
||||||
|
|
Loading…
Add table
Reference in a new issue