Files
outline/plugins/iframely/server/iframely.ts
Tom Moor f9a11a28d8 chore: Plugin registration (#6623)
* first pass

* test

* test

* priority

* Reduce boilerplate further

* Update server/utils/PluginManager.ts

Co-authored-by: Apoorv Mishra <apoorvmishra101092@gmail.com>

* fix: matchesNode error in destroyed editor transaction

* fix: Individual imported files do not display source correctly in 'Insights'

* chore: Add sleep before Slack notification

* docs

* fix: Error logged about missing plugin.json

* Remove email template glob

---------

Co-authored-by: Apoorv Mishra <apoorvmishra101092@gmail.com>
2024-03-08 20:32:05 -08:00

80 lines
2.1 KiB
TypeScript

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);
}
} 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): 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);
}
}
}
export default Iframely;