見出し画像

SNS(Bluesky)のつながりを可視化し相関図を作るWebアプリを作った

すいばりです。
Blueskyのつながりを可視化し相関図を作るWebアプリを作りました。

作ったのはWebサービス「ひろがるBluesky!」です。
以下がリンクです。
使い方は右下の「?」マークを押してみてください。

2024/9/2追記: URL変わったので、新URLを貼りました。

アプリ名は自分の長女も好きな、プリキュアをリスペクトして名付けさせていただきました。
劇中の「無限に広がる青い空(=Bluesky)」のセリフ通り、Blueskyユーザがアプリを通じて無限に広がる輪を作れたら素晴らしいなという思いがあります。…なんつって!


どんなもの?

入力されたユーザについて同心円状の相関図を出します。
相関図の中心に近づくほど仲のいいユーザになります。

さらに、別のユーザを選択することでそのユーザの相関図を出せます。
これにより「友達の友達」の一目での把握と、その人とつながるきっかけ作りに貢献したいです。

現状、実際につながるアクションまではちょっと遠い気もするので、継続的にアップデートしていきたいです。

どう作った?

実装

PaaSクラウドfly.io上に、node.jsで構築しました。

主な使用ライブラリはblueskyerCytescape.js(以下、単にCytoscape※)です。
blueskyerはnode.js製の自作ライブラリです。Typescript製の公式SDK@atproto/apiのラッパーで、ちょっとした便利関数を追加したものです。

Cytoscapeは相関図描画に使用しています。
※:jsのつかないCytoscapeがあるのでほんとは良くないんだけどね。

実装詳細はGitHubもどうぞ。

アルゴリズム

選択されたユーザの他ユーザに対するエンゲージメントを計算します。
現状の計算方法は以下。

  • 選択されたユーザのポスト1000件といいね100件を収集

  • ポスト1000件のうちのリプライ全件と、いいね100件の対象ユーザを集計

  • リプライは+3点、いいねは+1点としてそのユーザから各ユーザに対するエンゲージメントを計算

得られたエンゲージメント順にユーザをソートして相関図内側から配置しています。
(なのでリプライ0件いいね0件のユーザは、自分しか出てこないし、人の相関図にも出てこないです、ごめんね)

取得件数や点数などのパラメータは完全に自分の独断と偏見による塩梅です。
こういうアルゴリズムになった理由は後述します。

アプリ全体のシーケンス図ですが、気が向いたら追加するかも。

相関図の仕様変遷

相関図は相当難儀しました。
計5つのプロトタイプを作って試行錯誤し、現在の形になりました。
やろうと思えば何千人も出せるアプリですが、速度やUXとのトレードオフとなります。
何を何のためにどこまで出すのかはこのアプリの肝なので、その変遷、長くなりますが語らせてください。

力の初号機

まず初号機が「フォローしてる人のフォロー・フォロワーおよびフォロワーのフォロー・フォロワー」の表示です。
このやり方だと、収集対象が自分みたいな一般人でも、芋づる式に表示ユーザが増えるのは想像に難くないでしょう。
その数なんと約7500人です。
とんでもなく描画は重いし、出てきた図を見てもぐちゃぐちゃで何を伝えたいか分からんと思い、単純に「友達の友達」を集めてきて表示するのは止めました。

技の弐号機

弐号機から、ぱっと見の分かりやすさの面で同心円相関図を採用しました。
まず相関図に「相互フォローを内側の円、片思いを外側の円に配置する」ことを考えました。
ノード数が激減したこともあってか描画は相当改善しました。(Cytoscapeに切り替えたのもあるかも?)
また一時的な仕様として、ユーザごとにブルスカパワー(影響力)を算出しアイコンの大きさでそれを表現していました。
弐号機はいい線行っていましたが、以下の点で没にしました。

  • 取得時間1分はWebアプリとしては長すぎる。自分がユーザなら使わない。10秒くらいに収めたい

  • 自分のような一般人にとって、アプリを広く使ってもらうにはフォロワーの多いインフルエンサーに拡散してもらうことが必須になるのだが、インフルエンサー(フォローに比べてフォロワーが明らかに多い人)が使うと外側の円が大きくなりすぎて何も見えなくなる致命的欠点がある

  • ブルスカパワーと人とのつながりマシマシコンセプトとの親和性が薄い

序の参号機

