
お疲れ様です、ナッシーです。こちらの記事は後編になります。
前編記事では、AIを利用してChrome拡張機能を作る基本的な流れや、
拡張機能の構造についてお話しました。
今回はその続きとして実際に拡張機能を作ってみた記録になります。
INDEX
おさらい
AIを利用することで、プログラミングが全く分からない状態でもChrome拡張機能を作れるようになりました。
とはいえ、いきなり実務ツールを作るのはハードルが高いです。
そこで今回は、経験値を稼ぐために実際に拡張機能を作ってみる回になります。
いきなり実務ツールを作るのは少し怖いので、まずは遊び半分の拡張機能を3つ作ってみることにしました。
今回作るもの
- その1:ボタンを押すと、精霊馬が画面を横切る拡張機能
→ 右から左へ、トコトコ走り抜けます。 - その2:ポモドーロタイマー(通知付き)
→ ポップアップ内でタイマーを回し、時間が来たら通知を出します。 - その3:ダイエット向け昼ごはん診断
→ 「はい/いいえ」で答えていくと、今日の昼ごはん候補を提案してくれます。
その1:精霊馬おみくじを作ってみた
まずは、ボタンが出る → 押すと何かが起こるという、とてもシンプルな拡張機能から作ってみることにしました。
最初のイメージは、準備した画像ファイルがWebページ上を横切るだけの簡単なものでした。
しかし、せっかく作るならもう少し面白い要素を入れてみたいと思いました。
そこでAIに相談したところ、次のような案を出してくれました。
AIから出てきた案
- 走る位置を選べる(上 / 中 / 下 / ランダム)
- 走る向きがランダム(右→左 or 左→右)
- 速度やサイズをランダムにする
- 走りながらセリフを表示する
- クリックすると反応する
- 特定サイトでは表示しない
- キーボードショートカットで発動
- 1日1回だけ出る
- ポモドーロと連動する
思った以上にいろいろな案を出してくれました。
そこから仕様を整理し、最終的に「ボタンを押すと走る精霊馬おみくじ」という形に落ち着きました。
最終仕様
- ボタンを押すと画面上を右から左へ精霊馬が走る
- 走りながら運勢とラッキーアイテムを表示(ランダム)
- ラッキーアイテムは自宅から会社の間で触れられるもの
- 走っている途中でクリックすると「!?」と驚いて飛び跳ねる
この内容で、AIに拡張機能の指示書を生成してもらいました。
以下の仕様でChrome拡張機能を作成してください。
## 目的
ポップアップのボタンを押すと、アクティブタブ上で精霊馬(画像)が右から左へトコトコ走り抜ける。
追加要素として「おみくじ(運勢+ラッキーアイテム)」と「クリック反応(!?+上下ピョン)」を実装する。
---
## 前提
- Manifest V3
- アイコン画像指定なし(manifest.jsonでicons不要)
- 精霊馬画像は拡張機能フォルダに `seireiuma.png` として同梱(透過PNG推奨)
- ポップアップから実行
- 連打しても1匹だけ(既にいる場合は新規生成しない)
---
## UI(popup)
- ボタン1つ:「精霊馬おみくじ」
---
## 基本動作(走る)
- 画面右外から左外まで移動(translateX)
- 移動時間:2.5秒程度
- サイズ:高さ80px(比率維持)
- 位置:画面下部(下から20px程度)
- z-indexは高め(常に最前面)
- 終了後、DOMから削除
---
## 追加機能1:おみくじ(運勢+ラッキーアイテム)
### 運勢(配列からランダム)
- 大吉
- 中吉
- 小吉
- 吉
- 末吉
- 凶
- 大凶
### ラッキーアイテム(配列からランダム)
【既存+ナッシー色追加版】
- ゆで卵
- 無糖ヨーグルト
- ブラックコーヒー
- サラダチキン
- 炭酸水
- おにぎり
- 味噌汁
- バナナ
- ナッツ
- そば
- みかん
- チョコ(2粒まで)
- ふせん
- 充電ケーブル
- ふわふわタオル
追加30:
- 無糖カフェラテ
- 素焼きナッツ
- 高カカオチョコ(2粒まで)
- サラダパック
- 温かい緑茶
- 炭酸水(強め)
- プロテインバー
- ゆで卵(黄身まで)
- 低脂肪ヨーグルト
- バナナ半分
- カラーピッカー
- きれいな余白
- 整ったガイドライン
- ショートカットキー
- Ctrl+Z
- Figmaのオートレイアウト
- ぴったり揃ったpx
- 透過PNG
- コンポーネント化
- ダークモード
- 改札スムーズ通過
- エレベーター直通
- 空いてる席
- 静かな朝の時間
- ウォーターサーバーの冷水
- 充電100%
- イヤホン両耳成功
- 社内Wi-Fi安定
- 今日のToDo整理
- 5分のストレッチ
### 表示形式
吹き出しで表示:
例:
運勢:大吉
ラッキーアイテム:Ctrl+Z
- 吹き出しは馬の上に表示
- 約1.6秒でフェードアウト
- 馬は走り続ける
- 画面端ではみ出さないよう位置調整する
---
## 追加機能2:クリック反応(!?+上下ピョン)
- 精霊馬はクリック可能
- クリック時:
- 頭上に「!?」を0.6秒表示
- 馬が上下に8px程度ピョンと跳ねるアニメーション
- 連打対策として0.5秒のクールダウンを入れる
---
## 実装条件
- DOM要素には固定ID(例:seireiuma-runner)を付ける
- 既に存在する場合は新規生成しない(1匹ルール)
- 終了時は確実にDOMから削除
- CSSはcontent.js内でstyleタグを生成して注入する
- クリック反応は子要素で管理する
---
## ファイル構成
- manifest.json(MV3)
- popup.html
- popup.js
- content.js
- seireiuma.png
---
## 出力形式
各ファイルを以下の形式で分けて出力してください:
### manifest.json
````json
...
その後、Claudeでコードを生成し、必要な画像を準備して実装。
しかし、すぐにはきちんと動きませんでした。
すぐには動かない
- ボタンを押しても何も動かない
- 走る速度が速すぎておみくじが読めない
- デザインが微妙
などの不具合や改善点が出てきます。
その都度、日本語で指摘するとAIが修正点を見つけて改善してくれました。
修正 → テスト → 修正を繰り返し…ついに完成。
上部のボタンを押すと…

