mirror of
https://github.com/CompeyDev/fxtwitter-docker.git
synced 2025-04-14 17:04:02 +01:00
Minor improvements, bigger things coming
This commit is contained in:
parent
3715658141
commit
b72b9ea0bf
4 changed files with 67 additions and 66 deletions
20
src/author.ts
Normal file
20
src/author.ts
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
export const getAuthorText = (tweet: TweetPartial): string | null => {
|
||||||
|
/* Build out reply, retweet, like counts */
|
||||||
|
if (tweet.favorite_count > 0 || tweet.retweet_count > 0 || tweet.reply_count > 0) {
|
||||||
|
let authorText = '';
|
||||||
|
if (tweet.reply_count > 0) {
|
||||||
|
authorText += `${tweet.reply_count} 💬 `;
|
||||||
|
}
|
||||||
|
if (tweet.retweet_count > 0) {
|
||||||
|
authorText += `${tweet.retweet_count} 🔁 `;
|
||||||
|
}
|
||||||
|
if (tweet.favorite_count > 0) {
|
||||||
|
authorText += `${tweet.favorite_count} ❤️ `;
|
||||||
|
}
|
||||||
|
authorText = authorText.trim();
|
||||||
|
|
||||||
|
return authorText;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
|
@ -10,7 +10,7 @@ const statusRequest = async (
|
||||||
event: FetchEvent,
|
event: FetchEvent,
|
||||||
flags: InputFlags = {}
|
flags: InputFlags = {}
|
||||||
) => {
|
) => {
|
||||||
const { handle, id, mediaNumber, language } = request.params;
|
const { handle, id, mediaNumber, language, prefix } = request.params;
|
||||||
const url = new URL(request.url);
|
const url = new URL(request.url);
|
||||||
const userAgent = request.headers.get('User-Agent') || '';
|
const userAgent = request.headers.get('User-Agent') || '';
|
||||||
|
|
||||||
|
@ -19,13 +19,19 @@ const statusRequest = async (
|
||||||
|
|
||||||
if (
|
if (
|
||||||
url.pathname.match(/\/status(es)?\/\d+\.(mp4|png|jpg)/g) !== null ||
|
url.pathname.match(/\/status(es)?\/\d+\.(mp4|png|jpg)/g) !== null ||
|
||||||
Constants.DIRECT_MEDIA_DOMAINS.includes(url.hostname)
|
Constants.DIRECT_MEDIA_DOMAINS.includes(url.hostname) ||
|
||||||
|
(prefix === 'dl' || prefix === 'dir')
|
||||||
) {
|
) {
|
||||||
console.log('Direct media request by extension');
|
console.log('Direct media request by extension');
|
||||||
flags.direct = true;
|
flags.direct = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isBotUA || flags.direct) {
|
if (url.pathname.match(/\/status(es)?\/\d+\.(json)/g) !== null) {
|
||||||
|
console.log('JSON API request');
|
||||||
|
flags.api = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isBotUA || flags.direct || flags.api) {
|
||||||
console.log(`Matched bot UA ${userAgent}`);
|
console.log(`Matched bot UA ${userAgent}`);
|
||||||
|
|
||||||
let response: Response;
|
let response: Response;
|
||||||
|
@ -67,10 +73,6 @@ const statusRequest = async (
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const statusDirectMediaRequest = async (request: Request, event: FetchEvent) => {
|
|
||||||
return await statusRequest(request, event, { direct: true });
|
|
||||||
};
|
|
||||||
|
|
||||||
const profileRequest = async (request: Request, _event: FetchEvent) => {
|
const profileRequest = async (request: Request, _event: FetchEvent) => {
|
||||||
const { handle } = request.params;
|
const { handle } = request.params;
|
||||||
const url = new URL(request.url);
|
const url = new URL(request.url);
|
||||||
|
@ -82,36 +84,16 @@ const profileRequest = async (request: Request, _event: FetchEvent) => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Direct media handlers */
|
router.get('/:prefix?/:handle/status/:id', statusRequest);
|
||||||
router.get('/dl/:handle/status/:id', statusDirectMediaRequest);
|
router.get('/:prefix?/:handle/status/:id/photo/:mediaNumber', statusRequest);
|
||||||
router.get('/dl/:handle/status/:id/photo/:mediaNumber', statusDirectMediaRequest);
|
router.get('/:prefix?/:handle/status/:id/photos/:mediaNumber', statusRequest);
|
||||||
router.get('/dl/:handle/status/:id/photos/:mediaNumber', statusDirectMediaRequest);
|
router.get('/:prefix?/:handle/status/:id/video/:mediaNumber', statusRequest);
|
||||||
router.get('/dl/:handle/status/:id/video/:mediaNumber', statusDirectMediaRequest);
|
router.get('/:prefix?/:handle/statuses/:id', statusRequest);
|
||||||
router.get('/dl/:handle/statuses/:id', statusDirectMediaRequest);
|
router.get('/:prefix?/:handle/statuses/:id/photo/:mediaNumber', statusRequest);
|
||||||
router.get('/dl/:handle/statuses/:id/photo/:mediaNumber', statusDirectMediaRequest);
|
router.get('/:prefix?/:handle/statuses/:id/photos/:mediaNumber', statusRequest);
|
||||||
router.get('/dl/:handle/statuses/:id/photos/:mediaNumber', statusDirectMediaRequest);
|
router.get('/:prefix?/:handle/statuses/:id/video/:mediaNumber', statusRequest);
|
||||||
router.get('/dl/:handle/statuses/:id/video/:mediaNumber', statusDirectMediaRequest);
|
router.get('/:prefix?/:handle/status/:id/:language', statusRequest);
|
||||||
|
router.get('/:prefix?/:handle/statuses/:id/:language', statusRequest);
|
||||||
router.get('/dir/:handle/status/:id', statusDirectMediaRequest);
|
|
||||||
router.get('/dir/:handle/status/:id/photo/:mediaNumber', statusDirectMediaRequest);
|
|
||||||
router.get('/dir/:handle/status/:id/photos/:mediaNumber', statusDirectMediaRequest);
|
|
||||||
router.get('/dir/:handle/status/:id/video/:mediaNumber', statusDirectMediaRequest);
|
|
||||||
router.get('/dir/:handle/statuses/:id', statusDirectMediaRequest);
|
|
||||||
router.get('/dir/:handle/statuses/:id/photo/:mediaNumber', statusDirectMediaRequest);
|
|
||||||
router.get('/dir/:handle/statuses/:id/photos/:mediaNumber', statusDirectMediaRequest);
|
|
||||||
router.get('/dir/:handle/statuses/:id/video/:mediaNumber', statusDirectMediaRequest);
|
|
||||||
|
|
||||||
/* Handlers for Twitter statuses */
|
|
||||||
router.get('/:handle/status/:id', statusRequest);
|
|
||||||
router.get('/:handle/status/:id/photo/:mediaNumber', statusRequest);
|
|
||||||
router.get('/:handle/status/:id/photos/:mediaNumber', statusRequest);
|
|
||||||
router.get('/:handle/status/:id/video/:mediaNumber', statusRequest);
|
|
||||||
router.get('/:handle/statuses/:id', statusRequest);
|
|
||||||
router.get('/:handle/statuses/:id/photo/:mediaNumber', statusRequest);
|
|
||||||
router.get('/:handle/statuses/:id/photos/:mediaNumber', statusRequest);
|
|
||||||
router.get('/:handle/statuses/:id/video/:mediaNumber', statusRequest);
|
|
||||||
router.get('/:handle/status/:id/:language', statusRequest);
|
|
||||||
router.get('/:handle/statuses/:id/:language', statusRequest);
|
|
||||||
|
|
||||||
router.get('/owoembed', async (request: Request) => {
|
router.get('/owoembed', async (request: Request) => {
|
||||||
console.log('oembed hit!');
|
console.log('oembed hit!');
|
||||||
|
|
|
@ -8,6 +8,7 @@ import { sanitizeText } from './utils';
|
||||||
import { Strings } from './strings';
|
import { Strings } from './strings';
|
||||||
import { handleMosaic } from './mosaic';
|
import { handleMosaic } from './mosaic';
|
||||||
import { translateTweet } from './translate';
|
import { translateTweet } from './translate';
|
||||||
|
import { getAuthorText } from './author';
|
||||||
|
|
||||||
export const returnError = (error: string): StatusResponse => {
|
export const returnError = (error: string): StatusResponse => {
|
||||||
return {
|
return {
|
||||||
|
@ -30,6 +31,7 @@ export const handleStatus = async (
|
||||||
language?: string
|
language?: string
|
||||||
): Promise<StatusResponse> => {
|
): Promise<StatusResponse> => {
|
||||||
console.log('Direct?', flags?.direct);
|
console.log('Direct?', flags?.direct);
|
||||||
|
|
||||||
const conversation = await fetchUsingGuest(status, event);
|
const conversation = await fetchUsingGuest(status, event);
|
||||||
|
|
||||||
const tweet = conversation?.globalObjects?.tweets?.[status] || {};
|
const tweet = conversation?.globalObjects?.tweets?.[status] || {};
|
||||||
|
@ -38,17 +40,7 @@ export const handleStatus = async (
|
||||||
it in case a user appears multiple times in a thread. */
|
it in case a user appears multiple times in a thread. */
|
||||||
tweet.user = conversation?.globalObjects?.users?.[tweet.user_id_str] || {};
|
tweet.user = conversation?.globalObjects?.users?.[tweet.user_id_str] || {};
|
||||||
|
|
||||||
/* Try to deep link to mobile apps, just like Twitter does.
|
let headers: string[] = [];
|
||||||
No idea if this actually works.*/
|
|
||||||
let headers: string[] = [
|
|
||||||
`<meta property="fb:app_id" content="2231777543"/>`,
|
|
||||||
`<meta content="twitter://status?id=${status}" property="al:ios:url"/>`,
|
|
||||||
`<meta content="333903271" property="al:ios:app_store_id"/>`,
|
|
||||||
`<meta content="Twitter" property="al:ios:app_name"/>`,
|
|
||||||
`<meta content="twitter://status?id=${status}" property="al:android:url"/>`,
|
|
||||||
`<meta content="com.twitter.android" property="al:android:package"/>`,
|
|
||||||
`<meta content="Twitter" property="al:android:app_name"/>`
|
|
||||||
];
|
|
||||||
|
|
||||||
let redirectMedia = '';
|
let redirectMedia = '';
|
||||||
|
|
||||||
|
@ -91,25 +83,10 @@ export const handleStatus = async (
|
||||||
tweet.extended_entities?.media || tweet.entities?.media || []
|
tweet.extended_entities?.media || tweet.entities?.media || []
|
||||||
);
|
);
|
||||||
|
|
||||||
let authorText = Strings.DEFAULT_AUTHOR_TEXT;
|
let authorText = getAuthorText(tweet) || Strings.DEFAULT_AUTHOR_TEXT;
|
||||||
|
|
||||||
/* Build out reply, retweet, like counts */
|
// engagementText has less spacing than authorText
|
||||||
if (tweet.favorite_count > 0 || tweet.retweet_count > 0 || tweet.reply_count > 0) {
|
engagementText = authorText.replace(/ /g, ' ');
|
||||||
authorText = '';
|
|
||||||
if (tweet.reply_count > 0) {
|
|
||||||
authorText += `${tweet.reply_count} 💬 `;
|
|
||||||
}
|
|
||||||
if (tweet.retweet_count > 0) {
|
|
||||||
authorText += `${tweet.retweet_count} 🔁 `;
|
|
||||||
}
|
|
||||||
if (tweet.favorite_count > 0) {
|
|
||||||
authorText += `${tweet.favorite_count} ❤️ `;
|
|
||||||
}
|
|
||||||
authorText = authorText.trim();
|
|
||||||
|
|
||||||
// engagementText has less spacing than authorText
|
|
||||||
engagementText = authorText.replace(/ /g, ' ');
|
|
||||||
}
|
|
||||||
|
|
||||||
text = linkFixer(tweet, text);
|
text = linkFixer(tweet, text);
|
||||||
|
|
||||||
|
|
22
src/types.d.ts
vendored
22
src/types.d.ts
vendored
|
@ -3,6 +3,7 @@
|
||||||
type InputFlags = {
|
type InputFlags = {
|
||||||
standard?: boolean;
|
standard?: boolean;
|
||||||
direct?: boolean;
|
direct?: boolean;
|
||||||
|
api?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
interface StatusResponse {
|
interface StatusResponse {
|
||||||
|
@ -15,3 +16,24 @@ interface Request {
|
||||||
[param: string]: string;
|
[param: string]: string;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface APITweet {
|
||||||
|
id: string;
|
||||||
|
tweet: string;
|
||||||
|
text?: string;
|
||||||
|
created_at: string;
|
||||||
|
|
||||||
|
likes: number;
|
||||||
|
retweets: number;
|
||||||
|
replies: number;
|
||||||
|
|
||||||
|
name?: string;
|
||||||
|
screen_name?: string;
|
||||||
|
profile_picture_url?: string;
|
||||||
|
profile_banner_url?: string;
|
||||||
|
|
||||||
|
quote_tweet?: APITweet;
|
||||||
|
|
||||||
|
thumbnail: string;
|
||||||
|
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue