Helper for cache related utilities (#6696)
Co-authored-by: Tom Moor <tom@getoutline.com>
This commit is contained in:
@@ -1,57 +1,22 @@
|
||||
import type { Unfurl } from "@shared/types";
|
||||
import { Day } from "@shared/utils/time";
|
||||
import { InternalError } from "@server/errors";
|
||||
import Logger from "@server/logging/Logger";
|
||||
import Redis from "@server/storage/redis";
|
||||
import fetch from "@server/utils/fetch";
|
||||
import env from "./env";
|
||||
|
||||
class Iframely {
|
||||
private static apiUrl = `${env.IFRAMELY_URL}/api`;
|
||||
private static apiKey = env.IFRAMELY_API_KEY;
|
||||
private static cacheKeyPrefix = "unfurl";
|
||||
private static defaultCacheExpiry = Day;
|
||||
|
||||
private static cacheKey(url: string) {
|
||||
return `${this.cacheKeyPrefix}-${url}`;
|
||||
}
|
||||
|
||||
private static async cache(url: string, response: any) {
|
||||
// do not cache error responses
|
||||
if (response.error) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
await Redis.defaultClient.set(
|
||||
this.cacheKey(url),
|
||||
JSON.stringify(response),
|
||||
"EX",
|
||||
response.cache_age || this.defaultCacheExpiry
|
||||
);
|
||||
} catch (err) {
|
||||
// just log it, can skip caching and directly return response
|
||||
Logger.error("Could not cache Iframely response", err);
|
||||
}
|
||||
}
|
||||
|
||||
public static async fetch(url: string, type = "oembed") {
|
||||
const res = await fetch(
|
||||
`${this.apiUrl}/${type}?url=${encodeURIComponent(url)}&api_key=${
|
||||
this.apiKey
|
||||
}`
|
||||
);
|
||||
return res.json();
|
||||
}
|
||||
|
||||
private static async cached(url: string) {
|
||||
try {
|
||||
const val = await Redis.defaultClient.get(this.cacheKey(url));
|
||||
if (val) {
|
||||
return JSON.parse(val);
|
||||
}
|
||||
const res = await fetch(
|
||||
`${this.apiUrl}/${type}?url=${encodeURIComponent(url)}&api_key=${
|
||||
this.apiKey
|
||||
}`
|
||||
);
|
||||
return res.json();
|
||||
} catch (err) {
|
||||
// just log it, response can still be obtained using the fetch call
|
||||
Logger.error("Could not fetch cached Iframely response", err);
|
||||
throw InternalError(err);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,18 +26,8 @@ class Iframely {
|
||||
* @param url
|
||||
* @returns Preview data for the url
|
||||
*/
|
||||
public static async get(url: string): Promise<Unfurl | false> {
|
||||
try {
|
||||
const cached = await Iframely.cached(url);
|
||||
if (cached) {
|
||||
return cached;
|
||||
}
|
||||
const res = await Iframely.fetch(url);
|
||||
await Iframely.cache(url, res);
|
||||
return res;
|
||||
} catch (err) {
|
||||
throw InternalError(err);
|
||||
}
|
||||
public static async unfurl(url: string): Promise<Unfurl | false> {
|
||||
return Iframely.fetch(url);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { Day } from "@shared/utils/time";
|
||||
import {
|
||||
PluginManager,
|
||||
PluginPriority,
|
||||
@@ -12,7 +13,7 @@ if (enabled) {
|
||||
PluginManager.add([
|
||||
{
|
||||
type: Hook.UnfurlProvider,
|
||||
value: Iframely.get,
|
||||
value: { unfurl: Iframely.unfurl, cacheExpiry: Day },
|
||||
|
||||
// Make sure this is last in the stack to be evaluated after all other unfurl providers
|
||||
priority: PluginPriority.VeryLow,
|
||||
|
||||
Reference in New Issue
Block a user