slack-ruby-bot-server-rtm 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (60) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +10 -0
  3. data/.rspec +3 -0
  4. data/.rubocop.yml +15 -0
  5. data/.rubocop_todo.yml +29 -0
  6. data/.travis.yml +21 -0
  7. data/CHANGELOG.md +5 -0
  8. data/CONTRIBUTING.md +125 -0
  9. data/Dangerfile +3 -0
  10. data/Gemfile +40 -0
  11. data/LICENSE +21 -0
  12. data/README.md +61 -0
  13. data/RELEASING.md +61 -0
  14. data/Rakefile +16 -0
  15. data/lib/slack-ruby-bot-server-rtm.rb +10 -0
  16. data/lib/slack-ruby-bot-server-rtm/config.rb +29 -0
  17. data/lib/slack-ruby-bot-server-rtm/ext.rb +3 -0
  18. data/lib/slack-ruby-bot-server-rtm/ext/slack-ruby-bot.rb +4 -0
  19. data/lib/slack-ruby-bot-server-rtm/ext/slack-ruby-bot/client.rb +14 -0
  20. data/lib/slack-ruby-bot-server-rtm/ext/slack-ruby-bot/commands/base.rb +20 -0
  21. data/lib/slack-ruby-bot-server-rtm/lifecycle.rb +31 -0
  22. data/lib/slack-ruby-bot-server-rtm/rspec.rb +5 -0
  23. data/lib/slack-ruby-bot-server-rtm/server.rb +52 -0
  24. data/lib/slack-ruby-bot-server-rtm/version.rb +7 -0
  25. data/sample_apps/sample_app_activerecord/.rspec +3 -0
  26. data/sample_apps/sample_app_activerecord/.standalone_migrations +3 -0
  27. data/sample_apps/sample_app_activerecord/Gemfile +26 -0
  28. data/sample_apps/sample_app_activerecord/Procfile +1 -0
  29. data/sample_apps/sample_app_activerecord/README.md +12 -0
  30. data/sample_apps/sample_app_activerecord/Rakefile +16 -0
  31. data/sample_apps/sample_app_activerecord/commands.rb +4 -0
  32. data/sample_apps/sample_app_activerecord/commands/help.rb +21 -0
  33. data/sample_apps/sample_app_activerecord/commands/whoami.rb +8 -0
  34. data/sample_apps/sample_app_activerecord/config.ru +24 -0
  35. data/sample_apps/sample_app_activerecord/config/newrelic.yml +217 -0
  36. data/sample_apps/sample_app_activerecord/config/postgresql.yml +17 -0
  37. data/sample_apps/sample_app_activerecord/db/migrate/20170307164946_create_teams_table.rb +14 -0
  38. data/sample_apps/sample_app_activerecord/db/migrate/20190323181453_add_activated_fields.rb +9 -0
  39. data/sample_apps/sample_app_activerecord/db/schema.rb +31 -0
  40. data/sample_apps/sample_app_activerecord/spec/api/root_spec.rb +18 -0
  41. data/sample_apps/sample_app_activerecord/spec/commands/help_spec.rb +16 -0
  42. data/sample_apps/sample_app_activerecord/spec/commands/whoami_spec.rb +16 -0
  43. data/sample_apps/sample_app_activerecord/spec/spec_helper.rb +21 -0
  44. data/sample_apps/sample_app_mongoid/.rspec +3 -0
  45. data/sample_apps/sample_app_mongoid/Gemfile +22 -0
  46. data/sample_apps/sample_app_mongoid/Procfile +1 -0
  47. data/sample_apps/sample_app_mongoid/README.md +14 -0
  48. data/sample_apps/sample_app_mongoid/Rakefile +12 -0
  49. data/sample_apps/sample_app_mongoid/commands.rb +4 -0
  50. data/sample_apps/sample_app_mongoid/commands/help.rb +21 -0
  51. data/sample_apps/sample_app_mongoid/commands/whoami.rb +8 -0
  52. data/sample_apps/sample_app_mongoid/config.ru +16 -0
  53. data/sample_apps/sample_app_mongoid/config/mongoid.yml +27 -0
  54. data/sample_apps/sample_app_mongoid/config/newrelic.yml +217 -0
  55. data/sample_apps/sample_app_mongoid/spec/api/root_spec.rb +18 -0
  56. data/sample_apps/sample_app_mongoid/spec/commands/help_spec.rb +16 -0
  57. data/sample_apps/sample_app_mongoid/spec/commands/whoami_spec.rb +16 -0
  58. data/sample_apps/sample_app_mongoid/spec/spec_helper.rb +29 -0
  59. data/slack-ruby-bot-server-rtm.gemspec +22 -0
  60. metadata +142 -0
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SlackRubyBotServer
4
+ module RealTime
5
+ module Config
6
+ extend self
7
+
8
+ attr_accessor :server_class
9
+
10
+ def reset!
11
+ self.server_class = SlackRubyBotServer::RealTime::Server
12
+ end
13
+
14
+ reset!
15
+ end
16
+
17
+ class << self
18
+ def configure
19
+ block_given? ? yield(Config) : Config
20
+ end
21
+
22
+ def config
23
+ Config
24
+ end
25
+ end
26
+ end
27
+ end
28
+
29
+ SlackRubyBotServer::RealTime::Config.reset!
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'ext/slack-ruby-bot'
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'slack-ruby-bot/client'
4
+ require_relative 'slack-ruby-bot/commands/base'
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SlackRubyBot
4
+ class Client
5
+ # keep track of the team that the client is connected to
6
+ attr_accessor :owner
7
+ end
8
+ end
9
+
10
+ SlackRubyBot::Client.logger.level = Logger::WARN
11
+
12
+ Slack::RealTime::Client.configure do |config|
13
+ config.store_class = Slack::RealTime::Stores::Starter
14
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SlackRubyBot
4
+ module Commands
5
+ class Base
6
+ class << self
7
+ alias _invoke invoke
8
+
9
+ def invoke(client, data)
10
+ _invoke client, data
11
+ rescue StandardError => e
12
+ logger.info "#{name.demodulize.upcase}: #{client.owner}, #{e.class}: #{e}"
13
+ logger.debug e.backtrace.join("\n")
14
+ client.say(channel: data.channel, text: e.message)
15
+ true
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ SlackRubyBotServer.configure do |config|
4
+ config.oauth_scope ||= ['bot']
5
+ end
6
+
7
+ SlackRubyBotServer::Config.service_class.instance.on :starting do |team, _error, options|
8
+ SlackRubyBotServer::Config.service_class.instance.logger.info "Starting real-time team #{team}."
9
+ options = { team: team }
10
+ server = SlackRubyBotServer::RealTime::Config.server_class.new(options)
11
+ SlackRubyBotServer::RealTime::Server.start_server! team, server
12
+ end
13
+
14
+ SlackRubyBotServer::Config.service_class.instance.on :restarting do |team, _error, options|
15
+ SlackRubyBotServer::Config.service_class.instance.logger.info "Restarting real-time team #{team}."
16
+ SlackRubyBotServer::RealTime::Server.start_server! team, server, options[:wait]
17
+ end
18
+
19
+ SlackRubyBotServer::Config.service_class.instance.on :stopped do |team, _error, _options|
20
+ SlackRubyBotServer::Config.service_class.instance.logger.info "Stopping real-time team #{team}."
21
+ begin
22
+ team.server&.stop!
23
+ ensure
24
+ team.server = nil
25
+ end
26
+ end
27
+
28
+ SlackRubyBotServer::Config.service_class.instance.on :deactivated do |team, _error, _options|
29
+ SlackRubyBotServer::Config.service_class.instance.logger.info "De-activating real-time team #{team}."
30
+ team.server = nil
31
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'slack-ruby-bot/rspec'
4
+ require 'slack-ruby-bot-server/rspec'
5
+ require 'slack-ruby-bot-server-rtm'
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'ext/slack-ruby-bot/client'
4
+
5
+ module SlackRubyBotServer
6
+ module RealTime
7
+ class Server < ::SlackRubyBot::Server
8
+ attr_accessor :team
9
+
10
+ def initialize(attrs = {})
11
+ attrs = attrs.dup
12
+ @team = attrs.delete(:team)
13
+ raise 'Missing team' unless @team
14
+
15
+ attrs[:token] = @team.token
16
+ super(attrs)
17
+ open!
18
+ end
19
+
20
+ def self.start_server!(team, server, wait = 1)
21
+ team.server = server
22
+ server.start_async
23
+ rescue StandardError => e
24
+ SlackRubyBotServer::Config.service_class.instance.run_callbacks :error, team, e
25
+ case e.message
26
+ when 'account_inactive', 'invalid_auth' then
27
+ SlackRubyBotServer::Config.logger.error "#{team.name}: #{e.message}, team will be deactivated."
28
+ SlackRubyBotServer::RealTime::Service.instance.deactivate! team
29
+ elsef
30
+ wait = e.retry_after if e.is_a?(Slack::Web::Api::Errors::TooManyRequestsError)
31
+ SlackRubyBotServer::Config.logger.error "#{team.name}: #{e.message}, restarting in #{wait} second(s)."
32
+ sleep(wait)
33
+ start_server! team, server, [wait * 2, 60].min
34
+ end
35
+ end
36
+
37
+ def restart!(_wait = 1)
38
+ # when an integration is disabled, a live socket is closed, which causes the default behavior of the client to restart
39
+ # it would keep retrying without checking for account_inactive or such, we want to restart via service which will disable an inactive team
40
+ logger.info "#{team.name}: socket closed, restarting ..."
41
+ SlackRubyBotServer::RealTime::Service.instance.restart! team
42
+ open!
43
+ end
44
+
45
+ private
46
+
47
+ def open!
48
+ client.owner = team
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SlackRubyBotServer
4
+ module RealTime
5
+ VERSION = '0.1.0'
6
+ end
7
+ end
@@ -0,0 +1,3 @@
1
+ --color
2
+ --format=documentation
3
+
@@ -0,0 +1,3 @@
1
+ config:
2
+ database: config/postgresql.yml
3
+
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ gem 'activerecord', '~> 5.0.0', require: 'active_record'
6
+ gem 'newrelic-slack-ruby-bot'
7
+ gem 'otr-activerecord', '~> 1.2.1'
8
+ gem 'pg'
9
+ gem 'rack-server-pages'
10
+ gem 'rack-test'
11
+ gem 'slack-ruby-bot-server-rtm', path: '../../'
12
+ gem 'unicorn'
13
+
14
+ group :development, :test do
15
+ gem 'standalone_migrations', '~> 5.2'
16
+ end
17
+
18
+ group :test do
19
+ gem 'database_cleaner'
20
+ gem 'fabrication'
21
+ gem 'faker'
22
+ gem 'rake'
23
+ gem 'rspec'
24
+ gem 'vcr'
25
+ gem 'webmock'
26
+ end
@@ -0,0 +1 @@
1
+ web: bundle exec unicorn -p $PORT
@@ -0,0 +1,12 @@
1
+ ### What's this?
2
+
3
+ This is a sample slack-ruby-bot-server with ActiveRecord.
4
+
5
+ ### Run
6
+
7
+ ```
8
+ bundle install
9
+ rake db:create db:migrate
10
+ RAILS_ENV=test rake db:migrate
11
+ rackup
12
+ ```
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rubygems'
4
+ require 'bundler/setup'
5
+
6
+ require 'rspec/core'
7
+ require 'rspec/core/rake_task'
8
+
9
+ require 'standalone_migrations'
10
+ StandaloneMigrations::Tasks.load_tasks
11
+
12
+ RSpec::Core::RakeTask.new(:spec) do |spec|
13
+ spec.pattern = FileList['spec/**/*_spec.rb']
14
+ end
15
+
16
+ task default: ['db:create', 'db:migrate', :spec]
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'commands/help'
4
+ require_relative 'commands/whoami'
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Help < SlackRubyBot::Commands::Base
4
+ HELP = <<~EOS
5
+ ```
6
+ I am your friendly slack-ruby-bot-server, here to help.
7
+
8
+ General
9
+ -------
10
+
11
+ help - get this helpful message
12
+ whoami - print your username
13
+
14
+ ```
15
+ EOS
16
+ def self.call(client, data, _match)
17
+ client.say(channel: data.channel, text: [HELP, SlackRubyBotServer::INFO].join("\n"))
18
+ client.say(channel: data.channel)
19
+ logger.info "HELP: #{client.owner}, user=#{data.user}"
20
+ end
21
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Whoami < SlackRubyBot::Commands::Base
4
+ def self.call(client, data, _match)
5
+ client.say(channel: data.channel, text: "<@#{data.user}>")
6
+ logger.info "UNAME: #{client.owner}, user=#{data.user}"
7
+ end
8
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ ENV['RACK_ENV'] ||= 'development'
4
+
5
+ Bundler.require :default
6
+
7
+ require_relative 'commands'
8
+ require 'yaml'
9
+ require 'erb'
10
+
11
+ ActiveRecord::Base.establish_connection(
12
+ YAML.safe_load(
13
+ ERB.new(
14
+ File.read('config/postgresql.yml')
15
+ ).result, [], [], true
16
+ )[ENV['RACK_ENV']]
17
+ )
18
+
19
+ NewRelic::Agent.manual_start
20
+
21
+ SlackRubyBotServer::App.instance.prepare!
22
+ SlackRubyBotServer::Service.start!
23
+
24
+ run SlackRubyBotServer::Api::Middleware.instance
@@ -0,0 +1,217 @@
1
+ # Here are the settings that are common to all environments
2
+ common: &default_settings
3
+ # ============================== LICENSE KEY ===============================
4
+
5
+ # You must specify the license key associated with your New Relic
6
+ # account. This key binds your Agent's data to your account in the
7
+ # New Relic service.
8
+ license_key: '<%= ENV["NEW_RELIC_LICENSE_KEY"] %>'
9
+
10
+ # Application Name Set this to be the name of your application as
11
+ # you'd like it show up in New Relic. The service will then auto-map
12
+ # instances of your application into an "application" on your
13
+ # dashboard page. If you want to map this instance into multiple
14
+ # apps, like "AJAX Requests" and "All UI" then specify a semicolon
15
+ # separated list of up to three distinct names, or a yaml list.
16
+ app_name: <%= ENV["NEW_RELIC_APP_NAME"] || 'SlackRubyBotServer' %>
17
+
18
+ # When "true", the agent collects performance data about your
19
+ # application and reports this data to the New Relic service at
20
+ # newrelic.com. This global switch is normally overridden for each
21
+ # environment below. (formerly called 'enabled')
22
+ monitor_mode: true
23
+
24
+ # Developer mode should be off in every environment but
25
+ # development as it has very high overhead in memory.
26
+ developer_mode: false
27
+
28
+ # The newrelic agent generates its own log file to keep its logging
29
+ # information separate from that of your application. Specify its
30
+ # log level here.
31
+ log_level: info
32
+
33
+ # Optionally set the path to the log file This is expanded from the
34
+ # root directory (may be relative or absolute, e.g. 'log/' or
35
+ # '/var/log/') The agent will attempt to create this directory if it
36
+ # does not exist.
37
+ # log_file_path: 'log'
38
+
39
+ # Optionally set the name of the log file, defaults to 'newrelic_agent.log'
40
+ # log_file_name: 'newrelic_agent.log'
41
+
42
+ # The newrelic agent communicates with the service via http by
43
+ # default. If you want to communicate via https to increase
44
+ # security, then turn on SSL by setting this value to true. Note,
45
+ # this will result in increased CPU overhead to perform the
46
+ # encryption involved in SSL communication, but this work is done
47
+ # asynchronously to the threads that process your application code,
48
+ # so it should not impact response times.
49
+ ssl: false
50
+
51
+ # EXPERIMENTAL: enable verification of the SSL certificate sent by
52
+ # the server. This setting has no effect unless SSL is enabled
53
+ # above. This may block your application. Only enable it if the data
54
+ # you send us needs end-to-end verified certificates.
55
+ #
56
+ # This means we cannot cache the DNS lookup, so each request to the
57
+ # service will perform a lookup. It also means that we cannot
58
+ # use a non-blocking lookup, so in a worst case, if you have DNS
59
+ # problems, your app may block indefinitely.
60
+ # verify_certificate: true
61
+
62
+ # Set your application's Apdex threshold value with the 'apdex_t'
63
+ # setting, in seconds. The apdex_t value determines the buckets used
64
+ # to compute your overall Apdex score.
65
+ # Requests that take less than apdex_t seconds to process will be
66
+ # classified as Satisfying transactions; more than apdex_t seconds
67
+ # as Tolerating transactions; and more than four times the apdex_t
68
+ # value as Frustrating transactions.
69
+ # For more about the Apdex standard, see
70
+ # http://newrelic.com/docs/general/apdex
71
+
72
+ apdex_t: 0.5
73
+
74
+ #============================== Browser Monitoring ===============================
75
+ # New Relic Real User Monitoring gives you insight into the performance real users are
76
+ # experiencing with your website. This is accomplished by measuring the time it takes for
77
+ # your users' browsers to download and render your web pages by injecting a small amount
78
+ # of JavaScript code into the header and footer of each page.
79
+ browser_monitoring:
80
+ # By default the agent automatically injects the monitoring JavaScript
81
+ # into web pages. Set this attribute to false to turn off this behavior.
82
+ auto_instrument: true
83
+
84
+ # Proxy settings for connecting to the service.
85
+ #
86
+ # If a proxy is used, the host setting is required. Other settings
87
+ # are optional. Default port is 8080.
88
+ #
89
+ # proxy_host: hostname
90
+ # proxy_port: 8080
91
+ # proxy_user:
92
+ # proxy_pass:
93
+
94
+
95
+ # Tells transaction tracer and error collector (when enabled)
96
+ # whether or not to capture HTTP params. When true, frameworks can
97
+ # exclude HTTP parameters from being captured.
98
+ # Rails: the RoR filter_parameter_logging excludes parameters
99
+ # Java: create a config setting called "ignored_params" and set it to
100
+ # a comma separated list of HTTP parameter names.
101
+ # ex: ignored_params: credit_card, ssn, password
102
+ capture_params: true
103
+
104
+
105
+ # Transaction tracer captures deep information about slow
106
+ # transactions and sends this to the service once a
107
+ # minute. Included in the transaction is the exact call sequence of
108
+ # the transactions including any SQL statements issued.
109
+ transaction_tracer:
110
+
111
+ # Transaction tracer is enabled by default. Set this to false to
112
+ # turn it off. This feature is only available at the Professional
113
+ # and above product levels.
114
+ enabled: true
115
+
116
+ # Threshold in seconds for when to collect a transaction
117
+ # trace. When the response time of a controller action exceeds
118
+ # this threshold, a transaction trace will be recorded and sent to
119
+ # the service. Valid values are any float value, or (default)
120
+ # "apdex_f", which will use the threshold for an dissatisfying
121
+ # Apdex controller action - four times the Apdex T value.
122
+ transaction_threshold: apdex_f
123
+
124
+ # When transaction tracer is on, SQL statements can optionally be
125
+ # recorded. The recorder has three modes, "off" which sends no
126
+ # SQL, "raw" which sends the SQL statement in its original form,
127
+ # and "obfuscated", which strips out numeric and string literals
128
+ record_sql: obfuscated
129
+
130
+ # Threshold in seconds for when to collect stack trace for a SQL
131
+ # call. In other words, when SQL statements exceed this threshold,
132
+ # then capture and send the current stack trace. This is
133
+ # helpful for pinpointing where long SQL calls originate from
134
+ stack_trace_threshold: 0.500
135
+
136
+ # Determines whether the agent will capture query plans for slow
137
+ # SQL queries. Only supported in mysql and postgres. Should be
138
+ # set to false when using other adapters.
139
+ # explain_enabled: true
140
+
141
+ # Threshold for query execution time below which query plans will not
142
+ # not be captured. Relevant only when `explain_enabled` is true.
143
+ # explain_threshold: 0.5
144
+
145
+ # Error collector captures information about uncaught exceptions and
146
+ # sends them to the service for viewing
147
+ error_collector:
148
+
149
+ # Error collector is enabled by default. Set this to false to turn
150
+ # it off. This feature is only available at the Professional and above
151
+ # product levels
152
+ enabled: true
153
+
154
+ # Rails Only - tells error collector whether or not to capture a
155
+ # source snippet around the place of the error when errors are View
156
+ # related.
157
+ capture_source: true
158
+
159
+ # To stop specific errors from reporting to New Relic, set this property
160
+ # to comma separated values. Default is to ignore routing errors
161
+ # which are how 404's get triggered.
162
+ #
163
+ ignore_errors: ActionController::RoutingError
164
+
165
+ # (Advanced) Uncomment this to ensure the cpu and memory samplers
166
+ # won't run. Useful when you are using the agent to monitor an
167
+ # external resource
168
+ # disable_samplers: true
169
+
170
+ # If you aren't interested in visibility in these areas, you can
171
+ # disable the instrumentation to reduce overhead.
172
+ #
173
+ # disable_view_instrumentation: true
174
+ # disable_activerecord_instrumentation: true
175
+ # disable_memcache_instrumentation: true
176
+ # disable_dj: true
177
+
178
+ # If you're interested in capturing memcache keys as though they
179
+ # were SQL uncomment this flag. Note that this does increase
180
+ # overhead slightly on every memcached call, and can have security
181
+ # implications if your memcached keys are sensitive
182
+ # capture_memcache_keys: true
183
+
184
+ # Certain types of instrumentation such as GC stats will not work if
185
+ # you are running multi-threaded. Please let us know.
186
+ # multi_threaded = false
187
+
188
+ # Application Environments
189
+ # ------------------------------------------
190
+
191
+ development:
192
+ <<: *default_settings
193
+ # Turn off communication to New Relic service in development mode (also
194
+ # 'enabled').
195
+ # NOTE: for initial evaluation purposes, you may want to temporarily
196
+ # turn the agent on in development mode.
197
+ monitor_mode: false
198
+
199
+ # Rails Only - when running in Developer Mode, the New Relic Agent will
200
+ # present performance information on the last 100 transactions you have
201
+ # executed since starting the mongrel.
202
+ # NOTE: There is substantial overhead when running in developer mode.
203
+ # Do not use for production or load testing.
204
+ developer_mode: true
205
+
206
+ # Enable textmate links
207
+ # textmate: true
208
+
209
+ test:
210
+ <<: *default_settings
211
+ # It almost never makes sense to turn on the agent when running
212
+ # unit, functional or integration tests or the like.
213
+ monitor_mode: false
214
+
215
+ production:
216
+ <<: *default_settings
217
+ monitor_mode: true