嫁ちゃん
わたし
嫁ちゃん
わたし

届くのを待つ時間も、手仕事のプロローグ #
レザークラフトで新しい作品を作ろうと思い立つと、まずは資材の仕入れから始まる。
浅草橋のカワムラレザーさんで頼んだイタリアンレザーの切り革、楽天の「レザークラフトぱれっと」さんで買い足した手縫い糸や真鍮無垢のギボシ、あるいはAmazonで頼んだ消耗品の型紙用方眼紙。 それらの資材が今どこにあって、いつ自宅の工房デスクに届くのか。届くのを待つ数日間は、頭の中で制作工程の段取りを組み立てる、手仕事の大切なプロローグでもある。
世の中には荷物の追跡番号を一括管理してくれるスマートフォンアプリやWebサービスがたくさんある。だが、私はそうした専用アプリをほとんど使わなくなった。
外部のサービスにアカウントを作り、ショップから発送完了メールが届くたびに長いお問い合わせ伝票番号を指先でコピーし、アプリに貼り付けて「これは革資材」とメモを添える。その一連の作業が、どうにも生活のリズムと馴染まないのだ。道具を増やしたせいで、かえって管理の手間という雑念が増えているような気がしてしまう。
私が欲しかったのは、もっと静かで、手触りのある仕組みだった。
資材を注文したら、普段届くメール通知を起点にして、手元の愛用ノートアプリであるObsidianの「宅配受取一覧」に、勝手に小さな荷札ノートが並ぶ。 ヤマト運輸や佐川急便、日本郵便の配送状況を裏でそっと見に行き、「発送済み」「配達中」「お届け完了」とステータスを塗り替えてくれる。そして荷物が手元に届いたら、ノートのチェックボックスをポチッと押すだけで、一覧から静かに消え去る。
そんな「手作りのからくり」を、私はMacの標準メールアプリ(Mail.app)と小さなPythonスクリプト、そしてメニューバー常駐ツールの組み合わせで長年動かしてきた。
MacとObsidianが編み上げる「小さなからくり」 #
このからくりの仕掛けは、驚くほどローカルで泥臭い。
まず、ショップから届く注文確認や発送完了メールを、Mac標準の「メール」アプリの振り分けルールで専用のメールボックス(「AmazonAuto」「カワムラレザーAuto」「ぱれっとAuto」など)へ自動で仕分ける。
そして、メニューバーに常駐させている自作ツール「DoTools」が、設定ファイル(Config.json)に従って 180秒(3分)周期 で静かにPythonスクリプトを呼び出す。
{
"deliveryIntervalSec" : 180,
"scriptName" : "amazon_delivery.py.md",
"title" : "Amazon配送"
}呼び出されたスクリプトは、AppleScriptを通じてMail.appの該当メールボックスを覗き込む。 新着メールを見つけると、件名や本文から注文番号、商品名、伝票番号を正規表現で一本釣りし、各運送会社の追跡ページへ状況を確認しにいく。
ヤマト運輸ならWebページのHTMLから「荷物受付」「発送済み」「持出中」のタイムスタンプを行単位で抜き出し、佐川急便なら文字コードの癖(CP932)をいなしながらステータスを拾い上げる。
そうして手に入れた情報を、Obsidianの保管庫(Vault)の中にある 02_Area/Delivery/DATA/ フォルダへ、1つのMarkdownノートとして書き出すのだ。
---
shop: Amazon
order_id: "123-4567890-1234567"
status: shipped
latest_mail_date: "2026-09-26 14:46"
item_title: "安心の日本企業 USB-C マグネット式 アダプター..."
checked: false
---
[[02_Area/Delivery/宅配受取一覧]]
# Amazon注文 123-4567890-1234567
## 履歴
- 2026-09-26 14:46 | shipped | 定時巡回にてAmazonメールを自動検知(「商品発送完了」の解析)ノートの先頭にYAMLフロントマッターでメタデータを刻んでおけば、あとはObsidianの「Bases」や「Dataview」が、手帳のダッシュボードに美しい荷札カードとしてずらりと並べてくれる。
机の上で革を切ったり縫ったりしている合間に、ふとMacの画面のObsidianを見やると、「持出中(配達中)」という文字が静かに灯っている。 「よし、午前中のうちに小銭入れのコバ磨きを終わらせておこう。昼過ぎには注文していた真鍮ホックが届くはずだ」 そんな風に、デジタルの通知に急かされることなく、自分の手の動きと資材の到着が自然に重なり合う。この静けさがたまらなく気に入っていた。
ある日、メールアプリが倒れていた #
ところが、ここ最近、その平穏なからくりに不穏な影が差し始めた。
妻から「またメールが落ちてるで」と指摘されることが増えたのだ。 ふとDockを見ると、確かに常駐しているはずの「メール」アプリのアイコンの下から、起動中を示す小さな黒い丸が消えている。手動で立ち上げ直せば何事もなかったかのように動くのだが、数時間、あるいは半日ほど経つと、いつの間にか息絶えている。
最初はmacOSの気まぐれかメモリ不足を疑っていた。だが、頻度があまりにも高い。 そこで、システムが吐き出したクラッシュログ(クラッシュレポート)をじっくりと解剖してみることにした。
画面に表示されたスタックトレースの最上部を見て、私は思わず息を呑んだ。
Process: Mail [90560]
Exception Type: EXC_BAD_ACCESS (SIGSEGV)
Exception Subtype: KERN_INVALID_ADDRESS at 0x00000000000001e8
Thread 0 Crashed (Main Thread):
0 libobjc.A.dylib 0x189ee5218 objc_storeWeak + 116
1 WebCore 0x1c65f9500 WebCore::ResourceHandle::clearAuthentication()
2 WebCore 0x1c6a70d70 WebCore::ResourceLoader::cancel()
...
8 UIFoundation 0x193ec5934 -[NSHTMLReader _loadUsingWebKit] + 1372
...
18 Mail 0x1cf6221a0 -[MCMessage(ScriptingSupport) content] + 172クラッシュの直接原因は、EXC_BAD_ACCESS (SIGSEGV)。典型的なセグメンテーション違反、つまりメモリの不正アクセスによる即死である。
そして、その引き金を引いた犯人の足跡が、見事に一本の線となって記録されていた。
-[MCMessage content] ── PythonスクリプトがAppleScriptを通じて「メールの本文をちょうだい(content of m)」と呼び出した瞬間、Mail.appの内部で NSHTMLReader が起動し、巨大なブラウザエンジンである WebKit(WebCore) を呼び出していたのだ。
現代のAmazonなどの配送通知メールは、素朴なテキストメールではない。美しく組まれたレイアウト、商品画像、トラッキング用の透過ピクセル、複雑なCSSやHTMLタグが何重にも折り重なった「巨大なWebページ」そのものである。
Mail.appは律儀にも、AppleScriptから「本文(テキスト)」を求められるたびに、裏で小さなブラウザエンジンをフル稼働させ、HTMLをレンダリングしてプレーンテキストへ変換しようとしていた。
だが、Amazonメールの巨大な構造と外部リソースの読み込みキャンセル処理の最中に、WebKit内部の参照ポインタが狂い、無効なメモリアドレス(0x1e8)を踏み抜いてセグフォを起こしていたのだ。
メールアプリがクラッシュしていたのではない。 「荷札の文字を読みたかっただけなのに、毎回裏でブラウザを立ち上げては、巨大な広告HTMLの荒波に溺れて倒れていた」 のである。
知恵熱を出していた、というのはまさにこのことだった。

