Blueskyのポストをサイトに表示する

Bluesky の外部公開

Bluesky の公開用 web インターフェースが実装されログインしなくても投稿やプロフィールページを見ることができるようになった。

ubanis(Bluesky) (@ubanis.com)
futanari artist R18 ふたなり絵を描きます 絵 My Bluesky arts https://bsky.app/profile/did:plc:lmftezsq52hi53taz762s7pc/feed/aaalx2yzi3h5u Discord https://discord.gg/XE5WdZqU4b Links https://ubanis.com/card/
ubanis(Bluesky) (@ubanis.com) favicon https://bsky.app/profile/ubanis.com
ubanis(Bluesky) (@ubanis.com)

それに加えてポストの RSS が配信されるようになったので、それを取得してサイトで表示するようにした。

RSS の URL は profile/ユーザーのDID/rss のアドレスになっている。

bsky.app
bsky.app favicon https://bsky.app/profile/did:plc:lmftezsq52hi53taz762s7pc/rss

RSS を読み込む

最初は RSS から json への変換を rss-to-json で行おうとしたものの変換はできるものの表示できないので外部 API を利用することにした。

GitHub - nasa8x/rss-to-json: RSS and Atom feed generator for Node.js
RSS and Atom feed generator for Node.js. Contribute to nasa8x/rss-to-json development by creating an account on GitHub.
GitHub - nasa8x/rss-to-json: RSS and Atom feed generator for Node.js favicon https://github.com/nasa8x/rss-to-json
GitHub - nasa8x/rss-to-json: RSS and Atom feed generator for Node.js

rss-to-json は fetch ではなく axios を使っているのが原因かもしれない(よくわかってないので詳しい方教えて下さい)

nasa8x/rss-to-json
RSS and Atom feed generator for Node.js. Contribute to nasa8x/rss-to-json development by creating an account on GitHub.
nasa8x/rss-to-json favicon https://github.com/nasa8x/rss-to-json/issues/65
nasa8x/rss-to-json

RSS から json への変換は rss2json.com を利用する。無料版では1時間に1回 RSS が更新される。

RSS to JSON Converter online - rss2json.com
Free online API to convert RSS to JSON
RSS to JSON Converter online - rss2json.com favicon https://rss2json.com

Svelte のコード

以下は svelte のコード。

<script>
import { onMount } from "svelte";
import { fade, slide } from "svelte/transition";
let promise = new Promise(() => {});
onMount(() => {
promise = (async () => {
const res = await fetch("rss2jsonのapi URL");
const data = res.json();
return data;
})();
});
</script>
<div class="break-all rounded-xl bg-(color:--bg-base-color) pb-4">
<h2 class="rounded-t-xl bg-blue-500 p-2 text-lg font-bold leading-8 text-white">Bluesky</h2>
{#await promise}
<p
transition:slide
on:introstart={() => (visible = false)}
on:outroend={() => (visible = true)}
>
読み込み中...
</p>
{:then data}
<div class="loaded" in:fade>
<h3 class="bg-slate-300 p-2 text-base text-black underline">
<a href={data.feed.link}>{data.feed.title}</a>
</h3>
{#each data.items as item}
<p class="border-b border-dotted border-(color:--border-color) px-3 py-3 text-base">
{item.description}
<time class="pt-2 text-sm block">{item.pubDate} + 9h</time>
<a
class="hover:text-(color:--text-linkhover-color) text-(color:--text-link-color) text-sm pt-2"
href={item.link}
target="_blank">[ポスト元]</a
>
</p>
{/each}
</div>
{:catch error}
<p>ERROR {error.message}</p>
{/await}
</div>

完成品

実際に動作しているものは以下のようになる。(Astro の構造上ブログ用スタイルシートがコンポーネントに適用されてレイアウトがおかしいのはご了承ください。正しい表示なのはプロフィールページにあります。)

プロフィール
へび右曲がりはubanisによるふたなりサイトです
プロフィール favicon https://ubanis.com/profile
プロフィール

Bluesky

読み込み中...