Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for role mentions on the bot's autogenerated managed roleid. #262

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions lib/discordrb/bot.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1316,6 +1316,15 @@ def handle_dispatch(type, data)

if message.mentions.any? { |user| user.id == @profile.id }
event = MentionEvent.new(message, self)
event.role_mention = false
raise_event(event)
end
# Raises a MentionEvent for a bot's managed integration role:
# A managed role is auto-generated for any bots joined to a server with permissions > 0
# For this to generate an event, set role_managed: true
if message.role_mentions.any? { |role| role.managed? == true && role.tags.bot_id == @profile.id }
event = MentionEvent.new(message, self)
event.role_mention = true
raise_event(event)
end

Expand Down
1 change: 1 addition & 0 deletions lib/discordrb/container.rb
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,7 @@ def playing(attributes = {}, &block)
# @option attributes [Time] :after Matches a time after the time the message was sent at.
# @option attributes [Time] :before Matches a time before the time the message was sent at.
# @option attributes [Boolean] :private Matches whether or not the channel is private.
# @option attributes [Boolean] :allow_role_mention whether the event triggers on bot managed roleid mentions.
# @yield The block is executed when the event is raised.
# @yieldparam event [MentionEvent] The event that was raised.
# @return [MentionEventHandler] the event handler that was registered.
Expand Down
86 changes: 84 additions & 2 deletions lib/discordrb/events/message.rb
Original file line number Diff line number Diff line change
Expand Up @@ -264,10 +264,92 @@ def after_call(event)
end

# @see Discordrb::EventContainer#mention
class MentionEvent < MessageEvent; end
class MentionEvent < MessageEvent
attr_accessor :role_mention

def initialize(message, bot)
@bot = bot
@message = message
@channel = message.channel
@saved_message = ''
@file = nil
@filename = nil
@file_spoiler = nil
@role_mention = false
end
end

# Event handler for {MentionEvent}
class MentionEventHandler < MessageEventHandler; end
class MentionEventHandler < MessageEventHandler
def matches?(event)
# Check for the proper event type
return false unless event.is_a? MentionEvent
# Ensure this is not a role mention, or if it is, then allow_role_mention == true
return false unless (!event.role_mention) || (@attributes[:allow_role_mention] && event.role_mention)

[
matches_all(@attributes[:starting_with] || @attributes[:start_with], event.content) do |a, e|
case a
when String
e.start_with? a
when Regexp
(e =~ a)&.zero?
end
end,
matches_all(@attributes[:ending_with] || @attributes[:end_with], event.content) do |a, e|
case a
when String
e.end_with? a
when Regexp
!(e =~ Regexp.new("#{a}$")).nil?
end
end,
matches_all(@attributes[:containing] || @attributes[:contains], event.content) do |a, e|
case a
when String
e.include? a
when Regexp
(e =~ a)
end
end,
matches_all(@attributes[:in], event.channel) do |a, e|
case a
when String
# Make sure to remove the "#" from channel names in case it was specified
a.delete('#') == e.name
when Integer
a == e.id
else
a == e
end
end,
matches_all(@attributes[:from], event.author) do |a, e|
case a
when String
a == e.name
when Integer
a == e.id
when :bot
e.current_bot?
else
a == e
end
end,
matches_all(@attributes[:with_text] || @attributes[:content] || @attributes[:exact_text], event.content) do |a, e|
case a
when String
e == a
when Regexp
match = a.match(e)
match ? (e == match[0]) : false
end
end,
matches_all(@attributes[:after], event.timestamp) { |a, e| a > e },
matches_all(@attributes[:before], event.timestamp) { |a, e| a < e },
matches_all(@attributes[:private], event.channel.private?) { |a, e| !e == !a }
].reduce(true, &:&)
end
end

# @see Discordrb::EventContainer#pm
class PrivateMessageEvent < MessageEvent; end
Expand Down
2 changes: 1 addition & 1 deletion lib/discordrb/version.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@
# Discordrb and all its functionality, in this case only the version.
module Discordrb
# The current version of discordrb.
VERSION = '3.5.0'
VERSION = '3.5.1'
end
2 changes: 1 addition & 1 deletion spec/bot_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@
let(:user_id) { instance_double(Integer, 'user_id') }
let(:author) { instance_double(Discordrb::User, id: user_id) }
let(:message_fixture) { { 'author' => { 'id' => user_id }, 'channel_id' => channel_id } }
let(:message) { instance_double(Discordrb::Message, channel: channel, from_bot?: false, mentions: []) }
let(:message) { instance_double(Discordrb::Message, channel: channel, from_bot?: false, mentions: [], role_mentions: []) }

before do
allow(bot).to receive(:channel).with(channel_id).and_return(channel)
Expand Down