GitHub
Experimental

QR Exchange

QRコードを使用して、対面でActivityPubアカウントを簡単に交換するための仕様です。 LINEの友だち追加のような体験を分散SNSで実現します。

概要

QR Exchangeは、ActivityPubアカウントの情報をQRコードにエンコードし、 スマートフォンのカメラでスキャンすることで簡単にフォローできる機能です。

ユースケース

QRコードフォーマット

QRコードには Yurucommu のプロフィールURLをエンコードします。

プロフィールURL形式

スキャナーは /profile/ パスと username hash を読み取ります:

https://example.com/profile/https%3A%2F%2Fexample.com%2Fap%2Fusers%2Falice#alice

スキャン処理フロー

1. QRコードのスキャン

カメラでQRコードを読み取り、プロフィールURLを取得します。

2. アクター情報の取得

取得したプロフィールURLからActivityPubアクターを解決します:

同一ドメインの場合

  1. /profile/:actorIdactorId を decode
  2. ローカル actor API でプロフィールを取得

別ドメインの場合

  1. URL hash の username と QR URL の domain から @user@domain を作る
  2. リモート検索でプロフィールを取得

3. プロフィール表示

取得したアクター情報をユーザーに表示します:

4. フォローアクション

ユーザーが「フォロー」ボタンを押すと、通常のActivityPub Followアクティビティを送信します。

実装例

QRコード生成(React)

import QRCode from 'qrcode.react';

function MyQRCode({ actorUrl }) {
  return (
    <QRCode
      value={actorUrl}
      size={256}
      level="M"
    />
  );
}

QRコードスキャン

import { Html5QrcodeScanner } from 'html5-qrcode';

function startScanner(onSuccess) {
  const scanner = new Html5QrcodeScanner("reader", {
    fps: 10,
    qrbox: 250
  });

  scanner.render((decodedText) => {
    onSuccess(decodedText);
    scanner.clear();
  });
}

アクター解決

async function resolveActor(qrData) {
  const url = new URL(qrData);
  const match = url.pathname.match(/\/profile\/([^\/\?]+)/);
  if (!match) throw new Error('Invalid QR code');

  const actorId = decodeURIComponent(match[1]);
  const username = url.hash ? decodeURIComponent(url.hash.slice(1)) : null;

  if (url.host === window.location.host) return fetchActor(actorId);
  if (!username) throw new Error('Remote user info insufficient');
  return searchRemote(`@${username}@${url.host}`);
}

セキュリティ考慮事項

悪意あるQRコード

プライバシー

UI/UXガイドライン

QRコード表示画面

スキャン画面

プロフィールプレビュー

相互運用性

URL形式を使用することで、Yurucommu以外のActivityPub実装でも QRコードを読み取ってフォローすることができます。 特別な拡張プロトコルは不要です。

ヒント: URL形式を使用すれば、QRコードをスマートフォンの標準カメラアプリで スキャンしてもWebブラウザでプロフィールページを開くことができます。