Skip to content

Commit

Permalink
Add bot_config to bot users (#6220)
Browse files Browse the repository at this point in the history
  • Loading branch information
hpeebles authored Aug 8, 2024
1 parent 1e524b1 commit 1c3c94a
Show file tree
Hide file tree
Showing 12 changed files with 104 additions and 41 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use canister_tracing_macros::trace;
use group_prize_bot::initialize_bot::{Response::*, *};
use ic_cdk::update;
use types::Cycles;
use user_index_canister::c2c_register_bot::OptionalBotConfig;

const BOT_REGISTRATION_FEE: Cycles = 10_000_000_000_000; // 10T

Expand All @@ -21,6 +22,7 @@ async fn initialize_bot(args: Args) -> Response {
let register_bot_args = user_index_canister::c2c_register_bot::Args {
username: args.username.clone(),
display_name: None,
config: OptionalBotConfig::default(),
};
user_index_canister_c2c_client::c2c_register_bot(user_index_canister_id, &register_bot_args, BOT_REGISTRATION_FEE)
.await
Expand Down
4 changes: 4 additions & 0 deletions backend/canisters/user_index/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).

## [unreleased]

### Added

- Add `bot_config` to bot users ([#6220](https://github.com/open-chat-labs/open-chat/pull/6220))

### Removed

- Remove deprecated `is_bot` field from user records ([#6219](https://github.com/open-chat-labs/open-chat/pull/6219))
Expand Down
19 changes: 18 additions & 1 deletion backend/canisters/user_index/api/src/updates/c2c_register_bot.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
use candid::CandidType;
use serde::{Deserialize, Serialize};
use types::Cycles;
use types::{BotConfig, Cycles};

#[derive(CandidType, Serialize, Deserialize, Debug)]
pub struct Args {
pub username: String,
pub display_name: Option<String>,
pub config: OptionalBotConfig,
}

#[derive(CandidType, Serialize, Deserialize, Debug)]
Expand All @@ -20,3 +21,19 @@ pub enum Response {
InsufficientCyclesProvided(Cycles),
InternalError(String),
}

#[derive(CandidType, Serialize, Deserialize, Debug, Default)]
pub struct OptionalBotConfig {
pub supports_direct_messages: Option<bool>,
pub can_be_added_to_groups: Option<bool>,
}

impl From<OptionalBotConfig> for BotConfig {
fn from(value: OptionalBotConfig) -> Self {
BotConfig {
is_oc_controlled: false,
supports_direct_messages: value.supports_direct_messages.unwrap_or_default(),
can_be_added_to_groups: value.can_be_added_to_groups.unwrap_or_default(),
}
}
}
4 changes: 3 additions & 1 deletion backend/canisters/user_index/impl/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ use std::cell::RefCell;
use std::collections::{BTreeMap, HashMap, HashSet, VecDeque};
use std::time::Duration;
use types::{
BuildVersion, CanisterId, CanisterWasm, ChatId, Cryptocurrency, Cycles, DiamondMembershipFees, Milliseconds,
BotConfig, BuildVersion, CanisterId, CanisterWasm, ChatId, Cryptocurrency, Cycles, DiamondMembershipFees, Milliseconds,
TimestampMillis, Timestamped, UserId, UserType,
};
use utils::canister::{CanistersRequiringUpgrade, FailedUpgradeCount};
Expand Down Expand Up @@ -413,6 +413,7 @@ impl Data {
now,
None,
UserType::OcControlledBot,
Some(BotConfig::default()),
);

// Register the AirdropBot
Expand All @@ -423,6 +424,7 @@ impl Data {
now,
None,
UserType::OcControlledBot,
Some(BotConfig::default()),
);

data
Expand Down
49 changes: 23 additions & 26 deletions backend/canisters/user_index/impl/src/lifecycle/post_upgrade.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
use crate::lifecycle::{init_env, init_state};
use crate::memory::get_upgrades_memory;
use crate::{read_state, Data};
use crate::{mutate_state, Data};
use canister_logger::LogEntry;
use canister_tracing_macros::trace;
use ic_cdk::post_upgrade;
use icrc_ledger_types::icrc1::account::Account;
use icrc_ledger_types::icrc1::transfer::TransferArg;
use stable_memory::get_reader;
use std::time::Duration;
use tracing::info;
use types::Cryptocurrency;
use types::BotConfig;
use user_index_canister::post_upgrade::Args;
use utils::cycles::init_cycles_dispenser_client;

Expand All @@ -29,25 +26,25 @@ fn post_upgrade(args: Args) {

info!(version = %args.wasm_version, "Post-upgrade complete");

ic_cdk_timers::set_timer(Duration::ZERO, || ic_cdk::spawn(transfer_to_airdrop_bot()));
}

async fn transfer_to_airdrop_bot() {
let (airdrop_bot, test_mode) = read_state(|state| (state.data.airdrop_bot_canister_id, state.data.test_mode));

const ONE_CHAT: u64 = 1_0000_0000;
let amount = if test_mode { ONE_CHAT } else { 100_000 * ONE_CHAT };

let _ = icrc_ledger_canister_c2c_client::icrc1_transfer(
Cryptocurrency::CHAT.ledger_canister_id().unwrap(),
&TransferArg {
from_subaccount: None,
to: Account::from(airdrop_bot),
fee: None,
created_at_time: None,
memo: None,
amount: amount.into(),
},
)
.await;
mutate_state(|state| {
let now = state.env.now();
state.data.users.set_bot_config(
state.data.proposals_bot_canister_id.into(),
BotConfig {
is_oc_controlled: true,
supports_direct_messages: false,
can_be_added_to_groups: false,
},
now,
);
state.data.users.set_bot_config(
state.data.airdrop_bot_canister_id.into(),
BotConfig {
is_oc_controlled: true,
supports_direct_messages: true,
can_be_added_to_groups: false,
},
now,
);
});
}
8 changes: 7 additions & 1 deletion backend/canisters/user_index/impl/src/model/user.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use candid::{CandidType, Principal};
use serde::{Deserialize, Serialize};
use std::collections::BTreeMap;
use types::{
is_default, is_empty_slice, CyclesTopUp, CyclesTopUpInternal, PhoneNumber, RegistrationFee, SuspensionAction,
is_default, is_empty_slice, BotConfig, CyclesTopUp, CyclesTopUpInternal, PhoneNumber, RegistrationFee, SuspensionAction,
SuspensionDuration, TimestampMillis, UniquePersonProof, UserId, UserSummary, UserSummaryStable, UserSummaryV2,
UserSummaryVolatile, UserType,
};
Expand Down Expand Up @@ -40,6 +40,8 @@ pub struct User {
pub referred_by: Option<UserId>,
#[serde(rename = "ut", default, skip_serializing_if = "is_default")]
pub user_type: UserType,
#[serde(rename = "bc", default, skip_serializing_if = "Option::is_none")]
pub bot_config: Option<BotConfig>,
#[serde(rename = "sd", default, skip_serializing_if = "Option::is_none")]
pub suspension_details: Option<SuspensionDetails>,
#[serde(
Expand Down Expand Up @@ -99,6 +101,7 @@ impl User {
now: TimestampMillis,
referred_by: Option<UserId>,
user_type: UserType,
bot_config: Option<BotConfig>,
) -> User {
User {
principal,
Expand All @@ -115,6 +118,7 @@ impl User {
phone_status: PhoneStatus::None,
referred_by,
user_type,
bot_config,
suspension_details: None,
diamond_membership_details: DiamondMembershipDetailsInternal::default(),
moderation_flags_enabled: 0,
Expand Down Expand Up @@ -167,6 +171,7 @@ impl User {
suspended: self.suspension_details.is_some(),
diamond_membership_status: self.diamond_membership_details.status(now),
is_unique_person: self.unique_person_proof.is_some(),
bot_config: self.bot_config.clone(),
}
}

Expand Down Expand Up @@ -236,6 +241,7 @@ impl Default for User {
phone_status: PhoneStatus::None,
referred_by: None,
user_type: UserType::User,
bot_config: None,
suspension_details: None,
diamond_membership_details: DiamondMembershipDetailsInternal::default(),
moderation_flags_enabled: 0,
Expand Down
25 changes: 19 additions & 6 deletions backend/canisters/user_index/impl/src/model/user_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use serde::{Deserialize, Serialize};
use std::collections::{BTreeSet, HashMap};
use std::ops::RangeFrom;
use tracing::info;
use types::{CyclesTopUp, Milliseconds, SuspensionDuration, TimestampMillis, UniquePersonProof, UserId, UserType};
use types::{BotConfig, CyclesTopUp, Milliseconds, SuspensionDuration, TimestampMillis, UniquePersonProof, UserId, UserType};
use utils::case_insensitive_hash_map::CaseInsensitiveHashMap;
use utils::time::MonthKey;

Expand Down Expand Up @@ -62,11 +62,12 @@ impl UserMap {
now: TimestampMillis,
referred_by: Option<UserId>,
user_type: UserType,
bot_config: Option<BotConfig>,
) {
self.username_to_user_id.insert(&username, user_id);
self.principal_to_user_id.insert(principal, user_id);

let user = User::new(principal, user_id, username, now, referred_by, user_type);
let user = User::new(principal, user_id, username, now, referred_by, user_type, bot_config);
self.users.insert(user_id, user);

if let Some(ref_by) = referred_by {
Expand Down Expand Up @@ -224,6 +225,17 @@ impl UserMap {
true
}

pub fn set_bot_config(&mut self, user_id: UserId, config: BotConfig, now: TimestampMillis) -> bool {
if let Some(user) = self.users.get_mut(&user_id) {
if let Some(c) = &mut user.bot_config {
*c = config;
user.date_updated = now;
return true;
}
}
false
}

pub fn suspend_user(
&mut self,
user_id: UserId,
Expand Down Expand Up @@ -386,6 +398,7 @@ impl UserMap {
user.date_created,
None,
UserType::User,
None,
);
self.update(user, date_created, false);
}
Expand Down Expand Up @@ -457,9 +470,9 @@ mod tests {
let user_id2: UserId = Principal::from_slice(&[3, 2]).into();
let user_id3: UserId = Principal::from_slice(&[3, 3]).into();

user_map.register(principal1, user_id1, username1.clone(), 1, None, UserType::User);
user_map.register(principal2, user_id2, username2.clone(), 2, None, UserType::User);
user_map.register(principal3, user_id3, username3.clone(), 3, None, UserType::User);
user_map.register(principal1, user_id1, username1.clone(), 1, None, UserType::User, None);
user_map.register(principal2, user_id2, username2.clone(), 2, None, UserType::User, None);
user_map.register(principal3, user_id3, username3.clone(), 3, None, UserType::User, None);

let principal_to_user_id: Vec<_> = user_map
.principal_to_user_id
Expand Down Expand Up @@ -496,7 +509,7 @@ mod tests {

let user_id = Principal::from_slice(&[1, 1]).into();

user_map.register(principal, user_id, username1, 1, None, UserType::User);
user_map.register(principal, user_id, username1, 1, None, UserType::User, None);

if let Some(original) = user_map.get_by_principal(&principal) {
let mut updated = original.clone();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ fn process_new_user(
state
.data
.users
.register(caller, user_id, username.clone(), now, referred_by, UserType::User);
.register(caller, user_id, username.clone(), now, referred_by, UserType::User, None);

state.data.local_index_map.add_user(local_user_index_canister_id, user_id);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,15 @@ fn c2c_register_bot_impl(args: Args, state: &mut RuntimeState) -> Response {
}
ic_cdk::api::call::msg_cycles_accept128(BOT_REGISTRATION_FEE);

state
.data
.users
.register(caller, user_id, args.username.clone(), now, None, UserType::Bot);
state.data.users.register(
caller,
user_id,
args.username.clone(),
now,
None,
UserType::Bot,
Some(args.config.into()),
);

state.push_event_to_all_local_user_indexes(
Event::UserRegistered(UserRegistered {
Expand Down
7 changes: 7 additions & 0 deletions backend/libraries/types/can.did
Original file line number Diff line number Diff line change
Expand Up @@ -1885,6 +1885,7 @@ type UserSummaryStable = record {
suspended : bool;
diamond_membership_status : DiamondMembershipStatus;
is_unique_person : bool;
bot_config : opt BotConfig;
};

type UserSummaryVolatile = record {
Expand All @@ -1909,6 +1910,12 @@ type CurrentUserSummary = record {
is_unique_person : bool;
};

type BotConfig = record {
is_oc_controlled : bool;
supports_direct_messages : bool;
can_be_added_to_groups : bool;
};

type SuspensionDetails = record {
reason : text;
action : SuspensionAction;
Expand Down
7 changes: 7 additions & 0 deletions backend/libraries/types/src/bots.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@ use crate::{MessageContentInitial, MessageId};
use candid::CandidType;
use serde::{Deserialize, Serialize};

#[derive(CandidType, Serialize, Deserialize, Clone, Debug, Default)]
pub struct BotConfig {
pub is_oc_controlled: bool,
pub supports_direct_messages: bool,
pub can_be_added_to_groups: bool,
}

#[derive(CandidType, Serialize, Deserialize, Debug)]
pub struct BotMessage {
pub thread_root_message_id: Option<MessageId>,
Expand Down
5 changes: 4 additions & 1 deletion backend/libraries/types/src/user_summary.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
use crate::{DiamondMembershipDetails, DiamondMembershipStatus, DiamondMembershipStatusFull, SuspensionDetails, UserId};
use crate::{
BotConfig, DiamondMembershipDetails, DiamondMembershipStatus, DiamondMembershipStatusFull, SuspensionDetails, UserId,
};
use candid::CandidType;
use serde::{Deserialize, Serialize};

Expand Down Expand Up @@ -34,6 +36,7 @@ pub struct UserSummaryStable {
pub suspended: bool,
pub diamond_membership_status: DiamondMembershipStatus,
pub is_unique_person: bool,
pub bot_config: Option<BotConfig>,
}

#[derive(CandidType, Serialize, Deserialize, Debug)]
Expand Down

0 comments on commit 1c3c94a

Please sign in to comment.