A cross-platform config-driven ticket-purchasing bot for macOS and Windows. Connects to a live Chrome browser via CDP, extracts interactable elements from the DOM, walks a platform-specific FSM, and matches elements via a hybrid Aho-Corasick + Sentence-BERT pipeline.
Login is performed manually by the user before starting the bot.
- macOS (Intel or Apple Silicon) OR Windows 10/11
- Rust 1.70+
- Google Chrome
- Python 3.10+ (for model export scripts only)
- ONNX models in
models/directory (see ARCHITECTURE.md for setup)
Hardware Acceleration: NeverMiss automatically detects your OS and hardware to prioritize the optimal execution provider for the ONNX models:
- macOS: CoreML (Apple Neural Engine / Silicon) → CPU fallback.
- Windows: TensorRT / CUDA (NVIDIA GPUs) → DirectML (AMD/Intel GPUs) → CPU fallback.
- Linux: TensorRT / CUDA → CPU fallback.
Note: The bot was developed on macOS, so the .dmg installation file can be found directly in the releases. Technically, it can run on Windows, but users need to train the models and compile them themselves.
This project can be easily compiled and distributed as a standalone app/folder for macOS and Windows.
Run the included bash script to compile the release and construct a native macOS .app bundle and .dmg disk image:
./pack_mac.shThis script will:
- Compile the Rust binaries natively.
- Generate the Apple
AppIcon.icnsfor the squircle dock icon. - Bundle the
models/andconfig.yamldirectly intoNeverMiss.app/Contents/Resources/. - Output a ready-to-distribute
~/Downloads/NeverMiss.dmgwith a drag-and-drop/Applicationsfolder shortcut.
Run the included PowerShell script to compile the release and gather all necessary files into a portable folder:
.\pack_windows.ps1This creates a NeverMiss-Windows\ folder containing never-miss-gui.exe, the core bot executable, ONNX DLLs, and required models. You can zip and share this folder seamlessly.
cargo build --release
cargo run --release --bin never-miss-guiThe GUI lets you launch Chrome and configure all parameters with a visual interface.
/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome \
--remote-debugging-port=9222 \
--user-data-dir="chrome_profile"Open the event page manually in that Chrome window.
# Basic — auto-selects first date, first area, 1 ticket
cargo run --release --bin never-miss -- -w tixcraft
# Full options
cargo run --release --bin never-miss -- -w tixcraft -d "2026/05/15" -a "全區" -n 2 -f
# With pre-sale timing
cargo run --release --bin never-miss -- -w tixcraft -d "2026/05/15" -a "全區" -n 2 -f -t "12:00"| Flag | Default | Description |
|---|---|---|
-w, --website |
interactive prompt | Website profile name from config.yaml |
--cdp-url |
127.0.0.1:9222 |
Chrome DevTools Protocol endpoint |
-d, --date |
auto (first) | Date / session to select |
-a, --area |
auto (first) | Area or price tier |
-n, --tickets |
1 |
Number of tickets |
-t, --sale-time |
— | Pre-sale time (HH:MM, Taiwan time) |
-f, --fast |
off | Fast mode — reduced human-like delays |
-c, --config |
config.yaml |
Path to config file |
config.yaml declares one profile per platform. No credentials are stored.
fast_profile:
hover_delay: [10, 30]
click_hold: [15, 40]
poll_interval: 500
fast_profile:
hover_delay: [10, 30] # pause before clicking (ms)
click_hold: [15, 40] # mousedown → mouseup duration (ms)
think_delay: [5, 15] # pause before cursor starts moving (ms)
move_delay_fast: [1, 3] # cursor speed at mid-path (ms per step)
move_delay_slow: [3, 8] # cursor speed at start/end (ms per step)
steps_per_100px: [4, 8] # waypoints per 100px of travel
poll_interval: 500 # ms between FSM cycles when stalling
websites:
- name: tixcraft
display_name: "TixCraft (拓元售票)"
flow:
- state: Preparing
action: click
keywords: ["Buy tickets", "立即購票", "購票"]
url_pattern: "/activity/detail"
- state: SelectingDate
action: click
keywords: ["Find tickets", "立即訂購", "訂購"]
landmark: "場次"
- state: SelectingArea
action: click
keywords: ["區", "區域", "全區", "area", "樓", "zone"]
url_pattern: "/ticket/area"
- state: SelectingCount
action: select_count
keywords: ["數量", "Quantity", "張", "+", "+", "增加", "全票", "票"]
url_pattern: "/ticket/ticket"
- state: SolvingCaptcha
action: captcha_cnn
keywords: ["verifycode", "checkcode", "驗證碼", "verification code", "請輸入下方驗證碼數字"]
- state: AcceptingTerms
action: check_all
keywords: ["同意", "agree", "accept", "我已閱讀", "閱讀並同意", "確認同意"]
- state: Submitting
action: click
keywords: ["submit", "送出", "確認", "confirm", "下一步", "next"]
- state: Checkout
action: wait_url
keywords: []
url_pattern: "/ticket/checkout"For implementation details, see ARCHITECTURE.md.
| The graphical user interface | Demo on YouTube |
|---|---|
![]() |
![]() |
This project is for educational and research purposes only. The authors are not responsible for any misuse, account bans, or violations of terms of service resulting from the use of this software. Always comply with the ticketing platform's terms and conditions. Automated ticket purchasing may violate local laws or platform policies — use at your own risk.
This project is licensed under the GNU General Public License v3.0 - see the LICENSE file for details.


