From 177181bc7eefa91461386a69b63a660fce73b2c6 Mon Sep 17 00:00:00 2001 From: ItsRauf <31735267+ItsRauf@users.noreply.github.com> Date: Fri, 20 Feb 2026 22:26:19 +0000 Subject: [PATCH 1/3] =?UTF-8?q?=E2=9C=A8=20feat(platforms):=20add=20New=20?= =?UTF-8?q?York=20Times=20platform?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/platforms/src/NYTimes.ts | 130 ++++++++++++++++++++++++++++++ packages/platforms/src/main.ts | 4 +- packages/platforms/src/types.ts | 6 +- 3 files changed, 137 insertions(+), 3 deletions(-) create mode 100644 packages/platforms/src/NYTimes.ts diff --git a/packages/platforms/src/NYTimes.ts b/packages/platforms/src/NYTimes.ts new file mode 100644 index 0000000..4b78790 --- /dev/null +++ b/packages/platforms/src/NYTimes.ts @@ -0,0 +1,130 @@ +import { Embed } from "@embedly/builder"; +import * as cheerio from "cheerio"; +import he from "he"; +import { CF_CACHE_OPTIONS } from "./constants.ts"; +import { type BaseEmbedData, EmbedlyPlatform } from "./Platform.ts"; +import { EmbedlyPlatformType } from "./types.ts"; +import { validateRegexMatch } from "./utils.ts"; + +export class NYTimes extends EmbedlyPlatform { + readonly color = [0, 0, 0] as const; + readonly emoji = ""; + readonly regex = + /nytimes\.com\/(?\d{4}\/\d{2}\/\d{2}\/[^?#]+\.html)/; + + constructor() { + super(EmbedlyPlatformType.NYTimes, "nyt"); + } + + async parsePostId(url: string): Promise { + const match = this.regex.exec(url); + validateRegexMatch( + match, + "Invalid NYTimes URL: could not extract path" + ); + const { path } = match.groups; + return path; + } + + async fetchPost(post_id: string): Promise { + const resp = await fetch(`https://www.nytimes.com/${post_id}`, { + method: "GET", + redirect: "follow", + headers: { + "User-Agent": "Twitterbot/1.0" + }, + ...CF_CACHE_OPTIONS + }); + + if (!resp.ok) { + throw { code: resp.status, message: resp.statusText }; + } + + const html = await resp.text(); + const $ = cheerio.load(html); + const script = $('script[type="application/ld+json"]').first(); + const scriptText = script.text(); + + if (!scriptText) { + throw { + code: 500, + message: "NYTimes page structure changed: missing JSON-LD data" + }; + } + + let data: any; + try { + data = JSON.parse(scriptText); + } catch { + throw { + code: 500, + message: "Failed to parse NYTimes JSON-LD data" + }; + } + + if ( + data["@type"] !== "NewsArticle" || + !data.headline || + !data.description + ) { + throw { + code: 500, + message: + "NYTimes page structure changed: missing required fields" + }; + } + + return data; + } + + transformRawData(raw_data: any): BaseEmbedData { + let description = he.decode(raw_data.description); + + if ( + raw_data.author && + Array.isArray(raw_data.author) && + raw_data.author.length > 0 + ) { + const byline = raw_data.author + .map((a: any) => a.name) + .join(" and "); + description = `By ${byline}\n\n${description}`; + } + + return { + platform: this.name, + color: [...this.color], + emoji: this.emoji, + name: he.decode(raw_data.headline), + avatar_url: + "https://static01.nyt.com/images/icons/t_logo_291_black.png", + timestamp: Math.floor( + new Date(raw_data.datePublished).getTime() / 1000 + ), + url: raw_data["@id"], + description + }; + } + + createEmbed(post_data: any): Embed { + const embed = new Embed(this.transformRawData(post_data)); + + if ( + post_data.image && + Array.isArray(post_data.image) && + post_data.image.length > 0 + ) { + const image = post_data.image[0]; + embed.setMedia([ + { + media: { + url: image.url + }, + description: image.caption + } + ]); + } + + return embed; + } +} diff --git a/packages/platforms/src/main.ts b/packages/platforms/src/main.ts index 807a94b..b251a54 100644 --- a/packages/platforms/src/main.ts +++ b/packages/platforms/src/main.ts @@ -1,5 +1,6 @@ import { CBC } from "./CBC.ts"; import { Instagram } from "./Instagram.ts"; +import { NYTimes } from "./NYTimes.ts"; import { Reddit } from "./Reddit.ts"; import { Threads } from "./Threads.ts"; import { TikTok } from "./TikTok.ts"; @@ -12,7 +13,8 @@ export const Platforms = { [EmbedlyPlatformType.TikTok]: new TikTok(), [EmbedlyPlatformType.CBC]: new CBC(), [EmbedlyPlatformType.Threads]: new Threads(), - [EmbedlyPlatformType.Reddit]: new Reddit() + [EmbedlyPlatformType.Reddit]: new Reddit(), + [EmbedlyPlatformType.NYTimes]: new NYTimes() } as const; export const EmbedlyPlatformColors = Object.fromEntries( diff --git a/packages/platforms/src/types.ts b/packages/platforms/src/types.ts index 25762dd..9c702fb 100644 --- a/packages/platforms/src/types.ts +++ b/packages/platforms/src/types.ts @@ -4,7 +4,8 @@ export const EmbedlyPlatformType = { TikTok: "TikTok", CBC: "cbc.ca", Threads: "Threads", - Reddit: "Reddit" + Reddit: "Reddit", + NYTimes: "NYTimes" } as const; export type EmbedlyPlatformType = @@ -39,5 +40,6 @@ export const emojis: Emojis = { [EmbedlyPlatformType.TikTok]: "<:tiktok:1386641825963708446>", [EmbedlyPlatformType.CBC]: "<:cbc:1409997044495683674>", [EmbedlyPlatformType.Threads]: "<:threads:1413343483929956446>", - [EmbedlyPlatformType.Reddit]: "<:reddit:1461320093240655922>" + [EmbedlyPlatformType.Reddit]: "<:reddit:1461320093240655922>", + [EmbedlyPlatformType.NYTimes]: "" }; From a260b6180ddd33bf2f464607dec29475d20cd9cf Mon Sep 17 00:00:00 2001 From: ItsRauf <31735267+ItsRauf@users.noreply.github.com> Date: Fri, 27 Feb 2026 18:37:29 -0600 Subject: [PATCH 2/3] =?UTF-8?q?=F0=9F=90=9B=20fix(builder):=20cap=20media?= =?UTF-8?q?=20gallery=20items=20at=20Discord's=2010-item=20limit?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .changeset/wacky-teeth-ring.md | 5 +++++ packages/builder/src/Embed.ts | 16 +++++++++++++--- 2 files changed, 18 insertions(+), 3 deletions(-) create mode 100644 .changeset/wacky-teeth-ring.md diff --git a/.changeset/wacky-teeth-ring.md b/.changeset/wacky-teeth-ring.md new file mode 100644 index 0000000..b6da585 --- /dev/null +++ b/.changeset/wacky-teeth-ring.md @@ -0,0 +1,5 @@ +--- +"@embedly/builder": patch +--- + +cap media gallery items at Discord's 10-item limit diff --git a/packages/builder/src/Embed.ts b/packages/builder/src/Embed.ts index e3a0a36..19d203c 100644 --- a/packages/builder/src/Embed.ts +++ b/packages/builder/src/Embed.ts @@ -77,6 +77,8 @@ export interface EmbedFlags { [EmbedFlagNames.LinkStyle]: "control" | "inline" | "none"; } +const MAX_GALLERY_ITEMS = 10; + export class Embed implements EmbedData { public platform!: string; public color!: RGBTuple; @@ -102,6 +104,7 @@ export class Embed implements EmbedData { constructor(data: BaseEmbedData) { Object.assign(this, data); + if (this.media) this.media = this.media.slice(0, MAX_GALLERY_ITEMS); } public setDescription(text: string) { @@ -109,15 +112,22 @@ export class Embed implements EmbedData { } public setMedia(media: APIMediaGalleryItem[]) { - this.media = media; + this.media = media.slice(0, MAX_GALLERY_ITEMS); } public setQuote(quote: BaseEmbedDataWithoutPlatform) { - this.quote = quote; + this.quote = quote.media + ? { ...quote, media: quote.media.slice(0, MAX_GALLERY_ITEMS) } + : quote; } public setReplyingTo(replying_to: BaseEmbedDataWithoutPlatform) { - this.replying_to = replying_to; + this.replying_to = replying_to.media + ? { + ...replying_to, + media: replying_to.media.slice(0, MAX_GALLERY_ITEMS) + } + : replying_to; } static getDiscordEmbed(embed: Embed, flags?: Partial) { From dce1a35199ae8650714c02b8c8b853fa4cb22a29 Mon Sep 17 00:00:00 2001 From: Rose <31735267+ItsRauf@users.noreply.github.com> Date: Mon, 2 Mar 2026 00:33:57 -0600 Subject: [PATCH 3/3] =?UTF-8?q?=E2=9C=A8=20chort(platforms):=20add=20New?= =?UTF-8?q?=20York=20Times=20platform=20changeset?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Updated the version of '@embedly/platforms' from patch to minor and added the New York Times platform feature. --- .changeset/mighty-boxes-tease.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/mighty-boxes-tease.md diff --git a/.changeset/mighty-boxes-tease.md b/.changeset/mighty-boxes-tease.md new file mode 100644 index 0000000..532fefb --- /dev/null +++ b/.changeset/mighty-boxes-tease.md @@ -0,0 +1,5 @@ +--- +"@embedly/platforms": minor +--- + +✨ feat(platforms): add New York Times platform