diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 43e506e..b1ab9f7 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -1,6 +1,6 @@ # This configuration was generated by # `rubocop --auto-gen-config` -# on 2020-06-27 10:06:13 -0400 using RuboCop version 0.80.1. +# on 2020-06-27 10:38:47 -0400 using RuboCop version 0.80.1. # The point is for the user to remove these configuration records # one by one as the offenses are removed from the code base. # Note that changes in the inspected code, or installation of new @@ -32,9 +32,10 @@ Style/AccessModifierDeclarations: Exclude: - 'lib/slack-ruby-bot/hooks/hook_support.rb' -# Offense count: 3 +# Offense count: 5 Style/DoubleNegation: Exclude: + - 'lib/slack-ruby-bot/client.rb' - 'lib/slack-ruby-bot/commands/base.rb' - 'lib/slack-ruby-bot/config.rb' diff --git a/CHANGELOG.md b/CHANGELOG.md index d6fbc0d..2c66a57 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ * [#263](https://github.com/slack-ruby/slack-ruby-bot/pull/263): Removed Giphy support - [@dblock](https://github.com/dblock). * [#260](https://github.com/slack-ruby/slack-ruby-bot/pull/260): Add brief migration guide - [@wasabigeek](https://github.com/wasabigeek). * [#264](https://github.com/slack-ruby/slack-ruby-bot/pull/264): Added TOC to README - [@dblock](https://github.com/dblock). +* [#265](https://github.com/slack-ruby/slack-ruby-bot/pull/265): Make `allow_bot_messages` and `allow_message_loops` available in `SlackRubyBot::Client` - [@dblock](https://github.com/dblock). * Your contribution here. ### 0.15.0 (2020/5/8) diff --git a/README.md b/README.md index e032e6a..97373ea 100644 --- a/README.md +++ b/README.md @@ -188,8 +188,6 @@ SlackRubyBot.configure do |config| end ``` -This is particularly fun with emoji. - ![](screenshots/aliases.gif) Bots will also respond to a direct message, with or without the bot name in the message itself. @@ -479,7 +477,7 @@ server.hooks.add(:hello, ->(client, data) { puts "Hello!" }) ### Bot Message Protection -By default bots do not respond to self or other bots. If you wish to change that behavior, set `allow_bot_messages` to `true`. +By default bots do not respond to self or other bots. If you wish to change that behavior globally, set `allow_bot_messages` to `true`. ```ruby SlackRubyBot.configure do |config| @@ -489,7 +487,7 @@ end ### Message Loop Protection -By default bots do not respond to their own messages. If you wish to change that behavior, set `allow_message_loops` to `true`. +By default bots do not respond to their own messages. If you wish to change that behavior globally, set `allow_message_loops` to `true`. ```ruby SlackRubyBot.configure do |config| diff --git a/UPGRADING.md b/UPGRADING.md index da68db5..cd946a8 100644 --- a/UPGRADING.md +++ b/UPGRADING.md @@ -5,10 +5,7 @@ Upgrading SlackRubyBot #### Removed GIF support -GIF, Giphy and other animated GIF support has been removed. Remove `gif` options from all `client.say(gif: 'keyword')` method calls, the `GIPHY_API_KEY` ENV var, `gem 'giphy'` or `gem 'GiphyClient'`. -. - -The `SlackRubyBot::Commands::Base#send_message`, `send_message_with_gif` and `send_gif` methods have been removed. +GIF, Giphy and other animated GIF support has been removed. Remove `gif` options from all `client.say(gif: 'keyword')` method calls, the `GIPHY_API_KEY` ENV var, `gem 'giphy'` or `gem 'GiphyClient'`, and any references to `send_gifs`. The previously deprecated `SlackRubyBot::Commands::Base#send_message`, `send_message_with_gif` and `send_gif` methods have also been removed. See [#261](https://github.com/slack-ruby/slack-ruby-bot/issues/261) for details. diff --git a/lib/slack-ruby-bot/client.rb b/lib/slack-ruby-bot/client.rb index 49606fa..0a582b9 100644 --- a/lib/slack-ruby-bot/client.rb +++ b/lib/slack-ruby-bot/client.rb @@ -4,11 +4,30 @@ module SlackRubyBot class Client < Slack::RealTime::Client include Loggable attr_accessor :aliases - attr_accessor :send_gifs + attr_accessor :allow_bot_messages + attr_accessor :allow_message_loops def initialize(attrs = {}) super(attrs) @aliases = attrs[:aliases] + @allow_message_loops = attrs[:allow_message_loops] + @allow_bot_messages = attrs[:allow_bot_messages] + end + + def allow_message_loops? + @allow_message_loops.nil? ? SlackRubyBot::Config.allow_message_loops? : !!@allow_message_loops + end + + def allow_bot_messages? + @allow_bot_messages.nil? ? SlackRubyBot::Config.allow_bot_messages? : !!@allow_bot_messages + end + + def message_to_self?(data) + !!(self.self && self.self.id == data.user) + end + + def bot_message?(data) + data.subtype == 'bot_message' end def names diff --git a/lib/slack-ruby-bot/hooks/message.rb b/lib/slack-ruby-bot/hooks/message.rb index fb7362d..06fa77b 100644 --- a/lib/slack-ruby-bot/hooks/message.rb +++ b/lib/slack-ruby-bot/hooks/message.rb @@ -4,10 +4,11 @@ module SlackRubyBot module Hooks class Message def call(client, data) - return if message_to_self_not_allowed? && message_to_self?(client, data) - return if bot_message_not_allowed? && bot_message?(client, data) + return if !client.allow_message_loops? && client.message_to_self?(data) + return if !client.allow_bot_messages? && client.bot_message?(data) + + prepare!(data) - data.text = data.text.strip if data.text result = child_command_classes.detect { |d| d.invoke(client, data) } result ||= built_in_command_classes.detect { |d| d.invoke(client, data) } result ||= SlackRubyBot::Commands::Unknown.tap { |d| d.invoke(client, data) } @@ -16,20 +17,8 @@ def call(client, data) private - def message_to_self_not_allowed? - !SlackRubyBot::Config.allow_message_loops? - end - - def message_to_self?(client, data) - client.self && client.self.id == data.user - end - - def bot_message_not_allowed? - !SlackRubyBot::Config.allow_bot_messages? - end - - def bot_message?(_client, data) - data.subtype == 'bot_message' + def prepare!(data) + data.text = data.text.strip if data.text end # diff --git a/spec/slack-ruby-bot/client_spec.rb b/spec/slack-ruby-bot/client_spec.rb index 276fe4d..1ef735e 100644 --- a/spec/slack-ruby-bot/client_spec.rb +++ b/spec/slack-ruby-bot/client_spec.rb @@ -1,4 +1,114 @@ # frozen_string_literal: true describe SlackRubyBot::Client do + describe '#allow_message_loops?' do + context 'with global allow_message_loops set to true' do + before do + SlackRubyBot::Config.allow_message_loops = true + end + it do + expect(subject.allow_message_loops?).to be true + end + context 'overridden locally' do + subject do + SlackRubyBot::Client.new(allow_message_loops: false) + end + it do + expect(subject.allow_message_loops?).to be false + end + end + end + context 'with global allow_message_loops set to false' do + before do + SlackRubyBot::Config.allow_message_loops = false + end + it do + expect(subject.allow_message_loops?).to be false + end + context 'overridden locally' do + subject do + SlackRubyBot::Client.new(allow_message_loops: true) + end + it do + expect(subject.allow_message_loops?).to be true + end + end + end + context 'overridden locally' do + subject do + SlackRubyBot::Client.new(allow_message_loops: true) + end + it do + expect(subject.allow_message_loops?).to be true + end + end + end + describe '#allow_bot_messages?' do + context 'with global allow_bot_messages set to true' do + before do + SlackRubyBot::Config.allow_bot_messages = true + end + it do + expect(subject.allow_bot_messages?).to be true + end + context 'overridden locally' do + subject do + SlackRubyBot::Client.new(allow_bot_messages: false) + end + it do + expect(subject.allow_bot_messages?).to be false + end + end + end + context 'with global allow_bot_messages set to false' do + before do + SlackRubyBot::Config.allow_bot_messages = false + end + it do + expect(subject.allow_bot_messages?).to be false + end + context 'overridden locally' do + subject do + SlackRubyBot::Client.new(allow_bot_messages: true) + end + it do + expect(subject.allow_bot_messages?).to be true + end + end + end + context 'overridden locally' do + subject do + SlackRubyBot::Client.new(allow_bot_messages: true) + end + it do + expect(subject.allow_bot_messages?).to be true + end + end + end + describe '#message_to_self?' do + before do + allow(subject).to receive(:self).and_return(Hashie::Mash.new({ 'id' => 'U0K8CKKT1' })) + end + context 'with message to self' do + it do + expect(subject.message_to_self?(Hashie::Mash.new(user: 'U0K8CKKT1'))).to be true + end + end + context 'with message to another user' do + it do + expect(subject.message_to_self?(Hashie::Mash.new(user: 'U0K8CKKT2'))).to be false + end + end + end + describe '#bot_message?' do + it 'bot message' do + expect(subject.bot_message?(Hashie::Mash.new(subtype: 'bot_message'))).to be true + end + it 'not bot message' do + expect(subject.bot_message?(Hashie::Mash.new(subtype: 'other'))).to be false + end + it 'no subtype' do + expect(subject.bot_message?(Hashie::Mash.new)).to be false + end + end end diff --git a/spec/slack-ruby-bot/hooks/message_spec.rb b/spec/slack-ruby-bot/hooks/message_spec.rb index d476a67..80463b4 100644 --- a/spec/slack-ruby-bot/hooks/message_spec.rb +++ b/spec/slack-ruby-bot/hooks/message_spec.rb @@ -34,55 +34,6 @@ expect(built_in_command_classes).to_not include SlackRubyBot::Commands::Unknown end end - describe '#message_to_self_not_allowed?' do - context 'with allow_message_loops set to true' do - before do - SlackRubyBot::Config.allow_message_loops = true - end - it do - expect(message_hook.send(:message_to_self_not_allowed?)).to be false - end - end - context 'with allow_message_loops set to false' do - before do - SlackRubyBot::Config.allow_message_loops = false - end - it do - expect(message_hook.send(:message_to_self_not_allowed?)).to be true - end - end - end - describe '#bot_message_not_allowed?' do - context 'with allow_bot_messages set to true' do - before do - SlackRubyBot::Config.allow_bot_messages = true - end - it do - expect(message_hook.send(:bot_message_not_allowed?)).to be false - end - end - context 'with allow_bot_messages set to false' do - before do - SlackRubyBot::Config.allow_bot_messages = false - end - it do - expect(message_hook.send(:bot_message_not_allowed?)).to be true - end - end - end - describe '#message_to_self?' do - let(:client) { Hashie::Mash.new(self: { 'id' => 'U0K8CKKT1' }) } - context 'with message to self' do - it do - expect(message_hook.send(:message_to_self?, client, Hashie::Mash.new(user: 'U0K8CKKT1'))).to be true - end - end - context 'with message to another user' do - it do - expect(message_hook.send(:message_to_self?, client, Hashie::Mash.new(user: 'U0K8CKKT2'))).to be false - end - end - end describe '#message' do let(:client) { Hashie::Mash.new(self: { 'id' => 'U0K8CKKT1' }) } it 'invokes a command' do