Exec Body Fn should be passed Parent BotAction #43

Merged
modulatingforce merged 19 commits from parent-botaction-to-child-fn into main 2024-03-25 16:29:44 -04:00

Original Title : Exec Body Fn should be passed Parent BotAction

Passing Parent BotAction to Child ExecBody functions would allow child functions to access attributes of the BotAction including :

  • Parent BotAction's Module
    • This would allow child functions to be able to do additional validation based on BotAction module if required . For example, when validating the module is enabled on a target channel

At the moment, an example use case I want this is for Chat.Say() to validate the target channel first

  • #TODO Implementing this may be it's own PR or if easy enough, I can tack it on here as a type of test

This is a small blocker of enhanced routine functionality , as Child ExecBodies may want to pull attributes from the Parent Routine . Routine core functionality can run without the changes from this PR


The change would require relatively major refactoring, I believe. In particular, I believe the following areas :

  • bot_actions.rs
// ...
  pub type ExecBody = Box<
        dyn Fn(BotAR, PrivmsgMessage) -> Pin<Box<dyn Future<Output = ()> + Send>> + Send + Sync,
    >;

    pub fn asyncbox<T>(f: fn(BotAR, PrivmsgMessage) -> T) -> ExecBody
    where
        T: Future<Output = ()> + Send + 'static,
    {
        Box::new(move |a, b| Box::pin(f(a, b)))
    }
// ...
  • Every Definition of BotAction such such as BotCommand or Listener

Plan of Action :

  • Code in new BotAction structure in above areas for desired functionality
  • QA Test & Validate
    • In particular, with adjustment to Chat.Say() so it validates Module of Target Channel
    • Live tests
  • Clippy / Format & Comments Cleanup
_Original Title : Exec Body Fn should be passed Parent BotAction_ Passing Parent `BotAction` to Child ExecBody functions would allow child functions to access attributes of the BotAction including : - Parent BotAction's Module - This would allow child functions to be able to do additional validation based on BotAction module if required . For example, when validating the module is enabled on a target channel At the moment, an example use case I want this is for `Chat.Say()` to validate the target channel first - [x] _#TODO_ Implementing this may be it's own PR *or* if easy enough, I can tack it on here as a type of test --- This is a small blocker of enhanced routine functionality , as Child ExecBodies may want to pull attributes from the Parent Routine . Routine core functionality can run without the changes from this PR --- The change would require relatively major refactoring, I believe. In particular, I believe the following areas : - `bot_actions.rs` ```rust // ... pub type ExecBody = Box< dyn Fn(BotAR, PrivmsgMessage) -> Pin<Box<dyn Future<Output = ()> + Send>> + Send + Sync, >; pub fn asyncbox<T>(f: fn(BotAR, PrivmsgMessage) -> T) -> ExecBody where T: Future<Output = ()> + Send + 'static, { Box::new(move |a, b| Box::pin(f(a, b))) } // ... ``` - Every Definition of BotAction such such as BotCommand or Listener --- # Plan of Action : - [x] Code in new `BotAction` structure in above areas for desired functionality - [x] QA Test & Validate - [x] In particular, with adjustment to `Chat.Say()` so it validates Module of Target Channel - [x] Live tests - [x] Clippy / Format & Comments Cleanup
notif BotMsgType
All checks were successful
ci/woodpecker/pr/cargo-checks Pipeline was successful
10d25bf34f
Author
Owner

BotMsgType:Notif takes care of some recursive loops I kept seeing with new Chat validation

  • I want to ensure though the following scenario is covered :
  1. If a BotAdmin without Channel Level Elevated Role (Mod,etc), they must promote themselves first in Both Source & Destination Channels
  2. Otherwise, if they say/sayinreplyto to a Channel without those roles, a send_botmsg of BotMsgType:Notif is sent in the Source Channel - this is also validated to ensure the user has elevated privileges (any) here too but slightly different handling (it will send a notif even if BotAdmin but other roles also)

