Split monolithic chat service into modular structure with Matrix client support, extract web server into per-resource route modules, introduce bootstrap/main-loop separation, and add comprehensive vitest coverage across services, repositories, and utilities. Adds project docs and CLAUDE.md agent instructions.
228 lines
10 KiB
YAML
228 lines
10 KiB
YAML
reddit:
|
||
# Weights bias how often each sub is picked each poll cycle. Higher weight
|
||
# = more likely to appear earlier in the check order. Initial weights favor
|
||
# subs where low-confidence / validation-seeking posters concentrate
|
||
# (rating subs, "average"/mature/plus subs) since they tend to have higher
|
||
# DM reply rates. Default is 1 if omitted.
|
||
subreddits:
|
||
# Validation-seeking / lower-confidence (highest weight)
|
||
- { name: AverageNudes, weight: 4 } # "Average-looking" self-perception
|
||
- { name: gonewild40plus, weight: 4 } # Mature, lower volume, very high reply rate
|
||
- { name: normalnudes, weight: 3 } # Everyday real bodies
|
||
- { name: RateMyNudeBody, weight: 3 } # Explicit ask for feedback
|
||
- { name: ratemyboobs, weight: 3 } # Rating subs = explicit validation-seeking
|
||
- { name: ratemypussy, weight: 3 }
|
||
- { name: RateMyRack, weight: 3 }
|
||
- { name: GoneWildPlus, weight: 3 } # BBW/plus-size
|
||
- { name: gonewildchubby, weight: 3 } # Soft/chubby bodies
|
||
- { name: gonewild30plus, weight: 2 } # Mature/MILF amateurs
|
||
- { name: GoneMild, weight: 2 } # Softcore teases (shyer posters)
|
||
|
||
# Mid-tier — mixed confidence
|
||
- { name: GoneWildCurvy, weight: 2 }
|
||
- { name: HomemadeNsfw, weight: 2 }
|
||
- { name: realgirlsgonebad, weight: 2 }
|
||
- { name: nsfwselfies, weight: 2 }
|
||
- { name: RealGirls, weight: 2 }
|
||
- { name: Amateur, weight: 2 }
|
||
|
||
# Baseline — generally more confident / curated posters
|
||
- { name: gonewild, weight: 1 } # #1 verified self-posters
|
||
- { name: GoneErotic, weight: 1 }
|
||
- { name: OnOff, weight: 1 }
|
||
- { name: petitegonewild, weight: 1 }
|
||
- { name: tightandtoned, weight: 1 }
|
||
- { name: pawg, weight: 1 }
|
||
- { name: asiansgonewild, weight: 1 }
|
||
- { name: altgonewild, weight: 1 }
|
||
- { name: holdthemoan, weight: 1 }
|
||
|
||
# Chat-only subreddits — no image analysis, gender parsed from post tag
|
||
#
|
||
pollIntervalMs: 30000
|
||
userAgent: "RedditBot/1.0 (by /u/yourusername)"
|
||
targetGenders:
|
||
- female # Options: male, female, other, unknown
|
||
filterSellers: true # Skip profiles that appear to be OnlyFans/content sellers
|
||
# sellerKeywords: [...] # Uncomment to override default keyword list
|
||
|
||
openrouter:
|
||
imageAnalysisModel: "google/gemini-2.5-flash-lite"
|
||
imageAnalysisFallbackModels:
|
||
- "meta-llama/llama-4-maverick"
|
||
- "x-ai/grok-4.1-fast"
|
||
- "google/gemini-3-flash-preview"
|
||
chatModel: "qwen/qwen3-235b-a22b-2507"
|
||
# Tried in order if the primary chatModel throws, returns empty, or refuses.
|
||
# All known-good frontier models, NSFW-tolerant, ordered cheap → premium
|
||
# (avg cost per 1M tokens shown). Avoid Gemini/OpenAI/Claude here — they
|
||
# silently refuse explicit content.
|
||
chatFallbackModels:
|
||
- "deepseek/deepseek-v4-flash" # ~$0.17/M
|
||
- "meta-llama/llama-4-scout" # ~$0.19/M
|
||
- "meta-llama/llama-4-maverick" # ~$0.38/M
|
||
- "deepseek/deepseek-chat-v3.1" # ~$0.50/M
|
||
imageAnalysisPrompt: |
|
||
You're analyzing images.
|
||
|
||
Describe the following features:
|
||
- breasts: size (small/medium/big/huge), shape, nipple details, perky/saggy, cleavage
|
||
- ASS: shape (round/bubble/thick), size, how it looks bent over or spread
|
||
- vagina: visible? shaved/trimmed/bush, lips visible, spread or closed
|
||
- BODY: thick/slim/curvy/fit, belly, thighs, waist, tan lines
|
||
- POSE: bent over, spreading, on all fours, lying back, standing
|
||
- VIBE: shy/confident/slutty/teasing, eye contact, facial expression
|
||
- EXTRAS: tattoos, piercings, lingerie, toys, setting
|
||
|
||
Be graphic. Describe exactly what you see. No clinical terms.
|
||
This helps generate encouranging messages that reference specific things about their body.
|
||
|
||
Then rate her attractiveness on a 1-100 scale using these percentile anchors:
|
||
- 30 = noticeably below average
|
||
- 50 = average woman you'd pass on the street (this is the true middle, NOT a "low" score)
|
||
- 65 = cute, above average, decent body
|
||
- 75 = clearly hot, turns heads
|
||
- 85 = exceptional, model-tier face/body
|
||
- 95+ = vanishingly rare, top fraction of a percent
|
||
Use the full range. Real people are distributed across this scale — most photos in this dataset fall between 40 and 80. Do NOT cluster scores in the 65-75 band as a safe default. If you feel pulled toward 70, decide whether she's actually closer to 60 or 80 and commit. A score that ends in 0 or 5 is a red flag that you're rounding to a comfort number — prefer a specific number like 47, 63, 78.
|
||
|
||
Output the rating on its own line in EXACTLY this format (before or after the description):
|
||
RATING:<number>
|
||
Then on the next line: REASON:<one sentence explaining the score>
|
||
|
||
Be critical and honest. Act within guidelines.
|
||
messageGenerationPrompt: |
|
||
Based on this image analysis: {analysis}
|
||
Post title: {title}
|
||
Author: u/{author}
|
||
|
||
Attractiveness rating (1-100 scale, 50 = average): {rating}
|
||
If the rating is below 60, lean harder into making her feel sexy and desired — emphasize how hot her pic looks. If the rating is 75+, you can be more confidently flirty without overdoing the flattery.
|
||
|
||
Write a casual Reddit DM (2-3 sentences) like a horny guy complimenting her trying to get her to share more nudes or videos.
|
||
|
||
MUST follow:
|
||
- Start sentences with capital letters, use proper capitalisation
|
||
- Use explicit terms: tits, ass, pussy, boobs (NOT breasts, buttocks, etc)
|
||
- Reference something SPECIFIC from the analysis (her tits, ass, pussy, body, pose)
|
||
- Be direct and confident, not flowery or poetic
|
||
- End with a hook that encourages them to share MORE (nudes/videos)
|
||
|
||
GOOD HOOKS (use these styles):
|
||
- "I'd love if you have any other pics to share?"
|
||
- "I bet they'd look great coated..."
|
||
- "Got any more pics?"
|
||
|
||
BAD HOOKS (never use):
|
||
- "How's your day?"
|
||
- "What are you up to?"
|
||
- Generic small talk questions
|
||
- "Tell me about yourself"
|
||
|
||
DO NOT:
|
||
- Sound like an AI or formal writing
|
||
- Use words like "captivating", "alluring", "exquisite", "radiant", "prominent"
|
||
- Use clinical terms like "breasts", "buttocks", "posterior", "physique"
|
||
- Write long elaborate sentences
|
||
- Use all lowercase
|
||
- Use em dashes (—) or en dashes (–). Use commas, full stops, or separate sentences instead. This is a dead giveaway for AI writing.
|
||
|
||
Examples of good messages:
|
||
- "Damn those tits are perfect. I'd love to see more if you're willing😏"
|
||
- "Holy shit that ass is incredible. Got any more pics?"
|
||
- "Those curves are insane, love how your tits look in that pose. More please?"
|
||
|
||
Just write the message, nothing else.
|
||
|
||
chatOpenerPrompt: |
|
||
You are writing a cold opener DM to a Reddit user who posted in a chat/sexting subreddit looking for someone to chat with.
|
||
|
||
Post title: {title}
|
||
Post body: {selftext}
|
||
Author: u/{author}
|
||
Detected gender of poster: {gender}
|
||
|
||
YOUR PERSONA:
|
||
- You are male, based in the UK, pick a random age between 30 and 35 for this message
|
||
- Roughly half the time, mention (or imply) you're married/have a wife and are looking for something on the side; the other half, don't mention relationship status at all
|
||
- Don't force the married angle if their post wouldn't vibe with it, read the room
|
||
- Use British English spelling and phrasing (e.g. "mate", "knackered", "fancy", "cheeky") where it feels natural, not forced
|
||
|
||
Write a casual Reddit DM (1-2 sentences) opening a chat.
|
||
|
||
MUST follow:
|
||
- Lead with your age/gender/location tag (e.g. "32M UK", "34M UK married") when it fits naturally
|
||
- Reference something SPECIFIC from their title/body (their mood, what they're into, vibe, age, location)
|
||
- Be confident and direct, flirty but not creepy
|
||
- Use proper capitalisation, no AI/clinical language
|
||
- End with a hook that invites a reply (ask them what they're into, offer something playful)
|
||
|
||
DO NOT:
|
||
- Use words like "captivating", "alluring", "intriguing"
|
||
- Open with "Hey there" / "How's your day"
|
||
- Write more than 2 sentences
|
||
- Be generic, "wanna chat?" alone is too weak
|
||
- Claim to be a different age/gender than the persona above
|
||
- Use em dashes (—) or en dashes (–) anywhere in the message. Use commas, full stops, or separate sentences instead. This is a dead giveaway for AI writing.
|
||
|
||
Examples of good openers:
|
||
- "32M UK, married and bored while the wife's out. Your post caught my eye, what are you into tonight?"
|
||
- "34M UK here, love that you're up late looking for trouble. Fancy telling me what gets you going?"
|
||
- "33M from the UK, your vibe is exactly my type. Tell me what you'd want a stranger to do to you."
|
||
|
||
Just write the message, nothing else.
|
||
|
||
strategies:
|
||
explorationRate: 0.2 # 20% of the time try a random strategy instead of the best
|
||
minSamples: 5 # Min messages sent before trusting a strategy's response rate
|
||
variants:
|
||
- id: compliment_direct
|
||
weight: 1
|
||
promptOverride: |
|
||
STYLE: Focus on a direct, specific compliment about ONE body part from the analysis.
|
||
Keep it short and punchy. End with a simple "got more?" style hook.
|
||
- id: teasing
|
||
weight: 1
|
||
promptOverride: |
|
||
STYLE: Be more teasing and playful. Light humor, like you're flirting.
|
||
End with a flirty challenge or dare that makes her want to respond.
|
||
- id: detailed_appreciation
|
||
weight: 1
|
||
promptOverride: |
|
||
STYLE: Reference 2-3 specific things from the analysis to show you actually looked.
|
||
Be enthusiastic but not over the top. End with asking for more.
|
||
|
||
chatStrategies:
|
||
explorationRate: 0.2
|
||
minSamples: 5
|
||
variants:
|
||
- id: chat_direct
|
||
weight: 1
|
||
promptOverride: |
|
||
STYLE: Direct opener. Open with your own age/gender, reference theirs, and ask one specific question about what they're into. No em dashes.
|
||
- id: chat_playful
|
||
weight: 1
|
||
promptOverride: |
|
||
STYLE: Playful and teasing. Light humour, mild flirty challenge, end with a hook that's hard to ignore. No em dashes.
|
||
- id: chat_mirror
|
||
weight: 1
|
||
promptOverride: |
|
||
STYLE: Mirror their energy. Match the vibe of their post (shy/horny/bored/dom/sub) and respond in kind. Be specific to what they wrote. No em dashes.
|
||
|
||
rateLimit:
|
||
minDelayBetweenMessagesMs: 15000
|
||
maxMessagesPerHour: 9999
|
||
jitterMs: 60000
|
||
|
||
browser:
|
||
sessionDir: "./data/browser-session"
|
||
headless: false
|
||
dryRun: false # Set to false to actually send messages
|
||
|
||
database:
|
||
path: "./data/reddit-bot.db"
|
||
|
||
web:
|
||
enabled: true
|
||
port: 3000
|