Wednesday, July 15, 2026 1:11:52 AM
> project show esm_bot
A sophisticated Discord bot that bridges Arma 3 Exile servers with Discord communities. Built in Ruby with secure TCP communication, it delivers territory management, real-time notifications, and comprehensive server administration right in your Discord channels.
Details
> settings.yml
#
# ESM bot service configuration. Load order (later overrides earlier):
#   1. settings.yml                  (this file, committed defaults)
#   2. settings.local.yml            (gitignored secrets, template: settings.example.yml)
#   3. settings/#{ESM_ENV}.yml       (committed per-env overlays)
#
# Schema: lib/pre_init/01_settings.rb.
#

# Discord bot token. Required - define in settings.local.yml.
token: ""

# Steam Web API key. Required - define in settings.local.yml.
steam_api_key: ""

# Discord user IDs (as strings) allowed to run developer-only commands.
dev_user_allowlist: []

# Discord guild ID of the developer's home community. When a real community
# matches this ID, the bot enables developer-only behavior (welcome message
# on member join, cross-community command access for support). Leave blank
# in environments that don't need this.
developer_guild_id: ""

# Discord channel ID for posting unhandled errors. Leave blank to disable.
error_logging_channel_id: ""

# Website URL used to build accept/decline links in /requests embeds.
request_url: "http://localhost:3000/requests"

# Mirror log output to stdout in addition to log files.
print_to_stdout: true

ports:
  # WebSocket server (V1 Arma clients).
  websocket: 3001

  # HTTP API consumed by the website.
  api: 3002

  # TCP server for V2 Arma extension connections.
  connection_server: 3003

# NATS request/reply transport for website ↔ bot RPC. Both sides must agree on
# url, subject_prefix, and shared_secret.
nats:
  # Broker URL the bot connects to. Outbound only; no port is bound here.
  url: "nats://127.0.0.1:4222"

  # Prefix every RPC subject is published under. Handlers register as
  # "<subject_prefix><action>" (e.g. esm.bot.rpc.community_roles).
  subject_prefix: "esm.bot.rpc."

  # HMAC-SHA256 key used to sign and verify the wire envelope on every RPC.
  # The website signs; the bot verifies. The value below is a committed dev
  # seed so contributors can run both sides locally without extra setup.
  # IMPORTANT: production MUST override this in its settings overlay with a
  # fresh random secret (e.g. `openssl rand -hex 32`). Keep it identical on
  # both website and bot or every request rejects with signature_invalid.
  shared_secret: "0bbb8d3b285597fafaa4eced7cdeba4e5d1a1758de9cd9bec49f92281627714c"

# Poll interval (seconds) for sweeping outstanding /request records.
request_overseer:
  check_every: 15

# Poll interval (seconds) for outstanding requests on the WebSocket transport.
websocket_request_overseer:
  check_every: 15

# Poll interval (seconds) for pruning dead WebSocket connections.
websocket_connection_overseer:
  check_every: 3

# Seconds each delivery worker waits between sends. Paces outbound messages to stay under discordrb's preemptive rate
# limiting during restart-time bursts.
bot_delivery_overseer:
  check_every: 0.1

# TCP server that accepts incoming Arma extension connections.
connection_server:
  # How often (seconds) to sweep the lobby and accept new clients.
  connection_check: 0.1

  # How long (seconds) a client can sit in the connect lobby before being kicked.
  lobby_timeout: 1

  # How long (seconds) to wait for a heartbeat response before kicking a client.
  heartbeat_timeout: 5

# Per-server client that proxies bot/website requests to the Arma extension.
connection_client:
  # Polling interval (seconds) for pending requests on the queue.
  request_check: 0.0005

  # Default timeout (seconds) for the extension to respond.
  response_timeout: 5

  # concurrent-ruby thread pool sizing for in-flight requests.
  min_threads: 2
  max_threads: 20
  max_queue: 250

# TTL (seconds) for ID lookup caches. Set to 0 to disable (used in test).
cache:
  server_ids: 30
  community_ids: 30

# Random tip rendered as the footer on each /command invocation.
tips:
  - "Admins can use `/community admin find_player` to get comprehensive information about any player via their Steam UID, Discord ID, or @mention."
  - "Looking for a community or server ID? Use the ID lookup tool at https://esmbot.com/tools/id_lookup"
  - "Most commands can be used either in a Discord channel or via DM with ESM, except admin commands which must be used in channels."
  - "Not sure about a command's usage? Use `/help with: <command>` to see detailed documentation and examples."
  - "Server admins: Territory restoration is possible with `/territory admin restore` if a territory was marked for deletion due to missed payments."
  - "Server admins: The `/server admin broadcast` command lets you send messages to all registered players on your server(s)."
  - "Server admins: Use `/server admin search_logs` to find specific items or player activities."
  - "Server admins: Use `/server admin search_logs` to search through the last 14 days of trading, territory, and death logs."
  - "Server admins: You can customize where different types of XM8 notifications are sent through the server dashboard."
  - "Server admins: You can request to forward your members' XM8 notifications to specific channels through the server dashboard."
  - "Server admins: You can reset command cooldowns for specific players or entire servers using `/community admin reset_cooldown`."
  - "Server rewards require confirmation in your DMs with ESM before delivery - make sure you're online and alive first!"
  - "Territory IDs can be customized using `/territory set_id` to make them more memorable and easier to type."
  - "Use `/community servers` to see all registered servers for a community, whether they're online or not."
  - "Use `/server my territories` to see all territories you own or are a member of, including their IDs and payment status."
  - "Want to gamble all or half your poptabs? Use `all` or `half` instead of a number with the gamble command."
  - "Want your base raid notifications in one Discord and grinding notifications in another? Set up multiple notification routes in your dashboard!"
  - "When in a Discord server's text channel, you can omit the community ID part of a server ID - ESM will automatically use the current community's ID. For example, use `malden` instead of `esm_malden`."
  - "When using `/territory pay`, the cost will be taken from your locker's poptabs."
  - "XM8 notifications can be enabled/disabled individually - you don't have to receive all types if you don't want to!"
  - "You can check server details like connection info and next restart time with `/server details`."
  - "You can check your gambling statistics on any server using `/server gamble amount: stats`."
  - "You can forward your XM8 notifications to any channel in a player mode Discord server - check the XM8 Notification Routes section in your dashboard!"
  - "You can set default server and community IDs from the player dashboard to avoid typing them in every command."
All opinions represented herein are my own
- © 2024 - 2026 itsthedevman
- build 43aa0d7