mirror of
https://github.com/CompeyDev/fxtwitter-docker.git
synced 2025-04-09 12:30:54 +01:00
Change ERROR_PRIVATE string and run prettier
This commit is contained in:
parent
5fbe0be3bf
commit
d4cf2cc5b8
6 changed files with 52 additions and 42 deletions
26
README.md
26
README.md
|
@ -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!**
|
||||||
|
|
||||||
|
|
24
src/fetch.ts
24
src/fetch.ts
|
@ -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 {};
|
||||||
};
|
};
|
||||||
|
|
|
@ -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'
|
||||||
|
|
|
@ -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 :(`
|
||||||
};
|
};
|
||||||
|
|
|
@ -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 = {
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
export const sanitizeText = (text: string) => {
|
export const sanitizeText = (text: string) => {
|
||||||
return text.replace(/\"/g, '"').replace(/\'/g, ''').replace(/\</g, '<').replace(/\>/g, '>');
|
return text
|
||||||
|
.replace(/\"/g, '"')
|
||||||
|
.replace(/\'/g, ''')
|
||||||
|
.replace(/\</g, '<')
|
||||||
|
.replace(/\>/g, '>');
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Reference in a new issue