ActivityPubに対応するためにしたことのまとめ
Astroで生成しているwebサイト自体をAcitivityPubアカウントにするBridgy-Fedに対応するためにしたことをまとめた。
以下のサイトのお二人の情報が大変参考になった。
https://blog.tyage.net/post/2023/2023-07-17-bridgy-fed/
https://zenn.dev/dl10yr/articles/c13c7b974b32d0
Bridgy-Fedのためにプロフィールを設定する
Bridgy-Fedはサイトのルートに接続したときに見つけたh-cardクラスのブロックをActivityPubのプロフィールとして設定する。構造は以下のとおり。h-card以下の順序は関係ない。
詳細はmicroformatsとBridgy-FedのDocsを参照。
https://microformats.org/wiki/Main_Page-ja
h-cardブロックはプロフィールを表す p-nameはユーザー名 rel="me"href="/"を必ずつける p-noteはSNSにあるアカウント説明文 u-urlをつけたリンクはプロフィールに追加されるリンクになる これをAstro用に合わせる。自分はプロフィール部分のアイコンや名前は/src/components/Bio.astroに書いてあるのでこれを修正しトップページに<Bio />を追加した。表示する必要はないのでdisplay:noneで非表示にしておいた。
ubanis ふたなり絵描き ActivityPubアカウント 自分のAstroはトップページがまず/src/page/[...page].astroでインデックスページになっているのでそこにさきほどのコンポーネントである<Bio />を追加した。
Bridgy-Fedに対応するためのclassを投稿に追加する
投稿はAstroがMarkdownファイルから生成するのでHTML生成部分である/src/layouts/BlogPost.astroに投稿に必要なclassを追加する。
Bridgy-Fedは以下のようなclassがつけられた部分をFediverseへの投稿とみなす。HTMLタグは関係がなくclassがついているかどうかである。
h-entryブロックがFediverseへの投稿ブロックを表す p-nameは投稿のタイトルを表す。 p-nameクラスがある場合は投稿がArticleとなりマストドンなどでは タイトルとともに記事へのリンクだけの投稿となり本文が展開されない。 省略可能。 e-contentは投稿の本文。 このブロック内はHTMLタグなどが外された純粋なテキストに変換される。 当然省略不可。 u-in-reply-toがある場合その投稿はhrefで指定された マストドンなどの投稿URLへのリプライとなる。 省略可能。 以下はBridgy-Fedとやり取りするために必要なもの。 display:noneで非表示にしている。 u-bridgy-fedのリンクのタグには何も無くて良い。 投稿の日時 これに合わせてMarkdownの変換部分を以下のようにした。
{ frontmatter.isPname && ( {frontmatter.title} ) } { frontmatter.replyTo && ( [リプライ先] ) } {postDate.toJSON()} p-nameをつけるかどうかはfrontmatterにisPnameを追加することで対応した。
同様にリプライかどうかの判断もreplyToのfrontmatterを追加。
---import { z, defineCollection } from "astro:content";const blogCollection = defineCollection({ schema: z.object({ title: z.string(), date: z.string().transform((str) => new Date(str)), description: z.string().optional(), tags: z.array(z.string()).optional(), baseUrl: z.string().optional(), featured: z.string().optional(), heroImage: z.string().optional(), author: z.string().optional(), isDraft: z.boolean().optional(), category: z.string().optional(), isPname: z.boolean().optional(),// p-name replyTo: z.string().optional(),// u-in-reply-to updatedDate: z .string() .transform((str) => new Date(str)) .optional(), }),});export const collections = { blog: blogCollection, note: blogCollection,};リプライとp-nameは以下のようにMarkdwonファイルの中で指定する。
画像の添付
投稿に画像を添付したい場合はプロフィールの時のようにh-entryの中でu-photoクラスのついた<img>を追加する。
AstroのMarkdown生成では投稿内(ここではe-content)に含まれる<img>タグのclassが書けないので(やり方はあるかもしれない)u-photoクラスをつけて画像を添付したい場合はmdxファイルに直接<img>タグを書くことにした。
- - -webfingerなどのリダイレクトを設定する
私のサイトはVercelにあるのでBridgy-Fedへリダイレクトするためのvercel.jsonをルートディレクトリに作成する。公式の説明にあったワイルドカードだと正しく動作しなかったので以下のようにした。
2024-03-22 vercel.jsonを修正
redirectsではなくrewritesであり :pathもつける必要があった。
Bridgy-Fedから接続確認
https://fed.brid.gy/ から右側のConnect directly to the fediverse:@yoursite.comを選択する。
What's your web site?の下の入力欄に自分のドメインのアドレスを入力してOKを押す。
Next step: add the .well-known redirects. の部分は先程のリダイレクトの確認を行う部分なのでCheck nowを押しリダイレクト接続確認を行う。
Next step: add a representative h-card. サイトのルートにアクセスしてプロフィールの設定を確認するのでこれも同様にCheck nowを押す。
このふたつに成功するとめでたくFediverseに自分のサイトのアカウントが作成される。
アカウントのページ
例として自分のプロフィールが以下になる。
https://fed.brid.gy/web/ubanis.com
上部にある@ubanis.com@ubanis.comがFediverseにおけるユーザー名になる。
Profile以下のactivityにはアカウントのアクションが表示される。
followersとfollowingはそのままフォローとフォロワー。
Feedはフォローしているユーザーのアクションが表示される。
Notificationsは通知。
このままだとユーザーをフォローしたりはできないのでそれは後半で説明する。
記事の投稿からFediverseへのポスト
上記のプロフィールが無事作成されている状態ならば以下の通知を行えばFediverseに投稿される。
とりあえずテストとして/src/content/note/test.mdファイルを作成する。
- これをすでにvercelと連携しているGithubにpushする。
デプロイ後いつものようにサイトに記事が追加される。
これだけではBridgy-Fedに投稿が通知されるわけではないのでcurlで記事のURLを通知しなければならない。
これが実際に投稿されたかどうかはBridgy-Fedのプロフィールページを見ればわかる。
マストドンなどにアカウントを作成して自分のサイトをフォローしてみて投稿が流れているか確認したほうがいいかもしれない。
現状ではMisskey.ioには投稿が全く流れずリプライも動作しなかった。
IndieAuthを設定する
IndieAuthはOAuth2拡張の1つで、Webページ自体をアカウントとして成立させる仕様と説明されていた。
https://qiita.com/okuoku/items/edf0079f472e548041f3
webサイトのトップページの<a>又は<link>に自分のGithubアドレスを追加する。
GithubのプロフィールページからEdit Profileを押してPronounsとSocial accountsに自分のサイトのアドレスを追加してSaveする。
以下のページの最下段にあるTry it!から自分のサイトアドレスを入力する。
ログインしようとするとGithubとIndieAuthとの連携許可が表示されるのでこれを許可する。
これでIndieAuthを使ったログインが可能になった。
他のユーザーをフォローする
サイトを登録すると分かるがBridgy-Fed自体にログインするような仕組みはない。
他のユーザーをフォローするためにここでさきほどのIndieAuthを使ったログインが必要になる。
Bridgy-FedのプロフィールのFollowingからフォローしたいアカウントのアカウント名を入力しFollowボタンを押す。
IndieAuthで認証されフォローが完了すれば上部に通知が表示される。
記事のデプロイ後自動でBridgy-Fedに通知する
記事を増やすごとに手元でcurlコマンドを打ち通知していてはやってられないのでこれをGithub Actionsで自動化する。
こちらのコードを参考にさせていただいた。
https://zenn.dev/dl10yr/articles/c13c7b974b32d0
/.github/workflows/send-webmention.ymlを以下のようにする。
name: send webmentionon: push: branches: - mainjobs: deploy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 with: submodules: false fetch-depth: 0 - name: Send webmention uses: actions/setup-node@v3 - run: git fetch origin ${{ github.event.before }} # 直前のコミットハッシュをフェッチします。 - run: git fetch origin ${{ github.sha }} # 最新のコミットハッシュをフェッチします。 - run: node sendwebmention.mjs ${{ github.event.before }} ${{ github.sha }}/sendwebmention.mjsを追加する。
Astroはmdxも扱うのでそれに対応した。
このままだとnoteのほうだけ通知されるのでblogのほうも通知したい場合は改良が必要。
const = await importconst = 10const const = すべてデプロイした後に改めて記事を追加してデプロイした後Bridgy-Fedに投稿のアクションが表示されるかしばらく待ってから確認する。
webmentionで記事への反応を表示する
これは現在正しく動いてないようなので動作するようになってから書こうと思う。