At the moment, I'm able to do this (problem) scenario :

  1. In TestChannel, demote myself so I only have BotAdmin
  2. In my own (Broadcaster) channel, s TestChannel to send a message to the Destination Channel
  3. The message sends to the Destination Channel (ISSUE)
  4. (EXPECATION) The message should not have sent to Destination Channel & an Error Notification Should have been attempted on the Source Channel

Potential way to approach,
I should have a way so the roles are checked just in the destination if say message ?

`BotMsgType:Notif` takes care of some recursive loops I kept seeing with new `Chat` validation - [x] I want to ensure though the following scenario is covered : 1. If a `BotAdmin` without Channel Level Elevated Role (Mod,etc), they must promote themselves first in Both Source & Destination Channels 2. Otherwise, if they say/sayinreplyto to a Channel without those roles, a send_botmsg of BotMsgType:Notif is sent in the Source Channel - this is also validated to ensure the user has elevated privileges (any) here too but slightly different handling (it will send a notif even if BotAdmin but other roles also) At the moment, I'm able to do this (problem) scenario : 1. In TestChannel, demote myself so I only have BotAdmin 2. In my own (Broadcaster) channel, `s TestChannel` to send a message to the Destination Channel 3. The message sends to the Destination Channel (*ISSUE*) 4. (*EXPECATION*) The message should not have sent to Destination Channel & an Error Notification Should have been attempted on the Source Channel --- Potential way to approach, I should have a way so the roles are checked just in the destination if say message ?
Author
Owner

Live Tests - Passed

[x] Test Case > PASSED

Scenario

  • Sender has BotAdmin role
  • At Source Channel, Sender does NOT have any Channel_Elevated roles
  • At Destination Channel, Sender does NOT have any Channel_Elevated roles

Workflow

  1. Attempt Send Say to Destination
  2. Find the Sender does NOT have Channel_Elevated Roles for Desintation
  3. Send Notif to Source (by using PrivMsg)
  4. Find the Sender does NOT have Channel_Elevated Roles for Source
  5. Find the Sender does have BotAdmin Role
  6. Handle Notif by passing to Client.Say()

[x] Test Case > PASSED

Scenario

  • Sender has BotAdmin role
  • At Source Channel, Sender does have SOME Channel_Elevated roles
  • At Destination Channel, Sender does NOT have any Channel_Elevated roles

Workflow

  1. Attempt Send Say to Destination
  2. Find the Sender does NOT have Channel_Elevated Roles for Desintation
  3. Send Notif to Source (by using PrivMsg)
  4. Find the Sender does have SOME Channel_Elevated Roles for Source
  5. Handle Notif by passing to Client.Say()

[x] Test Case > PASSED

Scenario

  • Sender Does NOT have BotAdmin role
  • At Source Channel, Sender does NOT have any Channel_Elevated roles
  • At Destination Channel, Sender does NOT have any Channel_Elevated roles

Workflow

  1. Attempt Send Say to Destination
  2. Find the Sender does NOT have Channel_Elevated Roles for Desintation
  3. Send Notif to Source (by using PrivMsg)
  4. Find the Sender does NOT have Channel_Elevated Roles for Source
  5. Find the Sender does NOT have BotAdmin Role
  6. return without any Notif message sent

[x] Test Case > PASSED

Scenario

  • Sender Does NOT have BotAdmin role
  • At Source Channel, Sender does have SOME Channel_Elevated roles
  • At Destination Channel, Sender does NOT have any Channel_Elevated roles

Workflow

  1. Attempt Send Say to Destination
  2. Find the Sender does NOT have Channel_Elevated Roles for Desintation
  3. Send Notif to Source (by using PrivMsg)
  4. Find the Sender does have SOME Channel_Elevated Roles for Source
  5. Handle Notif by passing to Client.Say()

