[{"data":1,"prerenderedAt":240},["ShallowReactive",2],{"content-/chrome-extension-ux-and-download-path":3,"all-pages-for-dir":218,"related-/chrome-extension-ux-and-download-path":219,"og-image-/chrome-extension-ux-and-download-path":239},{"id":4,"title":5,"body":6,"category":198,"concepts":199,"description":200,"extension":201,"meta":202,"navigation":203,"ogImage":199,"path":204,"project_name":205,"published":206,"publishedAt":207,"seo":208,"source":209,"stem":210,"tags":211,"todo":199,"unpublished":206,"updatedAt":199,"__hash__":217},"pages/2026-09/2026-09-03/chrome-extension-ux-and-download-path.md","自作 Chrome 拡張の使い勝手を詰める：未入力件数のバッジと、動画の保存先が違っていた話",{"type":7,"value":8,"toc":186},"minimark",[9,13,16,19,23,26,29,32,35,43,46,49,52,59,62,65,68,71,82,85,88,95,98,101,108,115,126,129,132,135,138,141,144,147,150,153,156,159,162,183],[10,11,12],"p",{},"明細190件が、15種にまとまった。",[10,14,15],{},"会計ソフトAの取引一覧に載せている自作拡張へ、明細の内容サマリを作らせた結果だ。\n表示中の明細を内容ごとに集計して件数と金額を並べ、テーブルごと TSV でコピーできる。\nあるカードの明細で試すと、内容のまとめをONにして15種、そのままなら24種になった。\n190行を目で追う代わりに、15行を見ればいい。",[10,17,18],{},"なかでも効いたのは、未入力の件数がその場に出ることだった。",[20,21,22],"h2",{"id":22},"入力ステータスと勘定科目の列",[10,24,25],{},"続けて、「未入力」列を「入力ステータス / 勘定科目」に置き換えてもらった。\n入力済みの明細は、仕訳の借方科目で数える。\n1つの内容に複数の科目を使っていれば、その数だけ行が増える。\n内容、件数、合計金額、内訳は rowspan で縦につながるようにさせた。",[10,27,28],{},"できたものを画面で見ていたら、注文が2つ出てきた。\n1つは、サマリの上部がまだ空いていることだった。\nせっかく領域があるのに、何も置いていない。\nもう1つはバッジだった。",[20,30,31],{"id":31},"連携サービスの角に出す未入力件数",[10,33,34],{},"連携サービスの一覧には、口座ごとのカードが並ぶ。\nそのカードの右上の角に小さい丸を1つ載せて、未入力の件数を数字だけ入れてほしい。\nどの口座に何件残っているかを、一覧のまま知りたかった。",[10,36,37,38,42],{},"気にしたのは取得コストだった。\n連携サービス別の未入力件数を数えるのに、口座の数だけリクエストを投げるようだと重い。\n調べさせたら、1リクエストで全部取れることが分かった。\nある口座で1件と出て、画面の実数とも一致した。\n注文は2つとも入り、その場でコミットとプッシュまで済ませた（",[39,40,41],"code",{},"63dbfa6","）。",[20,44,45],{"id":45},"並び替えの優先順位",[10,47,48],{},"前日に入れてもらった機能で、1つ直してほしいところがあった。",[10,50,51],{},"この一覧は、ステータス（入力済み／未入力）でも日付でも並び替えられる。\nステータスで未入力に並べ替えてから、日付でもう一度並べ替える。\nこのとき第1キーになるのは、最後に押した日付のはずだ。\n表計算ソフトならそう動く。",[10,53,54,55,58],{},"直させたら、最後にクリックした列が第1キーになり、もう一方は同値のときの第2キーとして残る形になった（",[39,56,57],{},"d292ede","）。\nある口座の115件（うち未入力1件）で確かめた。\n直すたびに chrome-extension-reload で拡張を読み直させ、実機で見て確かめている。",[10,60,61],{},"セッションの残りを聞くと、4点挙がってきた。\n一番効くのは、拡張をリロードしても開きっぱなしのタブが古いまま動く点だ。\nページを1回読み直さないと反映されない。\n残りもまとめてコミットとプッシュをさせた。\n学習ゲートはスキップでいい。",[20,63,64],{"id":64},"効かないダウンロードボタン",[10,66,67],{},"昼、動画の再生ページで「ダウンロード」ボタンを押した。\n何も起きない。\n自分でセットしたボタンなのに、どの拡張がそれを出しているのかも思い出せなくなっていた。\nライブラリの更新でどこかが噛み合わなくなったのだろう、というのが最初の見立てだった。",[10,69,70],{},"この拡張は、動画のページにボタンを1つ足すだけのものだ。\n押すと Native Messaging でローカルのホストを叩き、yt-dlp が落としてくる。\nX 向けに作ったものを、YouTube にも広げてあった。",[10,72,73,74,77,78,81],{},"調べさせると、まず設定ファイルを生成しているバッチの JSON エスケープが壊れていた。\n",[39,75,76],{},"\\U"," や ",[39,79,80],{},"\\n"," が不正なエスケープになる。\n文字列置換をやめて Python で書き出す形に直させた。",[10,83,84],{},"続いて本命が出た。\nyt-dlp が 2026.01.31 のままで、YouTube 側の仕様変更に対して HTTP 403 を返していた。",[10,86,87],{},"ここで、見立てが1つ外れていたことも分かった。\nX 用と YouTube 用で別々の yt-dlp が入っていると思っていたが、実際は1本しかない。\nどちらの拡張も同じバイナリを呼んでいて、両方が古いままだった。\nX が動いていたのは、X の配信方式が変わっていなかったからだ。\nYouTube 側だけが SABR-only streaming の実験を進めた結果、同じバイナリが YouTube でだけ 403 を返していた。\n2026.08.19 に更新したので、X 拡張のほうも同時に新しくなった。",[10,89,90,91,94],{},"更新したあとに、もう1つ落とし穴が出た。\n",[39,92,93],{},"--trim-filenames"," は名前のとおりファイル名を切るのだと思っていたら、出力パス全体を切る。\nそのままでは、意図しない場所に保存される。\nここも直させた。",[10,96,97],{},"それでも、ボタンからはまだ落とせていない、という報告が返ってきた。",[20,99,100],{"id":100},"秘密鍵の警告",[10,102,103,104,107],{},"拡張の一覧に出ていた警告も、このとき気になって聞いた。\n拡張のフォルダに ",[39,105,106],{},"extension_private_key.pem"," が入っているが、おそらく必要ない、という文面だ。\nなぜ入っているのかが分からなかった。",[10,109,110,111,114],{},"答えは、警告のほうが正しい、というものだった。\nフォルダ読み込み（unpacked）で使う分には、秘密鍵は要らない。\n鍵が要るのは、",[39,112,113],{},".crx"," にパッケージ化して配布するときだけだ。",[10,116,117,118,121,122,125],{},"作った経緯にも理由はあった。\n拡張のIDはふつうフォルダのパスから決まるので、フォルダを移すとIDが変わる。\nIDが変わると Native Messaging の ",[39,119,120],{},"allowed_origins"," が合わなくなって壊れる。\nそれを避けるためにIDを固定したくて鍵ペアを作り、公開鍵だけを manifest.json の ",[39,123,124],{},"\"key\""," に入れていた。\nIDを決めているのは公開鍵のほうなので、秘密鍵は生成時の副産物として残っていた。",[10,127,128],{},"フォルダごと誰かに渡せば、鍵も一緒に出ていく。\nホーム配下の別ディレクトリへ移させた。\n拡張を読み直せば、警告は消える。",[20,130,131],{"id":131},"トーストに出す保存先のパス",[10,133,134],{},"ダウンロードが終わったあとの表示も注文した。\n「保存しました」とだけ出ても、どこに入ったのか分からない。\nX 拡張のほうでは保存先のフルパスを出しているので、同じものを YouTube 側にも出してほしい。",[10,136,137],{},"ページ内トーストにフルパスを表示し、「フォルダを開く」と「パスをコピー」を付ける形で実装させた。\nこのときは chrome-devtools MCP が落ちていて、描画までは確認できていない、と申告があった。",[10,139,140],{},"コミットの前にログを見せたら、実害のあるバグが1つ見つかり、直させて一緒に上げた。\n同時に、良い知らせも出てきた。\n12:36 に、最初に渡した動画（577MB）が拡張のボタン経由で落ちていた。\nボタンから native host を経て yt-dlp まで、経路は通っていた。",[20,142,143],{"id":143},"見当たらない保存先",[10,145,146],{},"ここで、自分が見ていたものとつながった。",[10,148,149],{},"クラウドドライブのマイドライブを開いても、そのファイルが無い。\n代わりに、C ドライブのダウンロードディレクトリに落ちていた。\n落ちてはいるのに、行き先が違う。",[10,151,152],{},"もう一度自分で実行して確かめることにした。\nマイドライブに入れば、C ドライブに残ったほうを消すだけで済む。\n実行の前に、拡張の再読み込みを押しておくよう念を押された。\n押さないと古い background.js が動いたままで、また同じ場所に落ちる。",[10,154,155],{},"再読み込みして、実行した。\n問題なかった。\n13:21:11 に、クラウドドライブのマイドライブ配下へ 577MB のファイルが保存されていた。\nファイル名にも、投稿者名、タイトル、動画IDが入っている。",[10,157,158],{},"「ライブラリの更新でうまくいっていない」という最初の見立ては、403 の部分では当たっていた。\nただ、最後まで残っていたのは保存先の設定と、拡張を読み直していなかったことだった。",[20,160,161],{"id":161},"学びメモ",[163,164,165,169,174,177,180],"ul",{},[166,167,168],"li",{},"拡張のコードを直しても、開いたままのタブとロード済みの background.js は古いまま動く。拡張の再読み込みとページの読み直しまでが1セット",[166,170,171,173],{},[39,172,93],{}," はファイル名ではなく出力パス全体を切る。意図しない場所に保存される",[166,175,176],{},"unpacked で使う拡張に秘密鍵は要らない。IDを決めているのは manifest の公開鍵で、秘密鍵はフォルダの外へ出す",[166,178,179],{},"「効かない」の原因は1つとは限らなかった。設定ファイルの生成、yt-dlp のバージョン、パスの切り詰め、ログから出たバグと、順に潰して、ようやくボタンから落とせた",[166,181,182],{},"件数を画面に出す機能は、取得コストを先に測ってから作らせる。1リクエストで済むなら、置ける場所はもっとある",[10,184,185],{},"同じ日に、2本とも同じところでつまずいた。\n片方は開きっぱなしのタブ、もう片方は再読み込み前の background.js だ。\nどちらも直したあとに、古いほうがそのまま動いていた。\n読み直しを押し忘れたかどうかを画面から知る手立ては、いまのところ思いつかない。",{"title":187,"searchDepth":188,"depth":188,"links":189},"",2,[190,191,192,193,194,195,196,197],{"id":22,"depth":188,"text":22},{"id":31,"depth":188,"text":31},{"id":45,"depth":188,"text":45},{"id":64,"depth":188,"text":64},{"id":100,"depth":188,"text":100},{"id":131,"depth":188,"text":131},{"id":143,"depth":188,"text":143},{"id":161,"depth":188,"text":161},"dev",null,"会計ソフトAの取引一覧に載せた自作拡張へ未入力件数のバッジと並び替えの優先順位を入れさせ、もう1本の動画ダウンロード拡張では効かないボタンの原因をライブラリの更新から保存先まで順に潰した一日の記録。","md",{},true,"/chrome-extension-ux-and-download-path","misc-dev",false,"2026-09-03T00:00:00.000Z",{"title":5,"description":200},"make-diary","2026-09/2026-09-03/chrome-extension-ux-and-download-path",[212,213,214,215,216],"Chrome拡張","yt-dlp","Native Messaging","UI改善","デバッグ","1QbI-UV4RLLlMkKGiHrLPAC47csOXUBcLH2i7kHSHh4",[],[220,224,228,232,236],{"title":221,"path":222,"publishedAt":223},"会計ソフトの明細一覧を Chrome 拡張で整える：列幅のずれ、全件自動表示、連携サービスの横並び","/accounting-saas-chrome-extension-ui","2026-09-02T00:00:00.000Z",{"title":225,"path":226,"publishedAt":227},"Chrome拡張のクリック領域が行全体に広がるバグと、__pycache__ で拡張が無効化される罠","/chrome-extension-click-area-and-pycache","2026-08-19T00:00:00.000Z",{"title":229,"path":230,"publishedAt":231},"自作Chrome拡張のXの動画ダウンロードボタンが消えた——DOM構造の変化を追って復活させた","/x-video-download-button-fix","2026-07-05T00:00:00.000Z",{"title":233,"path":234,"publishedAt":235},"2026年9月5日の開発日記 - ひと月遅れで届く開示を追う仕組みと、記事1本ごとに走っていた10万字の連鎖","/2026-09-05-diary","2026-09-05T00:00:00.000Z",{"title":237,"path":238,"publishedAt":235},"クラウド会計の帳簿を点検するChrome拡張を自作し、総勘定元帳まで広げた","/accounting-ledger-extension-phase23","https://log.eurekapu.com/og/blog/chrome-extension-ux-and-download-path.png?v=2026-09-03T00%3A00%3A00.000Z&title=%E8%87%AA%E4%BD%9C%20Chrome%20%E6%8B%A1%E5%BC%B5%E3%81%AE%E4%BD%BF%E3%81%84%E5%8B%9D%E6%89%8B%E3%82%92%E8%A9%B0%E3%82%81%E3%82%8B%EF%BC%9A%E6%9C%AA%E5%85%A5%E5%8A%9B%E4%BB%B6%E6%95%B0%E3%81%AE%E3%83%90%E3%83%83%E3%82%B8%E3%81%A8%E3%80%81%E5%8B%95%E7%94%BB%E3%81%AE%E4%BF%9D%E5%AD%98%E5%85%88%E3%81%8C%E9%81%95%E3%81%A3%E3%81%A6%E3%81%84%E3%81%9F%E8%A9%B1&author=Kei%20Komatsu&sig=7d3afeb49537f50d",1788821550875]