Preview arbitrary urls within a document (#5598)

This commit is contained in:
Apoorv Mishra
2023-07-30 05:21:49 +05:30
committed by GitHub
parent 67691477a9
commit ddc883bfcd
8 changed files with 83 additions and 38 deletions

View File

@@ -1,30 +1,35 @@
import fetch from "fetch-with-proxy";
import env from "@server/env";
import { InternalError } from "@server/errors";
import Logger from "@server/logging/Logger";
import Redis from "@server/redis";
class Iframely {
private static apiUrl = `${env.IFRAMELY_URL}/api`;
private static apiKey = env.IFRAMELY_API_KEY;
private static cacheKeyPrefix = "unfurl";
private static defaultCacheExpiry = 86400;
private static cacheKey(url: string) {
return `${this.cacheKeyPrefix}-${url}`;
}
private static async cache(url: string) {
const data = await this.fetch(url);
if (!data.error) {
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(data),
JSON.stringify(response),
"EX",
data.cache_age
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);
}
return data;
}
private static async fetch(url: string, type = "oembed") {
@@ -37,16 +42,33 @@ class Iframely {
}
private static async cached(url: string) {
const val = await Redis.defaultClient.get(this.cacheKey(url));
if (val) {
return JSON.parse(val);
try {
const val = await Redis.defaultClient.get(this.cacheKey(url));
if (val) {
return JSON.parse(val);
}
} catch (err) {
// just log it, response can still be obtained using the fetch call
Logger.error("Could not fetch cached Iframely response", err);
}
}
/**
* Fetches the preview data for the given url
* using Iframely oEmbed API
*
* @param url
* @returns Preview data for the url
*/
public static async get(url: string) {
try {
const cached = await this.cached(url);
return cached ? cached : this.cache(url);
if (cached) {
return cached;
}
const res = await this.fetch(url);
await this.cache(url, res);
return res;
} catch (err) {
throw InternalError(err);
}