参号機は言い方は悪いですが、フォロワーの表示を切り捨てました。
自分が仲良くしたい人=フォロー、という発想でフォローのみに絞り、フォローのフォローを表示することでつながりを作れないかと考えました。
結果は失敗で、これも芋づる式にユーザが増えてしまい、相関図が何も分からなくなりました。
弐号機と同じく没としました。

破の4号機

4号機からエンゲージメントを取り入れ、表示にフィルタリングをかけてノード数(表示するユーザ数)を減らす考え方をとりました。
取得範囲は参号機と変わらずです。
これで相関図は改善しましたが、取得時間が大幅に増える問題が生じました。
フォローのフォローだけでも時間がかかるのに、その全員に対してエンゲージメント計算のためのポスト取得を行うためです。
ノードを絞ってるので先代と比べると大した図も出ないのに、時間がかかるのはあかんと思い没としました。

Qの仮説伍号機

仮設伍号機は、4号機の弱点を補完するためにフォロー(フォローのフォローまでたどらない)とフォロワーのポストからエンゲージメントを算出する方式としました。
これで取得時間は改善し、大きな問題はほぼ消えました。
ただ、ここで改めてコンセプトに立ち返って思ったのは、取得時間を妥協して範囲をフォロー・フォロワーにしぼって、本当に新しいつながりや面白みが生まれるのか?ということです。

困ってた時、Twitterの同系統の相関図生成アプリ(実装不明)の情報を見つけました。
そこでは自分のリプライ先といいね先から相関図を作ってるようでした。そう、採用した方式です。
確かに、過去に自分がインタラクトした相手にしぼって相関図が出てくれば納得感はあるし、フォロー・フォロワー外とも自然とつながる機会が生まれるかもと思いました。

そしてMark-VIへ…

こうして現在のMark-VIが生まれたってわけ。

感想など

描画ライブラリの選定

当初は昔使っていたD3.jsを使おうとしました。
しかし自由度が高い分使い方が難しく、キャッチアップまでのコストを考慮しCytoscapeに切り替えました。
結果的には変えてよかったです。
Cytoscapeはドキュメントがざっくりなところもありますが、非常に扱いやすくおすすめです。

Bluesky APIの仕様がふわふわ

ずっとBluesky開発に携わっている方々には当たり前かもしれないのですが、新参者には見たままでは分からない仕様がいくつかあります。
例えば@atproto/apiのgetActorsLike()のAPIがあるのですが、

  • なぜかnpmのAPI一覧には記載がない(サポート外?って思っちゃう)

  • 仕様には認証不要と書いてあるが、実際には認証が必要

  • 仕様には特に何も書いていないが、実際には認証した本人のいいねしか取れない

などハマりどころがあります。
しかもgetActorsLike()ではなく、ライブラリ未実装APIのlistRecords()を自前で実装する※と、認証なしで他人のいいねも取れます。
…なんでやねん!
※blueskyerには実装してまっせ!

このように、新サービスのためかふわっとしてる仕様は随所にあるうえ、ググっても見つからないので大変でした。
こうして記事を残すことで、後進の参入者の助けになれば幸いです。
(もっとも、今後仕様が大きく変わる可能性は大いにありますが)

ChatGPTの強力なサポート

前から相棒として使っていましたが、今回はより一層サポートしてくれました。

まずアルゴリズム系では、これまでの自分の開発と同様に、自分がメインルーチンを担当してAIに細かいサブ関数(引数をソートしたりとかフィルターしたりとか)を作らせました。
サブ関数の実装ってあまり自分はときめきを感じないので、モチベーション面でもプラスですし、開発速度が純粋に上がります。

また今回特にデザイン系で強みを実感しました。
自分はCSSに疎いのですが「こんな感じでお願い」「なんか違うんだよなあ」「やっぱここをこう修正して」という(クソみたいな)指示でCSSやクライアントサイドJSをどんどん実装してくれます。
人に聞くのだとそもそも質問するのが億劫だし、仕様変更ってお互い悲劇ですが、AIなら何でも健気に答えてくれます。
回答がおかしかったり堂々巡りになったりすることもあるのですが、そんな時はおかしくなったチャットでAIが指示してきた実装を、新規チャットに貼って改めて仕様を列挙して指示を仰ぐと大体解決しました。
AIは人類の最高の相棒。

おわりに

楽しいけど、ぶるすこ開発中毒止まんねえ!!
過集中癖があるので正直やばいです。

アプリ、記事のご意見ご感想はコメント欄かすいばりまで!
いいねは最高の励みになります!

「そんなねぼけた集中が通用するか! 過集中はこうやるんだー!!(無事不眠と中途覚醒し、死亡)」