Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/Apeuriox/lazybot-renewal/llms.txt

Use this file to discover all available pages before exploring further.

Lazybot is configured entirely through a single file: src/main/resources/application.yaml. This file is not committed to the repository — instead, a template (application.yaml.template) is provided that you copy and fill in before building or running the bot. Every credential, feature flag, thread pool size, and cache TTL is controlled from this file.
application.yaml is listed in .gitignore and must never be committed with real credentials. If you fork or mirror this repository, double-check that your workflow does not accidentally include it. Use CI/CD secrets (see the provided deploy.yml workflow) to inject credentials at build time.

spring

Core Spring Boot settings including the datasource connection, Jackson serialization, and virtual thread configuration.

spring.datasource

spring.datasource.driver-class-name
string
default:"com.mysql.cj.jdbc.Driver"
JDBC driver class. Lazybot targets MySQL; keep this value unchanged unless you are using a different MySQL-compatible driver.
spring.datasource.url
string
required
Full JDBC connection URL. Example:
url: jdbc:mysql://localhost:3306/lazybot_schema
Adjust the host, port, and schema name to match your database server. Remove the leading $ present in the template — it is a placeholder marker, not a valid character.
spring.datasource.username
string
required
MySQL user with read/write access to the lazybot_schema database.
spring.datasource.password
string
required
Password for the MySQL user above.
spring.datasource.hikari.max-lifetime
integer
default:"120000"
Maximum lifetime (ms) of a HikariCP connection in the pool before it is retired and replaced. Default is 120 000 ms (2 minutes).

spring.jackson

spring.jackson.date-format
string
default:"yyyy-MM-dd HH:mm:ss"
Global date serialization format used by Jackson for all Date fields.
spring.jackson.time-zone
string
default:"GMT+8"
Timezone applied when formatting dates. Change to your server’s local timezone if needed.

spring.web

spring.web.resources.add-mappings
boolean
default:"false"
Disables Spring MVC’s default static resource handler. Lazybot is a bot backend, not a web application — keeping this false prevents Spring from attempting to serve files from the classpath and avoids unexpected 404-handling conflicts.

spring.threads

spring.threads.virtual.enabled
boolean
default:"true"
Enables Java 21 virtual threads for all Spring-managed thread pools. Strongly recommended — Lazybot is designed to run with virtual threads enabled and will fall back to platform threads if this is set to false, reducing concurrency capacity.

server

server.port
integer
default:"9001"
HTTP port Lazybot’s embedded Tomcat listens on. Used for the osu! OAuth callback endpoint and any HTTP-based integrations. Ensure this port is reachable from the internet if you are using OAuth redirects.

shiro

Settings for the Shiro framework, which provides QQ bot support over the OneBot v11 WebSocket protocol.

shiro.ws.server

shiro.ws.server.enable
boolean
default:"true"
When true, Lazybot starts a WebSocket server that your OneBot-compatible QQ client (e.g. NapCatQQ, LiteLoaderQQNT) should connect to.
shiro.ws.server.url
string
default:"/lazybot"
WebSocket endpoint path. Your OneBot client should be configured to connect to ws://<host>:<port>/lazybot.
shiro.ws.timeout
integer
default:"10"
WebSocket idle timeout in seconds.
shiro.ws.max-binary-message-buffer-size
integer
default:"5120000"
Maximum binary message buffer size in bytes (~5 MB). Increase if you experience truncated image messages.
shiro.ws.max-text-message-buffer-size
integer
default:"512000"
Maximum text message buffer size in bytes (~500 KB).

shiro.limiter

Shiro’s built-in per-message rate limiter (token bucket).
shiro.limiter.enable
boolean
default:"true"
Enables or disables Shiro’s internal rate limiter.
shiro.limiter.rate
integer
default:"10"
Number of tokens refilled per second.
shiro.limiter.capacity
integer
default:"30"
Maximum token bucket capacity (burst limit).
shiro.limiter.awaitTask
boolean
default:"true"
When true, tasks that exceed the rate limit will wait for a token instead of being dropped immediately.
shiro.limiter.timeout
integer
default:"10"
Maximum wait time (seconds) for a token when awaitTask is true. Tasks waiting longer than this are dropped.

