Change ERROR_PRIVATE string and run prettier

This commit is contained in:
dangered wolf 2022-07-15 16:01:49 -04:00
parent 5fbe0be3bf
commit d4cf2cc5b8
No known key found for this signature in database
GPG key ID: 41E4D37680ED8B58
6 changed files with 52 additions and 42 deletions

View file

@ -22,26 +22,26 @@
:heavy_check_mark: **Better privacy: We don't save tweets or their media** (Outside of temporary Cloudflare caching for speed) :heavy_check_mark: **Better privacy: We don't save tweets or their media** (Outside of temporary Cloudflare caching for speed)
-------------------- ---
Here's a little chart comparing features to Twitter default embeds and other embedding services Here's a little chart comparing features to Twitter default embeds and other embedding services
| | pxTwitter | Twitter default | vxTwitter (BetterTwitFix) | Twxtter (sixFix) | | | pxTwitter | Twitter default | vxTwitter (BetterTwitFix) | Twxtter (sixFix) |
|-------------------------------------|:------------------:|:------------------:|:--------------------------------:|:---------------------------------:| | ----------------------------------- | :----------------: | :----------------: | :------------------------------: | :------------------------------: |
| Embed Tweets / Photos | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | | Embed Tweets / Photos | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: |
| Embed Videos | :heavy_check_mark: | :x:¹ | :heavy_check_mark: | :heavy_check_mark: | | Embed Videos | :heavy_check_mark: | :x:¹ | :heavy_check_mark: | :heavy_check_mark: |
| Embed Poll results | :heavy_check_mark: | :x: | :x: | :x: | | Embed Poll results | :heavy_check_mark: | :x: | :x: | :x: |
| Embed Quote Tweets | :heavy_check_mark: | :x: | :heavy_minus_sign: Without Media | :heavy_minus_sign: Without Media | | Embed Quote Tweets | :heavy_check_mark: | :x: | :heavy_minus_sign: Without Media | :heavy_minus_sign: Without Media |
| Embed Multiple Images | :x: | On Discord | With c.vxtwitter.com | :x: | | Embed Multiple Images | :x: | On Discord | With c.vxtwitter.com | :x: |
| Publicly accessible embed index | :x:² | N/A | :x:² | :heavy_check_mark: | | Publicly accessible embed index | :x:² | N/A | :x:² | :heavy_check_mark: |
| Replace t.co with original links | :heavy_check_mark: | :x: | :x: | :x: | | Replace t.co with original links | :heavy_check_mark: | :x: | :x: | :x: |
| Media-based embed colors on Discord | :heavy_check_mark: | :x: | :x: | :x: | | Media-based embed colors on Discord | :heavy_check_mark: | :x: | :x: | :x: |
¹ Discord will attempt to embed Twitter's video player, but it is unreliable ¹ Discord will attempt to embed Twitter's video player, but it is unreliable
² Neither pxTwitter or vxTwitter have a public embed ledger, for privacy reasons. vxTwitter still stores all responses in a database / JSON file controlled by the owner. pxTwitter by contrast relies on Cloudflare caching of responses: there is no link store accessible to the owner. ² Neither pxTwitter or vxTwitter have a public embed ledger, for privacy reasons. vxTwitter still stores all responses in a database / JSON file controlled by the owner. pxTwitter by contrast relies on Cloudflare caching of responses: there is no link store accessible to the owner.
-------------------- ---
## Why pxTwitter is better to develop for and deploy ## Why pxTwitter is better to develop for and deploy
@ -59,7 +59,7 @@ Clone the repo, install [Node.js](https://nodejs.org/) and run `npm install` in
Once you're set up with your worker on `*.workers.dev`, [add your worker to your custom domain](https://developers.cloudflare.com/workers/platform/routing/custom-domains/). Once you're set up with your worker on `*.workers.dev`, [add your worker to your custom domain](https://developers.cloudflare.com/workers/platform/routing/custom-domains/).
-------------------- ---
**Licensed under the permissive MIT license. Feel free to send a pull request!** **Licensed under the permissive MIT license. Feel free to send a pull request!**

View file

@ -18,18 +18,21 @@ export const fetchUsingGuest = async (status: string): Promise<TimelineBlobParti
while (apiAttempts < 5) { while (apiAttempts < 5) {
apiAttempts++; apiAttempts++;
const activate = await fetch(`${Constants.TWITTER_API_ROOT}/1.1/guest/activate.json`, { const activate = await fetch(
method: 'POST', `${Constants.TWITTER_API_ROOT}/1.1/guest/activate.json`,
headers: headers, {
body: '' method: 'POST',
}); headers: headers,
body: ''
}
);
/* 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.json()) as { guest_token: string } activateJson = (await activate.json()) as { guest_token: string };
} catch(e: any) { } catch (e: any) {
continue; continue;
} }
@ -62,7 +65,10 @@ export const fetchUsingGuest = async (status: string): Promise<TimelineBlobParti
) )
).json()) as TimelineBlobPartial; ).json()) as TimelineBlobPartial;
if (typeof conversation.globalObjects === 'undefined' && typeof conversation.errors === '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;
} }
@ -71,5 +77,5 @@ export const fetchUsingGuest = async (status: string): Promise<TimelineBlobParti
} }
// @ts-ignore - This is only returned if we completely failed to fetch the conversation // @ts-ignore - This is only returned if we completely failed to fetch the conversation
return { }; return {};
}; };

View file

@ -15,7 +15,7 @@ export const returnError = (error: string) => {
`<meta content="${error}" property="og:description"/>` `<meta content="${error}" property="og:description"/>`
].join('') ].join('')
}); });
} };
export const handleStatus = async ( export const handleStatus = async (
status: string, status: string,
@ -62,7 +62,7 @@ export const handleStatus = async (
if (typeof conversation?.globalObjects?.tweets === 'undefined') { if (typeof conversation?.globalObjects?.tweets === 'undefined') {
return returnError(Strings.ERROR_API_FAIL); return returnError(Strings.ERROR_API_FAIL);
} }
/* If we have no idea what happened then just return API error */ /* If we have no idea what happened then just return API error */
return returnError(Strings.ERROR_API_FAIL); return returnError(Strings.ERROR_API_FAIL);
} }
@ -136,7 +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 // 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'

View file

@ -37,6 +37,6 @@ export const Strings = {
<head>{headers}</head>`, <head>{headers}</head>`,
DEFAULT_AUTHOR_TEXT: 'Twitter', DEFAULT_AUTHOR_TEXT: 'Twitter',
ERROR_API_FAIL: 'Tweet failed to load due to an API error :(', 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_PRIVATE: `I can't embed Tweets from private accounts, sorry about that :(`,
ERROR_TWEET_NOT_FOUND: `Sorry, that Tweet doesn't exist :(` ERROR_TWEET_NOT_FOUND: `Sorry, that Tweet doesn't exist :(`
}; };

View file

@ -10,26 +10,26 @@ type TimelineContent = {
timestoneInfo: { timestoneInfo: {
richText: { richText: {
text: string; text: string;
} };
} };
} };
} };
} };
} };
type TimelineInstruction = { type TimelineInstruction = {
addEntries?: { addEntries?: {
entries: { entries: {
content: TimelineContent, content: TimelineContent;
entryId: string entryId: string;
}[] }[];
} };
} };
type TwitterAPIError = { type TwitterAPIError = {
code: number; code: number;
message: string; message: string;
} };
type TimelineBlobPartial = { type TimelineBlobPartial = {
globalObjects: { globalObjects: {
@ -41,9 +41,9 @@ type TimelineBlobPartial = {
}; };
}; };
timeline: { timeline: {
instructions: TimelineInstruction[] instructions: TimelineInstruction[];
}, };
errors?: TwitterAPIError[] errors?: TwitterAPIError[];
}; };
type TweetMediaSize = { type TweetMediaSize = {

View file

@ -1,3 +1,7 @@
export const sanitizeText = (text: string) => { export const sanitizeText = (text: string) => {
return text.replace(/\"/g, '&#34;').replace(/\'/g, '&#39;').replace(/\</g, '&lt;').replace(/\>/g, '&gt;'); return text
.replace(/\"/g, '&#34;')
.replace(/\'/g, '&#39;')
.replace(/\</g, '&lt;')
.replace(/\>/g, '&gt;');
}; };