Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
UCC
Discord Bot
Commits
8a924d44
Unverified
Commit
8a924d44
authored
Jul 04, 2020
by
tec
Browse files
Extract main serenity logic into own file
parent
09674e97
Changes
4
Hide whitespace changes
Inline
Side-by-side
src/config.test.yml
View file @
8a924d44
...
...
@@ -2,6 +2,7 @@ server_id: 606351521117896704 # general
main_channel
:
606351521117896706
# the-corner
welcome_channel
:
606351613816209418
# general
announcement_channel
:
606351521117896706
# the-corner
readme_channel
:
606351613816209418
# general
bot_id
:
607078903969742848
...
...
@@ -10,6 +11,7 @@ vote_role: 607478818038480937 # Vote Role
tiebreaker_role
:
607509283483025409
# tie-breaker
unregistered_member_role
:
608282247350714408
# unregistered
registered_member_role
:
608282133118582815
# registered
expired_member_role
:
607479030370926613
# registered
command_prefix
:
"
!"
for_vote
:
"
👍"
...
...
src/config.ucc.yml
View file @
8a924d44
...
...
@@ -5,12 +5,14 @@ announcement_channel: 264411219627212801 # committee
readme_channel
:
674252245008908298
# readme
bot_id
:
635407267881156618
ical_url
:
"
https://calendar.google.com/calendar/ical/rb44is9l4dftsnk6lmf1qske6g%40group.calendar.google.com/public/basic.ics"
vote_pool_size
:
8
# 4 exec + Fresher rep + 3 ocm
vote_role
:
269817189966544896
# @committee
tiebreaker_role
:
0
# No tiebreak apparently 635370432568098817 # @Presiding Presidenterino
unregistered_member_role
:
674641042464833548
# @unregistered
registered_member_role
:
692754285557055490
# @member
expired_member_role
:
692754285557055490
# @member
command_prefix
:
"
!"
...
...
src/main.rs
View file @
8a924d44
...
...
@@ -12,241 +12,27 @@ extern crate guard;
extern
crate
diesel
;
extern
crate
ldap3
;
extern
crate
reqwest
;
use
simplelog
::
*
;
use
std
::
fs
::
File
;
use
chrono
::
prelude
::
Utc
;
use
serenity
::{
model
::{
channel
,
channel
::
Message
,
gateway
::
Ready
,
guild
::
Member
},
prelude
::
*
,
utils
::
MessageBuilder
,
};
use
serenity
::
client
::
Client
;
#[macro_use]
mod
util
;
mod
config
;
mod
database
;
mod
ical
;
mod
ldap
;
mod
reaction_roles
;
mod
serenity_handler
;
mod
token_management
;
mod
user_management
;
mod
voting
;
use
rand
::
seq
::
SliceRandom
;
use
config
::{
CONFIG
,
SECRETS
};
use
reaction_roles
::{
add_role_by_reaction
,
remove_role_by_reaction
};
use
util
::
get_string_from_react
;
struct
Handler
;
pub
const
MENTION_RESPONSES
:
&
[
&
str
]
=
&
[
"Oh hello there"
,
"Stop bothering me. I'm busy."
,
"You know, I'm trying to keep track of this place. I don't need any more distractions."
,
"Don't you have better things to do?"
,
"(sigh) what now?"
,
"Yes, yes, I know I'm brilliant"
,
"What do I need to do to catch a break around here? Eh."
,
"Mmmmhmmm. I'm still around, don't mind me."
,
"You know, some people would consider this rude. Luckily I'm not one of those people. In fact, I'm not even a person."
,
"Perhaps try bothering someone else for a change."
];
impl
EventHandler
for
Handler
{
// Set a handler for the `message` event - so that whenever a new message
// is received - the closure (or function) passed will be called.
//
// Event handlers are dispatched through a threadpool, and so multiple
// events can be dispatched simultaneously.
fn
message
(
&
self
,
ctx
:
Context
,
msg
:
Message
)
{
if
!
(
msg
.content
.starts_with
(
&
CONFIG
.command_prefix
))
{
if
msg
.content
.contains
(
&
format!
(
"<@!{}>"
,
CONFIG
.bot_id
))
// desktop mentions
||
msg
.content
.contains
(
&
format!
(
"<@{}>"
,
CONFIG
.bot_id
))
// mobile mentions
{
send_message!
(
msg
.channel_id
,
&
ctx
.http
,
MENTION_RESPONSES
.choose
(
&
mut
rand
::
thread_rng
())
.expect
(
"We couldn't get any sass"
)
);
}
return
;
}
let
message_content
:
Vec
<
_
>
=
msg
.content
[
1
..
]
.splitn
(
2
,
' '
)
.collect
();
let
content
=
if
message_content
.len
()
>
1
{
message_content
[
1
]
}
else
{
""
};
match
message_content
[
0
]
{
"say"
=>
println!
(
"{:#?}"
,
msg
.content
),
"register"
=>
user_management
::
Commands
::
register
(
ctx
,
msg
.clone
(),
content
),
"verify"
=>
user_management
::
Commands
::
verify
(
ctx
,
msg
.clone
(),
content
),
"profile"
=>
user_management
::
Commands
::
profile
(
ctx
,
msg
.clone
(),
content
),
"set"
=>
user_management
::
Commands
::
set_info
(
ctx
,
msg
.clone
(),
content
),
"clear"
=>
user_management
::
Commands
::
clear_info
(
ctx
,
msg
.clone
(),
content
),
"move"
=>
voting
::
Commands
::
move_something
(
ctx
,
msg
.clone
(),
content
),
"motion"
=>
voting
::
Commands
::
motion
(
ctx
,
msg
.clone
(),
content
),
"poll"
=>
voting
::
Commands
::
poll
(
ctx
,
msg
.clone
(),
content
),
"cowsay"
=>
voting
::
Commands
::
cowsay
(
ctx
,
msg
.clone
(),
content
),
"source"
=>
{
let
mut
mesg
=
MessageBuilder
::
new
();
mesg
.push
(
"You want to look at my insides!? Eurgh.
\n
Just kidding, you can go over "
,
);
mesg
.push_italic
(
"every inch"
);
mesg
.push
(
" of me here: https://gitlab.ucc.asn.au/UCC/discord-bot 😉"
);
send_message!
(
msg
.channel_id
,
&
ctx
.http
,
mesg
.build
());
}
"help"
=>
{
// Plaintext version, keep in case IRC users kick up a fuss
// let mut message = MessageBuilder::new();
// message.push_line(format!(
// "Use {}move <action> to make a circular motion",
// &CONFIG.command_prefix
// ));
// message.push_line(format!(
// "Use {}poll <proposal> to see what people think about something",
// &CONFIG.command_prefix
// ));
// send_message!(msg.channel_id, &ctx.http, message.build());
let
result
=
msg
.channel_id
.send_message
(
&
ctx
.http
,
|
m
|
{
m
.embed
(|
embed
|
{
embed
.colour
(
serenity
::
utils
::
Colour
::
DARK_GREY
);
embed
.title
(
"Commands for the UCC Bot"
);
embed
.field
(
"About"
,
"This is UCC's own little in-house bot, please treat it nicely :)"
,
false
);
embed
.field
(
"Commitee"
,
"`!move <text>` to make a circular motion
\n
\
`!poll <text>` to get people's opinions on something"
,
false
);
embed
.field
(
"Account"
,
"`!register <ucc username>` to link your Discord and UCC account
\n
\
`!profile <user>` to get the profile of a user
\n
\
`!set <bio|git|web|photo>` to set that property of _your_ profile
\n
\
`!updateroles` to update your registered roles"
,
false
);
embed
.field
(
"Fun"
,
"`!cowsay <text>` to have a cow say your words
\n
\
with no `<text>` it'll give you a fortune 😉"
,
false
);
embed
});
m
});
if
let
Err
(
why
)
=
result
{
error!
(
"Error sending help embed: {:?}"
,
why
);
}
}
// undocumented (in !help) functins
"logreact"
=>
{
e!
(
"Error deleting logreact prompt: {:?}"
,
msg
.delete
(
&
ctx
));
send_message!
(
msg
.channel_id
,
&
ctx
.http
,
"React to this to log the ID (for the next 5min)"
);
}
"ldap"
=>
send_message!
(
msg
.channel_id
,
&
ctx
.http
,
format!
(
"{:?}"
,
ldap
::
ldap_search
(
message_content
[
1
]))
),
"tla"
=>
send_message!
(
msg
.channel_id
,
&
ctx
.http
,
format!
(
"{:?}"
,
ldap
::
tla_search
(
message_content
[
1
]))
),
"updateroles"
=>
user_management
::
Commands
::
update_registered_role
(
ctx
,
msg
),
_
=>
send_message!
(
msg
.channel_id
,
&
ctx
.http
,
format!
(
"Unrecognised command. Try {}help"
,
&
CONFIG
.command_prefix
)
),
}
}
fn
reaction_add
(
&
self
,
ctx
:
Context
,
add_reaction
:
channel
::
Reaction
)
{
match
add_reaction
.message
(
&
ctx
.http
)
{
Ok
(
message
)
=>
match
get_message_type
(
&
message
)
{
MessageType
::
RoleReactMessage
if
add_reaction
.user_id
.0
!=
CONFIG
.bot_id
=>
{
add_role_by_reaction
(
&
ctx
,
message
,
add_reaction
);
return
;
}
_
if
message
.author.id
.0
!=
CONFIG
.bot_id
||
add_reaction
.user_id
==
CONFIG
.bot_id
=>
{
return
}
MessageType
::
Motion
=>
voting
::
reaction_add
(
ctx
,
add_reaction
),
MessageType
::
LogReact
=>
{
let
react_user
=
add_reaction
.user
(
&
ctx
)
.unwrap
();
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"
,
react_user
.name
);
return
;
}
info!
(
"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
);
msg
.push
(
format!
(
" wanted to know that {} is represented by "
,
add_reaction
.emoji
,
));
msg
.push_mono
(
react_as_string
);
send_message!
(
message
.channel_id
,
&
ctx
.http
,
msg
.build
());
}
_
=>
{}
},
Err
(
why
)
=>
error!
(
"Failed to get react message {:?}"
,
why
),
}
}
fn
reaction_remove
(
&
self
,
ctx
:
Context
,
removed_reaction
:
channel
::
Reaction
)
{
match
removed_reaction
.message
(
&
ctx
.http
)
{
Ok
(
message
)
=>
match
get_message_type
(
&
message
)
{
MessageType
::
RoleReactMessage
if
removed_reaction
.user_id
!=
CONFIG
.bot_id
=>
{
remove_role_by_reaction
(
&
ctx
,
message
,
removed_reaction
);
return
;
}
_
if
message
.author.id
.0
!=
CONFIG
.bot_id
||
removed_reaction
.user_id
==
CONFIG
.bot_id
=>
{
return
}
MessageType
::
Motion
=>
voting
::
reaction_remove
(
ctx
,
removed_reaction
),
_
=>
{}
},
Err
(
why
)
=>
error!
(
"Failed to get react message {:?}"
,
why
),
}
}
fn
guild_member_addition
(
&
self
,
ctx
:
Context
,
_guild_id
:
serenity
::
model
::
id
::
GuildId
,
the_new_member
:
Member
,
)
{
user_management
::
new_member
(
&
ctx
,
the_new_member
);
}
// Set a handler to be called on the `ready` event. This is called when a
// shard is booted, and a READY payload is sent by Discord. This payload
// contains data like the current user's guild Ids, current user data,
// private channels, and more.
//
// In this case, just print what the current user's username is.
fn
ready
(
&
self
,
ctx
:
Context
,
ready
:
Ready
)
{
info!
(
"{} is connected!"
,
ready
.user.name
);
reaction_roles
::
sync_all_role_reactions
(
&
ctx
);
}
fn
resume
(
&
self
,
ctx
:
Context
,
_
:
serenity
::
model
::
event
::
ResumedEvent
)
{
reaction_roles
::
sync_all_role_reactions
(
&
ctx
);
}
}
use
config
::
SECRETS
;
use
serenity_handler
::
Handler
;
fn
main
()
{
CombinedLogger
::
init
(
vec!
[
...
...
@@ -272,39 +58,3 @@ fn main() {
error!
(
"Client error: {:?}"
,
why
);
}
}
#[derive(Debug,
PartialEq)]
enum
MessageType
{
Motion
,
Role
,
RoleReactMessage
,
LogReact
,
Poll
,
Misc
,
}
fn
get_message_type
(
message
:
&
Message
)
->
MessageType
{
if
CONFIG
.react_role_messages
.iter
()
.any
(|
rrm
|
rrm
.message
==
message
.id
)
{
return
MessageType
::
RoleReactMessage
;
}
if
message
.embeds
.is_empty
()
{
// Get first word of message
return
match
message
.content
.splitn
(
2
,
' '
)
.next
()
.unwrap
()
{
"Role"
=>
MessageType
::
Role
,
"React"
=>
MessageType
::
LogReact
,
_
=>
MessageType
::
Misc
,
};
}
let
title
:
String
=
message
.embeds
[
0
]
.title
.clone
()
.unwrap
();
let
words_of_title
:
Vec
<
_
>
=
title
.splitn
(
2
,
' '
)
.collect
();
let
first_word_of_title
=
words_of_title
[
0
];
match
first_word_of_title
{
"Motion"
=>
MessageType
::
Motion
,
"Poll"
=>
MessageType
::
Poll
,
_
=>
MessageType
::
Misc
,
}
}
src/serenity_handler.rs
0 → 100644
View file @
8a924d44
use
chrono
::
prelude
::
Utc
;
use
serenity
::{
model
::{
channel
,
channel
::
Message
,
gateway
::
Ready
,
guild
::
Member
},
prelude
::
*
,
utils
::
MessageBuilder
,
};
use
rand
::
seq
::
SliceRandom
;
use
crate
::
config
::
CONFIG
;
use
crate
::
ldap
;
use
crate
::
reaction_roles
::{
add_role_by_reaction
,
remove_role_by_reaction
,
sync_all_role_reactions
,
};
use
crate
::
user_management
;
use
crate
::
util
::
get_string_from_react
;
use
crate
::
voting
;
pub
struct
Handler
;
impl
EventHandler
for
Handler
{
// Set a handler for the `message` event - so that whenever a new message
// is received - the closure (or function) passed will be called.
//
// Event handlers are dispatched through a threadpool, and so multiple
// events can be dispatched simultaneously.
fn
message
(
&
self
,
ctx
:
Context
,
msg
:
Message
)
{
if
!
(
msg
.content
.starts_with
(
&
CONFIG
.command_prefix
))
{
if
msg
.content
.contains
(
&
format!
(
"<@!{}>"
,
CONFIG
.bot_id
))
// desktop mentions
||
msg
.content
.contains
(
&
format!
(
"<@{}>"
,
CONFIG
.bot_id
))
// mobile mentions
{
send_message!
(
msg
.channel_id
,
&
ctx
.http
,
MENTION_RESPONSES
.choose
(
&
mut
rand
::
thread_rng
())
.expect
(
"We couldn't get any sass"
)
);
}
return
;
}
let
message_content
:
Vec
<
_
>
=
msg
.content
[
1
..
]
.splitn
(
2
,
' '
)
.collect
();
let
content
=
if
message_content
.len
()
>
1
{
message_content
[
1
]
}
else
{
""
};
match
message_content
[
0
]
{
"say"
=>
println!
(
"{:#?}"
,
msg
.content
),
"register"
=>
user_management
::
Commands
::
register
(
ctx
,
msg
.clone
(),
content
),
"verify"
=>
user_management
::
Commands
::
verify
(
ctx
,
msg
.clone
(),
content
),
"profile"
=>
user_management
::
Commands
::
profile
(
ctx
,
msg
.clone
(),
content
),
"set"
=>
user_management
::
Commands
::
set_info
(
ctx
,
msg
.clone
(),
content
),
"clear"
=>
user_management
::
Commands
::
clear_info
(
ctx
,
msg
.clone
(),
content
),
"move"
=>
voting
::
Commands
::
move_something
(
ctx
,
msg
.clone
(),
content
),
"motion"
=>
voting
::
Commands
::
motion
(
ctx
,
msg
.clone
(),
content
),
"poll"
=>
voting
::
Commands
::
poll
(
ctx
,
msg
.clone
(),
content
),
"cowsay"
=>
voting
::
Commands
::
cowsay
(
ctx
,
msg
.clone
(),
content
),
"source"
=>
{
let
mut
mesg
=
MessageBuilder
::
new
();
mesg
.push
(
"You want to look at my insides!? Eurgh.
\n
Just kidding, you can go over "
,
);
mesg
.push_italic
(
"every inch"
);
mesg
.push
(
" of me here: https://gitlab.ucc.asn.au/UCC/discord-bot 😉"
);
send_message!
(
msg
.channel_id
,
&
ctx
.http
,
mesg
.build
());
}
"help"
=>
{
// Plaintext version, keep in case IRC users kick up a fuss
// let mut message = MessageBuilder::new();
// message.push_line(format!(
// "Use {}move <action> to make a circular motion",
// &CONFIG.command_prefix
// ));
// message.push_line(format!(
// "Use {}poll <proposal> to see what people think about something",
// &CONFIG.command_prefix
// ));
// send_message!(msg.channel_id, &ctx.http, message.build());
let
result
=
msg
.channel_id
.send_message
(
&
ctx
.http
,
|
m
|
{
m
.embed
(|
embed
|
{
embed
.colour
(
serenity
::
utils
::
Colour
::
DARK_GREY
);
embed
.title
(
"Commands for the UCC Bot"
);
embed
.field
(
"About"
,
"This is UCC's own little in-house bot, please treat it nicely :)"
,
false
);
embed
.field
(
"Commitee"
,
"`!move <text>` to make a circular motion
\n
\
`!poll <text>` to get people's opinions on something"
,
false
);
embed
.field
(
"Account"
,
"`!register <ucc username>` to link your Discord and UCC account
\n
\
`!profile <user>` to get the profile of a user
\n
\
`!set <bio|git|web|photo>` to set that property of _your_ profile
\n
\
`!updateroles` to update your registered roles"
,
false
);
embed
.field
(
"Fun"
,
"`!cowsay <text>` to have a cow say your words
\n
\
with no `<text>` it'll give you a fortune 😉"
,
false
);
embed
});
m
});
if
let
Err
(
why
)
=
result
{
error!
(
"Error sending help embed: {:?}"
,
why
);
}
}
// undocumented (in !help) functins
"logreact"
=>
{
e!
(
"Error deleting logreact prompt: {:?}"
,
msg
.delete
(
&
ctx
));
send_message!
(
msg
.channel_id
,
&
ctx
.http
,
"React to this to log the ID (for the next 5min)"
);
}
"ldap"
=>
send_message!
(
msg
.channel_id
,
&
ctx
.http
,
format!
(
"{:?}"
,
ldap
::
ldap_search
(
message_content
[
1
]))
),
"tla"
=>
send_message!
(
msg
.channel_id
,
&
ctx
.http
,
format!
(
"{:?}"
,
ldap
::
tla_search
(
message_content
[
1
]))
),
"updateroles"
=>
user_management
::
Commands
::
update_registered_role
(
ctx
,
msg
),
_
=>
send_message!
(
msg
.channel_id
,
&
ctx
.http
,
format!
(
"Unrecognised command. Try {}help"
,
&
CONFIG
.command_prefix
)
),
}
}
fn
reaction_add
(
&
self
,
ctx
:
Context
,
add_reaction
:
channel
::
Reaction
)
{
match
add_reaction
.message
(
&
ctx
.http
)
{
Ok
(
message
)
=>
match
get_message_type
(
&
message
)
{
MessageType
::
RoleReactMessage
if
add_reaction
.user_id
.0
!=
CONFIG
.bot_id
=>
{
add_role_by_reaction
(
&
ctx
,
message
,
add_reaction
);
return
;
}
_
if
message
.author.id
.0
!=
CONFIG
.bot_id
||
add_reaction
.user_id
==
CONFIG
.bot_id
=>
{
return
}
MessageType
::
Motion
=>
voting
::
reaction_add
(
ctx
,
add_reaction
),
MessageType
::
LogReact
=>
{
let
react_user
=
add_reaction
.user
(
&
ctx
)
.unwrap
();
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"
,
react_user
.name
);
return
;
}
info!
(
"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
);
msg
.push
(
format!
(
" wanted to know that {} is represented by "
,
add_reaction
.emoji
,
));
msg
.push_mono
(
react_as_string
);
send_message!
(
message
.channel_id
,
&
ctx
.http
,
msg
.build
());
}
_
=>
{}
},
Err
(
why
)
=>
error!
(
"Failed to get react message {:?}"
,
why
),
}
}
fn
reaction_remove
(
&
self
,
ctx
:
Context
,
removed_reaction
:
channel
::
Reaction
)
{
match
removed_reaction
.message
(
&
ctx
.http
)
{
Ok
(
message
)
=>
match
get_message_type
(
&
message
)
{
MessageType
::
RoleReactMessage
if
removed_reaction
.user_id
!=
CONFIG
.bot_id
=>
{
remove_role_by_reaction
(
&
ctx
,
message
,
removed_reaction
);
return
;
}
_
if
message
.author.id
.0
!=
CONFIG
.bot_id
||
removed_reaction
.user_id
==
CONFIG
.bot_id
=>
{
return
}
MessageType
::
Motion
=>
voting
::
reaction_remove
(
ctx
,
removed_reaction
),
_
=>
{}
},
Err
(
why
)
=>
error!
(
"Failed to get react message {:?}"
,
why
),
}
}
fn
guild_member_addition
(
&
self
,
ctx
:
Context
,
_guild_id
:
serenity
::
model
::
id
::
GuildId
,
the_new_member
:
Member
,
)
{
user_management
::
new_member
(
&
ctx
,
the_new_member
);
}
// Set a handler to be called on the `ready` event. This is called when a
// shard is booted, and a READY payload is sent by Discord. This payload
// contains data like the current user's guild Ids, current user data,
// private channels, and more.
//
// In this case, just print what the current user's username is.
fn
ready
(
&
self
,
ctx
:
Context
,
ready
:
Ready
)
{
info!
(
"{} is connected!"
,
ready
.user.name
);
sync_all_role_reactions
(
&
ctx
);
}
fn
resume
(
&
self
,
ctx
:
Context
,
_
:
serenity
::
model
::
event
::
ResumedEvent
)
{
sync_all_role_reactions
(
&
ctx
);
}
}
pub
const
MENTION_RESPONSES
:
&
[
&
str
]
=
&
[
"Oh hello there"
,
"Stop bothering me. I'm busy."
,
"You know, I'm trying to keep track of this place. I don't need any more distractions."
,
"Don't you have better things to do?"
,
"(sigh) what now?"
,
"Yes, yes, I know I'm brilliant"
,
"What do I need to do to catch a break around here? Eh."
,
"Mmmmhmmm. I'm still around, don't mind me."
,
"You know, some people would consider this rude. Luckily I'm not one of those people. In fact, I'm not even a person."
,
"Perhaps try bothering someone else for a change."
];
#[derive(Debug,
PartialEq)]
enum
MessageType
{
Motion
,
Role
,
RoleReactMessage
,
LogReact
,
Poll
,
Misc
,
}
fn
get_message_type
(
message
:
&
Message
)
->
MessageType
{
if
CONFIG
.react_role_messages
.iter
()
.any
(|
rrm
|
rrm
.message
==
message
.id
)
{
return
MessageType
::
RoleReactMessage
;
}
if
message
.embeds
.is_empty
()
{
// Get first word of message
return
match
message
.content
.splitn
(
2
,
' '
)
.next
()
.unwrap
()
{
"Role"
=>
MessageType
::
Role
,
"React"
=>
MessageType
::
LogReact
,
_
=>
MessageType
::
Misc
,
};
}
let
title
:
String
=
message
.embeds
[
0
]
.title
.clone
()
.unwrap
();
let
words_of_title
:
Vec
<
_
>
=
title
.splitn
(
2
,
' '
)
.collect
();
let
first_word_of_title
=
words_of_title
[
0
];
match
first_word_of_title
{
"Motion"
=>
MessageType
::
Motion
,
"Poll"
=>
MessageType
::
Poll
,
_
=>
MessageType
::
Misc
,
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment