mirror of
https://github.com/MarekZegare4/MeshCore-Solo.git
synced 2026-08-03 18:56:15 +00:00
feat(bot): hardening + auto-responder, query commands, quiet hours
Reply-bot overhaul on top of the trigger/reply auto-reply: Robustness - single botTriggerMatches() shared by DM/channel paths; named constants (BOT_REPLY_COOLDOWN_MS / BOT_SCRATCH) replace magic numbers. - per-contact DM throttle (8-entry ring) so a second sender isn't starved while one contact is on cooldown. - channel anti-loop: skip only when an incoming message equals our own reply (was: any reply containing the trigger word — which silently killed channel replies for the common "trigger word in reply" setup). Features - away / reply-to-all: a lone "*" trigger matches every message. - independent DM vs channel triggers (bot_trigger / bot_trigger_ch); "*" works on the channel too, bounded by cooldown + echo guard. - query commands: a DM or monitored-channel message is scanned for "!word" tokens — !ping/!batt/!loc/!time/!temp/!hops/!status/!help — merged into one combined reply. DM = per-contact throttle, ignores quiet hours; channel = broadcast, per-channel cooldown, respects quiet hours. !hops uses getPathHashCount() (0 = direct). - quiet hours (bot_quiet_start/end, local, wraps midnight) silence push replies. - reply counter shown in the BotScreen header. UI / storage - BotScreen: 9 rows, scrolling list (no more cramming), field I/O via fieldBuf()/fieldCap(). - prefs bot_commands_enabled / bot_quiet_start / bot_quiet_end / bot_trigger_ch persisted; schema 0xC0DE000A → 0xC0DE000C with clamping + migration (bot_trigger_ch seeded from bot_trigger on upgrade). - docs: tools_screen bot section rewritten; FEATURES.md refreshed. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
8c0ccaed73
commit
8bd6fbf1cb
@@ -245,9 +245,20 @@ public:
|
||||
// To check if there is pending work
|
||||
bool hasPendingWork() const;
|
||||
|
||||
// Number of auto-replies sent since boot (DM + channel). Shown on BotScreen.
|
||||
uint16_t botReplyCount() const { return _bot_reply_count; }
|
||||
|
||||
private:
|
||||
void tryBotReplyDM(const ContactInfo& from, const char* text);
|
||||
void tryBotReplyChannel(uint8_t channel_idx, const char* text);
|
||||
bool tryBotCommand(const ContactInfo& from, const char* text, uint8_t hops); // DM commands
|
||||
bool tryBotChannelCommand(uint8_t channel_idx, const char* text, uint8_t hops); // channel commands
|
||||
bool botCommandReply(const char* cmd, uint8_t hops, uint32_t ts, char* out, int out_len); // one command → reply text
|
||||
int botScanCommands(const char* body, uint8_t hops, uint32_t ts, char* out, int out_len); // scan "!word"s → combined reply, returns count
|
||||
bool botTriggerMatches(const char* trigger, const char* body, bool allow_wildcard) const;
|
||||
bool botInQuietHours() const; // true when auto-replies should stay silent
|
||||
bool botDmAllowed(const uint8_t* pubkey); // per-contact DM throttle: ok to reply?
|
||||
void botDmRecord(const uint8_t* pubkey); // remember we just replied to this contact
|
||||
|
||||
void writeOKFrame();
|
||||
void writeErrFrame(uint8_t err_code);
|
||||
@@ -320,10 +331,16 @@ private:
|
||||
uint8_t *sign_data;
|
||||
uint32_t sign_data_len;
|
||||
unsigned long dirty_contacts_expiry;
|
||||
unsigned long _bot_last_dm_reply_ms;
|
||||
unsigned long _bot_last_ch_reply_ms;
|
||||
unsigned long _next_auto_advert_ms;
|
||||
|
||||
// Per-contact DM reply throttle: a small ring of the most recent recipients so
|
||||
// one chatty contact can't be spammed while a different sender is still served.
|
||||
struct BotReplyLog { uint8_t key[4]; unsigned long t_ms; bool used; };
|
||||
static const int BOT_DM_LOG_SIZE = 8;
|
||||
BotReplyLog _bot_dm_log[BOT_DM_LOG_SIZE];
|
||||
uint16_t _bot_reply_count; // total auto-replies sent since boot
|
||||
|
||||
TransportKey send_scope;
|
||||
|
||||
uint8_t cmd_frame[MAX_FRAME_SIZE + 1];
|
||||
|
||||
Reference in New Issue
Block a user