From ad8041bd9d85f2b7bd674ab53d3e5600cafb774d Mon Sep 17 00:00:00 2001 From: Jean Date: Mon, 13 Jul 2026 14:43:48 +0000 Subject: [PATCH] BotServ GREET + NickServ SET GREET Members set a personal greet with NickServ SET GREET; a channel founder enables display with BotServ SET <#channel> GREET ON. On join, if greets are enabled and the member has channel access and a non-empty greet, the assigned bot shows [account] greet in the channel. Per-account greet is a typed field on Account (AccountGreetSet event, rides the account snapshot); the per-channel toggle is a new ChanSetting::BotGreet bool. Greet is public in NickServ INFO. --- api/src/lib.rs | 8 +++++ botserv/src/lib.rs | 5 ++- botserv/src/set.rs | 34 +++++++++++++++++++ nickserv/src/info.rs | 4 +++ nickserv/src/set.rs | 12 ++++++- src/engine/db.rs | 35 ++++++++++++++++++-- src/engine/mod.rs | 77 +++++++++++++++++++++++++++++++++++++++++++- src/grpc.rs | 2 ++ 8 files changed, 172 insertions(+), 5 deletions(-) create mode 100644 botserv/src/set.rs diff --git a/api/src/lib.rs b/api/src/lib.rs index 5d15d22..d916bd4 100644 --- a/api/src/lib.rs +++ b/api/src/lib.rs @@ -307,6 +307,9 @@ pub struct AccountView { pub email: Option, pub ts: u64, pub verified: bool, + // Personal greet shown by a bot when this account joins a greet-enabled + // channel (empty = none). + pub greet: String, } // One channel access-list entry (account -> level, e.g. "op" / "voice"). @@ -383,6 +386,8 @@ pub struct ChannelView { pub topic: String, // BotServ bot assigned to this channel, if any. pub assigned_bot: Option, + // BotServ: whether members' personal greets are shown on join. + pub bot_greet: bool, } // A single ChanServ SET option, named for the typed `set_channel_setting` call. @@ -394,6 +399,8 @@ pub enum ChanSetting { SecureOps, KeepTopic, TopicLock, + // BotServ: show members' personal greets on join. + BotGreet, } impl ChannelView { @@ -507,6 +514,7 @@ pub trait Store { fn note_auth(&mut self, account: &str, success: bool); fn verify_account(&mut self, account: &str) -> Result<(), RegError>; fn set_email(&mut self, account: &str, email: Option) -> Result<(), RegError>; + fn set_greet(&mut self, account: &str, greet: &str) -> Result<(), RegError>; fn group_nick(&mut self, nick: &str, account: &str) -> Result<(), RegError>; fn ungroup_nick(&mut self, nick: &str) -> Result; fn drop_account(&mut self, account: &str) -> Result; diff --git a/botserv/src/lib.rs b/botserv/src/lib.rs index 9abb503..5e30804 100644 --- a/botserv/src/lib.rs +++ b/botserv/src/lib.rs @@ -12,6 +12,8 @@ mod assign; mod info; #[path = "say.rs"] mod say; +#[path = "set.rs"] +mod set; pub struct BotServ { pub uid: String, @@ -37,7 +39,8 @@ impl Service for BotServ { Some("INFO") => info::handle(me, from, args, ctx, db), Some("SAY") => say::handle(me, from, args, ctx, net, db, false), Some("ACT") => say::handle(me, from, args, ctx, net, db, true), - Some("HELP") | None => ctx.notice(me, from.uid, "BotServ keeps service bots for your channels: \x02ASSIGN\x02 <#channel> puts a bot in your channel, \x02UNASSIGN\x02 <#channel> removes it, \x02INFO\x02 shows details, \x02SAY\x02/\x02ACT\x02 <#channel> speaks through the bot. Operators also have \x02BOT\x02 ADD|DEL|LIST."), + Some("SET") => set::handle(me, from, args, ctx, db), + Some("HELP") | None => ctx.notice(me, from.uid, "BotServ keeps service bots for your channels: \x02ASSIGN\x02 <#channel> puts a bot in your channel, \x02UNASSIGN\x02 <#channel> removes it, \x02INFO\x02 shows details, \x02SAY\x02/\x02ACT\x02 <#channel> speaks through the bot, \x02SET\x02 <#channel> GREET toggles greets. Operators also have \x02BOT\x02 ADD|DEL|LIST."), Some(other) => ctx.notice(me, from.uid, format!("I don't know the command \x02{other}\x02. Try \x02HELP\x02.")), } } diff --git a/botserv/src/set.rs b/botserv/src/set.rs new file mode 100644 index 0000000..e92977d --- /dev/null +++ b/botserv/src/set.rs @@ -0,0 +1,34 @@ +use fedserv_api::{ChanSetting, Priv, Sender, ServiceCtx, Store}; + +// SET <#channel>