右から左に動きながら運勢を出してくれます!

今回作った3つの拡張機能の中で、実は一番修正が多かったのがこの精霊馬でした。
「画像を横切らせるだけだから簡単そう」と思っていたのですが、
- 走る速度の調整
- クリック時の挙動
- Mac環境での表示速度問題
など、細かい挙動の調整が意外と多く、最終的に一番手を入れた拡張機能になりました。
特に社内で試してもらった際には、

『Mac環境だと馬が爆速で走っていきますね…』
という指摘が。
AIに調査してもらったところ、Retinaディスプレイのpx倍率が原因でした。
移動距離と時間の考え方は以下のとおりです。
- 移動距離 = 画面幅(window.innerWidth)+ 馬の幅×2
- 所要時間 = 移動距離 × 7ms/px(この定数が「体感速度」)
修正後、Macでもゆっくり走ってくれる精霊馬が完成しました。
※ちなみにこの指摘をして頂いたメンバーの方は、この原因も検証前に当てていらっしゃいました。スゴイ!

その2:ポモドーロタイマー(通知付き)を作ってみた
次は、実務でも使えそうなタイマーを作ってみることにしました。
- ポモドーロタイマーとは
25分だけ集中して、5分休みます。これを繰り返すだけのシンプルな集中術です。
「とりあえず25分だけやるか」と思えるので、やる気が出ないときにも効果的です。
入れたい機能
- 作業 / 休憩タイマー(時間変更可)
- 通知(終了時にトースト通知)
- 何セット目か表示(1/4)
- 4セット後は長め休憩(例:15分、これも変更可)
- パステルで今っぽいUI(popup内CSS)
- アイコンに残り時間表示(バッジ)
バッジは色でモード分けにしました。
- 作業:紫
- 休憩:ミント
- 長休憩:ピンク
- ※表示は数字だけ
この内容を元に指示書を作成し、AIにコードを生成してもらいました。
以下の仕様でChrome拡張機能(Manifest V3)を作成してください。
# 目的
ポモドーロタイマー拡張を作る。
- 作業と休憩を繰り返す
- 終了時に通知(OS/Chromeのトースト通知)を出す
- アイコンバッジに残り時間を表示する
- 現在のセット数(1/4など)を表示し、4セット後は長め休憩にする
- popupの見た目は今っぽいパステルカラーでおしゃれにする
# 仕様
## モード
- work(作業)
- break(短い休憩)
- long_break(長い休憩:4セット終了後)
## デフォルト時間(変更可能)
- 作業:25分
- 短い休憩:5分
- 長い休憩:15分
※popupで分単位の入力欄(number)で変更可能にする
## ルール(セット管理)
- work が終了したら break に切り替える
- work を4回完了したら long_break に切り替える
- long_break が終了したらセット数をリセットして work に戻る
- popupに「現在:◯セット目(1/4)」を表示する
- work中は「作業:2/4」など
- break/long_break中も「休憩(次は作業 2/4)」など、分かる文言にする
## UI(popup)
- 現在モード表示(作業/休憩/長め休憩)
- 残り時間(mm:ss)
- 現在のセット数表示(例:2/4)
- ボタン:
- 開始 / 一時停止(トグル)
- リセット(現在モードを初期時間に戻す。基本は作業に戻してOK)
- (任意)スキップ(次モードへ)
- 設定:
- 作業時間(分)
- 休憩時間(分)
- 長め休憩時間(分)
- 保存ボタン(保存したら次回以降も保持)
## 通知
- work終了:タイトル「作業終了」本文「休憩しましょう」
- break終了:タイトル「休憩終了」本文「作業に戻りましょう」
- long_break終了:タイトル「長め休憩終了」本文「次の1セットいきましょう」
- chrome.notifications を使用(トースト表示)
## バッジ表示(拡張機能アイコン)
- 残り時間の「分」だけを表示(例:残り24分なら "24")
- 1分未満は "1" と表示(0は見づらいので避ける)
- バッジ色はパステル系(例:淡い紫など)※指定してよい
- バッジ更新は、開始中は定期的に更新する
- 1秒ごとは不要。10秒ごとや30秒ごとでOK
- popupを開いていなくても更新されるようにする
## タイマー実装方針(重要)
- service worker(background.js)がタイマー状態を管理
- 「終了予定時刻 endAt(Unix ms)」を保存し、現在時刻との差分で残り秒を計算する
- chrome.alarms を使って
- 終了通知用のアラーム(endAtに合わせる)
- バッジ更新用のアラーム(10秒または30秒周期)
を実装する
- popupを閉じてもタイマーが継続すること
## ストレージ(chrome.storage.local)
保存する値例:
- settings:
- workMinutes
- breakMinutes
- longBreakMinutes
- state:
- mode: "work" | "break" | "long_break"
- isRunning: boolean
- endAt: number | null
- remainingSecondsWhenPaused: number | null
- completedPomodoros: number(0〜4のカウント。work完了で+1、long_break終了で0に戻す)
## メッセージ連携
- popup.js から background.js に開始/停止/リセット/設定保存を送る(chrome.runtime.sendMessage)
- background.js は状態を更新し、popup側は必要なら状態を取得して描画する
## 必要権限
- storage
- alarms
- notifications
## ファイル構成
- manifest.json
- popup.html
- popup.css(またはpopup.html内styleでも可)
- popup.js
- background.js(service worker)
- (任意)images/icon16.png icon48.png icon128.png(時計アイコン等)
## 出力形式
各ファイルをファイル名見出し+コードブロックで分けて出力してください。
例:
### manifest.json
```json
...
その結果できあがったものがこちらです。

設定が保存できないバグ
機能面はほぼ問題なしでした。
ただ一点だけ、タイマーの分数を変更するときに入力文字が保存される前に上書きされてしまう不具合がありました。
原因は1秒ごとの画面更新処理(setInterval)が、設定欄の入力値まで上書きしていたためです。
そこで「設定欄を編集中かどうか」を判定し、編集中なら更新をスキップするように修正しました。

なるほど!(全部は分かっていない)
このへんの原因究明と解決もClaudeにやってもらいました。
その後、デザインを整えて完成。

その3:ダイエット向け昼ごはん診断を作ってみた
最後は「はい」「いいえ」で答える診断アプリを作ってみました。
質問内容や回答ロジックも含めて、AIに生成してもらいます。
スコア方式で判定する仕組み
昼ごはん診断は、単純な分岐ではなくスコア方式で判定しています。
「お腹が空いているか」「朝ごはんを食べたか」「運動予定があるか」などの回答に応じて、各メニューに設定された点数を加算していきます。
最終的に最もスコアが高いメニューを候補として選ぶ仕組みです。
分岐を無限に作るのではなく、条件に重みをつけることで柔軟に判定できるようにしました。
※計算ロジックはAIが作ってくれました。
選択肢を選ぶと…

内容に合ったお昼ご飯を提案してくれます!

偏り問題とランダム補正
しかし問題がありました。

診断のはずなのに、3日連続サラダチキンが出る…
同じ回答をすると、毎回ほぼ同じメニューが選ばれてしまうのです。
診断なのに結果が固定化してしまうと面白くありません。
そこで、
- 最高スコアが複数あった場合はランダム選択
- 全体スコアが低い場合は完全ランダム
という補正を追加しました。
これにより、納得感とランダム性のバランスを取ることができました。
最終的にサラダチキン以外も食べられるようになりました。

設計 → 修正 → 検証 のループ
今回の制作で何度も繰り返したのが、このループです。
- 仕様を書く(設計)
- 実装してみる
- 動かない / 思った挙動と違う
- 原因を整理する
- 修正して再検証する
精霊馬がMacで爆速になったときも、ポモドーロの入力欄が上書きされたときも、すべてこのループで解決しました。
一発で完成することはありませんでしたが、小さく作って、直して、また試すを繰り返すことで理解が深まっていきました。
まとめ
Chrome拡張機能は、思っていたより気軽に作れます。
AIを使えば、アイデアをすぐ形にでき、プログラミングが分からなくても小さなツールを作ることができます。
次はもう少し実務寄りの拡張機能にも挑戦してみたいと思います。