[x] Test Case > PASSED

Scenario

  • Sender has BotAdmin role
  • At Source Channel, Sender does NOT have any Channel_Elevated roles
  • At Destination Channel, Sender does have SOME Channel_Elevated roles

Workflow

  1. Attempt Send Say to Destination
  2. Find the Sender does have SOME Channel_Elevated Roles for Desintation
  3. Handle Say by passing to Client.Say()

[x] Test Case > PASSED

Scenario

  • Sender has BotAdmin role
  • At Source Channel, Sender does have SOME Channel_Elevated roles
  • At Destination Channel, Sender does have SOME Channel_Elevated roles

Workflow

  1. Attempt Send Say to Destination
  2. Find the Sender does have SOME Channel_Elevated Roles for Desintation
  3. Handle Say by passing to Client.Say()

[x] Test Case > PASSED

Scenario

  • Sender Does NOT have BotAdmin role
  • At Source Channel, Sender does NOT have any Channel_Elevated roles
  • At Destination Channel, Sender does have SOME Channel_Elevated roles

Workflow

  1. Attempt Send Say to Destination
  2. Find the Sender does have SOME Channel_Elevated Roles for Desintation
  3. Handle Say by passing to Client.Say()

[x] Test Case > PASSED

Scenario

  • Sender Does NOT have BotAdmin role
  • At Source Channel, Sender does have SOME Channel_Elevated roles
  • At Destination Channel, Sender does have SOME Channel_Elevated roles

Workflow

  1. Attempt Send Say to Destination
  2. Find the Sender does have SOME Channel_Elevated Roles for Desintation
  3. Handle Say by passing to Client.Say()
# Live Tests - Passed # [x] Test Case > PASSED Scenario - Sender has `BotAdmin` role - At `Source` Channel, Sender does NOT have any `Channel_Elevated` roles - At `Destination` Channel, Sender does NOT have any `Channel_Elevated` roles Workflow 1. Attempt Send `Say` to `Destination` 2. Find the Sender does NOT have `Channel_Elevated` Roles for `Desintation` 3. Send `Notif` to `Source` (by using `PrivMsg`) 4. Find the Sender does NOT have `Channel_Elevated` Roles for `Source` 5. Find the Sender does have `BotAdmin` Role 6. Handle `Notif` by passing to `Client.Say()` # [x] Test Case > PASSED Scenario - Sender has `BotAdmin` role - At `Source` Channel, Sender does have SOME `Channel_Elevated` roles - At `Destination` Channel, Sender does NOT have any `Channel_Elevated` roles Workflow 1. Attempt Send `Say` to `Destination` 2. Find the Sender does NOT have `Channel_Elevated` Roles for `Desintation` 3. Send `Notif` to `Source` (by using `PrivMsg`) 4. Find the Sender does have SOME `Channel_Elevated` Roles for `Source` 6. Handle `Notif` by passing to `Client.Say()` # [x] Test Case > PASSED Scenario - Sender Does NOT have `BotAdmin` role - At `Source` Channel, Sender does NOT have any `Channel_Elevated` roles - At `Destination` Channel, Sender does NOT have any `Channel_Elevated` roles Workflow 1. Attempt Send `Say` to `Destination` 2. Find the Sender does NOT have `Channel_Elevated` Roles for `Desintation` 3. Send `Notif` to `Source` (by using `PrivMsg`) 4. Find the Sender does NOT have `Channel_Elevated` Roles for `Source` 5. Find the Sender does NOT have `BotAdmin` Role 6. `return` without any `Notif` message sent # [x] Test Case > PASSED Scenario - Sender Does NOT have `BotAdmin` role - At `Source` Channel, Sender does have SOME `Channel_Elevated` roles - At `Destination` Channel, Sender does NOT have any `Channel_Elevated` roles Workflow 1. Attempt Send `Say` to `Destination` 2. Find the Sender does NOT have `Channel_Elevated` Roles for `Desintation` 3. Send `Notif` to `Source` (by using `PrivMsg`) 4. Find the Sender does have SOME `Channel_Elevated` Roles for `Source` 6. Handle `Notif` by passing to `Client.Say()` # [x] Test Case > PASSED Scenario - Sender has `BotAdmin` role - At `Source` Channel, Sender does NOT have any `Channel_Elevated` roles - At `Destination` Channel, Sender does have SOME `Channel_Elevated` roles Workflow 1. Attempt Send `Say` to `Destination` 2. Find the Sender does have SOME `Channel_Elevated` Roles for `Desintation` 3. Handle `Say` by passing to `Client.Say()` # [x] Test Case > PASSED Scenario - Sender has `BotAdmin` role - At `Source` Channel, Sender does have SOME `Channel_Elevated` roles - At `Destination` Channel, Sender does have SOME `Channel_Elevated` roles Workflow 1. Attempt Send `Say` to `Destination` 2. Find the Sender does have SOME `Channel_Elevated` Roles for `Desintation` 3. Handle `Say` by passing to `Client.Say()` # [x] Test Case > PASSED Scenario - Sender Does NOT have `BotAdmin` role - At `Source` Channel, Sender does NOT have any `Channel_Elevated` roles - At `Destination` Channel, Sender does have SOME `Channel_Elevated` roles Workflow 1. Attempt Send `Say` to `Destination` 2. Find the Sender does have SOME `Channel_Elevated` Roles for `Desintation` 3. Handle `Say` by passing to `Client.Say()` # [x] Test Case > PASSED Scenario - Sender Does NOT have `BotAdmin` role - At `Source` Channel, Sender does have SOME `Channel_Elevated` roles - At `Destination` Channel, Sender does have SOME `Channel_Elevated` roles Workflow 1. Attempt Send `Say` to `Destination` 2. Find the Sender does have SOME `Channel_Elevated` Roles for `Desintation` 3. Handle `Say` by passing to `Client.Say()`
Author
Owner

