e-Govからメールで通知文書送達のお知らせが来てもそこには何も書いておらず。さらにはアプリを開くまでも面倒だが、電子送達をダウンロードしないといけない。しかもXML拡張子で見るのも一苦労。
そんな面倒作業を自動化。ZIPファイルをダウンロードしたら勝手に解凍させてXMLファイルをPDFにしてしてフォルダに格納させる。
概要
e-Govの公文書zipをダウンロードすると、数秒〜十数秒で G-GOV電子申請フォルダに格納され、公文書本体と送付状がPDF化される。
- e-Govで公文書zip(
16桁の番号_14桁の日時.zip)をダウンロードする(Safariが自動解凍してもOK) - Automatorのフォルダアクションが、ダウンロードフォルダへの追加を検知する
egov2pdf.shが、zipか解凍済みフォルダを保存先(~/Documents/〇〇/G-GOV電子申請/)へ移動し、zipならその場で解凍する- XSL指定のあるXMLを
xsltprocでHTMLに変換し、Google Chromeのヘッドレス印刷でPDFにする - 結果を
_egov2pdf_log.txtに記録する
格納後のフォルダ構成(例)
| ファイル | 中身 |
|---|---|
(16桁)_(14桁).zip | 原本(電子署名付き)。消さない |
(16桁)/(公文書名).pdf | 公文書本体のPDF |
(16桁)/(18桁の数字).pdf | 送付状のPDF |
〜.xml / 〜.xsl / 〜.csv | 元データ。HTMLは変換の中間ファイル |
構成ファイルと場所
動かしている部品は4つ。すべてMac本体にだけ置いてある。
| 部品 | 場所 | 役割 |
|---|---|---|
| スクリプト | ~/bin/egov2pdf.sh | 格納・解凍・PDF化の本体 |
| フォルダアクション | Automatorで保存した「e-Gov公文書PDF化」(対象:ダウンロード) | 追加を検知してスクリプトを起動 |
| ログ | G-GOV電子申請/_egov2pdf_log.txt | 格納・PDF作成・失敗の記録 |
| 権限 | システム設定 → プライバシーとセキュリティ → フルディスクアクセス(またはファイルとフォルダ)の Folder Actions Dispatcher | フォルダアクションから「書類」を読み書きするために必要 |
使っているコマンドは、すべてMac標準かChrome。
ditto:zipの解凍(標準)xsltproc:XML+XSL → HTML(標準、/usr/bin)- Google Chrome:HTML → PDF(
/Applications/Google Chrome.app)
スクリプト全文(~/bin/egov2pdf.sh)
対象は名前が「16桁_14桁」のzipとフォルダだけ。PDFが作成済みのXMLはスキップするので、何回実行しても重複しない。
#!/bin/zsh
# e-Gov公文書(zip/Safari自動解凍フォルダ)→ G-GOV電子申請フォルダへ格納 → XML+XSLをPDF化
SRC="$HOME/Downloads"
DEST="$HOME/Documents/〇〇/G-GOV電子申請" # ← 自分の保存先に書き換える
CHROME="/Applications/Google Chrome.app/Contents/MacOS/Google Chrome"
LOG="$DEST/_egov2pdf_log.txt"
[[ -d "$DEST" ]] || { echo "保存先がありません: $DEST"; exit 1; }
log() { echo "$(date '+%Y-%m-%d %H:%M:%S') $1" >> "$LOG"; }
# 1. ダウンロード内の「16桁_14桁.zip」→ 保存先へ移動して、その場で解凍(「zip+16桁フォルダ」の並び)
# Safariが自動解凍した「16桁_14桁」フォルダ → そのまま保存先へ移動
for item in "$SRC"/*(N); do
base="${item:t}"
if [[ "$base" =~ '^[0-9]{16}_[0-9]{14}\.zip$' ]]; then
s1=$(stat -f %z "$item"); sleep 2; s2=$(stat -f %z "$item")
[[ "$s1" != "$s2" ]] && continue # ダウンロード途中
if [[ -e "$DEST/$base" ]]; then
log "同名zipが既にあるためスキップ $base"; continue
fi
mv "$item" "$DEST/"
if ditto -x -k "$DEST/$base" "$DEST"; then
log "格納・解凍 $base"
else
log "解凍失敗 $base"
fi
elif [[ -d "$item" && "$base" =~ '^[0-9]{16}_[0-9]{14}$' ]]; then
if [[ -e "$DEST/$base" ]]; then
log "同名フォルダが既にあるためスキップ $base"
else
mv "$item" "$DEST/"
log "格納 $base"
fi
fi
done
# 2. 保存先内の、XSL指定のあるXMLをPDF化(作成済みはスキップ)
find "$DEST" -name '*.xml' | while read -r xml; do
pdf="${xml%.xml}.pdf"
[[ -e "$pdf" ]] && continue
xsl=$(sed -n 's/.*xml-stylesheet[^>]*href="\([^"]*\)".*/\1/p' "$xml" | head -1)
[[ -z "$xsl" ]] && continue # 署名XMLなどは対象外
dir="${xml:h}"
[[ -e "$dir/$xsl" ]] || continue
html="${xml%.xml}.html"
if xsltproc -o "$html" "$dir/$xsl" "$xml" 2>>"$LOG"; then
"$CHROME" --headless=new --disable-gpu --no-pdf-header-footer \
--print-to-pdf="$pdf" "$html" >/dev/null 2>&1
if [[ -e "$pdf" ]]; then log "PDF作成 $pdf"; else log "PDF作成失敗 $pdf"; fi
else
log "XSL変換失敗 $xml"
fi
doneMacでのセットアップ手順
スクリプト本体は nanoやテキストエディットに貼り付けて保存しない。初回にnanoへ貼り付けたら引用符(" ')が崩れ、unmatched " で動かなかった。テキストエディットも、スマート引用符で " が “ ” に変わる。
| 場所 | 貼り付けたもの | 結果 |
|---|---|---|
| ターミナルのnano | スクリプト全文 | 引用符が崩れて失敗 |
| (Claudeから受け取ったファイル) | egov2pdf.sh をダウンロードして ~/bin に移動 | 成功 |
| Automatorの「シェルスクリプトを実行」の欄 | ~/bin/egov2pdf.sh の 1行だけ | 成功(スクリプト本体はここに貼らない) |
- Google Chromeをインストールする
- このメモの「スクリプト全文」のコードブロックをコピーし、ターミナルで次を実行する(
pbpasteはクリップボードの中身をそのままファイルに書き出すので、引用符が崩れない)
mkdir -p ~/bin
pbpaste > ~/bin/egov2pdf.sh
chmod +x ~/bin/egov2pdf.sh
head -3 ~/bin/egov2pdf.sh最後の行で、1行目が #!/bin/zsh と表示されればOK。
- スクリプトの
DEST=の行を、自分の保存先に書き換える(VS Codeで開いて編集するのが安全) - Automatorを開き、「新規書類」→「フォルダアクション」を選ぶ
- 「フォルダアクションが受け取る項目」で「ダウンロード」を指定する
- 「ユーティリティ」→「シェルスクリプトを実行」をドラッグする。シェルは
/bin/zsh、入力の引き渡し方法は「引数として」、本文は~/bin/egov2pdf.shの1行だけ - 「e-Gov公文書PDF化」という名前で保存する
- フルディスクアクセスの画面を開き、「+」→
command + shift + G→/System/Library/CoreServices/Folder Actions Dispatcher.appを追加してオンにする
open "x-apple.systempreferences:com.apple.preference.security?Privacy_AllFiles"
killall "Folder Actions Dispatcher"- 公文書zipを1つダウンロードフォルダに入れて、ログに「格納・解凍」と「PDF作成」が出ればOK
手動実行・確認コマンド
| やりたいこと | コマンド |
|---|---|
| 手動で実行(溜まった分をまとめて処理) | ~/bin/egov2pdf.sh |
| 直近のログを見る | tail -10 ~/Documents/〇〇/G-GOV電子申請/_egov2pdf_log.txt |
| 保存先を開く | open ~/Documents/〇〇/G-GOV電子申請 |
| できたPDFの一覧 | find ~/Documents/〇〇/G-GOV電子申請 -name '*.pdf' |
| ダウンロードに残っている対象 | ls ~/Downloads | grep -E '^[0-9]{16}_[0-9]{14}' |
| 動作テスト(既存zipを一度ダウンロードに戻す) | mv ~/Documents/〇〇/G-GOV電子申請/<zip名> ~/Downloads/ |
古いzipが解凍されていないときは、Finderでzipをダブルクリックして解凍してから ~/bin/egov2pdf.sh を実行すれば、PDFが作成される。
トラブルシューティング
困ったらまずログを見る。ログに何も出ていなければ、スクリプトが起動していないか、権限で止まっている。
| 症状 | 原因 | 対処 |
|---|---|---|
unmatched " で止まる | nanoへの貼り付けで引用符が崩れた | スクリプトはファイルで持ち込む |
| zipが見つからず、同じ名前のフォルダだけある | Safariの「ダウンロード後、”安全な”ファイルを開く」で自動解凍された | スクリプトは解凍済みフォルダにも対応済み。設定変更は不要 |
| 解凍まではできるが、PDFもログも無い | フォルダアクションに「書類」へのアクセス権が無い(operation not permitted) | Folder Actions Dispatcher にフルディスクアクセスを付け、killall "Folder Actions Dispatcher" を実行 |
| zipがダウンロードに残ったまま | フォルダアクションが無効、または未設定 | ダウンロードを右クリック →「サービス」→「フォルダアクション設定…」で、有効化と割り当てを確認 |
| 「同名zip(フォルダ)が既にあるためスキップ」 | 同じ公文書を再ダウンロードした | ダウンロードに残ったものは手で削除してOK |
| PDFのレイアウトが崩れる | XSLが外部ファイルを参照している可能性 | 未発生。起きたら該当のxsl・xmlを確認 |
原因を細かく追うときは、スクリプトの2行目に次を一時的に入れると、動作が1行ずつ ~/bin/egov2pdf_debug.log に残る。終わったら消す。
exec >> "$HOME/bin/egov2pdf_debug.log" 2>&1
set -xあー よくわからんかったが動いた。来月分が問題なく稼働することを願う。
NOTICES
- 記事内容は実装させたものがほとんどですが自己責任で参考にしてください。