Skip to main content

Bluesky公式クライアント v1.77とatprotoリポジトリの更新

·300 words·2 mins
Henoya
Author
Henoya
流しのプログラマ
Table of Contents

Bluesky公式クライアント v1.77
#

既にBluesky公式クライアント v1.77のWeb版は更新されています。

atproto リポジトリの更新内容と合わせると、こんな感じの内容になりそうです。

atprotoリポジトリ(Lexiconの変更を含みます)
#

  • ログインしている場合に、アカウントの検索サジェスチョンにブロック・ミュートしているアカウントなどがでないようになるようです(これまでは、アカウントの検索サジェスチョンのAPIはログインアカウント情報を見てなかった)

  • これまでuri が入るはずのアバター画像URLや画像URL等でstring指定だけだった所に、format=“uri”が追加されました。

  • 公式Webクライアントでの、ポストのWebページ埋め込み機能と関連して、ポスト関係の幾つかのViewに"replyCount”,“repostCount”,“likeCount”の表示が追加されました。

  • フィードに対するインタラクションのフィードバック機能が追加されました。 Feed interactions schema #2383 このプルリクでの追加なのですが、フィードジェネレータが"app.bsky.feed.generator”の"acceptsInteractions”に受け取れると書いた次のようなフィードに対するユーザのインタラクションがイベントとしてもらえるようになりそうです。

  • このフィードに対するインタラクションを送る”app.bsky.feed.sendInteractions” APIが追加されています。

  • ポスト検索にいろいろ条件が付けられるようになるようです。これらは検索APIに渡すパラメータとして追加されたものなので、これまでの”from:”のような検索テキスト中に入れるパラメータではないです。クライアント側がクエリテキストを解析してこれらのパラメータに分解してAPIに渡すのはありかも。

    • “sort”:top, latest 昇順・降順(というか、結果順と逆順)
    • ”since”:指定日時以降(キーとして使用されるのは”createdAt”ではなく”sortAt”とのこと。日時指定もしくは日付だけ(ISO date (YYYY-MM-DD))と書いてある。日時の時もこうなのかな?タイムゾーンとか
    • “until”:同じく指定日時まで。他は ”since” と同じ
    • “mentions”:検索アカウントに対する指定アカウントからの(handleもしくはDID)のメンションだけ。リッチテキストでメンションになっているポストだけが対象。文字列だけでメンションになっていないのはかからない
    • “author”:ポストしたアカウント。(handleもしくはDID)
    • ”lang”:言語ラベル。投稿時に付けた言語ラベルが対象だが、サーバが上書きする場合もある(付いていない場合とか過去のポストなど?)
    • “domain”:ポストに付けられたURLリンク(リッチテキストのリンク)とリンクカードの埋め込みリンクのドメイン名(ホスト名まで)で検索。サーバ側が正規化をおこなう場合がある(www. を省くとか、国際化ドメインとか?)
    • ”url”:リンクまたは埋め込みリンクカードのURLで検索。サーバ側が正規化やファジーマッチングをする場合がある
    • “tag”:ポストのタグやハッシュタグ(先頭の”#” はいらない)で検索。複数指定された場合はAND検索になる ちなみに、通常の検索テキストは ”q”:パラメータ、 “limit”:一回の結果の最大数(最大100まで)、 “cursor”:次の結果を要求するときのカーソルは従来と同じです。
  • Lexiconで従来”type”:”string”で定義されていたパラメータで、より細かい検証が必要な型として”format”要素で定義される型として、”tid””record-key”が追加されています。

    • ”tid”::tidは、一番身近な例で行くと、ポストのURLとして、アカウントのハンドルの後の/post/の後のそのアカウントでのポストなどのレコードを一意に時系列で表すrkey record key といわれている部分です。 https://bsky.app/profile/henoya.com/post/3kpvgji5lvc22 この僕のあるポストURLでの、3kpvgji5lvc22 の部分です。他のURLではこのrkeytidでなくてもいい場合もありますが、ポストの場合はtidであると定義されるようになりました。 ”record”の”key”として”tid”が指定されているのは、現在のLexiconではすべて”app.bsky”名前空間で、”feed.like””feed.post””feed.repost””feed.threadgate””graph.block””graph.follow””graph.list””graph.listblock””graph.listitem”になってます。

    • これまで”type”:”string”で”format”として検証メソッドが定義されているのは以下の型になります。この定義はatprotopackages/lexicon/src/validators/primitives.tsと同じ階層のformats.tsで定義されていますが、実際の検証メソッドの内容は検証内容によって分かれています。

      • ’datetime’:formats.datetime() ‘iso-datestring-validator’パッケージ
      • ’uri’:formats.uri() packages/lexicon/src/validators/formats.ts
      • ’at-uri’:formats.atUri() ‘@atproto/syntax’パッケージ
      • ’did’:formats.did() ‘@atproto/syntax’パッケージ
      • ’handle’:formats.handle() ‘@atproto/syntax’パッケージ
      • ’at-identifier’:formats.atIdentifier() packages/lexicon/src/validators/formats.ts内でhandledidを呼んでいる
      • ’nsid’:formats.nsid() ‘@atproto/syntax’パッケージ
      • ’cid’:formats.cid() ‘multiformats/cid’パッケージ
      • ’language’:formats.language() ‘@atproto/common-web’パッケージ
      • ’tid’:formats.tid() ‘@atproto/syntax’パッケージ
      • ’record-key’:formats.recordKey() ‘@atproto/syntax’パッケージ ただ、まだtidrecordKeyの検証メソッド自体はまだ実装されていないようです。

social-app リポジトリ (公式クライアント v1.77)
#

ポストの埋め込み機能実装
#

  • 「ログインしていなくてもポストが見られる」、URLなどの「Blueskyで共有」機能に加えて、「ポストのWebページなどへの埋め込み」機能が公式Webクライアントの機能として追加されました。

    • URL は https://embed.bsky.app/がベースのようです。

    • 仕組みとしては、 oEmbed を使っています。

    • Web版では既に対応していますので、ポストから埋め込みコードをコピーできるようになっています。

      1. ポストの右下のメニューから ”Embed post” を選びます

      2. 埋め込みコードのダイアログが表示されるので、”Copy code” ボタンをクリックすると、埋め込み用のHTMLコードがコピーされます

        メニュー表示
        埋め込みコードコピー

    • コピーされたコードは、以下のような<blockquote>タグになっています。 ちょっと改行やインデントしてますが、実際には1行です。

      <blockquote class="bluesky-embed" data-bluesky-uri="at://did:plc:trw6iydbhpncolfzwrrh5juw/app.bsky.feed.post/3kpuc5ymf6m2p" data-bluesky-cid="bafyreihzomyskb4lcsze7t6yznbdbagiwnin2vyrt7ruoiosz7uc3comc4">
        <p lang="ja">
          ちなみに、新しく追加された機能である、リンクを長押しすると共有できるようになった、というのは、フィード画面でも、ポスト表示画面でも長押しすると共有シートが出てきました。
      ポスト表示画面だと、同時に文字列選択も聞いてしまいますが、共有シートにはちゃんとリンクのURLが渡っているようです。
        </p>
        &mdash; Henoya🍄Shiitake (<a href="https://bsky.app/profile/did:plc:trw6iydbhpncolfzwrrh5juw?ref_src=embed">@henoya.com</a>) <a href="https://bsky.app/profile/did:plc:trw6iydbhpncolfzwrrh5juw/post/3kpuc5ymf6m2p?ref_src=embed">Apr 11, 2024 at 22:21</a>
      </blockquote>
      <script async src="https://embed.bsky.app/static/embed.js" charset="utf-8"></script>
      
    • このhtmlコードを見ると、このBlueskyの埋め込みコードの場合は、<blockquote>タグ(引用タグ) にclass="bluesky-embed"として、data-bluesky-uri=“<ポストのat-uri>”data-bluesky-cid=“<ポストのcid>”を付けることによってマークして、</blockquote>の次の<script>で読み込んでいるJavascriptでこの<blockquote>の部分をポストの埋め込みのかたちに書き換えて表示するようになっています。 このコードをWebページに追加すると、ポストの埋め込み表示になります。 Javascriptをオフにした場合などは、普通の引用ブロックとして表示されます。

      Webページに埋め込んだポスト
      Javascriptオフの場合

  • 公式クライアントWebサーバ版である Go製のサーバプログラム部分 bskyweb (共有や埋め込み、非ログイン時のポスト表示などは、こちらがおこなっています)の実行時パラメータが変更になっていて、従来はPDSのURLを指定していたのですが、それに変わって App View のURLを指定するように変わっています。

  • ポスト埋め込み機能の追加にともなって、ダイアログ表示として ”Embed” ダイアログと ”Signin” ダイアログが追加されています。サインインは、埋め込みポストからせんしした場合に出てくるのでしょうか。

アカウントプロフ情報のホバー表示
#

  • ポストのプロフィアルアイコンの上にマウスをホバーすると、そのアカウントプロファイルの概略が表示されるようになりました。また、ポスト中のメンションなどでのホバーでもプロファイルが表示されます。

    アカウントホバー表示

言語選択メニューの簡略化
#

  • ポスト書き込みダイアログで、言語選択のメニューが簡略化されています。

    ポスト言語選択

その他
#

  • OTA(On The Air update) 検出Web版のみ?と再起動表示が出るようです。
  • プロファイルの画面に表示される内容が多いアカウントの場合、行間が狭くなってプロファイル画面が広くてフィード部分がスクロールできない問題の対応でしょうか。
  • ラベラーでトグルボタンを操作したときにハプティック(細かい振動のフィードバック)がでるようになった?アプリ版のみかな?
  • フィード表示の場合、特にアカウントのフィードなどの場合にどのフィードを憑依しているかのタブが画面上部に残るようになった。タイムラインとカスタムフィードの場合は、スクロースして少しは表示されてるけど、もっとするロールしたら表示されなくなってしまうのは、意図どおりかな?

検索クエリー
#

  • ポスト検索のクエリワードからの検索条件のパースは Indigoリポジトリのsearch/parse_query.go でおこなっているようです。公式クライアントからはテキストクエリを投げているだけのようです。
  • Indigosearch/post_schema.json に、全文検索エンジンのOpensearch にポストデータをストアするときのスキーマがあるのですが、Japaneseは別にスキーマが追加され、kuromojiを使って解析しているようです。
  • また、取得している項目には、引用ポストの引用先のat-uriやリプライ先、添付画像数、画像のAltText、セルフラベル、絵文字なども記録されているので、使えるかもしれません。
  • アカウントプロファイルのスキーマは indigosearch/profile_schema.jsonにあり、”handle"”description"(bio)等とともに”tag"”pagerank””folloersFuzzy"などもあり、アカウント検索の時には参照されるようになるのかもしれません。

検索クエリーのパース
#

  • ポスト検索でのパラメータの追加は、検索クエリーの解析でおこなっているようです。
    • “sort”:まだ、indigosearchの方でsortのパースが入っていないもよう
    • ”since”since:2024-03-01 since:2024-03-01T12:00:00+09:00 は通った。since:2024-03-01 00:00:00 は、00:00:00 がクエリ文字列扱いになった。
    • “until””since” と同じ。
    • “mentions”mentions:henoya.comで自分宛のメンションが出てきたが、mentions:<他のアカウントのハンドル> でも、他のアカウント向けのメンションが検索で出てきた。@<アカウントのハンドル> でも同様。
    • “author”author:henoya.com ではだめで、from:henoya.comだと通った
    • ”lang”lang:ja で日本語ラベルの付いているポストが検索できた。ただ、langラベルが付いていない時期の指定をしても(例:lang:ja since:2023-03-01 untile:2023-05-01)、ほとんど表示されなかった。今の所言語ラベルだけを見ているのだろうか
    • “domain”domain:itmedia.co.jp とすると、itmedia.co.jpドメインのリンクかリンクカードが付いたポストのみが検索された。検索して気づいたが、ITmediaのリンクカードの文字化けが 2024-03-02あたりから解消されているもよう。
    • ”url”http://もしくはhttps://urlになる。://は必要
    • “tag”#付きのクエリ文字列で検索できる。#ハッシュタグ

クエリワードの例
#

  • 基本的には空白文字でワート単位に分割される。条件ワードも空白文字が入っていると分割されてしまう。from:などの場合、:の後には空白を挟まずにハンドルなどを続けないといけない。
    • “<フレーズ>” ダブルクオーテーションで囲むと、その間は空白文字があってもワードごとに分割されず、空白文字も含めた一つの文字列としてあつかわれる。ただし、 ダブルクオーテーションで囲んだ時点で、検索ワード扱いになるので、検索条件のパラメータの一部として で囲まれた文字列は使用できない。例:since:”2034-03-01 12:00:00” は、2034-03-01 12:00:00 というフレーズと、パラメータがないsince: に分割され、意図したとおりの検索条件にはならない。
    • @<ハンドル>:そのアカウントからのメンション
    • #<ハッシュタグ>:ハッシュタグ条件。
    • 以下は <キーワード>:<パラメータ> の組み合わせの検索条件 条件はすべてAND結合になる。
    • did:<DID> : ポスト作成者をDIDで指定する
      • 例:did:did:plc:trw6iydbhpncolfzwrrh5juw
    • from:<handle or did>:ポスト作成者をhandleもしくはDIDで指定
      • 例: from:henoya.com
    • from:@<handle>handleの前に@を付けてもOK
      • 例: from:@henoya.com
    • from:me:クエリを発行したログインしているアカウント自身
    • to:<handle or did>:リプライ先のアカウントをhandleもしくはDIDで指定
      • 例: from:me to:@henoya.com
    • mensions:<handle or did>:メンション先のアカウントをhandleもしくはDIDで指定
      • 検索しているアカウントが関係なくても、メンション先が指定したアカウントなら条件となる
    • from:henoya.com since:2024-03-01 until:2024-03-05T12:00:00+09:00
      • アカウントhenoya.comのポストで、2024-03-01から2024-03-05 12:00:00 JSTまでのポスト。
    • http://<url> もしくは https://<hrl> :このURLのリンクか埋め込みリンクカードが含まれるポスト。実際には先頭にwww.が付いていても取り除かれたり、?以降のクエリパラメータの一部(utm=など、追跡用に使用されるパラメータや、#以降の部分は削除されて検索される。また、末尾の/等は省略されてもかまわない
      • 例:https://henoya.comhttps://www.henoya.com/ は同じ
    • domain:<ドメイン>:ホスト名を含むドメイン部分のみがマッチするリンクやリンクカードを指定する。
      • 例:domain:itmedia.co.jp ニュースサイト IYmedia のドメイン指定
    • lang:<言語>:言語コードを指定して検索。言語コードとしては、BCP-47 といわれる言語を2文字または2文字に付加情報を付けたコードで表す。
      • 例:lang:ja 日本語
      • 例:lang:de ドイツ語
        • 現在は基本的に2文字の言語コードしか公式クライアントなどでも使用されていないが、同じ言語でも、使用される国や地域などで異なる場合に、2文字の言語コードにハイフンの後に付加情報(通常は国、地域を表す2文字コードだが、場合によってはさらに複雑な場合もある)
          • zh-Hant(繁体字で書かれた中国語)
          • zh-Hans(簡体字で書かれた中国語)
          • zh-Hans-CN(中国大陸にて用いられる、簡体字で書かれた中国語)
          • de-CH-1901(スイスにて用いられる、ドイツ語1901年正書法で書かれたドイツ語)
      • 詳しくはこちらを参照: IETF言語タグ - Wikipedia
    • since:<Date>
    • since:<DateTime>
    • untile:<Date>
    • untile:<DateTime>since:はその日時以降、until:はその日時までの条件。日時の判定の元となるタイムスタンプは、ポスト作成時に付けられたcretedAtではなく、ポストがリレーに収集されたのちにつけられるsortAtが使用される。createdAtが偽装されたポストは、その日時では条件に合わない
      • <Date>もしくは<DateTime>の書式は、日付と時刻の間に空白を入れないISO 8601形式の書式とされる。
      • 例:since:2024-03-01
        • 2024-03-01以降。正確には UTC での 00:00:00以降。日本時間だと2024-03-01 09:00:00 からとなる。
      • 例:until:2024-03-31T12:00:00+09:00
        • 日本時間(+09:00) の 2024-03-31 12:00:00まで
      • 例:since:2024-03-31T12:00:00Z
        • UTCで2024-03-31 12:00:00から
      • 例:until:2024-03-31T12:00:00.9999+09:001秒以下も指定はできる
      • Go言語でのタイムスタンプ書式指定
        • "2006-01-02T15:04:05.999Z"
        • 4桁年-2桁月-2桁日T2桁時:2桁分:2桁秒[.秒以下]UTCからの時差
      • 正規表現
        • ^[0-9]{4}-[01][0-9]-[0-3][0-9]T[0-2][0-9]:[0-6][0-9]:[0-6][0-9](.[0-9]{1,20})?(Z|([+-][0-2][0-9]:[0-5][0-9]))$
        • .の後の秒以下は20桁まで、時間帯はZ もしくは+-2桁時:2桁分
        • 時間帯は指定しなかったらUTCになる

Related

Bluesky公式クライアントチームリーダー Paul の昔話
·1080 words·6 mins
Bluesky公式クライアントチームリーダー Paul の昔話
カスタムフィードの挙動変更
·70 words·1 min
Bluesky公式クライアントのバージョン1.59でのフィードジェネレータへのアクセス方法の変更について説明しています。新しいバージョンでは、カスタムフィードへの最初のアクセス時は以前と同じですが、その後は定期的に新規ポストの有無を確認するためにlimit=1のリクエストが送信されます。この変更により、カスタムフィードへのリンクを踏んでも必ずしも更新されなくなり、フィードジェネレータへのリクエストの種類を判別するのが難しくなっています。
カスタムフィードのゲームへの応用〜迷路フィードの実装顛末記〜
·505 words·3 mins
Blueskyのカスタムフィード機能を使用して迷路ゲームを作る過程について説明しています。このカスタムフィードは、ユーザーがプログラムを自作して公開できる機能で、主に特定のキーワードでポストをフィルタリングする用途で使われています。しかし、この記事では、カスタムフィードを使ってインタラクティブなゲームを作るという新しいアプローチが採用されています。筆者は、3D迷路ゲームの作成に成功し、フィードジェネレーターのプログラミング、ゲームのメカニズム、選択肢の表示方法など、その開発プロセスを具体的に紹介しています。