Business Logic : Chat Module's enum BotMsgType

#[derive(Clone,Debug)]
pub enum BotMsgType<'a> {
    SayInReplyTo(&'a PrivmsgMessage,String),
    Say(String,String),
    Notif(String), // For Bot Sent Notifications
}

impl Chat {
    pub fn init(
        ratelimiters: HashMap<Channel, RateLimiter>,
        client: TwitchIRCClient<TCPTransport<TLS>, StaticLoginCredentials>,
    ) -> Chat {
//...
}

    #[async_recursion]
    // async fn send_botmsg(&self, msginput: BotMsgType<'_>, params : ExecBodyParams) {
    pub async fn send_botmsg(&self, msginput: BotMsgType<'async_recursion>, params : ExecBodyParams) {

//...
}


    pub async fn say_in_reply_to(&self, msg: &PrivmsgMessage, outmsg: String , params : ExecBodyParams) {


    pub async fn say(&self, channel_login: String, message: String , params : ExecBodyParams) {



As a Custom or Core Developer, when Sending a Message, I should keep the following in mind

  • Send a BotMsgType::Notif to send_botmsg() if I want to ensure the Roles of the Sender in the Source Channel is Considered first before sending the Notification message to the Source Channel

    • These are generally for Core Features ; for example, when sending an error response - but only to elevated users like BotAdmin or Channel elevated users
  • Send a say() or say_in_reply_to() that's very similar to Client API , but includes passing an ExecBodyParams

    • These are handled primarily in Custom Features . For example, when sending a fun message to a different channel
    • these still go through the same process and access control validation as send_botmsg(), but raises a BotMsgType::Notif in certain scenarios of access control failures
# Business Logic : `Chat` Module's `enum BotMsgType` ```rust #[derive(Clone,Debug)] pub enum BotMsgType<'a> { SayInReplyTo(&'a PrivmsgMessage,String), Say(String,String), Notif(String), // For Bot Sent Notifications } impl Chat { pub fn init( ratelimiters: HashMap<Channel, RateLimiter>, client: TwitchIRCClient<TCPTransport<TLS>, StaticLoginCredentials>, ) -> Chat { //... } #[async_recursion] // async fn send_botmsg(&self, msginput: BotMsgType<'_>, params : ExecBodyParams) { pub async fn send_botmsg(&self, msginput: BotMsgType<'async_recursion>, params : ExecBodyParams) { //... } pub async fn say_in_reply_to(&self, msg: &PrivmsgMessage, outmsg: String , params : ExecBodyParams) { pub async fn say(&self, channel_login: String, message: String , params : ExecBodyParams) { ``` --- As a Custom or Core Developer, when Sending a Message, I should keep the following in mind - Send a `BotMsgType::Notif` to `send_botmsg()` if I want to ensure the Roles of the Sender in the Source Channel is Considered first before sending the Notification message to the Source Channel - These are generally for Core Features ; for example, when sending an error response - but only to elevated users like `BotAdmin` or Channel elevated users - Send a `say()` or `say_in_reply_to()` that's very _similar_ to `Client` API , but includes passing an `ExecBodyParams` - These are handled primarily in Custom Features . For example, when sending a fun message to a different channel - these still go through the same process and access control validation as `send_botmsg()`, but raises a `BotMsgType::Notif` in certain scenarios of access control failures
Author
Owner

Business Logic : bot_actions module's struct ExecBodyParams


pub type BotAR = Arc<RwLock<BotInstance>>;
pub type ActAR = Arc<RwLock<BotAction>>;


#[derive(Clone)]
pub struct ExecBodyParams {
    pub bot : BotAR,
    pub msg : PrivmsgMessage,
    pub parent_act : ActAR , 
}


impl ExecBodyParams {

    pub async fn get_parent_module(&self) -> Option<BotModule> {
}

    pub fn get_sender(&self) -> String {
}

    pub fn get_sender_chatbadge(&self) -> Option<ChatBadge> {
}


As a Custom or Core Developer, for BotActions , I could used passed params::ExecBodyParams to pull locks or data from common parameters such as the bot or parent BotAction

As a Core Developer , when developing features that require enhancing (adding or adjusting) passed input parameters to ExecBodies , we can just adjust this one area at struct definition, then adjust other areas if required (generally is not required when at least adding more members)

# Business Logic : `bot_actions` module's `struct ExecBodyParams` ```rust pub type BotAR = Arc<RwLock<BotInstance>>; pub type ActAR = Arc<RwLock<BotAction>>; #[derive(Clone)] pub struct ExecBodyParams { pub bot : BotAR, pub msg : PrivmsgMessage, pub parent_act : ActAR , } impl ExecBodyParams { pub async fn get_parent_module(&self) -> Option<BotModule> { } pub fn get_sender(&self) -> String { } pub fn get_sender_chatbadge(&self) -> Option<ChatBadge> { } ``` --- As a Custom or Core Developer, for `BotActions` , I could used passed `params::ExecBodyParams` to pull locks or data from common parameters such as the `bot` or parent `BotAction` As a Core Developer , when developing features that require enhancing (adding or adjusting) passed input parameters to ExecBodies , we can just adjust this one area at struct definition, then adjust other areas if required (generally is not required when at least adding more members)
comments cleanup
All checks were successful
ci/woodpecker/pr/cargo-checks Pipeline was successful
6912708cfb
modulatingforce changed title from WIP: Exec Body Fn should be passed Parent BotAction to Exec Body Fn should be passed Parent BotAction 2024-03-25 16:27:03 -04:00
modulatingforce deleted branch parent-botaction-to-child-fn 2024-03-25 16:29:44 -04:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: modulatingforce/forcebot_rs#43
No description provided.