Home

Bluesky

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

ubanis(Bluesky) 2024年3月11日

これはテストのためのコピーです。 https://ubanis.com/note/bluesky-post-widget/

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

Blueskyの外部公開

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

https://bsky.app/profile/ubanis.com

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

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

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

RSSを読み込む

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

https://github.com/nasa8x/rss-to-json

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

https://github.com/nasa8x/rss-to-json/issues/65

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

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の構造上ブログ用スタイルシートがコンポーネントに適用 されてレイアウトがおかしいのはご了承ください。正しい表示なのはプロフィールページにあります。)

https://ubanis.com/profile