Agent Playbook: Autonomous Real-World Purchases via ADB + Bazos.cz
Date: 2026-02-19 Bead: beads-hub-sl1 GitHub Issue: #31 Status: Proven in production (DDR4 RAM purchase, 2026-02-19)
1. Overview
This playbook documents how an AI agent can autonomously complete a real-world purchase on Bazos.cz (Czech classifieds platform) using:
- Browser automation for web interactions (phone reveal, verification)
- ADB (Android Debug Bridge) for SMS read/write on a paired Android device
- Agent reasoning for negotiation, logistics lookup, and payment generation
End-to-end flow time: ~40 minutes (including seller response wait times)
2. Architecture
βββββββββββββββββββββββββββββββββββββββββββββββββββ
β AI Agent β
β (OpenClaw / Claude / any LLM orchestrator) β
βββββββββββββββ¬ββββββββββββββββ¬ββββββββββββββββββββ€
β Browser β ADB Bridge β Web Fetch β
β Control β (USB/TCP) β (HTTP client) β
β β β β
β bazos.cz β Samsung SMS β zasilkovna.cz β
β subdomain β app via UI β pickup points β
β navigation β automation β bank QR gen β
βββββββββββββββ΄ββββββββββββββββ΄ββββββββββββββββββββ
β β β
Phone reveal Read/Send SMS Logistics &
Verification Negotiation Payment
Components
| Component | Role | Interface |
|---|---|---|
| Browser | Navigate Bazos listings, trigger phone reveal, enter verification codes | JS evaluation via browser control |
| ADB | Read incoming SMS, compose and send outgoing SMS | adb shell commands (uiautomator, input, am) |
| Web Fetch | Look up shipping/pickup info (ZΓ‘silkovna), generate payment QR | HTTP GET + parse |
| Agent LLM | Orchestrate flow, negotiate with seller, make decisions | Prompt-based reasoning |
| Human | Approve payment (final confirmation gate) | QR code presented for manual bank transfer |
3. Complete Purchase Flow
Phase 1: Get Seller Phone Number
- Navigate to listing on correct subdomain (e.g.,
pc.bazos.cz) - Trigger phone reveal:
document.querySelector('.teldetail').click() - Enter agent phone number in overlay and submit
- Read verification SMS via ADB UI dump (see Β§4)
- Enter verification code in overlay β receive seller phone number
Phase 2: Initial Contact (SMS)
- Compose SMS via ADB to seller number
- Send inquiry β express interest, ask about shipping/availability
- Monitor for seller reply via ADB UI dumps
Phase 3: Negotiation
- Read seller reply β parse shipping terms, price confirmation
- Send follow-up β confirm price, request bank details and shipping info
- Handle seller questions β provide name, email, pickup point as needed
Phase 4: Logistics
- Look up pickup point (e.g., ZΓ‘silkovna) via web fetch
- Send logistics details to seller via SMS
Phase 5: Payment
- Receive bank account from seller (Czech format:
XXXXXXXXXX/BBBB) - Convert to IBAN and generate SPD payment QR code
- Present QR to human for approval and payment β HUMAN GATE
- Send payment confirmation SMS to seller after human confirms
4. ADB Interaction Patterns
4.1 Reading SMS (UI Dump Method)
Samsung devices block content://sms queries and SQLite access without root. The reliable method is UI automation:
# Dump current UI state
adb -s $DEVICE shell uiautomator dump /sdcard/ui.xml
adb -s $DEVICE pull /sdcard/ui.xml /tmp/ui.xml
# Extract all visible text
grep -o 'text="[^"]*"' /tmp/ui.xml | grep -v 'text=""'
To navigate to a specific SMS thread:
- Open Messages app:
adb -s $DEVICE shell am start -n com.samsung.android.messaging/.ui.ConversationListActivity - Dump UI to find the target thread row
- Calculate tap coordinates from
boundsattribute (center of bounding box) - Tap:
adb -s $DEVICE shell input tap X Y
4.2 Sending SMS
# ALWAYS force-stop first to get clean compose window
adb -s $DEVICE shell am force-stop com.samsung.android.messaging
sleep 1
# Open fresh compose to target number
adb -s $DEVICE shell 'am start -a android.intent.action.SENDTO -d "smsto:+420XXXXXXXXX"'
sleep 2
# Type word-by-word (spaces are eaten by `input text`)
for word in "Hello," "I" "am" "interested."; do
adb -s $DEVICE shell input text "$word"
adb -s $DEVICE shell input keyevent KEYCODE_SPACE
done
# Dismiss keyboard BEFORE tapping Send
adb -s $DEVICE shell input keyevent KEYCODE_BACK
sleep 1
# Find Send button via UI dump, tap its bounds center
adb -s $DEVICE shell uiautomator dump /sdcard/ui.xml
# Parse for content-desc="Send", extract bounds, tap center
adb -s $DEVICE shell input tap $SEND_X $SEND_Y
4.3 Verifying Send Success
adb -s $DEVICE shell uiautomator dump /sdcard/ui.xml
# Check compose field β empty means sent
grep 'editor_body' /tmp/ui.xml | grep -o 'text="[^"]*"'
# text="" β success | text="..." β still in compose, retry
4.4 Coordinate Systems β Critical
- UI dump
bounds= touch coordinate space β USE THESE - Screenshot pixels β touch coordinates on Samsung
- Check touch space:
adb shell wm size(e.g.,1080x1920) - Never derive tap coordinates from screenshot pixel positions
5. Bazos.cz Platform Specifics
Subdomain Scoping
- Verification is per-subdomain β verifying on
www.bazos.czdoes NOT work forpc.bazos.cz - Always verify on the same subdomain as the listing
- Codes expire quickly β complete the flow without navigating away
Phone Reveal DOM Selectors
// Trigger overlay
document.querySelector('.teldetail').click()
// Enter phone/code
document.querySelector('#overlaytel input[type=text]').value = 'VALUE'
document.querySelector('#overlaytel button').click()
// Read result
document.querySelector('#overlaytel').innerText
6. Czech Payment QR Generation
Czech banks use the SPD (Short Payment Descriptor) format.
Account Number β IBAN Conversion
def czech_account_to_iban(account: str, bank_code: str, prefix: str = '000000') -> str:
padded = prefix.zfill(6) + account.zfill(10)
bban = bank_code + padded
rearranged = bban + '1235' + '00' # CZ = 12,35
check = 98 - (int(rearranged) % 97)
return f'CZ{check:02d}{bban}'
SPD QR String
SPD*1.0*ACC:CZ{IBAN}*AM:{AMOUNT}*CC:CZK*MSG:{MESSAGE}
Generate a QR code from this string and present to the human for scanning with their banking app.
7. Security Considerations
7.1 Human-in-the-Loop Gates
| Gate | When | Why |
|---|---|---|
| Payment approval | Before any money transfer | Agent MUST NOT autonomously pay |
| Personal data sharing | Before sending name/address/email | Privacy protection |
| Price threshold | If negotiated price exceeds budget | Financial guardrail |
7.2 ADB Security
- Device authentication: ADB requires prior USB debugging authorization (device-level trust)
- Network exposure: Use USB connection, NOT
adb tcpipover network (exposes device to LAN) - Scope limitation: Agent should only interact with SMS app β no contacts, no file access, no app installs
- Credential isolation: Agent phone number is separate from human’s personal number
7.3 Data Handling
- No persistent storage of seller phone numbers or bank details after transaction completes
- SMS content should be processed in-memory, not logged to disk
- Redact phone numbers and account numbers in any logs or memory files
7.4 Anti-Abuse
- Rate limiting: Max 1 SMS per 30 seconds to avoid carrier spam flags
- Verification cooldown: Bazos may throttle repeated phone verifications β respect delays
- No automated bulk purchasing β this playbook is for single, intentional purchases
8. Known Pitfalls
| Pitfall | Impact | Mitigation |
|---|---|---|
input text drops spaces |
Garbled messages | Word-by-word + KEYCODE_SPACE |
| Keyboard obscures Send button | Silent tap failure | KEYCODE_BACK before tapping Send |
| Stale compose window | Text appended to old message | Always am force-stop before composing |
| Wrong subdomain verification | Code rejected | Verify on listing’s subdomain |
| Screenshot coords β touch coords | Tap misses target | Always use UI dump bounds |
| Script killed mid-send | Duplicate on retry | Verify compose field empty after each attempt |
| SMS content provider blocked | Can’t read SMS programmatically | Use UI dump method instead |
9. Proof-of-Concept Outline
A minimal PoC consists of three scripts:
bazos_phone_reveal.py
- Input: Bazos listing URL, agent phone number, ADB device ID
- Flow: Browser β trigger overlay β enter phone β read SMS via ADB β enter code β return seller phone
- Output: Seller phone number
adb_sms.sh
- Functions:
send_sms(device, number, message),read_thread(device, contact_name) - Handles: force-stop, word-by-word typing, keyboard dismiss, send verification
purchase_orchestrator.py
- Input: Listing URL, budget, shipping preference
- Orchestrates: phone reveal β SMS negotiation loop β logistics lookup β payment QR generation
- Human gate: Presents QR, waits for confirmation before sending payment confirmation SMS
10. Future Improvements
- OCR fallback: Screenshot + OCR when UI dump fails to capture dynamic content
- Multi-device support: Route SMS through different devices based on carrier/region
- Conversation memory: Track multi-turn negotiations across sessions
- Auto-retry with backoff: Handle transient ADB connection drops
- Platform expansion: Adapt patterns for other Czech classifieds (Sbazar, Facebook Marketplace)
This playbook is based on a successful real-world purchase completed on 2026-02-19. All techniques were validated against a Samsung device running Samsung Messages.