import { Constants } from './constants';
import { handleQuote } from './quote';
import { sanitizeText } from './utils';
import { Strings } from './strings';
import { getAuthorText } from './author';
import { statusAPI } from './api';
export const returnError = (error: string): StatusResponse => {
return {
text: Strings.BASE_HTML.format({
lang: '',
headers: [
``,
``
].join('')
})
};
};
export const handleStatus = async (
event: FetchEvent,
status: string,
mediaNumber?: number,
userAgent?: string,
flags?: InputFlags,
language?: string
): Promise => {
console.log('Direct?', flags?.direct);
let api = await statusAPI(event, status, language);
const tweet = api?.tweet as APITweet;
if (flags?.api) {
return {
response: new Response(JSON.stringify(api), {
headers: { ...Constants.RESPONSE_HEADERS, 'content-type': 'application/json' },
status: api.code
})
};
}
switch (api.code) {
case 401:
return returnError(Strings.ERROR_PRIVATE);
case 404:
return returnError(Strings.ERROR_TWEET_NOT_FOUND);
case 500:
return returnError(Strings.ERROR_API_FAIL);
}
if (flags?.direct) {
if (tweet.media) {
let redirectUrl: string | null = null;
if (tweet.media.video) {
redirectUrl = tweet.media.video.url;
} else if (tweet.media.photos) {
redirectUrl = (tweet.media.photos[mediaNumber || 0] || tweet.media.photos[0]).url;
}
if (redirectUrl) {
return { response: Response.redirect(redirectUrl, 302) };
}
}
}
/* Use quote media if there is no media */
if (!tweet.media && tweet.quote?.media) {
tweet.media = tweet.quote.media;
tweet.twitter_card = 'summary_large_image';
}
let authorText = getAuthorText(tweet) || Strings.DEFAULT_AUTHOR_TEXT;
let engagementText = authorText.replace(/ /g, ' ');
let siteName = Constants.BRANDING_NAME;
let newText = tweet.text;
let headers: string[] = [
``,
``,
``,
``,
``
];
if (tweet.translation) {
const { translation } = tweet;
let formatText =
language === 'en'
? Strings.TRANSLATE_TEXT.format({
language: translation.source_lang
})
: Strings.TRANSLATE_TEXT_INTL.format({
source: translation.source_lang.toUpperCase(),
destination: translation.target_lang.toUpperCase()
});
newText = `${translation.text}\n\n` + `${formatText}\n\n` + `${newText}`;
}
/* Video renderer */
if (tweet.media?.video) {
authorText = encodeURIComponent(newText || '');
if (tweet?.translation) {
authorText = encodeURIComponent(tweet.translation?.text || '');
}
const { video } = tweet.media;
headers.push(
``,
``,
``,
``,
``,
``,
``,
``,
``
);
}
/* Photo renderer */
if (tweet.media?.photos) {
const { photos } = tweet.media;
let photo = photos[(mediaNumber || 1) - 1];
if (
typeof mediaNumber !== 'number' &&
tweet.media.mosaic &&
userAgent?.indexOf('Telegram') === -1
) {
photo = {
url:
userAgent?.indexOf('Telegram') !== -1
? tweet.media.mosaic.formats.webp
: tweet.media.mosaic.formats.jpeg,
width: tweet.media.mosaic.width,
height: tweet.media.mosaic.height,
type: 'photo'
};
} else if (photos.length > 1) {
let photoCounter = Strings.PHOTO_COUNT.format({
number: photos.indexOf(photo) + 1,
total: photos.length
});
authorText =
authorText === Strings.DEFAULT_AUTHOR_TEXT
? photoCounter
: `${authorText} ― ${photoCounter}`;
let siteName = `${Constants.BRANDING_NAME} - ${photoCounter}`;
if (engagementText) {
siteName = `${Constants.BRANDING_NAME} - ${engagementText} - ${photoCounter}`;
}
headers.push(``);
}
headers.push(
``,
``,
``,
``,
``,
``
);
}
/* External media renderer (i.e. YouTube) */
if (tweet.media?.external) {
const { external } = tweet.media;
headers.push(
``,
``,
``,
``,
``,
``,
``,
``
);
}
/* Poll renderer */
if (tweet.poll) {
const { poll } = tweet;
let barLength = 34;
let str = '';
if (userAgent?.indexOf('Telegram') !== -1) {
barLength = 24;
}
tweet.poll.choices.forEach(choice => {
// render bar
const bar = '█'.repeat((choice.percentage / 100) * barLength);
str += `${bar}
${choice.label} (${choice.percentage}%)
`;
});
str += `\n${poll.total_votes} votes · ${poll.time_left_en}`;
newText += `\n\n${str}`;
}
if (!tweet.media?.video && !tweet.media?.photos) {
headers.push(
// Use a slightly higher resolution image for profile pics
``,
``
);
}
if (api.tweet?.quote) {
const quoteText = handleQuote(api.tweet.quote);
newText += `\n${quoteText}`;
}
headers.push(
``,
``,
``
);
/* Special reply handling if authorText is not overriden */
if (tweet.replying_to && authorText === Strings.DEFAULT_AUTHOR_TEXT) {
authorText = `↪ Replying to @${tweet.replying_to}`;
}
/* The additional oembed is pulled by Discord to enable improved embeds.
Telegram does not use this. */
headers.push(
``
);
/* When dealing with a Tweet of unknown lang, fall back to en */
let lang = tweet.lang === 'unk' ? 'en' : tweet.lang || 'en';
return {
text: Strings.BASE_HTML.format({
lang: `lang="${lang}"`,
headers: headers.join('')
})
};
};