rsshub
Version:
Make RSS Great Again!
149 lines (146 loc) • 5.22 kB
JavaScript
import "./esm-shims-CzJ_djXG.mjs";
import { t as config } from "./config-C37vj7VH.mjs";
import "./dist-BInvbO1W.mjs";
import { t as logger_default } from "./logger-Czu8UMNd.mjs";
import "./ofetch-BIyrKU3Y.mjs";
import { t as parseDate } from "./parse-date-BrP7mxXf.mjs";
import { t as cache_default } from "./cache-Bo__VnGm.mjs";
import "./helpers-DxBp0Pty.mjs";
import { t as got_default } from "./got-KxxWdaxq.mjs";
import { t as config_not_found_default } from "./config-not-found-Dyp3RlZZ.mjs";
import { i as queryToInteger, t as fallback } from "./readable-social-DoIL4WB3.mjs";
//#region lib/routes/tumblr/utils.ts
const getAccessToken = async () => {
let accessToken = await cache_default.get("tumblr:accessToken", false);
if (!accessToken) try {
const newAccessToken = await tokenRefresher();
if (newAccessToken) accessToken = newAccessToken;
} catch (error) {
logger_default.error("Failed to refresh Tumblr token, using only client id as fallback", error);
}
return accessToken;
};
const generateAuthHeaders = async () => {
const accessToken = await getAccessToken();
if (!accessToken) return {};
return { Authorization: `Bearer ${accessToken}` };
};
const generateAuthParams = () => ({ apiKey: config.tumblr.clientId });
const processPost = (post) => {
let description = "";
switch (post.type) {
case "text":
description = post.body;
break;
case "photo":
for (const photo of post.photos ?? []) description += `<img src="${photo.original_size.url}"/><br/>`;
break;
case "link":
description = post.url;
break;
case "audio":
description = post.embed;
break;
default: break;
}
return {
id: post.id_string,
title: post.summary ?? `New post from ${post.blog_name}`,
link: post.post_url,
pubDate: parseDate(post.timestamp * 1e3),
category: post.tags,
description
};
};
let tokenRefresher = () => Promise.resolve(null);
if (config.tumblr && config.tumblr.clientId && config.tumblr.clientSecret && config.tumblr.refreshToken) tokenRefresher = async () => {
let refreshToken = config.tumblr.refreshToken;
const previousRefreshTokenSerialized = await cache_default.get("tumblr:refreshToken", false);
if (previousRefreshTokenSerialized) {
const previousRefreshToken = JSON.parse(previousRefreshTokenSerialized);
if (previousRefreshToken.startToken === refreshToken) refreshToken = previousRefreshToken.currentToken;
}
const response = await got_default.post("https://api.tumblr.com/v2/oauth2/token", { form: {
grant_type: "refresh_token",
client_id: config.tumblr.clientId,
client_secret: config.tumblr.clientSecret,
refresh_token: refreshToken
} });
if (!response.data?.access_token || !response.data?.refresh_token) return null;
const accessToken = response.data.access_token;
const newRefreshToken = response.data.refresh_token;
const expiresIn = response.data.expires_in;
await cache_default.set("tumblr:accessToken", accessToken, (expiresIn ?? 2520) - 30);
const cacheEntry = {
startToken: config.tumblr.refreshToken,
currentToken: newRefreshToken
};
await cache_default.set(`tumblr:refreshToken`, JSON.stringify(cacheEntry), 31536e3);
return accessToken;
};
var utils_default = {
processPost,
generateAuthParams,
generateAuthHeaders
};
//#endregion
//#region lib/routes/tumblr/posts.ts
const route = {
path: "/posts/:blog",
categories: ["blog"],
example: "/tumblr/posts/biketouring-nearby",
parameters: { blog: "Blog identifier (see `https://www.tumblr.com/docs/en/api/v2#blog-identifiers`)" },
radar: [],
features: {
requireConfig: [
{
name: "TUMBLR_CLIENT_ID",
description: "Please see above for details."
},
{
name: "TUMBLR_CLIENT_SECRET",
description: "Please see above for details."
},
{
name: "TUMBLR_REFRESH_TOKEN",
description: "Please see above for details."
}
],
requirePuppeteer: false,
antiCrawler: false,
supportBT: false,
supportPodcast: false,
supportScihub: false
},
name: "Posts",
maintainers: ["Rakambda"],
description: `::: tip
Tumblr provides official RSS feeds for non "dashboard only" blogs, for instance [https://biketouring-nearby.tumblr.com](https://biketouring-nearby.tumblr.com/rss).
:::`,
handler
};
async function handler(ctx) {
if (!config.tumblr || !config.tumblr.clientId) throw new config_not_found_default("Tumblr RSS is disabled due to the lack of <a href=\"https://docs.rsshub.app/deploy/config#route-specific-configurations\">relevant config</a>");
const blogIdentifier = ctx.req.param("blog");
const limit = fallback(void 0, queryToInteger(ctx.req.query("limit")), 20);
const response = await got_default.get(`https://api.tumblr.com/v2/blog/${blogIdentifier}/posts`, {
searchParams: {
...utils_default.generateAuthParams(),
limit
},
headers: await utils_default.generateAuthHeaders()
});
const blog = response.data.response.blog;
const posts = response.data.response.posts.map((post) => utils_default.processPost(post));
return {
title: `Tumblr - ${blogIdentifier} - Posts`,
author: blog?.name,
link: blog?.url ?? `https://${blogIdentifier}/`,
item: posts,
allowEmpty: true,
image: blog?.avatar?.slice(-1)?.url,
description: blog?.description
};
}
//#endregion
export { route };