メールに中身を読ませるな、生の荷札(source)を渡せ #
原因がここまで綺麗に特定できれば、職人のやるべきことは決まっている。道具の調律だ。
Mail.appがWebKitのせいで倒れるのなら、解決策は極めてシンプルである。
「Mail.appに、危険な本文(content)の展開を二度とやらせない」。
AppleScriptでメールのプロパティを調べ直してみると、Mail.appには content だけでなく、source of m というプロパティが用意されていた。
-- ❌ 従来のコード(WebKitが起動してHTML解析で自爆)
set mailBody to content of m
-- ⭕️ 改善後のコード(身軽な生テキストをそのまま流す)
set mailRawSource to source of mこれは、メールサーバーから届いた未加工の生テキスト(RFC822準拠のMIMEソースコード)をそのまま返すものだ。
試しにPythonから source of m を叩いてみると、一瞬でコンソールにデータが返ってきた。
Mail.appは内部でHTMLのレンダリングなど一切行わない。ディスクにキャッシュしてある生データをそのまま横流しするだけだから、WebKit(NSHTMLReader)は指一本動かさない。CPU負荷もゼロ、クラッシュする危険も原理的に消滅する。
では、その生データからどうやって本文や注文番号を取り出すのか? それは、外側にいる Pythonの仕事 にすればいい。
Pythonの標準ライブラリには、堅牢な email モジュールが最初から備わっている。
Mail.appから受け取った生のMIMEテキストをPythonに渡し、Pythonのプロセスの中で安全にテキストパートをほどく。
import email
from email import policy
# Mail.appには生のsourceだけを吐き出させ、料理はPython側で行う
msg = email.message_from_string(raw_source, policy=policy.default)
body_part = msg.get_body(preferencelist=('plain', 'html'))
body_text = body_part.get_content() if body_part else ""こうすることで、Mail.appは「荷札の生データを手渡すだけ」の身軽な配達員に戻り、重たいパース処理はすべてPythonが引き受ける。 役割を綺麗に切り分けた瞬間、あれほど頻発していたクラッシュの気配が完全に消え去った。
普段は表紙だけをチラ見する「2段階フェッチ」 #
さらに、もう一段の「引き算」を施した。
3分周期で巡回するスクリプトが、毎回律儀に10件分の生ソースをごっそり取得していては、いくら軽量化されたとはいえ無駄な通信が発生する。 荷物が頻繁に届かない時間帯や、新着メールがない平穏な時間帯には、Macのファンを回すことすら野暮というものだ。
そこで、「2段階フェッチ(遅延取得)」 という所作を導入した。
- 第1段階(表紙のスキャン):
まず直近10件について、件名(
subject)とメッセージID(message id)だけをAppleScriptの単一クエリで一括取得する。所要時間はわずか 0.05秒。 - 第2段階(必要なときだけ中身を開く):
Python側でObsidian内のノートと照合し、「すでに同期済みの古いメール」や「処理済みのメール」はすべてその場でスルーする。
そして、「まだObsidianに登録されていない、本当の新着メール」が存在するときだけ、ピンポイントでその1件の生ソース(
source)を取得しにいく。
普段の巡回では、Mail.appは「表紙をパラパラと0.05秒チラ見して通り過ぎる」だけになる。 新着がないときは本文の取得処理すら1件も走らない。 おまけに、ノートの更新内容に実質的な変化がなければObsidianへのファイル上書き保存(ディスクI/O)もスキップするガードを設けた。
Amazon用のスクリプトでこの「2段階フェッチ&生ソース化」の有効性を確認したあと、同じ仕掛けをIKEA、カワムラレザー、楽天ぱれっとの全スクリプトへ水平展開した。
3分ごとに動く4つのからくりが、音もなく、風のようにMacの中を駆け抜けていく。 ターミナルでテストを走らせると、わずか2秒で静かに結果が返ってきた。
→ Mail.appから直近10件のヘッダー情報を安全に高速スキャンしています...
🍃 直近10件の中に新しい未処理の通知はありません。現状を維持します。もちろん、Mail.appは落ちることなく、涼しい顔で裏に佇んでいる。
引き算の調律がもたらす余白 #

