Unverified Commit 1be317fb authored by tec's avatar tec
Browse files

Do a bit of fixing/polishing with role reacts

parent 7b0765f7
Pipeline #146 canceled with stages
......@@ -7,10 +7,10 @@ _Involves: File r/w + parsing, discord reactions_
So, for reaction roles, afaict this is what needs to be done
- [X] Migrate config.rs to something like ~config.yml~
- [-] Complete ~reaction_roles.rs~
- [X] Complete ~reaction_roles.rs~
- [X] Load from config (roles, and the rr msg, if they exist)
- [X] Monitor reactions, update user roles etc.
- [ ] On updated to ~config.yml~ (and on bot load, now that I think of it) overwrite the rr msg with content based on roles in config
- [X] Only allow reacts which correspond to roles
* LDAP Integration
......
......@@ -20,8 +20,10 @@ disapprove_react: "⬇"
unsure_react: "❔"
react_role_messages:
- message: 673400351277187072
- message: 674164298632790026
mapping:
🐊: 609708723006472198 # Autonomous Alligators
🐃: 609708839243087892 # Bipedal Bison
🦆: 609708889763479562 # Omnipresent Ostriches
j5: 607478818038480937 # Vote role
👻: 634415546804338688 # Background charachter
......@@ -107,7 +107,9 @@ impl EventHandler for Handler {
match add_reaction.message(&ctx.http) {
Ok(message) => {
let message_type = get_message_type(&message);
if message_type == MessageType::RoleReactMessage {
if message_type == MessageType::RoleReactMessage
&& add_reaction.user_id.0 != CONFIG.bot_id
{
add_role_by_reaction(ctx, message, add_reaction);
return;
}
......@@ -120,7 +122,7 @@ impl EventHandler for Handler {
}
MessageType::LogReact => {
let react_user = add_reaction.user(&ctx).unwrap();
let react_as_string = get_string_from_react(add_reaction.emoji.clone());
let react_as_string = get_string_from_react(&add_reaction.emoji);
if Utc::now().timestamp() - message.timestamp.timestamp() > 300 {
warn!(
"The logreact message {} just tried to use is too old",
......@@ -129,8 +131,8 @@ impl EventHandler for Handler {
return;
}
info!(
"The react {} just added is {:?}",
react_user.name, react_as_string
"The react {} just added is {:?}. In full: {:?}",
react_user.name, react_as_string, add_reaction.emoji
);
let mut msg = MessageBuilder::new();
msg.push_italic(react_user.name);
......@@ -155,7 +157,9 @@ impl EventHandler for Handler {
match removed_reaction.message(&ctx.http) {
Ok(message) => {
let message_type = get_message_type(&message);
if message_type == MessageType::RoleReactMessage {
if message_type == MessageType::RoleReactMessage
&& removed_reaction.user_id != CONFIG.bot_id
{
remove_role_by_reaction(ctx, message, removed_reaction);
return;
}
......
......@@ -7,33 +7,48 @@ use serenity::{
use std::collections::{HashMap, HashSet};
use std::iter::FromIterator;
macro_rules! e {
($error: literal, $x:expr) => {
match $x {
Ok(_) => (),
Err(why) => error!($error, why),
}
};
}
pub fn add_role_by_reaction(ctx: Context, msg: Message, added_reaction: Reaction) {
CONFIG
let user = added_reaction
.user_id
.to_user(&ctx)
.expect("Unable to get user");
if let Some(role_id) = CONFIG
.react_role_messages
.iter()
.find(|rrm| rrm.message == msg.id)
.and_then(|reaction_mapping| {
let react_as_string = get_string_from_react(added_reaction.clone().emoji);
let react_as_string = get_string_from_react(&added_reaction.emoji);
reaction_mapping.mapping.get(&react_as_string)
})
.and_then(|role_id| {
info!(
"{} requested role {}",
added_reaction
.user_id
.to_user(&ctx)
.expect("Unable to get user")
.name,
role_id
);
ctx.http
.add_member_role(
CONFIG.server_id,
added_reaction.user_id.0,
*role_id.as_u64(),
)
.ok()
});
{
info!(
"{} requested role '{}'",
user.name,
role_id
.to_role_cached(&ctx)
.expect("Unable to get role")
.name
);
ctx.http
.add_member_role(
CONFIG.server_id,
added_reaction.user_id.0,
*role_id.as_u64(),
)
.ok();
} else {
warn!("{} provided invalid react for role", user.name);
e!("Unable to delete react: {:?}", added_reaction.delete(&ctx));
}
}
pub fn remove_role_by_reaction(ctx: Context, msg: Message, removed_reaction: Reaction) {
......@@ -42,11 +57,18 @@ pub fn remove_role_by_reaction(ctx: Context, msg: Message, removed_reaction: Rea
.iter()
.find(|rrm| rrm.message == msg.id)
.and_then(|reaction_mapping| {
let react_as_string = get_string_from_react(removed_reaction.clone().emoji);
let react_as_string = get_string_from_react(&removed_reaction.emoji);
reaction_mapping.mapping.get(&react_as_string)
})
.and_then(|role_id| {
info!("{} requested removal of role {}", msg.author.name, role_id);
info!(
"{} requested removal of role '{}'",
msg.author.name,
role_id
.to_role_cached(&ctx)
.expect("Unable to get role")
.name
);
ctx.http
.remove_member_role(
CONFIG.server_id,
......@@ -81,16 +103,38 @@ pub fn sync_all_role_reactions(ctx: Context) {
for (message, mapping) in messages_with_role_mappings {
i += 1;
info!(" Sync: prossessing message #{}", i);
for react in &message.reactions {
let react_as_string = get_string_from_react(&react.reaction_type);
if mapping.contains_key(&react_as_string) {
continue;
}
info!(
" message #{}: Removing non-role react '{}'",
i, react_as_string
);
for _illegal_react in
&message.reaction_users(&ctx, react.reaction_type.clone(), Some(100), None)
{
warn!(" need to implement react removal");
}
}
for (react, role) in mapping {
// the docs say this method can't retrieve more than 100 user reactions at a time, but it seems
// to work fine when set to 255...
info!(" message #{}: processing react '{}'", i, react);
// TODO: proper pagination for the unlikely scenario that there are more than 100 (255?) reactions?
let reaction_type = get_react_from_string(react.clone(), guild.clone());
let reactors = message
.reaction_users(ctx.http.clone(), reaction_type, Some(255), None)
.reaction_users(ctx.http.clone(), reaction_type.clone(), Some(100), None)
.unwrap();
let reactor_ids: HashSet<UserId> = HashSet::from_iter(reactors.iter().map(|r| r.id));
// ensure bot has reacted
if !reactor_ids.contains(&UserId::from(CONFIG.bot_id)) {
e!(
"Unable to add reaction, {:?}",
message.react(&ctx, reaction_type)
);
}
for member in all_members.clone() {
let user_id = &member.user_id();
if reactor_ids.contains(&user_id) {
......
use serenity::model::{channel::ReactionType, guild::PartialGuild};
pub fn get_string_from_react(react: ReactionType) -> String {
pub fn get_string_from_react(react: &ReactionType) -> String {
match react {
ReactionType::Custom {
name: Some(name), ..
} => name,
} => name.to_string(),
ReactionType::Custom { id, name: None, .. } => id.to_string(),
ReactionType::Unicode(name) => name,
ReactionType::Unicode(name) => name.to_string(),
_ => format!("Unrecognised reaction type: {:?}", react),
}
}
......@@ -18,6 +18,6 @@ pub fn get_react_from_string(string: String, guild: PartialGuild) -> ReactionTyp
.find(|e| e.name == string)
.map_or_else(
|| ReactionType::from(string), // unicode emoji
|custom_emoji| ReactionType::from(custom_emoji.id),
|custom_emoji| ReactionType::from(custom_emoji.clone()),
)
}
......@@ -179,17 +179,17 @@ fn get_cached_motion(ctx: &Context, msg: &Message) -> MotionInfo {
let mut m = HashMap::new();
m.insert(
CONFIG.for_vote.to_string(),
msg.reaction_users(ctx, CONFIG.for_vote.to_string(), None, None)
msg.reaction_users(ctx, CONFIG.for_vote.to_string(), Some(100), None)
.unwrap(),
);
m.insert(
CONFIG.against_vote.to_string(),
msg.reaction_users(ctx, CONFIG.against_vote.to_string(), None, None)
msg.reaction_users(ctx, CONFIG.against_vote.to_string(), Some(100), None)
.unwrap(),
);
m.insert(
CONFIG.abstain_vote.to_string(),
msg.reaction_users(ctx, CONFIG.abstain_vote.to_string(), None, None)
msg.reaction_users(ctx, CONFIG.abstain_vote.to_string(), Some(100), None)
.unwrap(),
);
m
......@@ -253,7 +253,7 @@ fn update_motion(
" {:10} {:6} {} on {}",
user.name,
change,
get_string_from_react(reaction.emoji),
get_string_from_react(&reaction.emoji),
topic
);
......@@ -339,7 +339,7 @@ fn update_motion(
}
pub fn reaction_add(ctx: Context, add_reaction: channel::Reaction) {
let react_as_string = get_string_from_react(add_reaction.emoji.clone());
let react_as_string = get_string_from_react(&add_reaction.emoji);
match add_reaction.message(&ctx.http) {
Ok(mut message) => {
if let Ok(user) = add_reaction.user(&ctx) {
......@@ -414,7 +414,7 @@ pub fn reaction_remove(ctx: Context, removed_reaction: channel::Reaction) {
let mut motion_info = get_cached_motion(&ctx, &message);
if let Some(vote) = motion_info
.votes
.get_mut(&get_string_from_react(removed_reaction.emoji.clone()))
.get_mut(&get_string_from_react(&removed_reaction.emoji))
{
vote.retain(|u| u.id != user.id);
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment