Files
openclaw/tools/dba-bid.py
Clawd Bot ca9b510922 chore: align with upstream openclaw/openclaw and overlay local additions
- Reset master to upstream/main (16,697 commits)
- Overlay 2,271 local-only files (skills, tools, workspace, configs, apps)
- Restore IDENTITY.md and USER.md templates
- Build verified, gateway running, Discord working

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 07:40:46 +01:00

210 lines
7.3 KiB
Python

#!/usr/bin/env python3
"""
DBA.dk bud/besked-tool — sender besked til sælger via Playwright.
Kræver at du er logget ind (gemmer session i ~/.openclaw/dba-session.json).
Brug:
python3 dba-bid.py <item-url-eller-id> "<besked>"
python3 dba-bid.py --login (åbn browser og log ind manuelt)
python3 dba-bid.py --check-login (test om session er aktiv)
Eksempel:
python3 dba-bid.py https://www.dba.dk/recommerce/forsale/item/16276129 \
"Hej, vil du tage 5000 kr? Kan afhente i weekenden."
"""
import sys, os, json, time, argparse
SESSION_FILE = os.path.expanduser('~/.openclaw/dba-session.json')
DBA_BASE = 'https://www.dba.dk'
def get_item_url(item_ref: str) -> str:
"""Konverterer item-id eller fuld URL til fuld URL."""
if item_ref.startswith('http'):
return item_ref
# Bare et ID
return f"{DBA_BASE}/recommerce/forsale/item/{item_ref}"
def login_interactive():
"""Åbn browser så brugeren kan logge ind, gem session bagefter."""
from playwright.sync_api import sync_playwright
print("Åbner DBA.dk — log ind og tryk Enter her bagefter...")
with sync_playwright() as p:
browser = p.chromium.launch(headless=False, slow_mo=100)
ctx = browser.new_context()
page = ctx.new_page()
page.goto(f"{DBA_BASE}/login/", wait_until='networkidle')
input("Tryk Enter efter du er logget ind...")
# Gem cookies
cookies = ctx.cookies()
with open(SESSION_FILE, 'w') as f:
json.dump(cookies, f, indent=2)
print(f"Session gemt ({len(cookies)} cookies) → {SESSION_FILE}")
browser.close()
def check_login() -> bool:
"""Tjek om session er aktiv."""
from playwright.sync_api import sync_playwright
if not os.path.exists(SESSION_FILE):
return False
with open(SESSION_FILE) as f:
cookies = json.load(f)
# Tjek om auth-cookies er der og ikke tomme
auth = [c for c in cookies if c.get('name') in ('id-jwt', 'schacc-session', 'login-webapp_jsession')]
if not auth or all(not c.get('value') for c in auth):
return False
with sync_playwright() as p:
browser = p.chromium.launch(headless=True)
ctx = browser.new_context()
ctx.add_cookies(cookies)
page = ctx.new_page()
page.goto(f"{DBA_BASE}/recommerce/forsale/search?q=test", wait_until='domcontentloaded', timeout=15000)
# Tjek om vi er logget ind (profilikon/knap)
logged_in = page.locator('[data-testid="profile-button"], [aria-label*="profil"], .user-avatar').count() > 0
browser.close()
return logged_in
def send_message(item_ref: str, message: str, dry_run: bool = False) -> dict:
"""Send besked til sælger på DBA."""
from playwright.sync_api import sync_playwright
item_url = get_item_url(item_ref)
if not os.path.exists(SESSION_FILE):
return {'success': False, 'error': 'Ikke logget ind. Kør: python3 dba-bid.py --login'}
with open(SESSION_FILE) as f:
cookies = json.load(f)
with sync_playwright() as p:
browser = p.chromium.launch(headless=True)
ctx = browser.new_context(
user_agent='Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 Chrome/131 Safari/537.36'
)
ctx.add_cookies(cookies)
page = ctx.new_page()
try:
page.goto(item_url, wait_until='domcontentloaded', timeout=20000)
time.sleep(2)
# Find "Skriv til sælger" knap
contact_btn = page.locator(
'button:has-text("Skriv til sælger"), '
'button:has-text("Kontakt sælger"), '
'a:has-text("Skriv til sælger"), '
'[data-testid="contact-seller-button"]'
).first
if contact_btn.count() == 0:
# Tag screenshot til debug
page.screenshot(path='/tmp/dba-debug.png')
browser.close()
return {'success': False, 'error': 'Kunne ikke finde "Skriv til sælger" knap. Screenshot: /tmp/dba-debug.png'}
if dry_run:
browser.close()
return {'success': True, 'dry_run': True, 'message': message, 'url': item_url}
contact_btn.click()
time.sleep(2)
# Find tekstfelt og skriv besked
textarea = page.locator(
'textarea[name*="message"], textarea[placeholder*="besked"], '
'textarea[placeholder*="Message"], #message, [data-testid="message-input"]'
).first
if textarea.count() == 0:
page.screenshot(path='/tmp/dba-debug.png')
browser.close()
return {'success': False, 'error': 'Tekstfelt ikke fundet. Screenshot: /tmp/dba-debug.png'}
textarea.fill(message)
time.sleep(1)
# Find Send-knap
send_btn = page.locator(
'button[type="submit"]:has-text("Send"), '
'button:has-text("Send besked"), '
'[data-testid="send-message-button"]'
).first
if send_btn.count() == 0:
page.screenshot(path='/tmp/dba-debug.png')
browser.close()
return {'success': False, 'error': 'Send-knap ikke fundet. Screenshot: /tmp/dba-debug.png'}
send_btn.click()
time.sleep(2)
# Bekræft
page.screenshot(path='/tmp/dba-sent.png')
browser.close()
return {'success': True, 'message': message, 'url': item_url, 'screenshot': '/tmp/dba-sent.png'}
except Exception as e:
try:
page.screenshot(path='/tmp/dba-error.png')
except Exception:
pass
browser.close()
return {'success': False, 'error': str(e)}
def main():
parser = argparse.ArgumentParser(description='DBA.dk bud/besked tool')
parser.add_argument('item', nargs='?', help='Item URL eller ID')
parser.add_argument('message', nargs='?', help='Besked til sælger')
parser.add_argument('--login', action='store_true', help='Log ind interaktivt og gem session')
parser.add_argument('--check-login', action='store_true', help='Tjek om session er aktiv')
parser.add_argument('--dry-run', action='store_true', help='Test uden at sende')
parser.add_argument('--json', action='store_true', help='Output som JSON')
args = parser.parse_args()
if args.login:
login_interactive()
return
if args.check_login:
ok = check_login()
if args.json:
print(json.dumps({'logged_in': ok}))
else:
print('Logget ind ✓' if ok else 'Ikke logget ind ✗')
return
if not args.item or not args.message:
parser.print_help()
sys.exit(1)
result = send_message(args.item, args.message, dry_run=args.dry_run)
if args.json:
print(json.dumps(result, ensure_ascii=False, indent=2))
else:
if result['success']:
if result.get('dry_run'):
print(f"[DRY-RUN] Ville sende: {result['message']}")
print(f"Til: {result['url']}")
else:
print(f"Besked sendt til {result['url']}")
print(f"Screenshot: {result.get('screenshot','')}")
else:
print(f"Fejl: {result['error']}", file=sys.stderr)
sys.exit(1)
if __name__ == '__main__':
main()