Skip to content

Commit

Permalink
Merge branch 'master' into send_message
Browse files Browse the repository at this point in the history
  • Loading branch information
hpeebles authored Jan 31, 2025
2 parents 126291b + 60b8b4c commit 44e73c7
Show file tree
Hide file tree
Showing 168 changed files with 1,255 additions and 719 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions backend/canisters/community/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).

- Introduce new `Integer` bot parameter type ([#7296](https://github.com/open-chat-labs/open-chat/pull/7296))
- Restructure to handle autonomous bots ([#7318](https://github.com/open-chat-labs/open-chat/pull/7318))
- Add `sender` to notifications to prevent notifications from blocked users ([#7330](https://github.com/open-chat-labs/open-chat/pull/7330))

### Fixed

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@ use serde::{Deserialize, Serialize};
use ts_export::ts_export;
use types::{BotPermissions, ChannelId, UserId};

#[ts_export(group, generate_bot_api_key)]
#[ts_export(community, generate_bot_api_key)]
#[derive(CandidType, Serialize, Deserialize, Debug)]
pub struct Args {
pub bot_id: UserId,
pub requested_permissions: BotPermissions,
pub channel_id: Option<ChannelId>,
}

#[ts_export(group, generate_bot_api_key)]
#[ts_export(community, generate_bot_api_key)]
#[derive(CandidType, Serialize, Deserialize, Debug)]
pub enum Response {
Success(SuccessResult),
Expand All @@ -21,7 +21,7 @@ pub enum Response {
NotAuthorized,
}

#[ts_export]
#[ts_export(community, generate_bot_api_key)]
#[derive(CandidType, Serialize, Deserialize, Debug)]
pub struct SuccessResult {
pub api_key: String,
Expand Down
3 changes: 2 additions & 1 deletion backend/canisters/community/impl/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,9 +104,10 @@ impl RuntimeState {
self.data.video_call_operators.iter().any(|o| *o == caller)
}

pub fn push_notification(&mut self, recipients: Vec<UserId>, notification: Notification) {
pub fn push_notification(&mut self, sender: Option<UserId>, recipients: Vec<UserId>, notification: Notification) {
if !recipients.is_empty() {
let args = c2c_push_notification::Args {
sender,
recipients,
authorizer: Some(self.data.local_group_index_canister_id),
notification_bytes: ByteBuf::from(candid::encode_one(notification).unwrap()),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
use crate::CommunityMemberInternal;
use candid::Deserialize;
use serde::Serialize;
use stable_memory_map::{MemberKeyPrefix, StableMemoryMap};
use stable_memory_map::{StableMemoryMap, UserIdKeyPrefix};
use std::collections::BTreeSet;
use types::{is_default, CommunityRole, TimestampMillis, Timestamped, UserId, UserType, Version};

#[derive(Serialize, Deserialize)]
pub struct MembersStableStorage {
prefix: MemberKeyPrefix,
prefix: UserIdKeyPrefix,
}

impl StableMemoryMap<MemberKeyPrefix, CommunityMemberInternal> for MembersStableStorage {
fn prefix(&self) -> &MemberKeyPrefix {
impl StableMemoryMap<UserIdKeyPrefix, CommunityMemberInternal> for MembersStableStorage {
fn prefix(&self) -> &UserIdKeyPrefix {
&self.prefix
}

Expand Down Expand Up @@ -48,7 +48,7 @@ impl MembersStableStorage {
impl Default for MembersStableStorage {
fn default() -> Self {
MembersStableStorage {
prefix: MemberKeyPrefix::new_from_community(),
prefix: UserIdKeyPrefix::new_from_community(),
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::{can_borrow_state, run_regular_jobs};
use timer_job_queues::{grouped_timer_job_batch, TimerJobItem, TimerJobItemGroup};
use timer_job_queues::{grouped_timer_job_batch, TimerJobItem};
use types::UserId;
use user_canister::CommunityCanisterEvent;
use utils::canister::should_retry_failed_c2c_call;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ fn commit(
channel_avatar_id,
});

state.push_notification(users_added.clone(), notification);
state.push_notification(Some(added_by), users_added.clone(), notification);

jobs::expire_members::start_job_if_required(state);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ fn add_reaction_impl(args: Args, state: &mut RuntimeState) -> Response {
channel_avatar_id: channel.chat.avatar.as_ref().map(|d| d.id),
});

state.push_notification(vec![message.sender], notification);
state.push_notification(Some(user_id), vec![message.sender], notification);
}

state
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ fn c2c_tip_message_impl(args: Args, state: &mut RuntimeState) -> Response {
community_avatar_id: state.data.avatar.as_ref().map(|a| a.id),
channel_avatar_id: channel.chat.avatar.as_ref().map(|a| a.id),
});
state.push_notification(vec![message.sender], notification);
state.push_notification(Some(user_id), vec![message.sender], notification);

state
.data
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use crate::{
use canister_api_macros::update;
use canister_tracing_macros::trace;
use community_canister::delete_channel::{Response::*, *};
use stable_memory_map::{BaseKeyPrefix, ChatEventKeyPrefix, MemberKeyPrefix};
use stable_memory_map::{BaseKeyPrefix, ChatEventKeyPrefix, UserIdKeyPrefix};
use tracing::info;
use types::{ChannelDeleted, ChannelId};

Expand Down Expand Up @@ -76,7 +76,7 @@ fn delete_channel_impl(channel_id: ChannelId, state: &mut RuntimeState) -> Respo
state
.data
.stable_memory_keys_to_garbage_collect
.push(BaseKeyPrefix::from(MemberKeyPrefix::new_from_channel(channel_id)));
.push(BaseKeyPrefix::from(UserIdKeyPrefix::new_from_channel(channel_id)));

crate::jobs::garbage_collect_stable_memory::start_job_if_required(state);

Expand Down
14 changes: 8 additions & 6 deletions backend/canisters/community/impl/src/updates/send_message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,16 +151,17 @@ fn prepare(
}

let now = state.env.now();
let sender = caller.agent();

if let Some(version) = community_rules_accepted {
state.data.members.mark_rules_accepted(&caller.agent(), version, now);
state.data.members.mark_rules_accepted(&sender, version, now);
}

if caller.is_bot() {
return Ok(None);
}

if let Some(member) = state.data.members.get_by_user_id(&caller.agent()) {
if let Some(member) = state.data.members.get_by_user_id(&sender) {
if state.data.rules.enabled
&& !member.user_type.is_bot()
&& member
Expand Down Expand Up @@ -205,6 +206,7 @@ fn process_send_message_result(
register_timer_jobs(channel_id, thread_root_message_index, message_event, now, &mut state.data);

if !result.unfinalised_bot_message {
let sender = caller.agent();
let notification = Notification::ChannelMessage(ChannelMessageNotification {
community_id,
channel_id,
Expand All @@ -213,7 +215,7 @@ fn process_send_message_result(
event_index: message_event.index,
community_name: state.data.name.value.clone(),
channel_name,
sender: caller.agent(),
sender,
sender_name: sender_username,
sender_display_name,
message_type: content.message_type(),
Expand All @@ -224,15 +226,15 @@ fn process_send_message_result(
channel_avatar_id,
crypto_transfer: content.notification_crypto_transfer_details(&users_mentioned.mentioned_directly),
});
state.push_notification(result.users_to_notify, notification);
state.push_notification(Some(sender), result.users_to_notify, notification);

if new_achievement && !caller.is_bot() {
for a in result
.message_event
.event
.achievements(false, thread_root_message_index.is_some())
{
state.data.notify_user_of_achievement(caller.agent(), a);
state.data.notify_user_of_achievement(sender, a);
}
}

Expand Down Expand Up @@ -299,7 +301,7 @@ fn process_send_message_result(
event_index,
activity,
timestamp: now,
user_id: Some(caller.agent()),
user_id: Some(sender),
}),
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ fn start_video_call_impl(args: Args, state: &mut RuntimeState) -> Response {
channel_avatar_id: channel.chat.avatar.as_ref().map(|d| d.id),
});

state.push_notification(users_to_notify, notification);
state.push_notification(Some(sender), users_to_notify, notification);
handle_activity_notification(state);

if let Some(expiry) = expires_at {
Expand Down
1 change: 1 addition & 0 deletions backend/canisters/group/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
### Changed

- Restructure to handle autonomous bots ([#7318](https://github.com/open-chat-labs/open-chat/pull/7318))
- Add `sender` to notifications to prevent notifications from blocked users ([#7330](https://github.com/open-chat-labs/open-chat/pull/7330))

### Fixed

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ pub enum Response {
NotAuthorized,
}

#[ts_export]
#[ts_export(group, generate_bot_api_key)]
#[derive(CandidType, Serialize, Deserialize, Debug)]
pub struct SuccessResult {
pub api_key: String,
Expand Down
3 changes: 2 additions & 1 deletion backend/canisters/group/impl/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,9 +109,10 @@ impl RuntimeState {
}
}

pub fn push_notification(&mut self, recipients: Vec<UserId>, notification: Notification) {
pub fn push_notification(&mut self, sender: Option<UserId>, recipients: Vec<UserId>, notification: Notification) {
if !recipients.is_empty() {
let args = c2c_push_notification::Args {
sender,
recipients,
authorizer: Some(self.data.local_group_index_canister_id),
notification_bytes: ByteBuf::from(candid::encode_one(notification).unwrap()),
Expand Down
2 changes: 1 addition & 1 deletion backend/canisters/group/impl/src/model/user_event_batch.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::{can_borrow_state, run_regular_jobs};
use timer_job_queues::{grouped_timer_job_batch, TimerJobItem, TimerJobItemGroup};
use timer_job_queues::{grouped_timer_job_batch, TimerJobItem};
use types::UserId;
use user_canister::GroupCanisterEvent;
use utils::canister::should_retry_failed_c2c_call;
Expand Down
1 change: 1 addition & 0 deletions backend/canisters/group/impl/src/updates/add_reaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ fn add_reaction_impl(args: Args, state: &mut RuntimeState) -> Response {

if !notifications_muted {
state.push_notification(
Some(user_id),
vec![message.sender],
Notification::GroupReactionAdded(GroupReactionAddedNotification {
chat_id,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ fn c2c_tip_message_impl(args: Args, state: &mut RuntimeState) -> Response {
let chat_id = state.env.canister_id().into();

state.push_notification(
Some(user_id),
vec![message.sender],
Notification::GroupMessageTipped(GroupMessageTipped {
chat_id,
Expand Down
9 changes: 5 additions & 4 deletions backend/canisters/group/impl/src/updates/send_message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ fn process_send_message_result(
register_timer_jobs(thread_root_message_index, message_event, now, &mut state.data);

if !result.unfinalised_bot_message {
let sender = caller.agent();
let content = &message_event.event.content;
let chat_id = state.env.canister_id().into();

Expand All @@ -146,7 +147,7 @@ fn process_send_message_result(
message_index,
event_index,
group_name: state.data.chat.name.value.clone(),
sender: caller.agent(),
sender,
sender_name: sender_username,
sender_display_name,
message_type: content.message_type(),
Expand All @@ -155,11 +156,11 @@ fn process_send_message_result(
group_avatar_id: state.data.chat.avatar.as_ref().map(|d| d.id),
crypto_transfer: content.notification_crypto_transfer_details(&mentioned),
});
state.push_notification(result.users_to_notify, notification);
state.push_notification(Some(sender), result.users_to_notify, notification);

if new_achievement && !caller.is_bot() {
for a in message_event.event.achievements(false, thread_root_message_index.is_some()) {
state.data.notify_user_of_achievement(caller.agent(), a);
state.data.notify_user_of_achievement(sender, a);
}
}

Expand Down Expand Up @@ -230,7 +231,7 @@ fn process_send_message_result(
event_index,
activity,
timestamp: now,
user_id: Some(caller.agent()),
user_id: Some(sender),
}),
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ fn start_video_call_impl(args: Args, state: &mut RuntimeState) -> Response {
group_avatar_id: state.data.chat.avatar.as_ref().map(|d| d.id),
crypto_transfer: None,
});
state.push_notification(result.users_to_notify, notification);
state.push_notification(Some(sender), result.users_to_notify, notification);
handle_activity_notification(state);

let max_duration = args.max_duration.unwrap_or(HOUR_IN_MS);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::LocalGroupIndexEvent;
use timer_job_queues::{grouped_timer_job_batch, TimerJobItem, TimerJobItemGroup};
use timer_job_queues::{grouped_timer_job_batch, TimerJobItem};
use types::CanisterId;
use utils::canister::should_retry_failed_c2c_call;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::updates::c2c_notify_low_balance::top_up_canister;
use crate::CommunityEvent;
use timer_job_queues::{grouped_timer_job_batch, TimerJobItem, TimerJobItemGroup};
use timer_job_queues::{grouped_timer_job_batch, TimerJobItem};
use types::CanisterId;
use utils::canister::{is_out_of_cycles_error, should_retry_failed_c2c_call};

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::updates::c2c_notify_low_balance::top_up_canister;
use crate::GroupEvent;
use timer_job_queues::{grouped_timer_job_batch, TimerJobItem, TimerJobItemGroup};
use timer_job_queues::{grouped_timer_job_batch, TimerJobItem};
use types::CanisterId;
use utils::canister::{is_out_of_cycles_error, should_retry_failed_c2c_call};

Expand Down
11 changes: 6 additions & 5 deletions backend/canisters/local_user_index/api/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@ use candid::{CandidType, Principal};
use serde::{Deserialize, Serialize};
use types::nns::CryptoAmount;
use types::{
is_default, AutonomousConfig, BotInstallationLocation, CanisterId, ChannelLatestMessageIndex, ChatId, ChitEarnedReason,
CommunityId, Cryptocurrency, DiamondMembershipPlanDuration, MessageContent, MessageContentInitial, MessageId, MessageIndex,
NotifyChit, PhoneNumber, ReferralType, SlashCommandSchema, SuspensionDuration, TimestampMillis, UniquePersonProof,
UpdateUserPrincipalArgs, User, UserCanisterStreakInsuranceClaim, UserCanisterStreakInsurancePayment, UserId, UserType,
is_default, AutonomousConfig, BotDefinition, BotInstallationLocation, CanisterId, ChannelLatestMessageIndex, ChatId,
ChitEarnedReason, CommunityId, Cryptocurrency, DiamondMembershipPlanDuration, MessageContent, MessageContentInitial,
MessageId, MessageIndex, NotifyChit, PhoneNumber, ReferralType, SlashCommandSchema, SuspensionDuration, TimestampMillis,
UniquePersonProof, UpdateUserPrincipalArgs, User, UserCanisterStreakInsuranceClaim, UserCanisterStreakInsurancePayment,
UserId, UserType,
};

mod lifecycle;
Expand Down Expand Up @@ -96,7 +97,7 @@ pub struct BotRegistered {
#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct BotUpdated {
pub user_id: UserId,
pub commands: Option<Vec<SlashCommandSchema>>,
pub definition: BotDefinition,
}

#[derive(Serialize, Deserialize, Clone, Debug)]
Expand Down
1 change: 1 addition & 0 deletions backend/canisters/local_user_index/api/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ fn main() {
}

generate_ts_method!(local_user_index, access_token);
generate_ts_method!(local_user_index, access_token_v2);
generate_ts_method!(local_user_index, chat_events);
generate_ts_method!(local_user_index, group_and_community_summary_updates);

Expand Down
9 changes: 4 additions & 5 deletions backend/canisters/local_user_index/impl/src/model/bots_map.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use candid::Principal;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use types::{AutonomousConfig, SlashCommandSchema, UserId};
use types::{AutonomousConfig, BotDefinition, SlashCommandSchema, UserId};

#[derive(Serialize, Deserialize, Default)]
pub struct BotsMap {
Expand Down Expand Up @@ -53,11 +53,10 @@ impl BotsMap {
self.principal_to_user_id.insert(user_principal, user_id);
}

pub fn update(&mut self, user_id: UserId, commands: Option<Vec<SlashCommandSchema>>) {
pub fn update(&mut self, user_id: UserId, definition: BotDefinition) {
self.bots.entry(user_id).and_modify(|bot| {
if let Some(commands) = commands {
bot.commands = commands;
}
bot.commands = definition.commands;
bot.autonomous_config = definition.autonomous_config;
});
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::updates::c2c_notify_low_balance::top_up_user;
use crate::UserEvent;
use timer_job_queues::{grouped_timer_job_batch, TimerJobItem, TimerJobItemGroup};
use timer_job_queues::{grouped_timer_job_batch, TimerJobItem};
use types::UserId;
use utils::canister::{is_out_of_cycles_error, should_retry_failed_c2c_call};

Expand Down
Loading

0 comments on commit 44e73c7

Please sign in to comment.