1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

プログラミング初心者が超高機能なX検索ツールを作って、爆速デプロイ&公開してみた

1
Posted at

Xの検索、使いにくくないですか?

たとえば、

  • 特定の人の投稿だけ見たい
  • 2025年以降の投稿だけ探したい
  • 100いいね以上の投稿に絞りたい
  • リポストや返信は除外したい
  • 画像付きの投稿だけ見たい

こういう検索は、実はXの検索コマンドを使えばできます。

たとえばこんな感じです。

Qiita from:username since:2025-01-01 min_faves:100 -filter:replies -is:retweet

強い。

めちゃくちゃ強い。

でも、毎回これを手で書くのは普通に面倒です。

コマンドを覚えていないと使えないし、日付の書き方やスペースの位置を間違えるとうまく検索できない。

そこで思いました。

「これ、全部フォームで選ぶだけにしたらよくない?」

というわけで作ったのが、X検索クエリ作成ツール「PostSift」です。

スクリーンショット 2026-07-04 20.34.37.png

作ったもの

PostSiftは、Xの高度な検索条件を画面から選ぶだけで、検索クエリを自動生成してくれるツールです。

できることはかなり多いです。

  • キーワード検索
  • 完全一致検索
  • OR検索
  • 除外キーワード
  • 特定アカウントの投稿
  • 特定アカウント宛ての投稿
  • 開始日・終了日指定
  • 最低いいね数
  • 最低リポスト数
  • 最低返信数
  • 言語指定
  • 画像付きのみ
  • 動画付きのみ
  • リンク付きのみ
  • 返信を除外
  • リポストを除外

たとえば画面上で、

キーワード:Qiita
投稿者:test
最低いいね数:100
画像付きのみ:ON
返信を除外:ON

のように指定すると、

Qiita from:test min_faves:100 filter:images -filter:replies

のような検索クエリを自動で作ります。

あとはボタンを押すだけ。

Xの検索画面が開きます。

正直、自分で使いたくて作ったのですが、完成してみると想像していた以上に便利でした。

ちなみに、僕はプログラミング初心者です

ここが今回いちばん書きたかったところです。

自分は、最初からWebアプリの設計が全部頭に入っていたわけではありません。

むしろ、

「この処理はどのファイルに書けばいいのか」

「フォームの値ってどうやって取るのか」

「ブラウザに履歴を保存するには何を使うのか」

「APIってどう作るのか」

そんなところから一つずつ調べながら作りました。

でも、作っていて気づいたことがあります。

プログラミング初心者でも、“作りたいもの”が具体的なら、思っているよりかなり遠くまで行けます。

今回、自分が作りたかったものは最初から明確でした。

「Xの面倒な検索コマンドを、誰でも使える画面にしたい」

これだけです。

最初から巨大なサービスを作ろうとすると何から手を付ければいいか分かりません。

でも、

「キーワードを入力する」

「検索クエリを作る」

「Xを開く」

というように小さく分けていくと、急に現実的になります。

最初に作ったのは、本当にただの検索フォーム

最初から全部の機能を作ったわけではありません。

まず必要だったのは、

  1. 入力欄を作る
  2. 入力された値を取得する
  3. Xの検索クエリに変換する
  4. 検索ページを開く

この4つだけでした。

仕組み自体はシンプルです。

ユーザーが入力した値を取得して、

getInputValues()

検索クエリに変換して、

buildQuery()

完成した検索URLを開く。

基本はこれです。

ただ、作り始めると欲が出ます。

「除外キーワードも欲しい」

「日付指定も欲しい」

「検索履歴も残したい」

「よく使う検索をテンプレートにしたい」

「作った検索条件を共有できたら便利では?」

こうして機能がどんどん増えていきました。

検索クエリ生成は、見た目以上に奥が深かった

今回の中核は、Xの検索クエリを組み立てる処理です。

たとえば普通のキーワードなら、そのまま追加できます。

自動車

完全一致なら引用符で囲みます。

"自動車"

OR検索なら、

(日産 OR トヨタ OR ホンダ)

除外ワードなら、

-広告

投稿者を絞るなら、

from:username

こうした条件を、入力された内容に応じて正しい順序で組み立てていきます。

ただ文字をつなげればいいわけではありません。

空欄は無視する。

数字としておかしい値は入れない。

アカウント名の先頭に @ があっても正しく処理する。

日付形式も確認する。

こういう細かい処理を入れないと、すぐに壊れます。

特に日付指定は少しハマりました。

Xの until: は、指定した日そのものを含める感覚で使うとズレます。

そのためPostSiftでは、終了日に指定された日の翌日を until: に渡すようにしています。

たとえば7月4日まで検索したい場合は、

until:2026-07-05

を生成します。

こういう細かい部分は、実際に作って動かして初めて気づきました。

検索履歴もブラウザに保存した

毎回同じ条件を入力するのも面倒なので、検索履歴も付けました。

保存には localStorage を使っています。

サーバーに送らなくても、ブラウザ側だけでデータを保存できます。

履歴には、

  • 実際に生成した検索クエリ
  • 入力フォームの状態
  • 検索した日時

などを保存しています。

最大50件まで。

同じ検索をもう一度使った場合は、重複して増やすのではなく、最新の履歴として先頭に移動します。

最初は、

「履歴なんてクエリ文字列だけ保存すればいい」

と思っていました。

でも、それだと検索条件をフォームに復元できません。

