Skip to content

Instantly share code, notes, and snippets.

@cmpadden
Last active June 17, 2026 01:26
Show Gist options
  • Select an option

  • Save cmpadden/27c1ca3806c7e41b82d5d29a730e559d to your computer and use it in GitHub Desktop.

Select an option

Save cmpadden/27c1ca3806c7e41b82d5d29a730e559d to your computer and use it in GitHub Desktop.
Bulk Scan Receipts with Codex
#!/usr/bin/env bash
set -euo pipefail
INPUT_PATH="${1:-receipts}"
OUTPUT_PATH="${2:-receipts.jsonl}"
MODEL="${MODEL:-gpt-5.5}"
PROMPT='Extract receipt data from the attached image.
Return only compact JSON with these keys:
source_file, store, transaction_date, transaction_time, card_last4, total, currency, items, notes.
Use null for unknown values.
transaction_date must be YYYY-MM-DD when visible.
total must be a number string with two decimals.
items should be an array of {name, quantity, total} when itemization is readable, otherwise [].
Do not infer values that are not visible.'
TMP_DIR="$(mktemp -d)"
trap 'rm -rf "$TMP_DIR"' EXIT
receipt_files() {
local path="$1"
if [[ ! -d "$path" ]]; then
printf '%s\0' "$path"
return
fi
find "$path" -type f \
\( -iname '*.heic' -o -iname '*.heif' \
-o -iname '*.jpg' -o -iname '*.jpeg' \
-o -iname '*.png' -o -iname '*.webp' \
-o -iname '*.tif' -o -iname '*.tiff' \) \
-print0
}
image_for_codex() {
local file="$1"
case "${file##*.}" in
[Hh][Ee][Ii][Cc] | [Hh][Ee][Ii][F])
local converted="$TMP_DIR/$(basename "${file%.*}").png"
sips -s format png "$file" --out "$converted" >/dev/null
printf '%s\n' "$converted"
;;
*)
printf '%s\n' "$file"
;;
esac
}
scan_receipt() {
local file="$1"
local image="$2"
local result="$TMP_DIR/result.json"
printf 'Scanning %s\n' "$file" >&2
codex exec \
--ephemeral \
--model "$MODEL" \
--image "$image" \
--output-last-message "$result" \
"$PROMPT source_file=$file" \
>/dev/null
tr -d '\n' < "$result"
printf '\n'
}
main() {
files=()
while IFS= read -r -d '' file; do
files+=("$file")
done < <(receipt_files "$INPUT_PATH")
: > "$OUTPUT_PATH"
for file in "${files[@]}"; do
scan_receipt "$file" "$(image_for_codex "$file")" >> "$OUTPUT_PATH"
done
printf 'Wrote %s\n' "$OUTPUT_PATH" >&2
}
main "$@"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment