16
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

クソアプリAdvent Calendar 2022

Day 8

平和にTwitterライフを送れるChrome拡張

Last updated at Posted at 2022-12-07

はじめに

こんにちは、@rs_tukkiです。
これはクソアプリ Advent Calendar 2022の8日目の記事です。

去年作ったクソ拡張

推しに貢ぎたいChrome拡張

概要

10/27にイーロン・マスク氏によってTwitter社が買収されたのは記憶に新しいところかと思います。
最近激動続きのTwitterですが、そんな時だからこそツイート検索によって望まない情報が目に入ってしまうことも多いのではないでしょうか。
そこで今回は、Twitter検索によって不快な情報を目に入れることなく、心の平穏を保てるようなChrome拡張を作ってみました。

完成品

まずはこちらをご覧ください。

cw61k-p0h6s.gif

なんと言うことでしょう。
たとえどんなワードで検索しようが、そこに表示されるのは自分のツイートのみ。
これで意図しない検索結果で心をかき乱されることはありません。Twitter万歳。

種明かし

Twitter検索にはいくつかのオプションが付いていて、その中にfrom:Idオプションというのがあります。
これは指定したIDのアカウントによるツイートのみを検索対象とするというオプションです。

本拡張機能は、検索結果に勝手にfrom:自分のIDを付与することで、自分のツイートのみを検索できる拡張機能となっています。

実装

コードはGithubに上げているので、良かったらこちらからどうぞ。

とは言っても、特に凝った実装をしているわけではありません。
まずはコード全体をドン。

script.ts
'use strict';

/**
 * Redirect with from me Param.
 */
const init: (() => void) = function() {
  const newUrl = new URL(location.href);
  if (newUrl.pathname !== '/search') {
    return;
  }

  const myId = getMyId();
  var query = newUrl.searchParams.get('q')?.toString();

  if (query?.includes('from:') || myId === '') {
    return;
  }

  query = query + ` from:${myId}`;
  newUrl.searchParams.set("q", query);
  location.href = newUrl.toString();
};

const getMyId = (): string => {
  const profileLink = document.querySelector('[data-testid="AppTabBar_Profile_Link"]');
  const myId = profileLink?.getAttribute('href')?.substring(1);
  return myId ? myId : '';
};

const mutationObserver = new MutationObserver(init)
const config = {
  childList: true,
  subtree: true
}
mutationObserver.observe(document, config)

内容は至極単純で、「検索ワードにfrom:自分のIDを追加して再検索する」という処理をしています。

URLで処理を分岐させる

script.ts
'use strict';

/**
 * Redirect with from me Param.
 */
const init: (() => void) = function() {
  const newUrl = new URL(location.href);
  if (newUrl.pathname !== '/search') {
    return;
  }

まずは現在のURLを取得する処理です。
本来は最初から検索画面のURLでだけ動作するようにしたかったのですが、検索時に上手く動作してくれなかったので仕方なくTwitterドメイン全体を対象とした上で、
URLパスが/searchでなければ早期returnする形としました。

自分のアカウントのIDを取得する

script.ts
const getMyId = (): string => {
  const profileLink = document.querySelector('[data-testid="AppTabBar_Profile_Link"]');
  const myId = profileLink?.getAttribute('href')?.substring(1);
  return myId ? myId : '';
};

自分のIDはどこから取得するか迷ったのですが、プロフィールボタン(↓)のパスがそのまま/自分のIDを差していたので、ここから取得するのが楽そうです。
スクリーンショット 2022-12-06 233055.png
Id属性も楽に取得できそうなclass属性もなかったので明らかにテスト用の属性値から引っ張ってますがそこはご愛敬。

検索ワードを取得する

script.ts
  const myId = getMyId();
  var query = newUrl.searchParams.get('q')?.toString();

  if (query?.includes('from:') || myId === '') {
    return;
  }

検索ワードはGETパラメータで渡されているので、簡単に取得することができます。
最終的には同じ検索URLにリダイレクトさせることになるため、無限ループを防ぐ目的でパラメータにfrom:句が含まれていればその場で処理を終了させておきます。
また、自分のIDが取れていない場合も意味がないので早期returnしておくようにします。

検索操作を監視してリダイレクトする

script.ts
const mutationObserver = new MutationObserver(init)
const config = {
  childList: true,
  subtree: true
}
mutationObserver.observe(document, config)

こちらも本当は検索画面に遷移した後一度だけ発火するようにしたかったのですが、
単純に実行させるだけだと上手く発火させられなかったため、検索操作の実行画面要素の変更と解釈して無理矢理全体を監視させるようなやり方にしています。
無論無駄に処理が走りまくるのは言わずもがなですが...

この実装によって、任意の言葉で検索した際に自分のツイートのみを抽出してくれるようになります。

本拡張機能のクソな点

  • from:句が付いていない限り勝手に変換し続けるため通常の検索ができない
  • MutationObserverで無駄に監視し続けてしまっている
  • 自分のIDをプロフィールページのパスから取得している
  • TypeScriptなのでコンパイルしないと使えない
  • というかそこまで凝った実装ではないので別にTypeScriptで書く必要もない
  • 過去ツイを漁るのにはちょっと便利かもしれない

本拡張機能を使って適度に自衛をしつつ、快適なTwitterライフをお過ごしください!

あとがき

実は最初は「TwitterからMastodonへ移行するユーザが増えている」みたいなニュースを見たので升と丼ゲームとか作ろうかなとか思ってたんですが時間がなくて諦めたという経緯があります...

来年はもう少し凝ったクソアプリを作りたいなと思う年の瀬でした。

参考

16
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
16
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?