BlueskyアプリのURL短縮

By びるず (@bills-appworks.blue)
Published:

BlueskyアプリのURL短縮

Blueskyではポスト中にURLを記述すると、(公式)アプリではクリッカブルリンクとしてレンダリングされると共に、一部が省略されたり、URLが一定以上の文字数の場合は末尾が「...」となって省略される加工が行われます。

Blueskyではポストの文字数は現時点で300文字までの制限があり、URLは短縮された表示の文字数でカウントされるため、長いURLでも短縮されることによって文字数制限への圧迫を軽減する効果があります。

私が開発しているBlueskyクライアントアプリbsky-sh-cli (Bluesky in the shell)では、この記事の執筆時点(バージョン0.6.0)ではURL短縮に対応しておらず、次のリリースでの対応を予定しています。

この記事では開発のために調査した公式アプリのURL短縮の挙動を記載するものです。

軽くしか調査しておらず、ソースも見ていませんので、不足や不正確が多分に含まれると思われます。そのため当記事の内容は保証いたしません。御指摘はいただければ大変助かります。豆腐メンタルなので優しくお願いします:-)。

確認した範囲でのURL短縮の挙動概要

URL短縮の挙動詳細

先頭のスキーム部分は省略される

WebサイトのURLは多くの場合http://またはhttps://で始まりますが、これが省略されます。

(例) | 元の文字列 | 短縮URL表示 | | --- | --- | | https://example.com | example.com |

先頭のスキームに続く認証部分は省略される

Basic認証のWebサイトでユーザ名/パスワードを認証ダイアログに対して入力せずに、URL中に埋め込んで認証を通すにはhttps://<ユーザ名>:<パスワード>@example.comのようにスキームに続いて記述しますが、これも省略されます。

(例) | 元の文字列 | 短縮URL表示 | | --- | --- | | https://aa:[email protected] | example.com |

ルートの場合ホスト名末尾(パス先頭)スラッシュは省略される

たとえば「https://example.com/aa/bb」というURLの場合、「/aa/bb」の部分はWebサイト「https://example.com」内のパスを示します。Webサイトのルート(トップページ)を示すには「https://example.com/」のように書きますが、ルート「/」以降のパスが指定されていない場合、ルートを示すスラッシュ「/」は省略されます。

(例) | 元の文字列 | 短縮URL表示 | | --- | --- | | https://example.com/ | example.com |

26文字を超えると末尾省略加工が行われる

(追記)文字数に関して異なるケースを多数観測しており、不正確です。

スキームおよび認証部分を省いた残り(ホスト名、パス)の文字数が26文字を超える(27文字以上)場合、短縮後の文字数が27文字となるように末尾が「...」となり、以降は省略されます。

(例)「example.com/aa/bb/cc/dd/ee」までが26文字 | 元の文字列 | 短縮URL表示 | | --- | --- | | https://example.com/aa/bb/cc/dd/ | example.com/aa/bb/cc/dd/ | | https://example.com/aa/bb/cc/dd/e | example.com/aa/bb/cc/dd/e | | https://example.com/aa/bb/cc/dd/ee | example.com/aa/bb/cc/dd/ee | | https://example.com/aa/bb/cc/dd/ee/ | example.com/aa/bb/cc/dd/... | | https://example.com/aa/bb/cc/dd/ee/f | example.com/aa/bb/cc/dd/... |

サーバ(PDS)上のデータ

URLを含むポスト内容のデータは変換されてサーバ(PDS)に格納されます。たとえば「https://example.com/aa/bb/cc/dd/ee/f」という文字列をポストすると、以下のようなデータとなります(説明に必要な部分以外は省略し、順番等も実際と異なる場合があります)。

"post": {
  "record": {
    "$type": "app.bsky.feed.post",
    "text": "example.com/aa/bb/cc/dd/..."
    "facets": [
      {
        "features": [
          "$type": "app.bsky.richtext.facet#link",
          "uri": "https://example.com/aa/bb/cc/dd/ee/f"
        ],
        "index": {
          "byteStart": 0,
          "byteEnd": 27
        }
      }
    ]
  }
}
textキーの値が表示されるポスト内容(URLの場合省略URL)で、facetsキーの値(配列)はポスト内容を修飾する付加情報となります。上記の場合、表示は「example.com/aa/bb/cc/dd/...」とし、位置0(先頭)~位置27(末尾)までの範囲の文字列を対象として、実際にはURL(uri)「https://example.com/aa/bb/cc/dd/ee/f」によるハイパーリンクとなることがクライアントアプリの動作として期待(要請)されます。ポストに複数のURLが含まれる場合は、facetsキーの配列要素が複数となります。

なおこのデータ変換(上記構造JSONのポスト時作成および表示時レンダリング)はBluesky(APIサーバ)サイドでは行われず、クライアントアプリで実装することが要求されます。

クライアントアプリでURL短縮を行わなかった場合

クライアントアプリでポスト時にURL短縮を行わなかった場合、つまりURLをそのままtextキーの値としてデータを構成した場合、クライアントアプリによってレンダリング結果が異なる可能性があります(規定されていたらすみません)。

たとえば執筆時点のbsky-sh-cli(バージョン0.6.0)で長いURLを含むポストを行い、bsky-sh-cli自身で表示すると長いURLのまま表示されますが、公式Blueskyクライアントアプリで同じポストを表示するとURLが短縮表示になります。

(参考)URLのパターンマッチ

URL短縮には直接関係ありませんが、bsky-sh-cli (Bluesky in the shell)ではポスト中のURLを抽出するためのパターンとして以下の記事を参考にしました。