デジタルの自動化を組んでいると、ついつい機能を盛り盛りにしたくなる。 高機能な外部APIを契約してみたり、重量級のライブラリを組み込んでみたり、通知音を派手に鳴らしてみたり。
だが、仕組みが複雑になればなるほど、どこかに歪みが生まれ、ある日突然セグフォのような無機質な悲鳴を上げて止まってしまう。 そして、そのトラブルの火消しに追われて、肝心の手仕事や暮らしの時間が奪われていくのでは本末転倒だ。
道具が悲鳴を上げたときは、何かを足すのではなく、「何を引いてやれるか」 を考える。
Mail.appにHTMLを読ませるのをやめる。 必要になるまで中身を開かない。 変わっていないならノートを上書きしない。
過剰な仕事をそっと引き算してやるだけで、Macの小さなメールアプリは再び機嫌を取り戻し、私の工房の片隅で静かに荷札を仕分け続けてくれるようになった。
嫁ちゃん
わたし
嫁ちゃん
わたし
夕方、工房のデスクで革のヘリ落としをしていると、画面のObsidianがチカッと瞬き、荷札のステータスが「配達完了」に切り替わった。 カチャリと玄関のポストが開く音がする。
道具が整っていれば、生活はどこまでも静かだ。 私は作業の手を止め、届いたばかりの革の匂いを確かめに、作業部屋のドアを開けた。