Config File Reference¶
Complete reference for config/config.toml. All settings are shown with their default values.
Tip
You only need to include settings you want to override. See config/config.example.toml in the PoracleNG repository for the full annotated reference, or use the Poracle Config UI to build your config visually.
Processor¶
Network settings for the processor binary. PoracleNG is a single Go binary — there is no separate alerter component, so this is the only network section.
[processor]
host = "0.0.0.0" # Listen address (0.0.0.0 = all interfaces)
port = 3030 # Listen port (receives webhooks and serves the API)
ip_whitelist = [] # Restrict webhook sources (empty = allow all)
ip_blacklist = [] # Block specific IPs
api_secret = "" # API secret for /api/* (blank = authenticated API disabled)
Note
The api_secret is required for external API access (e.g. PoracleWeb). The public endpoints (POST /, GET /health, GET /metrics) remain accessible regardless. Older configs that placed api_secret under [alerter] are still read for backward compatibility but should be migrated to [processor].
Database¶
Database connection for PoracleNG's own data (users, tracking rules, etc.).
[database]
host = "127.0.0.1"
port = 3306
user = "poracleuser"
password = "poraclepassword"
database = "poracle"
Scanner Database¶
If using RDM for quest/pokestop name lookups, configure the scanner database. The scanner type (golbat or rdm) lives here under the type key:
[database.scanner]
host = "127.0.0.1"
port = 3306
user = "scanneruser"
password = "scannerpassword"
database = "scannerdb"
type = "golbat" # "golbat" (default) or "rdm"
Note
Older configs may set scanner_type directly under [database]. That spelling is still accepted as a back-compat alias, but the canonical location is [database.scanner].type.
Geofence¶
See Geofences for detailed configuration.
[geofence]
paths = ["geofences/geofence.json"] # Geofence file paths
default_name = "city" # Default fence name
[geofence.koji]
bearer_token = "" # Koji API token for geofence downloads
cache_dir = ".cache/geofences" # Cache directory for downloaded geofences
PVP¶
PVP ranking calculation settings.
[pvp]
level_caps = [50] # Level caps for rank calculations (e.g. [50, 51])
include_mega_evolution = false # Include mega evolutions in rankings
evolution_direct_tracking = false # Track PVP evolutions directly (e.g. Vaporeon matches Eevee)
filter_by_track = false # Auto-filter PVP listings by user's track requirements
# Minimums on track command to prevent overly broad tracking
filter_max_rank = 10
filter_great_min_cp = 1400
filter_ultra_min_cp = 2350
filter_little_min_cp = 450
# Display thresholds passed into DTS
display_max_rank = 10
display_great_min_cp = 1400
display_ultra_min_cp = 2350
display_little_min_cp = 450
Weather¶
See Weather for detailed configuration.
[weather]
change_alert = false # Enable weather change alerts
show_altered_pokemon = false # Show weather-affected pokemon in alerts
show_altered_pokemon_static_map = false
show_altered_pokemon_max_count = 10
# AccuWeather forecast
enable_forecast = false
accuweather_api_keys = []
accuweather_day_quota = 50
forecast_refresh_interval = 8 # Hours between API calls per cell
local_first_fetch_hod = 3 # First fetch hour of day (local time)
smart_forecast = false # Pull on demand for missing cells
Area Security¶
See Area Security for detailed configuration.
Locale¶
Date, time, and language formatting.
[locale]
timeformat = "en-gb"
time = "LTS"
date = "L"
address_format = "{{{streetName}}} {{streetNumber}}"
language = "en" # Secondary language for 'alt' translations in DTS
General¶
General application settings.
[general]
environment = "production"
alert_minimum_time = 120 # Seconds before expiry to suppress alerts
ignore_long_raids = false # Ignore raids > 47min (reduce event spam)
img_url = "https://raw.githubusercontent.com/nileplumb/PkmnShuffleMap/master/UICONS"
img_url_alt = ""
sticker_url = "https://raw.githubusercontent.com/bbdoc/tgUICONS/main/Shuffle"
request_shiny_images = false
populate_pokestop_name = false # [RDM] Lookup pokestop names in scanner DB
locale = "en" # Default locale (en, fr, de, it, ru, etc.)
default_template_name = "1" # Default DTS template for new trackings
shortlink_provider = "hideuri" # hideuri, shlink, or yourls
shortlink_provider_url = ""
shortlink_provider_key = ""
shortlink_provider_domain = ""
rdm_url = "" # URL for RDM map links in DTS
react_map_url = "" # URL for ReactMap links in DTS
rocket_mad_url = "" # URL for RocketMAD links in DTS
Role Check Mode¶
Controls what happens when a user loses their Discord role or Telegram group membership:
role_check_mode = "ignore"
# "ignore" - Log and don't take action
# "delete" - Delete user and all trackings
# "disable-user" - Disable user (re-enable when restored), trackings preserved
Disable Webhook Types¶
Selectively disable processing of specific webhook types:
disable_pokemon = false
disable_raid = false
disable_pokestop = false # Also disables invasions for RDM/Golbat
disable_invasion = false
disable_lure = false
disable_quest = false
disable_weather = false
disable_nest = false
disable_gym = false
disable_fort_update = false
process_confirmed_invasion_lineups = false
disable_unconfirmed_invasion = false
Disabled Commands¶
Prevent specific commands from being used:
Available Languages¶
Configure languages users can switch between:
# [general.available_languages.en]
# poracle = "poracle"
# help = "help"
# [general.available_languages.de]
# poracle = "dasporacle"
# help = "hilfe"
Geocoding¶
See Geocoding and Static Maps for detailed configuration.
[geocoding]
provider = "none" # none, nominatim, or google
provider_url = ""
forward_only = false
cache_detail = 3
static_provider = "none" # none, tileservercache, google, osm, or mapbox
static_provider_url = ""
geocoding_key = [""] # Google API keys (array, rotated)
static_key = [""] # Map tile keys (array, rotated)
width = 320
height = 200
zoom = 15
Tuning¶
Performance tuning parameters.
Warning
Do not change these settings without consulting the Poracle community on Discord.
See the [tuning] reference page for the full field list and the tileserver section.
[tuning]
# Processor
reload_interval_secs = 60 # How often to reload tracking data from DB
encounter_cache_ttl = 3600 # Seconds to cache encounter data
worker_pool_size = 4 # Number of matching worker goroutines
batch_size = 50 # Items per batch
flush_interval_millis = 100 # Max time before flushing partial batch
# Alerter
max_database_connections = 15 # Max DB connections per worker
concurrent_matched_processors = 10 # Concurrent matched payload processors
matched_max_queue_size = 5000 # Max buffered items before backpressure
concurrent_discord_destinations = 10 # Concurrent Discord sends per bot
concurrent_telegram_destinations = 10 # Concurrent Telegram sends per bot
concurrent_discord_webhooks = 10 # Concurrent Discord webhook sends
The "Alerter" subheading above is historical — these are sender-side concurrency limits inside the single processor binary.
Alert Limits¶
Rate limiting to prevent individual users or channels from overwhelming the system.
[alert_limits]
timing_period = 240 # Seconds over which limits are calculated
dm_limit = 20 # Max messages per user per period
channel_limit = 40 # Max messages per channel per period
max_limits_before_stop = 10 # Times hitting limit before user is stopped
disable_on_stop = false # Admin disable (vs just stop)
shame_channel = "" # Discord channel to report stopped users
Limit Overrides¶
Override limits for specific channels, users, or webhooks:
# [[alert_limits.overrides]]
# target = "channel_or_user_id"
# limit = 100
# [[alert_limits.overrides]]
# target = "webhook_name"
# limit = 200
Tracking¶
Restrictions on user tracking commands.
[tracking]
everything_flag_permissions = "allow-any"
# "allow-any" - Unrestricted, recorded as wildcard
# "allow-and-always-individually" - Unrestricted, recorded as individual rows
# "allow-and-ignore-individually" - Unrestricted, users can't opt for individual rows
# "deny" - Users must track individual pokemon
default_distance = 0 # Default distance for distance-only tracking
max_distance = 0 # Max tracking circle radius (0 = no limit)
enable_gym_battle = false # Allow battle_changes option in !gym
default_user_tracking_level_cap = 0 # Default PVP level cap (0 = all)
Reconciliation¶
Automated user and channel sync settings.
[reconciliation.discord]
update_user_names = false
remove_invalid_users = true
register_new_users = false
update_channel_names = true
update_channel_notes = false
unregister_missing_channels = false
[reconciliation.telegram]
update_user_names = false
remove_invalid_users = true
Stats¶
Rarity and shiny statistics calculation.
[stats]
min_sample_size = 10000 # Min sightings before calculating rarity
window_hours = 8 # Rolling window for stats
refresh_interval_mins = 5 # Recalculation interval
rarity_group_2_uncommon = 1.0 # % threshold for uncommon
rarity_group_3_rare = 0.5 # % threshold for rare
rarity_group_4_very_rare = 0.03 # % threshold for very rare
rarity_group_5_ultra_rare = 0.01 # % threshold for ultra rare
Fallbacks¶
Fallback image URLs used when normal image sources fail.
[fallbacks]
static_map = "https://raw.githubusercontent.com/KartulUdus/PoracleJS/images/fallback/staticMap.png"
img_url = "https://raw.githubusercontent.com/KartulUdus/PoracleJS/images/fallback/mon.png"
img_url_weather = "https://raw.githubusercontent.com/KartulUdus/PoracleJS/images/fallback/weather.png"
img_url_egg = "https://raw.githubusercontent.com/KartulUdus/PoracleJS/images/fallback/uni.png"
img_url_gym = "https://raw.githubusercontent.com/KartulUdus/PoracleJS/images/fallback/gym.png"
img_url_pokestop = "https://raw.githubusercontent.com/KartulUdus/PoracleJS/images/fallback/pokestop.png"
pokestop_url = "https://raw.githubusercontent.com/KartulUdus/PoracleJS/images/fallback/pokestop.png"
Logging¶
[logging]
level = "verbose" # silly, debug, verbose, info, warn
file_logging_enabled = true # Write logs to file
filename = "logs/processor.log" # Log file path
max_size = 50 # Max log file size in MB
max_age = 7 # Days to keep log files
max_backups = 5 # Old log files to keep
compress = true # Gzip compress rotated logs
# Raw webhook logging
[webhookLogging]
enabled = false
filename = "logs/webhooks.log"
max_size = 100 # MB (also rotates on rotate_interval)
max_age = 1 # Days
max_backups = 12
compress = true
rotate_interval = 60 # Minutes between forced rotations (0 = size-based only)