そこで、完成したクエリだけではなく、フォームの状態そのものも保存するようにしました。

この変更で、一気に使いやすくなりました。

さらに「みんなの検索レシピ」機能まで作った

ここから少し話が大きくなります。

自分で作った検索条件を、自分だけで使うのではなく公開できたら面白いと思いました。

そこで「みんなのレシピ」という機能を追加しました。

誰かが作った検索クエリを公開すると、他のユーザーもその検索条件を使えます。

たとえば、

  • バズったAI投稿を探す
  • 特定ジャンルの画像投稿を探す
  • 海外の最新情報だけ探す
  • 特定アカウントの人気投稿を見る

といった検索条件を共有できます。

ここで初めて、フロントエンドだけでは終わらなくなりました。

公開された検索条件を保存する場所が必要です。

そこで使ったのが、

  • Cloudflare Pages
  • Pages Functions
  • D1

です。

フロントは普通のHTML、CSS、JavaScript。

公開レシピの取得や投稿だけ、Pages Functions経由で処理します。

データはD1に保存します。

構成としては、

ブラウザ
↓
Pages Functions
↓
D1

という形です。

初めて見ると難しそうですが、役割を分けると意外と理解しやすかったです。

ブラウザは画面担当。

FunctionsはAPI担当。

D1はデータ保存担当。

これだけです。

不正投稿対策にTurnstileも入れた

公開機能を作ると、誰でもAPIにPOSTできる状態になります。

さすがにそのままは怖い。

そこでCloudflare Turnstileを入れました。

公開ボタンを押すと、

  1. Turnstileのトークンを取得
  2. サーバー側で検証
  3. 問題なければD1へ保存

という流れです。

検索クエリ側にも制限を付けています。

  • 長すぎるクエリは拒否
  • 短すぎるクエリも拒否
  • 制御文字は拒否
  • 対応していない言語コードは拒否

同じ検索クエリは重複登録されないようにもしています。

初心者の自分にとって、

「動けば完成」

から、

「公開しても壊れにくい状態にする」

という考え方に変わったのは、このあたりからでした。

作って終わりではなく、テストも書いた

機能が増えると、1か所直しただけで別の場所が壊れます。

これは本当に起きます。

そこで、検索クエリ生成部分を中心にテストを書きました。

実際に、

  • クエリ生成
  • 公開レシピAPI
  • 検索履歴
  • モジュール読み込み

をテストしています。

現時点では、

query tests passed
recipes tests passed
history tests passed
imports tests passed

という状態です。

最初はテストに対して、

「その時間で機能を作ったほうが早くない?」

と思っていました。

でも機能が増えてくると逆でした。

テストがあるほうが圧倒的に速いです。

特に検索クエリのような、入力パターンが多い処理では効果が大きい。

仕様を変えたあとにテストを実行すれば、どこかを壊していないかすぐに分かります。

これはかなり大きな学びでした。

デプロイは想像以上に速かった

Webアプリを作る前は、

「公開って大変そう」

と思っていました。

サーバーを借りて、

何かをインストールして、

難しい設定をして、

というイメージです。

でも今回の構成はかなりシンプルでした。

PostSift本体は静的なSPAです。

そこにCloudflare Pages FunctionsとD1を組み合わせています。

そのため、公開までの流れがかなり軽い。

ローカルで動かす。

テストする。

デプロイする。

公開。

昔の自分が想像していた「Webサービスを世の中に出す」という作業より、はるかに速かったです。

初心者だからこそ、インフラを複雑にしなかったのは正解でした。

いちばん大きかったのは、「自分でも公開まで行ける」と分かったこと

今回の開発で作れたものは、もちろん完璧ではありません。

UIも改善できる。

機能もまだ増やせる。

コードも、もっときれいにできると思います。

でも、それ以上に大きかったのは、

「初心者でも、自分が本当に欲しいものを形にして、他の人が使える場所まで持っていける」

と分かったことです。

プログラミングを始めたばかりのころは、完成しているサービスを見るたびに、

「こんなの自分には作れない」

と思っていました。

でも完成しているサービスも、分解すれば小さな処理の集まりです。

入力する。

変換する。

保存する。

表示する。

送信する。

結局は、それを一つずつ作ってつないでいく。

PostSiftも同じでした。

最初から「高機能なX検索ツール」を作れたわけではありません。

ただの検索フォームから始めて、一つずつ機能を追加しました。

気づけば、

検索クエリ生成。

履歴。

テンプレート。

共有URL。

公開レシピ。

API。

データベース。

Bot対策。

テスト。

そしてデプロイ。

ここまで来ていました。

これからプログラミングを始める人へ

最初の作品で、すごいサービスを作る必要はないと思います。

むしろおすすめなのは、

自分が普段「面倒だな」と感じていることを一つ消すことです。

毎回同じ作業をしている。

既存サービスが微妙に使いにくい。

手作業でやっていることがある。

そこには、かなり高い確率でアプリの種があります。

自分の場合は、

「Xの検索コマンドを毎回手で書くのが面倒」

でした。

たったそれだけです。

でも、その小さな不満をちゃんと掘っていくと、一つのWebアプリになりました。

プログラミング初心者でも、作れます。

少なくとも、自分は作れました。

次はまた、自分が「これ面倒だな」と思ったものを潰しにいきます。

たぶん、個人開発ってそういうところから始めるのが一番面白いです。

1
2
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
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?