discord

Discord bot credentials. All four values are required when lazybot.global.discord.enabled is true.
discord.bot.key
string
required
Discord bot public key, found on the application’s General Information page in the Developer Portal. Used for interaction endpoint verification.
discord.bot.id
string
required
Discord application/client ID. Found on the General Information page.
discord.bot.secret
string
required
Discord OAuth2 client secret. Found on the OAuth2 page of the Developer Portal.
discord.bot.token
string
required
Discord bot token. Found on the Bot page of the Developer Portal. This is the credential JDA uses to connect to the Discord gateway. Treat it like a password.

lazybot

Core Lazybot settings: command behaviour, osu! API credentials, OAuth, caching, PP+, and feature flags.

Command & Prefix

lazybot.prefix
string
default:"/"
The character(s) that prefix all bot commands. For example, with the default /, users type /bp 1. You can change this to any string (e.g. ! or lb).

osu! API

lazybot.client_id
string
required
osu! OAuth application client ID. Register at osu.ppy.sh → Settings → OAuth.
lazybot.client_secret
string
required
osu! OAuth application client secret.
lazybot.response_type
string
default:"code"
OAuth 2.0 response type. Do not change.
lazybot.scopes
string
default:"friends.read identify public"
osu! API scopes requested during the user authorization flow.
lazybot.grant_type
string
default:"authorization_code"
OAuth 2.0 grant type. Do not change.

OAuth Callback

lazybot.oauth.redirect-uri
string
required
Publicly accessible URL that osu! redirects to after a user authorizes your application. Must be registered as a callback URL in your osu! OAuth application settings. Example:
redirect-uri: https://your-domain.example/oauth/osu/callback
The path /oauth/osu/callback is handled by Lazybot’s embedded HTTP server on server.port.
lazybot.oauth.scopes
string
default:"identify public"
Scopes included in the OAuth authorization URL sent to users during the /link flow.

Avatar Cache

lazybot.avatar-cache.revalidate-hours
integer
default:"24"
Number of hours before a cached player avatar is considered stale and re-fetched from the osu! CDN. Reducing this value increases freshness but adds more outbound HTTP traffic.

PP+ Integration

lazybot.plus.client_id
string
Client ID for the PP+ service. Required if you want /plus and /Pb commands to function. Contact the PP+ service operator for credentials.
lazybot.plus.client_password
string
Password for the PP+ service client.

Platform Toggles

lazybot.global.discord.enabled
boolean
default:"false"
Set to true to activate the Discord (JDA) bot. When false, the Discord gateway connection is not established and all Discord credentials are ignored.
lazybot.global.tencent.enabled
boolean
default:"true"
Set to true to activate the QQ (Shiro/OneBot) bot. When false, the WebSocket server still starts (controlled by shiro.ws.server.enable) but no commands are processed.

Command Limits

lazybot.command.whatif_calc_max_count
integer
default:"200"
Maximum number of PP recalculations Lazybot will perform in a single /bpif (what-if) request. Raising this limit increases response time and CPU load. Keep at 200 or lower for interactive use.

Local Test Mode

lazybot.test.enabled
boolean
default:"true"
Enables a local test mode that exposes HTTP endpoints for every command, useful for development without a connected chat platform.
lazybot.test.path
string
Directory where test-mode rendered images are written. Example: X:\lazybot-output (Windows) or /tmp/lazybot-output (Linux).
lazybot.test.identity
string
Fake user identity string used in test mode to simulate a linked osu! account.

async

Configuration for Lazybot’s internal async thread pool, used for concurrent osu! API requests and image rendering tasks.
async.executor.thread.core_pool_size
integer
default:"5"
Number of threads kept alive in the pool even when idle.
async.executor.thread.max_pool_size
integer
default:"5"
Maximum number of threads allowed in the pool. Because spring.threads.virtual.enabled is true by default, each “thread” in this pool is a virtual thread, so this limit is less critical than with platform threads.
async.executor.thread.queue_capacity
integer
default:"1000"
Size of the task queue. Tasks submitted when all threads are busy are queued here. If the queue is full, new submissions are rejected.
async.executor.thread.name.prefix
string
default:"api_request_pool-"
Name prefix for threads in this pool, useful for identifying Lazybot threads in thread dumps and profiler output.

rate-limit

Application-level token-bucket rate limiter (backed by Bucket4j) applied globally across all incoming commands.
rate-limit.capacity
integer
default:"24"
Maximum token bucket capacity (burst limit). A user or group can send at most this many commands in rapid succession before being throttled.
rate-limit.refill
integer
default:"8"
Tokens added to the bucket per refill interval. Combined with the capacity, this controls the sustained request rate.
rate-limit.enabled
boolean
default:"true"
Globally enables or disables the application-level rate limiter. Set to false only in development or testing environments.

Full Annotated Example

The following is a complete, annotated application.yaml based on the official template. Replace every your_* / $* placeholder with real values before running.
spring:
  application:
    name: lazybot-renewal

  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    # Full JDBC URL — remove the leading $ from the template
    url: jdbc:mysql://localhost:3306/lazybot_schema
    username: root
    password: your_database_password
    hikari:
      # Retire connections after 2 minutes of idle time
      max-lifetime: 120000

  jackson:
    date-format: yyyy-MM-dd HH:mm:ss
    time-zone: GMT+8

  web:
    resources:
      add-mappings: false   # Disable static resource mapping (bot only)

  threads:
    virtual:
      enabled: true         # Java 21 virtual threads — keep true

server:
  port: 9001                # HTTP port for OAuth callback + test endpoints

# QQ bot via Shiro / OneBot v11
shiro:
  ws:
    server:
      enable: true
      url: /lazybot          # ws://<host>:9001/lazybot
    timeout: 10
    max-binary-message-buffer-size: 5120000   # 5 MB
    max-text-message-buffer-size: 512000      # 500 KB
  limiter:
    enable: true
    rate: 10                 # 10 tokens/second
    capacity: 30             # burst up to 30
    awaitTask: true
    timeout: 10

# Discord bot via JDA
discord:
  bot:
    key: your_discord_bot_public_key
    id: your_discord_application_id
    secret: your_discord_oauth2_client_secret
    token: your_discord_bot_token

lazybot:
  prefix: /                  # Command prefix used in both Discord and QQ

  # osu! API OAuth credentials
  client_id: your_osu_client_id
  response_type: code
  scopes: friends.read identify public
  client_secret: your_osu_client_secret
  grant_type: authorization_code

  avatar-cache:
    revalidate-hours: 24     # Re-fetch avatars after 24 hours

  oauth:
    redirect-uri: https://your-domain.example/oauth/osu/callback
    scopes: identify public

  # PP+ service credentials (optional — required for /plus and /Pb)
  plus:
    client_id: your_pp_plus_client_id
    client_password: your_pp_plus_client_password

  # Platform toggles
  global:
    discord:
      enabled: true          # Set true to enable Discord bot
    tencent:
      enabled: true          # Set true to enable QQ bot

  # Local development test mode
  test:
    path: /tmp/lazybot-output
    identity: localTestIdentity
    enabled: false           # Disable in production

  command:
    whatif_calc_max_count: 200  # Max /bpif recalculations per request

# Async thread pool for osu! API requests and image rendering
async:
  executor:
    thread:
      core_pool_size: 5
      max_pool_size: 5
      queue_capacity: 1000
      name:
        prefix: api_request_pool-

# Application-level rate limiter (Bucket4j token bucket)
rate-limit:
  capacity: 24               # Burst limit
  refill: 8                  # Tokens added per refill
  enabled: true
The tencent.bot block present in the template (with id, secret, and token fields) is for an abandoned official Tencent bot API integration and is not actively used. QQ support is provided entirely through the Shiro / OneBot WebSocket path. You can safely leave that block with its placeholder values.

Build docs developers (and LLMs) love