-
Notifications
You must be signed in to change notification settings - Fork 89
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Adds bluesky embed plugin * Updates bluesky tests
- Loading branch information
1 parent
345cf75
commit b73f36b
Showing
3 changed files
with
138 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
/* from bluesky docs: | ||
oEmbed Endpoint | ||
The official oEmbed endpoint for Bluesky posts is https://embed.bsky.app/oembed, which accepts the following HTTP GET query parameters: | ||
url (required): bsky.app or AT-URI pointing to a post | ||
format (optional): json is the default and only supported format | ||
maxwidth (optional, integer): range is 220 to 600; default is 600 | ||
maxheight (optional, integer): part of oEmbed specification, but not used for Bluesky post embeds | ||
The rendered height of posts is not known until rendered, so the maxheight is ignored and the height field in the response JSON is always null. This follows the precedent of Twitter tweet embeds. | ||
The oEmebd response contains roughly the same HTML snippet as found at embed.bsky.app, with the same public content policy mentioned above. | ||
The HTTP URL patterns which the oEmbed endpoint supports are: | ||
https://bsky.app/profile/:user/post/:id: post embeds | ||
You can learn more about oEmbed at https://oembed.com. Bluesky is a registered provider, included in the JSON directory at https://oembed.com/providers.json. | ||
*/ | ||
|
||
const each = require("../eachEl"); | ||
const Url = require("url"); | ||
const fetch = require("node-fetch"); | ||
|
||
function render($, callback) { | ||
console.log("bluesky plugin", "render", $.html()); | ||
|
||
each( | ||
$, | ||
"a", | ||
function (el, next) { | ||
var href, host, text, id; | ||
|
||
try { | ||
href = $(el).attr("href"); | ||
text = $(el).text(); | ||
host = Url.parse(href).host; | ||
} catch (e) { | ||
return next(); | ||
} | ||
|
||
// Ensure we managed to extract everything from the url | ||
if (!href || !text || !host) return next(); | ||
|
||
// Look for bare links | ||
if (href !== text) return next(); | ||
|
||
// which point to a post on bluesky | ||
if (host !== "bsky.app") return next(); | ||
|
||
var params = { | ||
url: href, | ||
format: "json", | ||
maxwidth: 600, | ||
}; | ||
|
||
var oembedUrl = | ||
"https://embed.bsky.app/oembed?" + | ||
new URLSearchParams(params).toString(); | ||
|
||
console.log(oembedUrl); | ||
|
||
fetch(oembedUrl) | ||
.then((res) => res.json()) | ||
.then((data) => { | ||
if (!data || !data.html) return next(); | ||
|
||
var html = data.html; | ||
|
||
$(el).replaceWith(html); | ||
next(); | ||
}) | ||
.catch(() => { | ||
return next(); | ||
}); | ||
}, | ||
function () { | ||
callback(); | ||
} | ||
); | ||
} | ||
|
||
module.exports = { | ||
render: render, | ||
category: "external", | ||
title: "Bluesky", | ||
description: "Embed posts from Bluesky URLs", | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
describe("bluesky plugin", function () { | ||
const replaceURLsWithEmbeds = require("./index.js").render; | ||
const cheerio = require("cheerio"); | ||
|
||
it("works", function (done) { | ||
// html bare link to a post on bluesky | ||
const html = | ||
'<a href="https://bsky.app/profile/logicallyjc.bsky.social/post/3lbretguxqk2b">https://bsky.app/profile/logicallyjc.bsky.social/post/3lbretguxqk2b</a>'; | ||
|
||
const $ = cheerio.load(html); | ||
|
||
replaceURLsWithEmbeds($, function () { | ||
|
||
console.log('html:', $.html()); | ||
expect($("a[href='https://bsky.app/profile/logicallyjc.bsky.social/post/3lbretguxqk2b']").length).toBe(0); | ||
expect($("blockquote").length).toBe(1); | ||
done(); | ||
}); | ||
}); | ||
|
||
it("does not error when there are no links", function (done) { | ||
const html = "<p>hello</p>"; | ||
|
||
const $ = cheerio.load(html); | ||
|
||
replaceURLsWithEmbeds($, function () { | ||
expect($("a").length).toBe(0); | ||
expect($("blockquote").length).toBe(0); | ||
done(); | ||
}); | ||
}); | ||
|
||
// if the bluesky link is invalid or poorly formatted, it should not be replaced | ||
it("does not error when the link is invalid", function (done) { | ||
const html = '<a href="https://bsky.app">https://bsky.app</a>'; | ||
|
||
const $ = cheerio.load(html); | ||
|
||
replaceURLsWithEmbeds($, function () { | ||
expect($("a").length).toBe(1); | ||
expect($("blockquote").length).toBe(0); | ||
done(); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters