{
  "id": "agessaman-meshcore-bot",
  "name": "MeshCore Bot",
  "short_name": "agessaman bot",
  "kind": "bot",
  "status": "active",
  "maturity": "stable",
  "description": "Extensible Python MeshCore service bot with keyword and plugin commands, weather and alert services, scheduling, rate limits, web administration and optional Discord, Telegram, MQTT, webhook and map integrations.",
  "image": "icon.png",
  "maintainers": [
    {
      "name": "agessaman",
      "url": "https://github.com/agessaman"
    }
  ],
  "repository": "https://github.com/agessaman/meshcore-bot",
  "documentation": "https://agessaman.github.io/meshcore-bot/",
  "license_type": "source-available",
  "languages": [
    "python",
    "javascript",
    "html"
  ],
  "platforms": [
    "linux",
    "docker",
    "nixos",
    "web"
  ],
  "interfaces": [
    "web",
    "tui",
    "api",
    "headless"
  ],
  "connections": [
    "ble",
    "serial",
    "usb",
    "tcp",
    "mqtt",
    "http",
    "websocket"
  ],
  "node_roles": [
    "companion",
    "repeater"
  ],
  "capabilities": [
    "messaging",
    "contacts",
    "channels",
    "remote-administration",
    "monitoring",
    "telemetry",
    "packet-analysis",
    "automation",
    "notifications",
    "bridging"
  ],
  "install": [
    {
      "type": "docker-compose",
      "url": "https://agessaman.github.io/meshcore-bot/docker/",
      "command": "docker compose up -d --build"
    },
    {
      "type": "nixos",
      "package": "meshcore-bot",
      "url": "https://github.com/agessaman/meshcore-bot"
    },
    {
      "type": "bare-metal",
      "package": "Python / systemd",
      "url": "https://agessaman.github.io/meshcore-bot/service-installation/",
      "command": "sudo ./install-service.sh"
    },
    {
      "type": "source",
      "url": "https://github.com/agessaman/meshcore-bot"
    }
  ],
  "popularity": {
    "githubStars": 163,
    "githubForks": 63,
    "githubWatchers": 6,
    "githubOpenIssues": 31,
    "githubContributors": 13,
    "latestReleaseDownloads": 0,
    "lastChecked": "2026-06-23"
  },
  "verification": {
    "sourceAvailable": true,
    "releasesAvailable": true,
    "signedReleases": false,
    "ciBuilds": true,
    "hasDocumentation": true,
    "lastChecked": "2026-06-23",
    "notes": [
      "The project warns operators to avoid duplicate bots and constrain response scope to protect mesh airtime.",
      "The repository does not currently declare an SPDX license."
    ]
  },
  "tags": [
    "command-bot",
    "weather",
    "service-plugins",
    "self-hosted",
    "web-dashboard"
  ],
  "last_reviewed": "2026-06-23",
  "source": {
    "path": "data/software/agessaman-meshcore-bot/software.yaml",
    "updatedAt": "2026-06-24T05:12:55+02:00"
  },
  "latest_version": "0.9.3",
  "released": "2026-05-31",
  "releases": [
    {
      "version": "v0.9.3",
      "name": "v0.9.3",
      "datetime": "2026-05-31T00:34:40Z",
      "url": "https://github.com/agessaman/meshcore-bot/releases/tag/v0.9.3",
      "prerelease": false,
      "notes": "It was discovered that if the bot webhook was feeding a Discord channel via a webhook, sending messages to `@everyone`, `@here`, etc. would tag all users in the Discord. This is fixed.\r\n\r\n**Full Changelog**: https://github.com/agessaman/meshcore-bot/compare/v0.9.2...v0.9.3",
      "notesHtml": "<p>It was discovered that if the bot webhook was feeding a Discord channel via a webhook, sending messages to <code>@everyone</code>, <code>@here</code>, etc. would tag all users in the Discord. This is fixed.</p>\n<p><strong>Full Changelog</strong>: <a href=\"https://github.com/agessaman/meshcore-bot/compare/v0.9.2...v0.9.3\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/agessaman/meshcore-bot/compare/v0.9.2...v0.9.3</a></p>\n"
    },
    {
      "version": "v0.9.2",
      "name": "v0.9.2",
      "datetime": "2026-05-17T21:44:14Z",
      "url": "https://github.com/agessaman/meshcore-bot/releases/tag/v0.9.2",
      "prerelease": false,
      "notes": "## What's Changed\r\n* Fix scope handling behavior and improve logging options for packet capture service. by @agessaman in https://github.com/agessaman/meshcore-bot/pull/185\r\n\r\n\r\n**Full Changelog**: https://github.com/agessaman/meshcore-bot/compare/v0.9.1...v0.9.2",
      "notesHtml": "<h2>What's Changed</h2>\n<ul>\n<li>Fix scope handling behavior and improve logging options for packet capture service. by @agessaman in <a href=\"https://github.com/agessaman/meshcore-bot/pull/185\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/agessaman/meshcore-bot/pull/185</a></li>\n</ul>\n<p><strong>Full Changelog</strong>: <a href=\"https://github.com/agessaman/meshcore-bot/compare/v0.9.1...v0.9.2\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/agessaman/meshcore-bot/compare/v0.9.1...v0.9.2</a></p>\n"
    },
    {
      "version": "v0.9.1",
      "name": "v0.9.1",
      "datetime": "2026-05-16T19:55:44Z",
      "url": "https://github.com/agessaman/meshcore-bot/releases/tag/v0.9.1",
      "prerelease": false,
      "notes": "## Highlights\r\n\r\nThis release has improvements to regions handling, fixes for a couple of deadlock issues in the scheduler that might cause the bot to become unresponsive, and bugfixes in various areas.\r\n\r\n- **Regions flood scope** end-to-end: per-service config, scheduled messages, webhook body override, and correct scope on keyword/RandomLine replies.\r\n- **Scheduler overhaul**: 5-field cron and `@` presets (HHMM deprecated), optional per-job `#scope`, stagger for colliding jobs, better concurrency.\r\n- **DARC MoWaS reliability**: bit-identical retransmits with stable timestamps; ascending timestamps on multi-chunk sends.\r\n- **Path & test commands**: optional reply prefix, gated repeater naming by bytes/hop, customizable `test`/`t` templates with pipe filters.\r\n\r\n## Features\r\n\r\n**Scheduling**\r\n- `[Scheduled_Messages]` supports cron (`0 8 * * *`), presets (`@daily`, `@hourly`, …); legacy `HHMM` still works with a warning. (*Note:* APScheduler Day of Week starts on Monday unlike Vixie cron, so Monday = 0.)\r\n- Per-job regional scope: `channel:#scope:message` (middle field must start with `#`).\r\n- Added optional `scheduled_message_max_stagger_seconds` to spread out jobs that fire at the same time; scheduled sends skip global `rate_limit_seconds` (channel and `bot_tx_rate_limit` still apply).\r\n\r\n**Flood scope**\r\n- `CommandManager.resolve_channel_send_scope()` with precedence: explicit arg → `message.reply_scope` → section `flood_scope` → `[Channels] outgoing_flood_scope_override`.\r\n- Optional `flood_scope` on Weather, Earthquake, Webhook, DARC MoWaS, and related services; webhook JSON may include `\"flood_scope\": \"#scope\"`.\r\n- Keyword and RandomLine channel replies use `send_response` so incoming regional scope is honored. #178\r\n\r\n**Commands**\r\n- **Path**: `reply_prefix` (first chunk only when split) allows you to add `@[{sender}]` or similar to first reply. `minimum_path_bytes` (2/3) defers DB name lookup on paths with single byte path hashes, this is useful to avoid returning inaccurate information in dense meshes with highly duplicated single-byte prefixes.\r\n- **Test**: `[Test_Command] response_format` overrides `[Keywords] test`; pipe filters (`pathbytes_min`, `prefix_if_nonempty`). This enables things like not returning values unless conditions are met. Example that only returns path distance if multibyte paths are used:\r\n\r\n```ini\r\nresponse_format = ack @[{sender}]{phrase_part} | {path}{path_distance|pathbytes_min:2|prefix_if_nonempty: | Path Dist: } | F/L Dist: {firstlast_distance} | Rec: {timestamp}\r\n```\r\n\r\n**Packet capture / MQTT**\r\n- Added global `jwt_ttl_seconds` and per-broker `mqttN_jwt_ttl_seconds` / `mqttN_jwt_renewal_interval` for token lifetime vs refresh cadence. This enables JWTs with a TTL shorter than 24 hours.\r\n\r\n**DARC MoWaS**\r\n- Retransmissions reuse the original timestamp for network deduplication; chunk sends get `base + index` second timestamps.\r\n\r\n**Other**\r\n- `send_channel_message(..., timestamp=...)` for bit-identical channel replays.\r\n- Service display names strip trailing underscores (e.g. `foo_Service` → `foo`, not `foo_`).\r\n\r\n---\r\n\r\n## Fixes\r\n\r\n- **DM routing**: responses use `sender_pubkey` when available (avoids misrouting when display names collide). Thanks for raising this @Tigro14 in #180\r\n- **Scheduler / feeds**: fire-and-forget scheduled processing; feed send lock avoids coroutine pileup; per-feed last-send tracking.\r\n- **Mesh graph**: `flush_needed` flag reduces redundant flush calls and a deadlock risk.\r\n- **Contact adverts**: `track_contact_advertisement` returns structured success/duplicate status for clearer handler logic.\r\n- **DARC MoWaS / webhook**: chunk timestamp ordering; webhook scope resolution cleanup.\r\n\r\n---\r\n\r\n## Configuration notes\r\n\r\n| Area | Action |\r\n|------|--------|\r\n| Scheduled messages | Prefer cron over `HHMM`; use `channel:#scope:body` for regional sends. |\r\n| MQTT brokers with short-lived tokens | Set `jwt_ttl_seconds` and renewal interval **below** TTL per broker. |\r\n…",
      "notesHtml": "<h2>Highlights</h2>\n<p>This release has improvements to regions handling, fixes for a couple of deadlock issues in the scheduler that might cause the bot to become unresponsive, and bugfixes in various areas.</p>\n<ul>\n<li><strong>Regions flood scope</strong> end-to-end: per-service config, scheduled messages, webhook body override, and correct scope on keyword/RandomLine replies.</li>\n<li><strong>Scheduler overhaul</strong>: 5-field cron and <code>@</code> presets (HHMM deprecated), optional per-job <code>#scope</code>, stagger for colliding jobs, better concurrency.</li>\n<li><strong>DARC MoWaS reliability</strong>: bit-identical retransmits with stable timestamps; ascending timestamps on multi-chunk sends.</li>\n<li><strong>Path &amp; test commands</strong>: optional reply prefix, gated repeater naming by bytes/hop, customizable <code>test</code>/<code>t</code> templates with pipe filters.</li>\n</ul>\n<h2>Features</h2>\n<p><strong>Scheduling</strong></p>\n<ul>\n<li><code>[Scheduled_Messages]</code> supports cron (<code>0 8 * * *</code>), presets (<code>@daily</code>, <code>@hourly</code>, …); legacy <code>HHMM</code> still works with a warning. (<em>Note:</em> APScheduler Day of Week starts on Monday unlike Vixie cron, so Monday = 0.)</li>\n<li>Per-job regional scope: <code>channel:#scope:message</code> (middle field must start with <code>#</code>).</li>\n<li>Added optional <code>scheduled_message_max_stagger_seconds</code> to spread out jobs that fire at the same time; scheduled sends skip global <code>rate_limit_seconds</code> (channel and <code>bot_tx_rate_limit</code> still apply).</li>\n</ul>\n<p><strong>Flood scope</strong></p>\n<ul>\n<li><code>CommandManager.resolve_channel_send_scope()</code> with precedence: explicit arg → <code>message.reply_scope</code> → section <code>flood_scope</code> → <code>[Channels] outgoing_flood_scope_override</code>.</li>\n<li>Optional <code>flood_scope</code> on Weather, Earthquake, Webhook, DARC MoWaS, and related services; webhook JSON may include <code>\"flood_scope\": \"#scope\"</code>.</li>\n<li>Keyword and RandomLine channel replies use <code>send_response</code> so incoming regional scope is honored. #178</li>\n</ul>\n<p><strong>Commands</strong></p>\n<ul>\n<li><strong>Path</strong>: <code>reply_prefix</code> (first chunk only when split) allows you to add <code>@[{sender}]</code> or similar to first reply. <code>minimum_path_bytes</code> (2/3) defers DB name lookup on paths with single byte path hashes, this is useful to avoid returning inaccurate information in dense meshes with highly duplicated single-byte prefixes.</li>\n<li><strong>Test</strong>: <code>[Test_Command] response_format</code> overrides <code>[Keywords] test</code>; pipe filters (<code>pathbytes_min</code>, <code>prefix_if_nonempty</code>). This enables things like not returning values unless conditions are met. Example that only returns path distance if multibyte paths are used:</li>\n</ul>\n<pre><code>response_format = ack @[{sender}]{phrase_part} | {path}{path_distance|pathbytes_min:2|prefix_if_nonempty: | Path Dist: } | F/L Dist: {firstlast_distance} | Rec: {timestamp}\n</code></pre>\n<p><strong>Packet capture / MQTT</strong></p>\n<ul>\n<li>Added global <code>jwt_ttl_seconds</code> and per-broker <code>mqttN_jwt_ttl_seconds</code> / <code>mqttN_jwt_renewal_interval</code> for token lifetime vs refresh cadence. This enables JWTs with a TTL shorter than 24 hours.</li>\n</ul>\n<p><strong>DARC MoWaS</strong></p>\n<ul>\n<li>Retransmissions reuse the original timestamp for network deduplication; chunk sends get <code>base + index</code> second timestamps.</li>\n</ul>\n<p><strong>Other</strong></p>\n<ul>\n<li><code>send_channel_message(..., timestamp=...)</code> for bit-identical channel replays.</li>\n<li>Service display names strip trailing underscores (e.g. <code>foo_Service</code> → <code>foo</code>, not <code>foo_</code>).</li>\n</ul>\n<hr />\n<h2>Fixes</h2>\n<ul>\n<li><strong>DM routing</strong>: responses use <code>sender_pubkey</code> when available (avoids misrouting when display names collide). Thanks for raising this @Tigro14 in #180</li>\n<li><strong>Scheduler / feeds</strong>: fire-and-forget scheduled processing; feed send lock avoids coroutine pileup; per-feed last-send tracking.</li>\n<li><strong>Mesh graph</strong>: <code>flush_needed</code> flag reduces redundant flush calls and a deadlock risk.</li>\n<li><strong>Contact adverts</strong>: <code>track_contact_advertisement</code> returns structured success/duplicate status for clearer handler logic.</li>\n<li><strong>DARC MoWaS / webhook</strong>: chunk timestamp ordering; webhook scope resolution cleanup.</li>\n</ul>\n<hr />\n<h2>Configuration notes</h2>\n<table>\n<thead>\n<tr>\n<th>Area</th>\n<th>Action</th>\n</tr>\n</thead>\n<tbody><tr>\n<td>Scheduled messages</td>\n<td>Prefer cron over <code>HHMM</code>; use <code>channel:#scope:body</code> for regional sends.</td>\n</tr>\n<tr>\n<td>MQTT brokers with short-lived tokens</td>\n<td>Set <code>jwt_ttl_seconds</code> and renewal interval <strong>below</strong> TTL per broker.</td>\n</tr>\n<tr>\n<td>…</td>\n<td></td>\n</tr>\n</tbody></table>\n"
    },
    {
      "version": "v0.9.0",
      "name": "v0.9.0",
      "datetime": "2026-05-03T05:20:07Z",
      "url": "https://github.com/agessaman/meshcore-bot/releases/tag/v0.9.0",
      "prerelease": false,
      "notes": "# v0.9.0 Release Notes\r\n\r\nv0.9.0 is a release focused on stability and enhancing and refining existing features. It adds features to the web dashboard, rewrites the scheduler on APScheduler for improved reliability, and introduces radio-health monitoring. It also adds versioned database migrations, multi-arch Docker images, `.deb` packaging, async guard rails, and several new commands. **Python 3.9 is no longer supported; the minimum is now 3.10.**\r\n\r\nThanks to @KG7QIN for the work on adding tests and working on radio reliability.\r\n\r\n---\r\n\r\n## Web Viewer\r\n\r\n- Optional authentication for the admin dashboard\r\n- Updated live streams for packets, commands, messages, and logs.\r\n- Admin config editor lets operators view and edit `config.ini` from the browser, with automatic password redaction and CSRF protection.\r\n- Contact management, DB backup management, maintenance tools, and an API Explorer tab are all available from the viewer.\r\n- Zombie-radio and radio-offline banners surface hardware status on every page; channel-name validation and live update-feed controls added.\r\n- The viewer starts with an \"initializing\" banner during bot startup and polls for live status without blocking the bot.\r\n\r\n## Radio Reliability\r\n\r\n- Zombie-radio detection periodically probes the radio with a health check; unresponsive radios trigger a configurable alert and banner.\r\n- Radio-offline fail state suppresses outbound sends until the radio reconnects, then resumes normally.\r\n- `asyncio.wait_for` guards wrap `send_advert`, `disconnect_radio`, and `reboot_radio` to prevent event-loop lockups.\r\n- A debounce guard prevents the packet-capture service from storm-restarting during radio reconnects.\r\n- Radio debug logging can be toggled from the web UI at runtime without a restart.\r\n\r\n## Scheduler & Database\r\n\r\n- Scheduler rewritten on APScheduler; a new maintenance module handles housekeeping tasks independently.\r\n- Graceful shutdown and config reload are signal-driven (`SIGTERM` / `SIGHUP`).\r\n- Database layer migrated to `aiosqlite` with `AsyncDBManager` and versioned migrations; `ALTER TABLE` startup migrations run safely without data loss.\r\n- Background polling operations (feed polling, channel/radio ops) use fire-and-forget callbacks to avoid blocking the scheduler thread.\r\n\r\n## Commands\r\n\r\n- `!version` reports the running bot version; `!schedule` lists scheduled messages and the current advert interval.\r\n- `!path` gains a geographic scoring toggle and corrected multibyte chart rendering.\r\n- Weather: high/low temperatures, MQTT weather source, Open-Meteo model selection, configurable default city, multi-day forecasts, and location fallback.\r\n- Airplane results are configurable via `max_results`.\r\n- Additional keyword-triggered auto-responses via the RandomLine matcher; a BSD fortune file ships as default data.\r\n\r\n## Bridges & Integrations\r\n\r\n- Discord bridge now supports multiple webhooks per channel, configurable per channel key.\r\n- Discord and Telegram outbound helpers added for cross-service notification delivery.\r\n- Repeater discovery and collision alerts service with optional delivery to mesh or external notification services (Discord/Telegram).\r\n- Inbound webhook relay accepts external HTTP POST events with bearer-token authentication and forwards them to mesh channels.\r\n- MQTT packet publishing controls added with configurable path-length decoding.\r\n\r\n## Security & Rate Limiting\r\n\r\n- SSRF hardening added to all outbound HTTP calls, including an explicit CGN-network check; an `allow_local_smtp` flag enables opt-in local SMTP relay.\r\n- Log-injection sanitization applied to all user-supplied log lines; a CI regression check guards against regressions.\r\n- CSRF protection added to the web viewer admin editor.\r\n- Per-channel rate limiting and tightened per-user cooldown defaults; thread-safe rate limiter with LRU SNR/RSSI caches.\r\n\r\n## Packaging & Infrastructure\r\n\r\n- `.deb` packaging via `scripts/build-deb.sh` for systemd-based deployments.\r\n- Multi-ar\n…",
      "notesHtml": "<h1>v0.9.0 Release Notes</h1>\n<p>v0.9.0 is a release focused on stability and enhancing and refining existing features. It adds features to the web dashboard, rewrites the scheduler on APScheduler for improved reliability, and introduces radio-health monitoring. It also adds versioned database migrations, multi-arch Docker images, <code>.deb</code> packaging, async guard rails, and several new commands. <strong>Python 3.9 is no longer supported; the minimum is now 3.10.</strong></p>\n<p>Thanks to @KG7QIN for the work on adding tests and working on radio reliability.</p>\n<hr />\n<h2>Web Viewer</h2>\n<ul>\n<li>Optional authentication for the admin dashboard</li>\n<li>Updated live streams for packets, commands, messages, and logs.</li>\n<li>Admin config editor lets operators view and edit <code>config.ini</code> from the browser, with automatic password redaction and CSRF protection.</li>\n<li>Contact management, DB backup management, maintenance tools, and an API Explorer tab are all available from the viewer.</li>\n<li>Zombie-radio and radio-offline banners surface hardware status on every page; channel-name validation and live update-feed controls added.</li>\n<li>The viewer starts with an \"initializing\" banner during bot startup and polls for live status without blocking the bot.</li>\n</ul>\n<h2>Radio Reliability</h2>\n<ul>\n<li>Zombie-radio detection periodically probes the radio with a health check; unresponsive radios trigger a configurable alert and banner.</li>\n<li>Radio-offline fail state suppresses outbound sends until the radio reconnects, then resumes normally.</li>\n<li><code>asyncio.wait_for</code> guards wrap <code>send_advert</code>, <code>disconnect_radio</code>, and <code>reboot_radio</code> to prevent event-loop lockups.</li>\n<li>A debounce guard prevents the packet-capture service from storm-restarting during radio reconnects.</li>\n<li>Radio debug logging can be toggled from the web UI at runtime without a restart.</li>\n</ul>\n<h2>Scheduler &amp; Database</h2>\n<ul>\n<li>Scheduler rewritten on APScheduler; a new maintenance module handles housekeeping tasks independently.</li>\n<li>Graceful shutdown and config reload are signal-driven (<code>SIGTERM</code> / <code>SIGHUP</code>).</li>\n<li>Database layer migrated to <code>aiosqlite</code> with <code>AsyncDBManager</code> and versioned migrations; <code>ALTER TABLE</code> startup migrations run safely without data loss.</li>\n<li>Background polling operations (feed polling, channel/radio ops) use fire-and-forget callbacks to avoid blocking the scheduler thread.</li>\n</ul>\n<h2>Commands</h2>\n<ul>\n<li><code>!version</code> reports the running bot version; <code>!schedule</code> lists scheduled messages and the current advert interval.</li>\n<li><code>!path</code> gains a geographic scoring toggle and corrected multibyte chart rendering.</li>\n<li>Weather: high/low temperatures, MQTT weather source, Open-Meteo model selection, configurable default city, multi-day forecasts, and location fallback.</li>\n<li>Airplane results are configurable via <code>max_results</code>.</li>\n<li>Additional keyword-triggered auto-responses via the RandomLine matcher; a BSD fortune file ships as default data.</li>\n</ul>\n<h2>Bridges &amp; Integrations</h2>\n<ul>\n<li>Discord bridge now supports multiple webhooks per channel, configurable per channel key.</li>\n<li>Discord and Telegram outbound helpers added for cross-service notification delivery.</li>\n<li>Repeater discovery and collision alerts service with optional delivery to mesh or external notification services (Discord/Telegram).</li>\n<li>Inbound webhook relay accepts external HTTP POST events with bearer-token authentication and forwards them to mesh channels.</li>\n<li>MQTT packet publishing controls added with configurable path-length decoding.</li>\n</ul>\n<h2>Security &amp; Rate Limiting</h2>\n<ul>\n<li>SSRF hardening added to all outbound HTTP calls, including an explicit CGN-network check; an <code>allow_local_smtp</code> flag enables opt-in local SMTP relay.</li>\n<li>Log-injection sanitization applied to all user-supplied log lines; a CI regression check guards against regressions.</li>\n<li>CSRF protection added to the web viewer admin editor.</li>\n<li>Per-channel rate limiting and tightened per-user cooldown defaults; thread-safe rate limiter with LRU SNR/RSSI caches.</li>\n</ul>\n<h2>Packaging &amp; Infrastructure</h2>\n<ul>\n<li><code>.deb</code> packaging via <code>scripts/build-deb.sh</code> for systemd-based deployments.</li>\n<li>Multi-ar\n…</li>\n</ul>\n"
    },
    {
      "version": "v0.8.3",
      "name": "v0.8.3",
      "datetime": "2026-03-12T03:57:19Z",
      "url": "https://github.com/agessaman/meshcore-bot/releases/tag/v0.8.3",
      "prerelease": false,
      "notes": "This release adds support for parsing multi-byte paths across the bot.\r\n\r\n- Adds a `trace` command (and its companion `tracer`, trace reciprocal) that enables the bot to perform traces.\r\n- Adds a new RandomLine matcher for file-based command responses. Thanks Ian!\r\n- Adds data-retention rules for all databases and purges old records periodically.\r\n- Added Earthquake notification service. Thanks [davidkjackson54](https://github.com/davidkjackson54)!\r\n- Adds a Bot → Telegram bridge that enables messages from one or more channels to be posted to Telegram\r\n- Adds a profanity and hate symbol filter to prevent bad actors on the mesh from getting your Discord banned.\r\n- Adds support for local service plugins in a separate directory for easy backups. Thanks for the suggestion and testing [davidkjackson54](https://github.com/davidkjackson54)",
      "notesHtml": "<p>This release adds support for parsing multi-byte paths across the bot.</p>\n<ul>\n<li>Adds a <code>trace</code> command (and its companion <code>tracer</code>, trace reciprocal) that enables the bot to perform traces.</li>\n<li>Adds a new RandomLine matcher for file-based command responses. Thanks Ian!</li>\n<li>Adds data-retention rules for all databases and purges old records periodically.</li>\n<li>Added Earthquake notification service. Thanks <a href=\"https://github.com/davidkjackson54\" target=\"_blank\" rel=\"noopener noreferrer\">davidkjackson54</a>!</li>\n<li>Adds a Bot → Telegram bridge that enables messages from one or more channels to be posted to Telegram</li>\n<li>Adds a profanity and hate symbol filter to prevent bad actors on the mesh from getting your Discord banned.</li>\n<li>Adds support for local service plugins in a separate directory for easy backups. Thanks for the suggestion and testing <a href=\"https://github.com/davidkjackson54\" target=\"_blank\" rel=\"noopener noreferrer\">davidkjackson54</a></li>\n</ul>\n"
    },
    {
      "version": "v0.8.2.1",
      "name": "v0.8.2.1",
      "datetime": "2026-02-22T20:04:15Z",
      "url": "https://github.com/agessaman/meshcore-bot/releases/tag/v0.8.2.1",
      "prerelease": false,
      "notes": "Small bugfix release that fixes a configparser error for users using Python 3.13+",
      "notesHtml": "<p>Small bugfix release that fixes a configparser error for users using Python 3.13+</p>\n"
    },
    {
      "version": "v0.8.2",
      "name": "v0.8.2",
      "datetime": "2026-02-21T17:54:02Z",
      "url": "https://github.com/agessaman/meshcore-bot/releases/tag/v0.8.2",
      "prerelease": false,
      "notes": "- Added a version indicator to the bottom of the Web Viewer\r\n- Added ability to filter by packet type in Packet Capture Service.\r\n- Improved mesh graph efficiency, added documentation for how to configure mesh graph calculations (or disable it) on lightweight nodes like Raspberry Pi Zero 2s.\r\n- Simplify contact removal logic. Occasional errors will still occur until race condition in meshcore_py \r\n- Improvements to documentation.",
      "notesHtml": "<ul>\n<li>Added a version indicator to the bottom of the Web Viewer</li>\n<li>Added ability to filter by packet type in Packet Capture Service.</li>\n<li>Improved mesh graph efficiency, added documentation for how to configure mesh graph calculations (or disable it) on lightweight nodes like Raspberry Pi Zero 2s.</li>\n<li>Simplify contact removal logic. Occasional errors will still occur until race condition in meshcore_py </li>\n<li>Improvements to documentation.</li>\n</ul>\n"
    },
    {
      "version": "v0.8.1",
      "name": "v0.8.1",
      "datetime": "2026-02-18T18:01:33Z",
      "url": "https://github.com/agessaman/meshcore-bot/releases/tag/v0.8.1",
      "prerelease": false,
      "notes": "A couple little fixes.\r\n\r\nFixed logic in multitest command to avoid having a subsequent request block both test requests.\r\nFixed issue with per-user rate limit that prevented second message responses from commands from being sent.",
      "notesHtml": "<p>A couple little fixes.</p>\n<p>Fixed logic in multitest command to avoid having a subsequent request block both test requests.\nFixed issue with per-user rate limit that prevented second message responses from commands from being sent.</p>\n"
    },
    {
      "version": "v0.8",
      "name": "v0.8",
      "datetime": "2026-02-17T00:50:31Z",
      "url": "https://github.com/agessaman/meshcore-bot/releases/tag/v0.8",
      "prerelease": false,
      "notes": "## Release notes\r\n\r\n**New commands & features**\r\n\r\n- **Aurora** — New command for aurora/space weather (NOAA client).\r\n- **Airplanes** — Aircraft tracking command.\r\n- **Reload** — Admin command to reload configuration without restarting the bot.\r\n- **Command prefix** — Optional prefix for bot commands (e.g. `!path`).\r\n- **Sub-commands & help** — Commands can expose sub-commands and clearer usage/help; help respects channel restrictions and avoids truncation issues.\r\n- **Polish** — Polish translation added (with thanks to the contributor).\r\n\r\n**Path & mesh**\r\n\r\n- **Path command** — Graph-based path validation using observed mesh links; presets: `balanced`, `geographic`, `graph`. SNR integration, “prefix best location,” and improved multitest with per-user sessions and path tracking.\r\n- **Mesh graph** — New mesh graph logic and **mesh view in the web viewer** (connections, highlighting, sync).\r\n- **Contacts (web)** — Time filtering, path sorting, bulk delete, starred nodes, and automatic device name updates.\r\n\r\n**Weather**\r\n\r\n- **WXSIM** — Support for custom WXSIM weather sources in `wx_command` and international weather.\r\n- **Global weather** — ZIP code geocoding and companion location features.\r\n\r\n**Configuration & behavior**\r\n\r\n- **Config validation** — `validate_config.py` and validation in `modules/config_validation.py`; standardized command sections (e.g. `[Joke_Command]` with `enabled`); legacy `*_enabled` still supported.\r\n- **Rate limiting** — Per-user rate limiting for bot responses.\r\n- **Channel keyword filtering** — Configurable channel filtering for keyword responses.\r\n- **Banned users** — Prefix (starts-with) matching for banned user entries.\r\n- **Feed manager** — Dedicated `[Feed_Manager]` section; optional RSS/API feeds.\r\n- **Config file** — UTF-8 support and quoted values for monitor channels.\r\n\r\n**Web viewer**\r\n\r\n- Mesh graph view, improved error handling and database path handling, favicons, realtime view.\r\n- **Service health checks** — Optional checks and restart logic for the viewer.\r\n\r\n**Docker & deployment**\r\n\r\n- **Docker** — Dockerfile, `docker-compose.yml`, and `docker-setup.sh` for device detection, paths, and serial handling. Docs in `docs/DOCKER.md`.\r\n- **Install script** — `install-service.sh` supports Python venv and clearer echo formatting.\r\n- **CI** — GitHub Actions for Docker build, tests, and docs; `dev` branch supported.\r\n\r\n**Under the hood**\r\n\r\n- Command queuing for global cooldowns; escape sequence decoding for greetings and keyword responses; transmission and repeat tracking; unique advert packet tracking and leaderboard.\r\n- **Tests** — pytest suite (commands, config validation, rate limiter, mesh graph, path resolution, etc.).\r\n- **Docs** — MkDocs site and guides: getting started, configuration, path command config, upgrade, Docker, FAQ.\r\n- **Website generator** — `generate_website.py` with dynamic styling and sample generation.\r\n\r\n**Upgrade**\r\n\r\n- Existing configs remain valid. See **docs/UPGRADE.md** for optional migrations (e.g. `[Joke_Command]`, `[Feed_Manager]`, `[Path_Command]`) and the banned-users prefix-matching behavior.\r\n\r\n## Contributions\r\n* Feature: Add Polish translation (pl) 80% by @smithpl2000 in https://github.com/agessaman/meshcore-bot/pull/40\r\n* Web_Viewer: fix loading of db_path from config by @Mateusz-Krajewski in https://github.com/agessaman/meshcore-bot/pull/43\r\n* Respond to only `wx` and `gwx` command with usage. by @jeroenvermeulen in https://github.com/agessaman/meshcore-bot/pull/50\r\n\r\n## New Contributors\r\n* @smithpl2000 made their first contribution in https://github.com/agessaman/meshcore-bot/pull/40\r\n* @Mateusz-Krajewski made their first contribution in https://github.com/agessaman/meshcore-bot/pull/43\r\n* @jeroenvermeulen made their first contribution in https://github.com/agessaman/meshcore-bot/pull/50\r\n\r\n**Full Changelog**: https://github.com/agessaman/meshcore-bot/compare/v0.7...v0.8",
      "notesHtml": "<h2>Release notes</h2>\n<p><strong>New commands &amp; features</strong></p>\n<ul>\n<li><strong>Aurora</strong> — New command for aurora/space weather (NOAA client).</li>\n<li><strong>Airplanes</strong> — Aircraft tracking command.</li>\n<li><strong>Reload</strong> — Admin command to reload configuration without restarting the bot.</li>\n<li><strong>Command prefix</strong> — Optional prefix for bot commands (e.g. <code>!path</code>).</li>\n<li><strong>Sub-commands &amp; help</strong> — Commands can expose sub-commands and clearer usage/help; help respects channel restrictions and avoids truncation issues.</li>\n<li><strong>Polish</strong> — Polish translation added (with thanks to the contributor).</li>\n</ul>\n<p><strong>Path &amp; mesh</strong></p>\n<ul>\n<li><strong>Path command</strong> — Graph-based path validation using observed mesh links; presets: <code>balanced</code>, <code>geographic</code>, <code>graph</code>. SNR integration, “prefix best location,” and improved multitest with per-user sessions and path tracking.</li>\n<li><strong>Mesh graph</strong> — New mesh graph logic and <strong>mesh view in the web viewer</strong> (connections, highlighting, sync).</li>\n<li><strong>Contacts (web)</strong> — Time filtering, path sorting, bulk delete, starred nodes, and automatic device name updates.</li>\n</ul>\n<p><strong>Weather</strong></p>\n<ul>\n<li><strong>WXSIM</strong> — Support for custom WXSIM weather sources in <code>wx_command</code> and international weather.</li>\n<li><strong>Global weather</strong> — ZIP code geocoding and companion location features.</li>\n</ul>\n<p><strong>Configuration &amp; behavior</strong></p>\n<ul>\n<li><strong>Config validation</strong> — <code>validate_config.py</code> and validation in <code>modules/config_validation.py</code>; standardized command sections (e.g. <code>[Joke_Command]</code> with <code>enabled</code>); legacy <code>*_enabled</code> still supported.</li>\n<li><strong>Rate limiting</strong> — Per-user rate limiting for bot responses.</li>\n<li><strong>Channel keyword filtering</strong> — Configurable channel filtering for keyword responses.</li>\n<li><strong>Banned users</strong> — Prefix (starts-with) matching for banned user entries.</li>\n<li><strong>Feed manager</strong> — Dedicated <code>[Feed_Manager]</code> section; optional RSS/API feeds.</li>\n<li><strong>Config file</strong> — UTF-8 support and quoted values for monitor channels.</li>\n</ul>\n<p><strong>Web viewer</strong></p>\n<ul>\n<li>Mesh graph view, improved error handling and database path handling, favicons, realtime view.</li>\n<li><strong>Service health checks</strong> — Optional checks and restart logic for the viewer.</li>\n</ul>\n<p><strong>Docker &amp; deployment</strong></p>\n<ul>\n<li><strong>Docker</strong> — Dockerfile, <code>docker-compose.yml</code>, and <code>docker-setup.sh</code> for device detection, paths, and serial handling. Docs in <code>docs/DOCKER.md</code>.</li>\n<li><strong>Install script</strong> — <code>install-service.sh</code> supports Python venv and clearer echo formatting.</li>\n<li><strong>CI</strong> — GitHub Actions for Docker build, tests, and docs; <code>dev</code> branch supported.</li>\n</ul>\n<p><strong>Under the hood</strong></p>\n<ul>\n<li>Command queuing for global cooldowns; escape sequence decoding for greetings and keyword responses; transmission and repeat tracking; unique advert packet tracking and leaderboard.</li>\n<li><strong>Tests</strong> — pytest suite (commands, config validation, rate limiter, mesh graph, path resolution, etc.).</li>\n<li><strong>Docs</strong> — MkDocs site and guides: getting started, configuration, path command config, upgrade, Docker, FAQ.</li>\n<li><strong>Website generator</strong> — <code>generate_website.py</code> with dynamic styling and sample generation.</li>\n</ul>\n<p><strong>Upgrade</strong></p>\n<ul>\n<li>Existing configs remain valid. See <strong>docs/UPGRADE.md</strong> for optional migrations (e.g. <code>[Joke_Command]</code>, <code>[Feed_Manager]</code>, <code>[Path_Command]</code>) and the banned-users prefix-matching behavior.</li>\n</ul>\n<h2>Contributions</h2>\n<ul>\n<li>Feature: Add Polish translation (pl) 80% by @smithpl2000 in <a href=\"https://github.com/agessaman/meshcore-bot/pull/40\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/agessaman/meshcore-bot/pull/40</a></li>\n<li>Web_Viewer: fix loading of db_path from config by @Mateusz-Krajewski in <a href=\"https://github.com/agessaman/meshcore-bot/pull/43\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/agessaman/meshcore-bot/pull/43</a></li>\n<li>Respond to only <code>wx</code> and <code>gwx</code> command with usage. by @jeroenvermeulen in <a href=\"https://github.com/agessaman/meshcore-bot/pull/50\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/agessaman/meshcore-bot/pull/50</a></li>\n</ul>\n<h2>New Contributors</h2>\n<ul>\n<li>@smithpl2000 made their first contribution in <a href=\"https://github.com/agessaman/meshcore-bot/pull/40\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/agessaman/meshcore-bot/pull/40</a></li>\n<li>@Mateusz-Krajewski made their first contribution in <a href=\"https://github.com/agessaman/meshcore-bot/pull/43\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/agessaman/meshcore-bot/pull/43</a></li>\n<li>@jeroenvermeulen made their first contribution in <a href=\"https://github.com/agessaman/meshcore-bot/pull/50\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/agessaman/meshcore-bot/pull/50</a></li>\n</ul>\n<p><strong>Full Changelog</strong>: <a href=\"https://github.com/agessaman/meshcore-bot/compare/v0.7...v0.8\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/agessaman/meshcore-bot/compare/v0.7...v0.8</a></p>\n"
    },
    {
      "version": "v0.7",
      "name": "v0.7",
      "datetime": "2026-01-11T19:35:35Z",
      "url": "https://github.com/agessaman/meshcore-bot/releases/tag/v0.7",
      "prerelease": false,
      "notes": "# Release Notes\r\n\r\n## New Features\r\n\r\n- **Service Plugin Architecture**: Implemented service plugin system for background services that run alongside the bot\r\n- **Packet Capture Service**: Captures packets from MeshCore network and publishes to MQTT brokers for analyzer.letsmesh.net\r\n- **Map Uploader Service**: Uploads node adverts to map.meshcore.dev with signed data authentication\r\n- **Weather Service**: Scheduled weather forecasts, NOAA alert monitoring, and regional lightning detection via MQTT\r\n- **Discord Bridge**: New service plugin to post channel messages to Discord with message queuing and rate limiting for webhook posts\r\n- **Command Enable/Disable**: Individual commands can now be enabled/disabled via configuration\r\n- **Sports Data Clients**: Added ESPN and TheSportsDB API clients for sports command functionality\r\n- **System Health Monitoring**: New `/api/system-health` endpoint for system status reporting\r\n- **Minimal Configuration**: New `config.ini.minimal-example` for users who only need core testing commands\r\n- **Announcements Command**: New command for admin triggered announcements\r\n- **Magic 8 Command**: Added magic 8-ball command for fun responses (thanks @lincomatic)\r\n- **Enhanced Packet Decoding**: Web viewer packet stream now supports packet analysis using `meshcore-decoder`\r\n- **Nix/NixOS Support**: Added Nix flake infrastructure with NixOS module for declarative system-wide deployments (thanks @tbaumann)\r\n- **Web Viewer NixOS Option**: Added `services.meshcore-bot.webviewer.enable` option for NixOS deployments (thanks @tbaumann)\r\n\r\n## Bug Fixes\r\n\r\n- **Segfault Prevention**: Fixed potential segfaults by deep copying event payloads in ChannelManager and service plugins\r\n- **Path Decoding**: Fixed path decoding logic to better handle single nodes and hex values\r\n- **Weather Emoji Truncation**: Improved weather string handling to prevent emoji truncation\r\n- **Database Connections**: Fixed database connection handling and timeout issues\r\n- **Keyword Reporting**: Fixed keyword reporting to web viewer\r\n- **Error Handling**: Improved error handling and logging across multiple modules\r\n\r\n## Improvements\r\n\r\n- **Python Packaging**: Migrated to `pyproject.toml` with proper entry points (`meshcore-bot`, `meshcore-viewer`) (thanks @tbaumann)\r\n- **Code Quality**: Added type hints and docstrings across modules\r\n- **Cooldown Management**: Refactored to centralized cooldown tracking system in BaseCommand\r\n- **Location Resolution**: Improved location name resolution from database using public keys\r\n- **Weather Data**: Improved weather forecast formatting and data retrieval in international weather command\r\n- **Async Handling**: Improved asyncio event loop handling to prevent deadlocks\r\n- **Internet Connectivity**: Implemented thread-safe caching for internet connectivity status\r\n- **MQTT Handling**: Improved non-blocking MQTT connection handling in service plugins\r\n- **Logging**: Added rotating file handlers and improved error reporting\r\n- **Web Viewer**: Improved stability by logging stdout/stderr to files instead of PIPE\r\n- **Database Management**: Optimized database cleanup with smaller batch deletions to reduce lock contention\r\n- **Message Processing**: Improved message content processing by stripping trailing whitespace\r\n- **Help Command**: Added dynamic command list based on usage statistics\r\n\r\n## Configuration Changes\r\n\r\n- Added `--config` parameter support for both main bot and web viewer\r\n- New service plugin configuration sections: `[PacketCapture]`, `[MapUploader]`, `[Weather_Service]`, `[Discord_Bridge]`\r\n- Added `db_path` configuration options for web viewer\r\n- Updated JWT renewal interval to 24 hours\r\n- Added command-specific enable/disable options\r\n\r\n## Dependencies\r\n\r\n- Added: `urllib3>=2.0.0`, `paho-mqtt>=1.6.0`, `cryptography>=41.0.0`, `pynacl>=1.5.0`\r\n- Updated Python dependencies across the board\r\n\r\n## New Contributors\r\n* @lincomatic made their first contribution in https://github.com/agessaman/meshcor\n…",
      "notesHtml": "<h1>Release Notes</h1>\n<h2>New Features</h2>\n<ul>\n<li><strong>Service Plugin Architecture</strong>: Implemented service plugin system for background services that run alongside the bot</li>\n<li><strong>Packet Capture Service</strong>: Captures packets from MeshCore network and publishes to MQTT brokers for analyzer.letsmesh.net</li>\n<li><strong>Map Uploader Service</strong>: Uploads node adverts to map.meshcore.dev with signed data authentication</li>\n<li><strong>Weather Service</strong>: Scheduled weather forecasts, NOAA alert monitoring, and regional lightning detection via MQTT</li>\n<li><strong>Discord Bridge</strong>: New service plugin to post channel messages to Discord with message queuing and rate limiting for webhook posts</li>\n<li><strong>Command Enable/Disable</strong>: Individual commands can now be enabled/disabled via configuration</li>\n<li><strong>Sports Data Clients</strong>: Added ESPN and TheSportsDB API clients for sports command functionality</li>\n<li><strong>System Health Monitoring</strong>: New <code>/api/system-health</code> endpoint for system status reporting</li>\n<li><strong>Minimal Configuration</strong>: New <code>config.ini.minimal-example</code> for users who only need core testing commands</li>\n<li><strong>Announcements Command</strong>: New command for admin triggered announcements</li>\n<li><strong>Magic 8 Command</strong>: Added magic 8-ball command for fun responses (thanks @lincomatic)</li>\n<li><strong>Enhanced Packet Decoding</strong>: Web viewer packet stream now supports packet analysis using <code>meshcore-decoder</code></li>\n<li><strong>Nix/NixOS Support</strong>: Added Nix flake infrastructure with NixOS module for declarative system-wide deployments (thanks @tbaumann)</li>\n<li><strong>Web Viewer NixOS Option</strong>: Added <code>services.meshcore-bot.webviewer.enable</code> option for NixOS deployments (thanks @tbaumann)</li>\n</ul>\n<h2>Bug Fixes</h2>\n<ul>\n<li><strong>Segfault Prevention</strong>: Fixed potential segfaults by deep copying event payloads in ChannelManager and service plugins</li>\n<li><strong>Path Decoding</strong>: Fixed path decoding logic to better handle single nodes and hex values</li>\n<li><strong>Weather Emoji Truncation</strong>: Improved weather string handling to prevent emoji truncation</li>\n<li><strong>Database Connections</strong>: Fixed database connection handling and timeout issues</li>\n<li><strong>Keyword Reporting</strong>: Fixed keyword reporting to web viewer</li>\n<li><strong>Error Handling</strong>: Improved error handling and logging across multiple modules</li>\n</ul>\n<h2>Improvements</h2>\n<ul>\n<li><strong>Python Packaging</strong>: Migrated to <code>pyproject.toml</code> with proper entry points (<code>meshcore-bot</code>, <code>meshcore-viewer</code>) (thanks @tbaumann)</li>\n<li><strong>Code Quality</strong>: Added type hints and docstrings across modules</li>\n<li><strong>Cooldown Management</strong>: Refactored to centralized cooldown tracking system in BaseCommand</li>\n<li><strong>Location Resolution</strong>: Improved location name resolution from database using public keys</li>\n<li><strong>Weather Data</strong>: Improved weather forecast formatting and data retrieval in international weather command</li>\n<li><strong>Async Handling</strong>: Improved asyncio event loop handling to prevent deadlocks</li>\n<li><strong>Internet Connectivity</strong>: Implemented thread-safe caching for internet connectivity status</li>\n<li><strong>MQTT Handling</strong>: Improved non-blocking MQTT connection handling in service plugins</li>\n<li><strong>Logging</strong>: Added rotating file handlers and improved error reporting</li>\n<li><strong>Web Viewer</strong>: Improved stability by logging stdout/stderr to files instead of PIPE</li>\n<li><strong>Database Management</strong>: Optimized database cleanup with smaller batch deletions to reduce lock contention</li>\n<li><strong>Message Processing</strong>: Improved message content processing by stripping trailing whitespace</li>\n<li><strong>Help Command</strong>: Added dynamic command list based on usage statistics</li>\n</ul>\n<h2>Configuration Changes</h2>\n<ul>\n<li>Added <code>--config</code> parameter support for both main bot and web viewer</li>\n<li>New service plugin configuration sections: <code>[PacketCapture]</code>, <code>[MapUploader]</code>, <code>[Weather_Service]</code>, <code>[Discord_Bridge]</code></li>\n<li>Added <code>db_path</code> configuration options for web viewer</li>\n<li>Updated JWT renewal interval to 24 hours</li>\n<li>Added command-specific enable/disable options</li>\n</ul>\n<h2>Dependencies</h2>\n<ul>\n<li>Added: <code>urllib3&gt;=2.0.0</code>, <code>paho-mqtt&gt;=1.6.0</code>, <code>cryptography&gt;=41.0.0</code>, <code>pynacl&gt;=1.5.0</code></li>\n<li>Updated Python dependencies across the board</li>\n</ul>\n<h2>New Contributors</h2>\n<ul>\n<li>@lincomatic made their first contribution in <a href=\"https://github.com/agessaman/meshcor\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/agessaman/meshcor</a>\n…</li>\n</ul>\n"
    },
    {
      "version": "v0.6.1",
      "name": "v0.6.1",
      "datetime": "2025-12-20T23:17:28Z",
      "url": "https://github.com/agessaman/meshcore-bot/releases/tag/v0.6.1",
      "prerelease": false,
      "notes": "- Improved security and enhanced warnings of insecure elements. Thanks @eddieoz!\r\n- Improved path guessing algorithm.\r\n- Added dark mode.\r\n- Improved service installation and added upgrade mode to update existing service integrations.\r\n- Improvements to WebViewer stats and mobile accessibility, introduced limited channel management tool\r\n- Improved sports command logic for game selection.\r\n- Added path length placeholder options for test command.\r\n- Improved reliability of NOAA weather reports.",
      "notesHtml": "<ul>\n<li>Improved security and enhanced warnings of insecure elements. Thanks @eddieoz!</li>\n<li>Improved path guessing algorithm.</li>\n<li>Added dark mode.</li>\n<li>Improved service installation and added upgrade mode to update existing service integrations.</li>\n<li>Improvements to WebViewer stats and mobile accessibility, introduced limited channel management tool</li>\n<li>Improved sports command logic for game selection.</li>\n<li>Added path length placeholder options for test command.</li>\n<li>Improved reliability of NOAA weather reports.</li>\n</ul>\n"
    },
    {
      "version": "v0.6",
      "name": "v0.6",
      "datetime": "2025-12-03T04:12:04Z",
      "url": "https://github.com/agessaman/meshcore-bot/releases/tag/v0.6",
      "prerelease": false,
      "notes": "This version adds these new features:\r\n\r\n- calculation of packet hashes for deduplication of nodes\r\n- the addition of an automated greeter command with an onboarding period to avoid spamming existing active members\r\n- improved localization of bot commands\r\n- commands have a generic per-channel configuration, instead of requiring custom code to work outside of the standard channels, this allows per-command channels\r\n\r\nThis version adds the following improvements:\r\n\r\n- the weather command now has better hourly updates\r\n- improvements to score extraction in the sports command\r\n- better installation scripts\r\n- WebViewer UI improvements\r\n  - delete contacts from the contacts database\r\n  - override the path guessing weighting for key infrastructure nodes\r\n  - cleaned up dashboard to make stats more useful\r\n- improve multi-test command response format",
      "notesHtml": "<p>This version adds these new features:</p>\n<ul>\n<li>calculation of packet hashes for deduplication of nodes</li>\n<li>the addition of an automated greeter command with an onboarding period to avoid spamming existing active members</li>\n<li>improved localization of bot commands</li>\n<li>commands have a generic per-channel configuration, instead of requiring custom code to work outside of the standard channels, this allows per-command channels</li>\n</ul>\n<p>This version adds the following improvements:</p>\n<ul>\n<li>the weather command now has better hourly updates</li>\n<li>improvements to score extraction in the sports command</li>\n<li>better installation scripts</li>\n<li>WebViewer UI improvements<ul>\n<li>delete contacts from the contacts database</li>\n<li>override the path guessing weighting for key infrastructure nodes</li>\n<li>cleaned up dashboard to make stats more useful</li>\n</ul>\n</li>\n<li>improve multi-test command response format</li>\n</ul>\n"
    },
    {
      "version": "v0.5",
      "name": "v0.5",
      "datetime": "2025-11-22T03:39:05Z",
      "url": "https://github.com/agessaman/meshcore-bot/releases/tag/v0.5",
      "prerelease": false,
      "notes": "Added localization to all commands.\r\n\r\nUsed machine translation of strings into German, British English, Spanish, French Canadian, Dutch, Portuguese and Brazilian Portuguese. Any assistance with native-speaker localization would be appreciated.\r\n\r\nAdded wx <location> tomorrow and wx <location> #day commands.\r\n\r\nImplemented a globally accessible weather API using OpenMeteo, currently running as gwx. Command structure is the same as wx command.\r\n\r\nAdded command overrides. If you want to make modifications to a command, you can duplicate the file into ./modules/commands/alternatives and they will override existing commands with the same name field. If you change `name = \"gwx\"` to `name = \"wx\"` the example global weather command will unload the  standard wx command in favor of your replacement.\r\n\r\nUsed path guessing logic to estimate path lengths in test messages. New placeholders are {path_distance} for the estimated total path traveled, and {firstlast_distance} for the distance between the first and last known repeater.\r\n\r\nFixed an issue where we weren't initiating the packet_stream table for the WebViewer integration.\r\n\r\nSeveral bug fixes, and sadly probably several more bugs. This is a work in progress.",
      "notesHtml": "<p>Added localization to all commands.</p>\n<p>Used machine translation of strings into German, British English, Spanish, French Canadian, Dutch, Portuguese and Brazilian Portuguese. Any assistance with native-speaker localization would be appreciated.</p>\n<p>Added wx  tomorrow and wx  #day commands.</p>\n<p>Implemented a globally accessible weather API using OpenMeteo, currently running as gwx. Command structure is the same as wx command.</p>\n<p>Added command overrides. If you want to make modifications to a command, you can duplicate the file into ./modules/commands/alternatives and they will override existing commands with the same name field. If you change <code>name = \"gwx\"</code> to <code>name = \"wx\"</code> the example global weather command will unload the  standard wx command in favor of your replacement.</p>\n<p>Used path guessing logic to estimate path lengths in test messages. New placeholders are {path_distance} for the estimated total path traveled, and {firstlast_distance} for the distance between the first and last known repeater.</p>\n<p>Fixed an issue where we weren't initiating the packet_stream table for the WebViewer integration.</p>\n<p>Several bug fixes, and sadly probably several more bugs. This is a work in progress.</p>\n"
    },
    {
      "version": "v0.4",
      "name": "v0.4",
      "datetime": "2025-10-22T05:13:35Z",
      "url": "https://github.com/agessaman/meshcore-bot/releases/tag/v0.4",
      "prerelease": false,
      "notes": "This version does some internal clean-up on the databases. A new contact database will be populated when you launch this version for the first time.\r\n\r\n- Added processing of all adverts and discovery events. All contact data is stored information in database\r\n- Added repeater geolocation data in the prefix command\r\n- Added logic in the path command to try to deconflict prefixes in path based on distance and node advert age\r\n- Significantly speeds up channel loading during bot startup. Detects all channels now, regardless of empty slots.\r\n- Add web viewer with dashboard that runs in a separate process and provides stats, contact information and \r\n- Various code structure and import improvements to core bot and command modules to support integration\r\n- Add ACL support to restrict access to sensitive commands to DMs from known public keys\r\n- Updated example config.ini files—to use some of the new features, you will need to update your config.ini. The Web_Viewer, Path_Command, Prefix_Command, and Admin_ACL sections have been added, and are necessary for full functionality of the bot.",
      "notesHtml": "<p>This version does some internal clean-up on the databases. A new contact database will be populated when you launch this version for the first time.</p>\n<ul>\n<li>Added processing of all adverts and discovery events. All contact data is stored information in database</li>\n<li>Added repeater geolocation data in the prefix command</li>\n<li>Added logic in the path command to try to deconflict prefixes in path based on distance and node advert age</li>\n<li>Significantly speeds up channel loading during bot startup. Detects all channels now, regardless of empty slots.</li>\n<li>Add web viewer with dashboard that runs in a separate process and provides stats, contact information and </li>\n<li>Various code structure and import improvements to core bot and command modules to support integration</li>\n<li>Add ACL support to restrict access to sensitive commands to DMs from known public keys</li>\n<li>Updated example config.ini files—to use some of the new features, you will need to update your config.ini. The Web_Viewer, Path_Command, Prefix_Command, and Admin_ACL sections have been added, and are necessary for full functionality of the bot.</li>\n</ul>\n"
    },
    {
      "version": "v0.3",
      "name": "v0.3",
      "datetime": "2025-10-10T04:17:05Z",
      "url": "https://github.com/agessaman/meshcore-bot/releases/tag/v0.3",
      "prerelease": false,
      "notes": "- Added channels command to share common hashtag channels, configurable in config.ini\r\n- Added option to geolocate repeaters in output of the prefix command\r\n- Cleaned up config.ini.example to reflect recent changes\r\n- Revised path command to improve consistency of decoding and output.\r\n- Improved ZIP code handling for aqi command\r\n- Added responses for emoji greetings\r\n- Improved sports command to format soccer home/away properly\r\n- Added dice and roll commands for increased randomness\r\n- Improved plugin architecture so command configuration is handled in config.ini and commands code is held in individual files",
      "notesHtml": "<ul>\n<li>Added channels command to share common hashtag channels, configurable in config.ini</li>\n<li>Added option to geolocate repeaters in output of the prefix command</li>\n<li>Cleaned up config.ini.example to reflect recent changes</li>\n<li>Revised path command to improve consistency of decoding and output.</li>\n<li>Improved ZIP code handling for aqi command</li>\n<li>Added responses for emoji greetings</li>\n<li>Improved sports command to format soccer home/away properly</li>\n<li>Added dice and roll commands for increased randomness</li>\n<li>Improved plugin architecture so command configuration is handled in config.ini and commands code is held in individual files</li>\n</ul>\n"
    },
    {
      "version": "v0.2",
      "name": "v0.2",
      "datetime": "2025-09-08T02:55:53Z",
      "url": "https://github.com/agessaman/meshcore-bot/releases/tag/v0.2",
      "prerelease": false,
      "notes": "#### **Enhanced DM Reliability with meshcore-2.1.6**\r\n- **NEW**: Implemented `send_msg_with_retry` for Direct Messages using meshcore-2.1.6\r\n- **NEW**: Automatic ACK confirmation for all DM sends\r\n- **NEW**: Configurable retry parameters with intelligent fallback\r\n- **NEW**: Path optimization and flood mode fallback for failed deliveries\r\n- **NEW**: Enhanced DM logging with success/failure indicators\r\n\r\n#### **Advanced Prefix Command System**\r\n- **NEW**: `prefix <XX>` command to query repeater prefixes via API\r\n- **NEW**: `prefix refresh` subcommand to manually refresh API cache\r\n- **NEW**: `prefix free` command to list available (unused) prefixes\r\n- **NEW**: SQLite database fallback when API is unavailable\r\n- **NEW**: 1-hour in-memory caching for API responses\r\n- **NEW**: Dynamic API source detection in responses\r\n- **NEW**: Random selection of free prefixes for better distribution\r\n\r\n#### **Command Matching Precision**\r\n- **FIXED**: `prefix` command now only matches at the beginning of messages\r\n- **FIXED**: `t_phrase` command restricted to beginning of message (`t ` or `T `)\r\n- **FIXED**: `@` command no longer triggers on \"at\" in middle of messages\r\n- **FIXED**: `repeater` command restricted to DM-only and beginning of message\r\n- **IMPROVED**: All commands now use precise keyword matching",
      "notesHtml": "<h4><strong>Enhanced DM Reliability with meshcore-2.1.6</strong></h4>\n<ul>\n<li><strong>NEW</strong>: Implemented <code>send_msg_with_retry</code> for Direct Messages using meshcore-2.1.6</li>\n<li><strong>NEW</strong>: Automatic ACK confirmation for all DM sends</li>\n<li><strong>NEW</strong>: Configurable retry parameters with intelligent fallback</li>\n<li><strong>NEW</strong>: Path optimization and flood mode fallback for failed deliveries</li>\n<li><strong>NEW</strong>: Enhanced DM logging with success/failure indicators</li>\n</ul>\n<h4><strong>Advanced Prefix Command System</strong></h4>\n<ul>\n<li><strong>NEW</strong>: <code>prefix &lt;XX&gt;</code> command to query repeater prefixes via API</li>\n<li><strong>NEW</strong>: <code>prefix refresh</code> subcommand to manually refresh API cache</li>\n<li><strong>NEW</strong>: <code>prefix free</code> command to list available (unused) prefixes</li>\n<li><strong>NEW</strong>: SQLite database fallback when API is unavailable</li>\n<li><strong>NEW</strong>: 1-hour in-memory caching for API responses</li>\n<li><strong>NEW</strong>: Dynamic API source detection in responses</li>\n<li><strong>NEW</strong>: Random selection of free prefixes for better distribution</li>\n</ul>\n<h4><strong>Command Matching Precision</strong></h4>\n<ul>\n<li><strong>FIXED</strong>: <code>prefix</code> command now only matches at the beginning of messages</li>\n<li><strong>FIXED</strong>: <code>t_phrase</code> command restricted to beginning of message (<code>t </code> or <code>T </code>)</li>\n<li><strong>FIXED</strong>: <code>@</code> command no longer triggers on \"at\" in middle of messages</li>\n<li><strong>FIXED</strong>: <code>repeater</code> command restricted to DM-only and beginning of message</li>\n<li><strong>IMPROVED</strong>: All commands now use precise keyword matching</li>\n</ul>\n"
    },
    {
      "version": "v0.1.1",
      "name": "v0.1.1",
      "datetime": "2025-09-06T19:14:04Z",
      "url": "https://github.com/agessaman/meshcore-bot/releases/tag/v0.1.1",
      "prerelease": false,
      "notes": "Some additional cleanup to remove test files, etc.",
      "notesHtml": "<p>Some additional cleanup to remove test files, etc.</p>\n"
    },
    {
      "version": "v0.1",
      "name": "v0.1 Initial Release",
      "datetime": "2025-09-06T19:05:12Z",
      "url": "https://github.com/agessaman/meshcore-bot/releases/tag/v0.1",
      "prerelease": false,
      "notes": "It wasn't a bot, then it was... forgive my hacking.",
      "notesHtml": "<p>It wasn't a bot, then it was... forgive my hacking.</p>\n"
    }
  ],
  "changelogSource": "github",
  "changelogUpdatedAt": "2026-06-23T22:03:42.155Z"
}
