├── .gitignore ├── .rspec ├── .rubocop.yml ├── .rubocop_todo.yml ├── .travis.yml ├── CHANGELOG.md ├── CONTRIBUTING.md ├── Dangerfile ├── Gemfile ├── LICENSE ├── README.md ├── RELEASING.md ├── Rakefile ├── lib ├── slack-ruby-bot-server-events-app-mentions.rb └── slack-ruby-bot-server-events-app-mentions │ ├── config.rb │ ├── events.rb │ ├── mentions.rb │ ├── mentions │ ├── mention.rb │ └── support │ │ ├── attrs.rb │ │ └── match.rb │ └── version.rb ├── slack-ruby-bot-server-events-app-mentions.gemspec └── spec ├── database_adapters ├── activerecord │ ├── activerecord.rb │ ├── postgresql.yml │ └── schema.rb └── mongoid │ ├── mongoid.rb │ ├── mongoid.yml │ └── rspec.rb ├── slack-ruby-bot-server-events-app-mentions ├── config │ └── handlers_spec.rb ├── config_spec.rb ├── mentions │ ├── mention_spec.rb │ └── regexp_mention_spec.rb └── version_spec.rb ├── spec_helper.rb └── support ├── config.rb └── rspec.rb /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .rvmrc 3 | .irbrc 4 | .bundle 5 | log 6 | .env 7 | *.swp 8 | Gemfile.lock 9 | .ruby-version 10 | pkg 11 | -------------------------------------------------------------------------------- /.rspec: -------------------------------------------------------------------------------- 1 | --color 2 | --format=documentation 3 | 4 | -------------------------------------------------------------------------------- /.rubocop.yml: -------------------------------------------------------------------------------- 1 | Metrics: 2 | Enabled: false 3 | 4 | Layout/LineLength: 5 | Max: 500 6 | Enabled: false 7 | 8 | Style/Documentation: 9 | Enabled: false 10 | 11 | Style/ModuleFunction: 12 | EnforcedStyle: extend_self 13 | 14 | inherit_from: .rubocop_todo.yml 15 | 16 | -------------------------------------------------------------------------------- /.rubocop_todo.yml: -------------------------------------------------------------------------------- 1 | # This configuration was generated by 2 | # `rubocop --auto-gen-config` 3 | # on 2020-11-30 08:47:05 -0500 using RuboCop version 0.81.0. 4 | # The point is for the user to remove these configuration records 5 | # one by one as the offenses are removed from the code base. 6 | # Note that changes in the inspected code, or installation of new 7 | # versions of RuboCop, may require this file to be generated again. 8 | 9 | # Offense count: 1 10 | # Configuration parameters: ExpectMatchingDefinition, Regex, IgnoreExecutableScripts, AllowedAcronyms. 11 | # AllowedAcronyms: CLI, DSL, ACL, API, ASCII, CPU, CSS, DNS, EOF, GUID, HTML, HTTP, HTTPS, ID, IP, JSON, LHS, QPS, RAM, RHS, RPC, SLA, SMTP, SQL, SSH, TCP, TLS, TTL, UDP, UI, UID, UUID, URI, URL, UTF8, VM, XML, XMPP, XSRF, XSS 12 | Naming/FileName: 13 | Exclude: 14 | - 'lib/slack-ruby-bot-server-events-app-mentions.rb' 15 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: ruby 2 | 3 | cache: bundler 4 | 5 | matrix: 6 | include: 7 | - rvm: 2.6.6 8 | script: 9 | - bundle exec danger 10 | - rvm: 2.6.6 11 | env: DATABASE_ADAPTER=activerecord 12 | services: 13 | - postgresql 14 | - rvm: 2.6.6 15 | env: DATABASE_ADAPTER=mongoid 16 | services: 17 | - mongodb 18 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ### Changelog 2 | 3 | #### 0.1.2 (Next) 4 | 5 | * Your contribution here. 6 | 7 | #### 0.1.1 (01/06/2021) 8 | 9 | * [#1](https://github.com/slack-ruby/slack-ruby-bot-server-events-app-mentions/pull/1): Fix: fetch text via hash accessor - [@robholland](https://github.com/robholland). 10 | 11 | #### 0.1.0 (11/30/2020) 12 | 13 | * Initial public release - [@dblock](https://github.com/dblock). 14 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to SlackRubyBotServer::Events 2 | 3 | This project is work of [many contributors](https://github.com/slack-ruby/slack-ruby-bot-server-events-app-mentions/graphs/contributors). 4 | 5 | You're encouraged to submit [pull requests](https://github.com/slack-ruby/slack-ruby-bot-server-events-app-mentions/pulls), [propose features and discuss issues](https://github.com/slack-ruby/slack-ruby-bot-server-events-app-mentions/issues). 6 | 7 | In the examples below, substitute your Github username for `contributor` in URLs. 8 | 9 | ## Fork the Project 10 | 11 | Fork the [project on Github](https://github.com/slack-ruby/slack-ruby-bot-server-events-app-mentions) and check out your copy. 12 | 13 | ``` 14 | git clone https://github.com/contributor/slack-ruby-bot-server-events-app-mentions.git 15 | cd slack-ruby-bot-server-events-app-mentions 16 | git remote add upstream https://github.com/slack-ruby/slack-ruby-bot-server-events-app-mentions.git 17 | ``` 18 | 19 | ## Create a Topic Branch 20 | 21 | Make sure your fork is up-to-date and create a topic branch for your feature or bug fix. 22 | 23 | ``` 24 | git checkout master 25 | git pull upstream master 26 | git checkout -b my-feature-branch 27 | ``` 28 | 29 | ## Bundle Install and Test 30 | 31 | Ensure that you can build the project and run tests. 32 | 33 | ``` 34 | bundle install 35 | bundle exec rake 36 | ``` 37 | 38 | ## Write Tests 39 | 40 | Try to write a test that reproduces the problem you're trying to fix or describes a feature that you want to build. 41 | Add to [spec](spec). 42 | 43 | We definitely appreciate pull requests that highlight or reproduce a problem, even without a fix. 44 | 45 | ## Write Code 46 | 47 | Implement your feature or bug fix. 48 | 49 | Ruby style is enforced with [Rubocop](https://github.com/bbatsov/rubocop). 50 | Run `bundle exec rubocop` and fix any style issues highlighted. 51 | 52 | Make sure that `bundle exec rake` completes without errors. 53 | 54 | ## Write Documentation 55 | 56 | Document any external behavior in the [README](README.md). 57 | 58 | ## Update Changelog 59 | 60 | Add a line to [CHANGELOG](CHANGELOG.md) under *Next Release*. 61 | Make it look like every other line, including your name and link to your Github account. 62 | 63 | ## Commit Changes 64 | 65 | Make sure git knows your name and email address: 66 | 67 | ``` 68 | git config --global user.name "Your Name" 69 | git config --global user.email "contributor@example.com" 70 | ``` 71 | 72 | Writing good commit logs is important. A commit log should describe what changed and why. 73 | 74 | ``` 75 | git add ... 76 | git commit 77 | ``` 78 | 79 | ## Push 80 | 81 | ``` 82 | git push origin my-feature-branch 83 | ``` 84 | 85 | ## Make a Pull Request 86 | 87 | Go to https://github.com/contributor/slack-ruby-bot-server-events-app-mentions and select your feature branch. 88 | Click the 'Pull Request' button and fill out the form. Pull requests are usually reviewed within a few days. 89 | 90 | ## Rebase 91 | 92 | If you've been working on a change for a while, rebase with upstream/master. 93 | 94 | ``` 95 | git fetch upstream 96 | git rebase upstream/master 97 | git push origin my-feature-branch -f 98 | ``` 99 | 100 | ## Update CHANGELOG Again 101 | 102 | Update the [CHANGELOG](CHANGELOG.md) with the pull request number. A typical entry looks as follows. 103 | 104 | ``` 105 | * [#123](https://github.com/slack-ruby/slack-ruby-bot-server-events-app-mentions/pull/123): Reticulated splines - [@contributor](https://github.com/contributor). 106 | ``` 107 | 108 | Amend your previous commit and force push the changes. 109 | 110 | ``` 111 | git commit --amend 112 | git push origin my-feature-branch -f 113 | ``` 114 | 115 | ## Check on Your Pull Request 116 | 117 | Go back to your pull request after a few minutes and see whether it passed muster with Travis-CI. Everything should look green, otherwise fix issues and amend your commit as described above. 118 | 119 | ## Be Patient 120 | 121 | It's likely that your change will not be merged and that the nitpicky maintainers will ask you to do more, or fix seemingly benign problems. Hang on there! 122 | 123 | ## Thank You 124 | 125 | Please do know that we really appreciate and value your time and work. We love you, really. 126 | -------------------------------------------------------------------------------- /Dangerfile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | danger.import_dangerfile(gem: 'slack-ruby-danger') 4 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | source 'https://rubygems.org' 4 | 5 | case ENV['DATABASE_ADAPTER'] 6 | when 'mongoid' then 7 | gem 'kaminari-mongoid' 8 | gem 'mongoid' 9 | gem 'mongoid-scroll' 10 | when 'activerecord' then 11 | gem 'activerecord', '~> 5.0.0' 12 | gem 'otr-activerecord', '~> 1.2.1' 13 | gem 'virtus' 14 | gem 'cursor_pagination' # rubocop:disable Bundler/OrderedGems 15 | gem 'pg' 16 | when nil 17 | warn "Missing ENV['DATABASE_ADAPTER']." 18 | else 19 | warn "Invalid ENV['DATABASE_ADAPTER']: #{ENV['DATABASE_ADAPTER']}." 20 | end 21 | 22 | gemspec 23 | 24 | group :development, :test do 25 | gem 'bundler' 26 | gem 'database_cleaner' 27 | gem 'fabrication' 28 | gem 'faker' 29 | gem 'hyperclient' 30 | gem 'rack-test' 31 | gem 'rake' 32 | gem 'rspec' 33 | gem 'rubocop', '0.81.0' 34 | gem 'vcr' 35 | gem 'webmock' 36 | end 37 | 38 | group :test do 39 | gem 'slack-ruby-danger', '~> 0.1.0', require: false 40 | end 41 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2020 Daniel Doubrovkine & Contributors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Slack Ruby Bot Server Events App Mentions 2 | ========================================= 3 | 4 | [![Gem Version](https://badge.fury.io/rb/slack-ruby-bot-server-events-app-mentions.svg)](https://badge.fury.io/rb/slack-ruby-bot-server-events-app-mentions) 5 | [![Build Status](https://travis-ci.org/slack-ruby/slack-ruby-bot-server-events-app-mentions.svg?branch=master)](https://travis-ci.org/slack-ruby/slack-ruby-bot-server-events-app-mentions) 6 | 7 | An extension to [slack-ruby-bot-server-events](https://github.com/slack-ruby/slack-ruby-bot-server-events) that makes it easier to handle [app mentions](https://api.slack.com/events/app_mention) - message events that directly mention your bot user. 8 | 9 | ### Sample 10 | 11 | See [slack-ruby/slack-ruby-bot-server-events-app-mentions-sample](https://github.com/slack-ruby/slack-ruby-bot-server-events-app-mentions-sample) for a working sample. 12 | 13 | ### Usage 14 | 15 | #### Gemfile 16 | 17 | Add 'slack-ruby-bot-server-events-app-mentions' to Gemfile. 18 | 19 | ```ruby 20 | gem 'slack-ruby-bot-server-events-app-mentions' 21 | ``` 22 | 23 | #### Configure OAuth Scopes 24 | 25 | The [`app_mentions:read`](https://api.slack.com/scopes/app_mentions:read) OAuth scope is required to receive mentions in channels and [`im:history`](https://api.slack.com/scopes/im:history) to receive direct messages. 26 | 27 | ```ruby 28 | SlackRubyBotServer.configure do |config| 29 | config.oauth_version = :v2 30 | config.oauth_scope = ['app_mentions:read', 'im:history'] 31 | end 32 | ``` 33 | 34 | #### Implement Mentions 35 | 36 | Define a `mention` and implement a `call` class method that takes event data that has been extended with `team` and a regular expression `match` object. 37 | 38 | ```ruby 39 | class Ping < SlackRubyBotServer::Events::AppMentions::Mention 40 | mention 'ping' 41 | 42 | def self.call(data) 43 | client = Slack::Web::Client.new(token: data.team.token) 44 | client.chat_postMessage(channel: data.channel, text: 'pong') 45 | end 46 | end 47 | ``` 48 | 49 | Mentions can be free-formed regular expressions. 50 | 51 | ```ruby 52 | class PingWithNumber < SlackRubyBotServer::Events::AppMentions::Mention 53 | mention(/ping[[:space:]]+(?[[:digit:]]+)$/) 54 | 55 | def self.call(data) 56 | client = Slack::Web::Client.new(token: data.team.token) 57 | client.chat_postMessage(channel: data.channel, text: "pong #{data.match['number']}") 58 | end 59 | end 60 | ``` 61 | 62 | #### Configure Handlers 63 | 64 | By default this library will attempt to match any mention that inherits from `SlackRubyBotServer::Events::AppMentions::Mention` in the order of class loading. You can also configure the list of handlers. 65 | 66 | ```ruby 67 | SlackRubyBotServer::Events::AppMentions.configure do |config| 68 | config.handlers = [ Ping, Ring ] 69 | end 70 | ``` 71 | 72 | ### Copyright & License 73 | 74 | Copyright [Daniel Doubrovkine](http://code.dblock.org) and Contributors, 2020 75 | 76 | [MIT License](LICENSE) 77 | -------------------------------------------------------------------------------- /RELEASING.md: -------------------------------------------------------------------------------- 1 | # Releasing Slack-Ruby-Bot-Server-Events-AppMentions 2 | 3 | There're no hard rules about when to release slack-ruby-bot-server-events-app-mentions. Release bug fixes frequently, features not so frequently and breaking API changes rarely. 4 | 5 | ### Release 6 | 7 | Run tests, check that all tests succeed locally. 8 | 9 | ``` 10 | bundle install 11 | rake 12 | ``` 13 | 14 | Check that the last build succeeded in [Travis CI](https://travis-ci.org/slack-ruby/slack-ruby-bot-server-events-app-mentions) for all supported platforms. 15 | 16 | Change "Next" in [CHANGELOG.md](CHANGELOG.md) to the current date. 17 | 18 | ``` 19 | ### 0.2.2 (7/10/2015) 20 | ``` 21 | 22 | Remove the line with "Your contribution here.", since there will be no more contributions to this release. 23 | 24 | Commit your changes. 25 | 26 | ``` 27 | git add CHANGELOG.md 28 | git commit -m "Preparing for release, 0.2.2." 29 | git push origin master 30 | ``` 31 | 32 | Release. 33 | 34 | ``` 35 | $ rake release 36 | 37 | slack-ruby-bot-server-events-app-mentions 0.2.2 built to pkg/slack-ruby-bot-server-events-app-mentions-0.2.2.gem. 38 | Tagged v0.2.2. 39 | Pushed git commits and tags. 40 | Pushed slack-ruby-bot-server-events-app-mentions 0.2.2 to rubygems.org. 41 | ``` 42 | 43 | ### Prepare for the Next Version 44 | 45 | Add the next release to [CHANGELOG.md](CHANGELOG.md). 46 | 47 | ``` 48 | ### 0.2.3 (Next) 49 | 50 | * Your contribution here. 51 | ``` 52 | 53 | Increment the third version number in [lib/slack-ruby-bot-server-events-app-mentions/version.rb](lib/slack-ruby-bot-server-events-app-mentions/version.rb). 54 | 55 | Commit your changes. 56 | 57 | ``` 58 | git add CHANGELOG.md lib/slack-ruby-bot-server-events-app-mentions/version.rb 59 | git commit -m "Preparing for next development iteration, 0.2.3." 60 | git push origin master 61 | ``` 62 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'rubygems' 4 | require 'bundler/gem_tasks' 5 | 6 | require 'rspec/core' 7 | require 'rspec/core/rake_task' 8 | 9 | RSpec::Core::RakeTask.new(:spec) do |spec| 10 | spec.pattern = FileList['spec/**/*_spec.rb'].exclude(%r{ext\/(?!#{ENV['DATABASE_ADAPTER']})}) 11 | end 12 | 13 | require 'rubocop/rake_task' 14 | RuboCop::RakeTask.new 15 | 16 | task default: %i[rubocop spec] 17 | -------------------------------------------------------------------------------- /lib/slack-ruby-bot-server-events-app-mentions.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'slack-ruby-bot-server-events' 4 | 5 | require_relative 'slack-ruby-bot-server-events-app-mentions/version' 6 | require_relative 'slack-ruby-bot-server-events-app-mentions/config' 7 | require_relative 'slack-ruby-bot-server-events-app-mentions/mentions' 8 | require_relative 'slack-ruby-bot-server-events-app-mentions/events' 9 | -------------------------------------------------------------------------------- /lib/slack-ruby-bot-server-events-app-mentions/config.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module SlackRubyBotServer 4 | module Events 5 | module AppMentions 6 | module Config 7 | extend self 8 | 9 | ATTRIBUTES = %i[ 10 | handlers 11 | ].freeze 12 | 13 | attr_accessor(*Config::ATTRIBUTES - [:handlers]) 14 | attr_writer :handlers 15 | 16 | def handlers 17 | @handlers || SlackRubyBotServer::Events::AppMentions::Mention.handlers 18 | end 19 | 20 | def reset! 21 | self.handlers = nil 22 | end 23 | end 24 | 25 | class << self 26 | def configure 27 | block_given? ? yield(Config) : Config 28 | end 29 | 30 | def config 31 | Config 32 | end 33 | end 34 | end 35 | end 36 | end 37 | 38 | SlackRubyBotServer::Events::AppMentions::Config.reset! 39 | -------------------------------------------------------------------------------- /lib/slack-ruby-bot-server-events-app-mentions/events.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | SlackRubyBotServer::Events.configure do |config| 4 | config.on :event, 'event_callback', 'app_mention' do |event| 5 | data = event['event'] 6 | next unless data 7 | 8 | team = Team.where(team_id: event['team_id']).first 9 | next unless team 10 | 11 | bot_regexp = Regexp.new("^\<\@#{team.bot_user_id}\>[[:space:]]*") 12 | 13 | data = Slack::Messages::Message.new(data).merge( 14 | text: data['text'].gsub(bot_regexp, ''), 15 | team: team 16 | ) 17 | 18 | SlackRubyBotServer::Events::AppMentions.config.handlers.detect { |c| c.invoke(data) } 19 | end 20 | 21 | config.on :event, 'event_callback', 'message' do |event| 22 | data = event['event'] 23 | next unless data 24 | 25 | # direct message only 26 | next unless data['channel_type'] == 'im' 27 | 28 | team = Team.where(team_id: event['team_id']).first 29 | next unless team 30 | 31 | data = Slack::Messages::Message.new(data).merge(team: team) 32 | 33 | SlackRubyBotServer::Events::AppMentions.config.handlers.detect { |c| c.invoke(data) } 34 | end 35 | end 36 | -------------------------------------------------------------------------------- /lib/slack-ruby-bot-server-events-app-mentions/mentions.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require_relative 'mentions/mention' 4 | -------------------------------------------------------------------------------- /lib/slack-ruby-bot-server-events-app-mentions/mentions/mention.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require_relative 'support/match' 4 | 5 | module SlackRubyBotServer 6 | module Events 7 | module AppMentions 8 | class Mention 9 | include SlackRubyBotServer::Loggable 10 | 11 | class << self 12 | attr_accessor :handlers 13 | 14 | def inherited(subclass) 15 | SlackRubyBotServer::Events::AppMentions::Mention.handlers ||= [] 16 | SlackRubyBotServer::Events::AppMentions::Mention.handlers << subclass 17 | end 18 | 19 | def mention(*values, &block) 20 | values = values.map { |value| value.is_a?(Regexp) ? value.source : Regexp.escape(value) }.join('|') 21 | match Regexp.new("(?#{values})([[:space:]]+(?.*)|)$", Regexp::IGNORECASE | Regexp::MULTILINE), &block 22 | end 23 | 24 | def invoke(data) 25 | finalize_routes! 26 | 27 | routes.each_pair do |route, options| 28 | match = route.match(data.text) 29 | next unless match 30 | 31 | call_mention(data.merge(match: Support::Match.new(match)), options[:block]) 32 | return true 33 | end 34 | false 35 | end 36 | 37 | def match(match, &block) 38 | routes[match] = { block: block } 39 | end 40 | 41 | def routes 42 | @routes ||= ActiveSupport::OrderedHash.new 43 | end 44 | 45 | private 46 | 47 | def mention_name_from_class 48 | name ? name.split(':').last.downcase : object_id.to_s 49 | end 50 | 51 | def call_mention(data, block) 52 | if block 53 | block.call(data) 54 | elsif respond_to?(:call) 55 | send(:call, data) 56 | else 57 | raise NotImplementedError, data.text 58 | end 59 | end 60 | 61 | def finalize_routes! 62 | return if routes&.any? 63 | 64 | mention mention_name_from_class 65 | end 66 | end 67 | end 68 | end 69 | end 70 | end 71 | -------------------------------------------------------------------------------- /lib/slack-ruby-bot-server-events-app-mentions/mentions/support/attrs.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module SlackRubyBotServer 4 | module Events 5 | module AppMentions 6 | module Support 7 | class Attrs 8 | attr_accessor :mention_name, :mention_desc, :mention_long_desc 9 | attr_reader :klass, :mentions 10 | 11 | def initialize(klass) 12 | @klass = klass 13 | @mentions = [] 14 | end 15 | 16 | def title(title) 17 | self.mention_name = title 18 | end 19 | 20 | def desc(desc) 21 | self.mention_desc = desc 22 | end 23 | 24 | def long_desc(long_desc) 25 | self.mention_long_desc = long_desc 26 | end 27 | 28 | def mention(title, &block) 29 | @mentions << self.class.new(klass).tap do |k| 30 | k.title(title) 31 | k.instance_eval(&block) 32 | end 33 | end 34 | end 35 | end 36 | end 37 | end 38 | end 39 | -------------------------------------------------------------------------------- /lib/slack-ruby-bot-server-events-app-mentions/mentions/support/match.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module SlackRubyBotServer 4 | module Events 5 | module AppMentions 6 | module Support 7 | class Match 8 | extend Forwardable 9 | 10 | delegate MatchData.public_instance_methods(false) => :@match_data 11 | 12 | def initialize(match_data) 13 | raise ArgumentError, 'match_data should be a type of MatchData' unless match_data.is_a? MatchData 14 | 15 | @match_data = match_data 16 | end 17 | end 18 | end 19 | end 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /lib/slack-ruby-bot-server-events-app-mentions/version.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module SlackRubyBotServer 4 | module Events 5 | module AppMentions 6 | VERSION = '0.1.2' 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /slack-ruby-bot-server-events-app-mentions.gemspec: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | lib = File.expand_path('lib', __dir__) 4 | $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) 5 | require 'slack-ruby-bot-server-events-app-mentions/version' 6 | 7 | Gem::Specification.new do |spec| 8 | spec.name = 'slack-ruby-bot-server-events-app-mentions' 9 | spec.version = SlackRubyBotServer::Events::AppMentions::VERSION 10 | spec.authors = ['Daniel Doubrovkine'] 11 | spec.email = ['dblock@dblock.org'] 12 | 13 | spec.summary = 'Adds commands to slack-ruby-bot-server-events.' 14 | spec.homepage = 'https://github.com/slack-ruby/slack-ruby-bot-server-events-app-mentions' 15 | 16 | spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(spec)/}) } 17 | spec.require_paths = ['lib'] 18 | 19 | spec.add_dependency 'slack-ruby-bot-server-events' 20 | end 21 | -------------------------------------------------------------------------------- /spec/database_adapters/activerecord/activerecord.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | db_config = YAML.safe_load(File.read(File.expand_path('postgresql.yml', __dir__)), [], [], true)[ENV['RACK_ENV']] 4 | ActiveRecord::Tasks::DatabaseTasks.create(db_config) 5 | ActiveRecord::Base.establish_connection(db_config) 6 | ActiveRecord::Base.logger.level = :info 7 | -------------------------------------------------------------------------------- /spec/database_adapters/activerecord/postgresql.yml: -------------------------------------------------------------------------------- 1 | default: &default 2 | adapter: postgresql 3 | pool: 10 4 | timeout: 5000 5 | encoding: unicode 6 | 7 | development: 8 | <<: *default 9 | database: slack_ruby_bot_server_slack_development 10 | 11 | test: 12 | <<: *default 13 | database: slack_ruby_bot_server_slack_test 14 | 15 | production: 16 | <<: *default 17 | database: slack_ruby_bot_server_slack_production 18 | -------------------------------------------------------------------------------- /spec/database_adapters/activerecord/schema.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require_relative 'activerecord' 4 | 5 | ActiveRecord::Schema.define do 6 | self.verbose = false 7 | 8 | create_table :teams, force: true do |t| 9 | t.string :team_id 10 | t.string :name 11 | t.string :domain 12 | t.string :token 13 | t.string :bot_user_id 14 | t.string :activated_user_id 15 | t.string :activated_user_access_token 16 | t.boolean :active, default: true 17 | t.timestamps 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /spec/database_adapters/mongoid/mongoid.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | Mongo::Logger.logger.level = Logger::INFO 4 | Mongoid.load!(File.expand_path('mongoid.yml', __dir__), ENV['RACK_ENV']) 5 | -------------------------------------------------------------------------------- /spec/database_adapters/mongoid/mongoid.yml: -------------------------------------------------------------------------------- 1 | development: 2 | clients: 3 | default: 4 | database: slack-ruby-bot-server-events-app-mentions_development 5 | hosts: 6 | - 127.0.0.1:27017 7 | options: 8 | raise_not_found_error: false 9 | use_utc: true 10 | 11 | test: 12 | clients: 13 | default: 14 | database: slack-ruby-bot-server-events-app-mentions_test 15 | hosts: 16 | - 127.0.0.1:27017 17 | options: 18 | raise_not_found_error: false 19 | use_utc: true 20 | -------------------------------------------------------------------------------- /spec/database_adapters/mongoid/rspec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | RSpec.configure do |config| 4 | config.before :suite do 5 | Mongoid::Tasks::Database.create_indexes 6 | end 7 | 8 | config.after :suite do 9 | Mongoid.purge! 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /spec/slack-ruby-bot-server-events-app-mentions/config/handlers_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'spec_helper' 4 | 5 | describe SlackRubyBotServer::Events::AppMentions do 6 | let!(:team) { Fabricate(:team) } 7 | 8 | let(:message) do 9 | Slack::Messages::Message.new( 10 | 'team_id' => team.team_id, 11 | 'event' => { 12 | 'channel' => 'channel', 13 | 'text' => "<@#{team.bot_user_id}> ping" 14 | } 15 | ) 16 | end 17 | 18 | let!(:one) do 19 | Class.new(SlackRubyBotServer::Events::AppMentions::Mention) do 20 | mention 'ping' do |data| 21 | client = Slack::Web::Client.new(token: data.team.token) 22 | client.chat_postMessage(text: 'one', channel: data.channel) 23 | end 24 | end 25 | end 26 | 27 | let!(:two) do 28 | Class.new(SlackRubyBotServer::Events::AppMentions::Mention) do 29 | mention 'ping' do |data| 30 | client = Slack::Web::Client.new(token: data.team.token) 31 | client.chat_postMessage(text: 'two', channel: data.channel) 32 | end 33 | end 34 | end 35 | 36 | context 'one' do 37 | before do 38 | SlackRubyBotServer::Events::AppMentions.configure do |config| 39 | config.handlers = [one] 40 | end 41 | end 42 | 43 | it 'only invokes one registered mention' do 44 | expect_any_instance_of(Slack::Web::Client).to receive(:chat_postMessage).with(text: 'one', channel: 'channel') 45 | SlackRubyBotServer::Events.config.run_callbacks(:event, %w[event_callback app_mention], message) 46 | end 47 | end 48 | 49 | context 'two' do 50 | before do 51 | SlackRubyBotServer::Events::AppMentions.configure do |config| 52 | config.handlers = [two] 53 | end 54 | end 55 | 56 | it 'only invokes two registered mention' do 57 | expect_any_instance_of(Slack::Web::Client).to receive(:chat_postMessage).with(text: 'two', channel: 'channel') 58 | SlackRubyBotServer::Events.config.run_callbacks(:event, %w[event_callback app_mention], message) 59 | end 60 | end 61 | 62 | context 'both' do 63 | context 'one, two' do 64 | before do 65 | SlackRubyBotServer::Events::AppMentions.configure do |config| 66 | config.handlers = [one, two] 67 | end 68 | end 69 | 70 | it 'only invokes first registered mention' do 71 | expect_any_instance_of(Slack::Web::Client).to receive(:chat_postMessage).with(text: 'one', channel: 'channel') 72 | SlackRubyBotServer::Events.config.run_callbacks(:event, %w[event_callback app_mention], message) 73 | end 74 | end 75 | 76 | context 'two, one' do 77 | before do 78 | SlackRubyBotServer::Events::AppMentions.configure do |config| 79 | config.handlers = [two, one] 80 | end 81 | end 82 | 83 | it 'only invokes first registered mention' do 84 | expect_any_instance_of(Slack::Web::Client).to receive(:chat_postMessage).with(text: 'two', channel: 'channel') 85 | SlackRubyBotServer::Events.config.run_callbacks(:event, %w[event_callback app_mention], message) 86 | end 87 | end 88 | end 89 | end 90 | -------------------------------------------------------------------------------- /spec/slack-ruby-bot-server-events-app-mentions/config_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'spec_helper' 4 | 5 | describe SlackRubyBotServer::Events::AppMentions::Config do 6 | %i[ 7 | handlers 8 | ].each do |k| 9 | context "with #{k} set" do 10 | before do 11 | SlackRubyBotServer::Events::AppMentions.configure do |config| 12 | config.send("#{k}=", 'set') 13 | end 14 | end 15 | it "sets and returns #{k}" do 16 | expect(SlackRubyBotServer::Events::AppMentions.config.send(k)).to eq 'set' 17 | end 18 | end 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /spec/slack-ruby-bot-server-events-app-mentions/mentions/mention_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'spec_helper' 4 | 5 | describe SlackRubyBotServer::Events::AppMentions do 6 | let!(:team) { Fabricate(:team) } 7 | 8 | let(:message) do 9 | SlackRubyBotServer::Events::Requests::Event.new( 10 | { 11 | 'token' => 'fake', 12 | 'team_id' => team.team_id, 13 | 'event' => { 14 | 'channel' => 'channel', 15 | 'text' => "<@#{team.bot_user_id}> ping" 16 | } 17 | }, 18 | nil 19 | ) 20 | end 21 | 22 | let!(:mention) do 23 | Class.new(SlackRubyBotServer::Events::AppMentions::Mention) do 24 | mention 'ping' do |data| 25 | client = Slack::Web::Client.new(token: data.team.token) 26 | client.chat_postMessage(text: 'pong', channel: data.channel) 27 | end 28 | end 29 | end 30 | 31 | it 'registers mention' do 32 | expect(SlackRubyBotServer::Events::AppMentions::Mention.handlers).to include mention 33 | end 34 | 35 | it 'invokes a mention' do 36 | expect_any_instance_of(Slack::Web::Client).to receive(:chat_postMessage).with( 37 | text: 'pong', channel: 'channel' 38 | ) 39 | 40 | SlackRubyBotServer::Events.config.run_callbacks( 41 | :event, 42 | %w[event_callback app_mention], 43 | message 44 | ) 45 | end 46 | end 47 | -------------------------------------------------------------------------------- /spec/slack-ruby-bot-server-events-app-mentions/mentions/regexp_mention_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'spec_helper' 4 | 5 | describe SlackRubyBotServer::Events::AppMentions do 6 | let!(:team) { Fabricate(:team) } 7 | 8 | let(:message) do 9 | Slack::Messages::Message.new( 10 | 'team_id' => team.team_id, 11 | 'event' => { 12 | 'channel' => 'channel', 13 | 'text' => "<@#{team.bot_user_id}> ping 10" 14 | } 15 | ) 16 | end 17 | 18 | let!(:mention) do 19 | Class.new(SlackRubyBotServer::Events::AppMentions::Mention) do 20 | mention(/ping[[:space:]]+(?[[:digit:]]+)/) do |data| 21 | client = Slack::Web::Client.new(token: data.team.token) 22 | client.chat_postMessage(text: "pong #{data.match['number']}", channel: data.channel) 23 | end 24 | end 25 | end 26 | 27 | it 'registers mention' do 28 | expect(SlackRubyBotServer::Events::AppMentions::Mention.handlers).to include mention 29 | end 30 | 31 | it 'invokes a mention' do 32 | expect_any_instance_of(Slack::Web::Client).to receive(:chat_postMessage).with( 33 | text: 'pong 10', channel: 'channel' 34 | ) 35 | 36 | SlackRubyBotServer::Events.config.run_callbacks( 37 | :event, 38 | %w[event_callback app_mention], 39 | message 40 | ) 41 | end 42 | end 43 | -------------------------------------------------------------------------------- /spec/slack-ruby-bot-server-events-app-mentions/version_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'spec_helper' 4 | 5 | describe SlackRubyBotServer::Events::AppMentions do 6 | it 'has a version' do 7 | expect(SlackRubyBotServer::Events::AppMentions::VERSION).to_not be nil 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /spec/spec_helper.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | ENV['RACK_ENV'] = 'test' 4 | ENV['DATABASE_ADAPTER'] ||= 'mongoid' 5 | 6 | Bundler.require 7 | 8 | require 'slack-ruby-bot-server/rspec' 9 | 10 | Dir[File.join(__dir__, 'support', '**/*.rb')].sort.each do |file| 11 | require file 12 | end 13 | 14 | SlackRubyBotServer::Service.logger.level = Logger::WARN 15 | 16 | Dir[File.join(__dir__, 'database_adapters', SlackRubyBotServer::Config.database_adapter.to_s, '**/*.rb')].sort.each do |file| 17 | require file 18 | end 19 | -------------------------------------------------------------------------------- /spec/support/config.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | RSpec.configure do |config| 4 | config.before do 5 | SlackRubyBotServer::Events::AppMentions::Config.reset! 6 | @handlers = SlackRubyBotServer::Events::AppMentions::Mention.handlers 7 | end 8 | 9 | config.after do 10 | SlackRubyBotServer::Events::AppMentions::Mention.handlers = @handlers 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /spec/support/rspec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | RSpec.configure do |config| 4 | config.mock_with :rspec 5 | config.expect_with :rspec 6 | config.raise_errors_for_deprecations! 7 | end 8 | --------------------------------------------------------------------------------