slack_bot-events 0.4.1 → 0.4.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +4 -0
- data/Gemfile.lock +1 -1
- data/README.md +125 -0
- data/boring_slack_configuration.md +39 -0
- data/changelog.md +7 -0
- data/examples/README.md +30 -0
- data/examples/basic/Gemfile +4 -0
- data/examples/basic/main.rb +26 -0
- data/examples/basic/message_listener.rb +22 -0
- data/examples/middleware/Gemfile +4 -0
- data/examples/middleware/main.rb +21 -0
- data/examples/middleware/meddling_message_middleware.rb +33 -0
- data/examples/middleware/message_listener.rb +22 -0
- data/examples/middleware_no_yield/Gemfile +4 -0
- data/examples/middleware_no_yield/main.rb +21 -0
- data/examples/middleware_no_yield/meddling_message_middleware.rb +10 -0
- data/examples/middleware_no_yield/message_listener.rb +20 -0
- data/examples/multi_listener/Gemfile +4 -0
- data/examples/multi_listener/main.rb +42 -0
- data/examples/multi_listener/message_listener.rb +23 -0
- data/examples/multi_listener/reaction_removed_listener.rb +23 -0
- data/lib/slack_bot/events/client.rb +1 -1
- data/lib/slack_bot/events/middleware/chain.rb +8 -5
- data/lib/slack_bot/events/middleware/event_tracer.rb +9 -7
- data/lib/slack_bot/events/middleware/message_handler.rb +0 -2
- data/lib/slack_bot/events/version.rb +1 -1
- metadata +20 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4db0e3fd554d51024ebf0d4c1b6d63856ccd4d72c6c83901d0542926db70c2ac
|
4
|
+
data.tar.gz: 154cc348c600534eda58f68d3b66bcae1ef924f73964f9787e98fc18882c363c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6dca807680fbd02f2c8ce30ba2a019c03e5acf47373fbc73133ff61fcd981973f3bee7b1257f014d1b1d05bb46b1af92a8e07336186a3a20118a851ffe8713f3
|
7
|
+
data.tar.gz: 52449fa2a7f111fd5dc06fd605995bac87994822dda2e483d0ab012a2df330d25bd22e42692b0428f6967340a99b1fa4e71a5c0dccb4475abcd4b124b15d3ba6
|
data/.gitignore
CHANGED
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -0,0 +1,125 @@
|
|
1
|
+
# SlackBot Events
|
2
|
+
|
3
|
+
Welcome to SlackBot Events Gem! This gem provides a seamless way to hook into your paid Slack Workspace's Events API and run complex or simple automation. You can run automations based on events like: Message Deleted, Reactions Added, Reactions Removed, Message sent to channel, Message sent to Thread, User added to Channel, and so many more. [View Full list of Events Here](https://api.slack.com/events).
|
4
|
+
|
5
|
+
SlackBot Events provides the foundational tooling to run a SlackBot, automate Jira tickets based on Events, Customize and Automate AI responses to messages, Automate tagging relavant groups in threads, track time to respond and time to resolve threads, and so much more.
|
6
|
+
|
7
|
+
SlackBot Events Gem connects directly into your paid Slack workspace by utilizing websockets. Websockets provides a resilient, safe, and reliable connection to retreive events without the need to expose a public endpoint for Slack Events.
|
8
|
+
|
9
|
+
## Installation
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
source 'http://rubygems.org'
|
13
|
+
gem 'slack_bot-events'
|
14
|
+
```
|
15
|
+
|
16
|
+
[Example Use Cases](/examples)
|
17
|
+
|
18
|
+
## SlackBot Events inspiration
|
19
|
+
|
20
|
+
There already exists No to Low code Slack workflow Engines like Zappier. However, these workflows are often slow and buggy. They cost money based on usage. Additionally, creating complex workflows with low code is a bit messy.
|
21
|
+
|
22
|
+
SlackBot Events provides a free alternative to exposing events from your paid Slack Workspace.
|
23
|
+
|
24
|
+
## Configuration
|
25
|
+
|
26
|
+
### Required Slack Bot Configuration
|
27
|
+
This bit is rather boring. Check out the [Boring Slack Configuration Setup](/boring_slack_configuration.md). You will need the App Level Token for the next step
|
28
|
+
|
29
|
+
### Required ENV variables:
|
30
|
+
`SLACK_SOCKET_TOKEN` is the only ENV variable that is required for this Gem. Using the token that was saved from an earlier step, set the token to the ENV variable `SLACK_SOCKET_TOKEN`. There is an alternate assignment option below.
|
31
|
+
|
32
|
+
### Configuration Options:
|
33
|
+
``` ruby
|
34
|
+
SlackBot::Events.configure do |config|
|
35
|
+
# This token is needed to retreive a WebSocket connection to the Events API
|
36
|
+
# Default value: ENV["SLACK_SOCKET_TOKEN"]
|
37
|
+
config.client_socket_token = "AppLevelToken"
|
38
|
+
|
39
|
+
# By default, SlackBot::Events will print out a TLDR of every events message that comes through
|
40
|
+
# Default value: true
|
41
|
+
config.print_tldr = true
|
42
|
+
|
43
|
+
# By default, SlackBot::Events will acknowledge at the end of the middleware chain after it passes the message to the event listener. Available options:
|
44
|
+
# => on_complete: Acknowledge after listener has completed on failure and on success
|
45
|
+
# => on_success: Acknowledge only on succesful listener events (Use with caution)
|
46
|
+
# => on_receive: Acknowledge at the beginning of the middleware chain before it gets to listener events
|
47
|
+
# Default value: :on_complete
|
48
|
+
config.envelope_acknowledge = :on_complete
|
49
|
+
|
50
|
+
# By default, this gem outputs to STDOUT. You can set your own logger ot set it to the Rails logger if desired
|
51
|
+
# Default value: Logger.new(STDOUT)
|
52
|
+
config.logger = Rails.logger
|
53
|
+
end
|
54
|
+
```
|
55
|
+
|
56
|
+
### Event Listeners:
|
57
|
+
Event Listeners is where the configurable power comes in. Listeners are custom code that gets run on specific event_api actions as defined in [Slack Event Types](https://api.slack.com/events).
|
58
|
+
|
59
|
+
There can be at most 1 configured listener listeing to any given event type.
|
60
|
+
|
61
|
+
To Register a new listener:
|
62
|
+
```ruby
|
63
|
+
SlackBot::Events.register_listener(name: "event_type_name", handler: handler_object)
|
64
|
+
SlackBot::Events.register_listener(name: "event_type_name_2", handler: handler_object2, on_success: on_success_proc)
|
65
|
+
SlackBot::Events.register_listener(name: "event_type_name_3", handler: handler_object3, on_failure: on_failure_proc)
|
66
|
+
|
67
|
+
### Or via the config
|
68
|
+
|
69
|
+
SlackBot::Events.configure do |c|
|
70
|
+
c.register_listener(name: "event_type_name4", handler: handler_object4)
|
71
|
+
end
|
72
|
+
|
73
|
+
```
|
74
|
+
|
75
|
+
#### Handler
|
76
|
+
The Handler argument must be an object that responds to `call` with KWargs `schema` and `raw_data`.
|
77
|
+
|
78
|
+
#### On Failure (Optional Argument)
|
79
|
+
The `on_failure` argument must be an object that resoonds to `call` with 2 arguments. The first argument will be the converted schema if available. The second argument will be the error that caused the Handler to fail
|
80
|
+
|
81
|
+
#### On Success (Optional Argument)
|
82
|
+
The `on_success` argument must be an object that resoonds to `call` with 1 argument. The argument will be the converted schema if available.
|
83
|
+
|
84
|
+
[Example with Basic Listeners](/examples/basic)
|
85
|
+
|
86
|
+
[Example with Multiple Listeners](/examples/multi_listener)
|
87
|
+
|
88
|
+
## Middleware
|
89
|
+
|
90
|
+
Middlewares can help add additional observability into a unit of work. For the Websocket message type, you can add any number of middlewars via the Configure block.
|
91
|
+
|
92
|
+
|
93
|
+
```ruby
|
94
|
+
SlackBot::Events.configure do |c|
|
95
|
+
c.message_middleware.add(DataDogObeservabilityMiddleware)
|
96
|
+
end
|
97
|
+
```
|
98
|
+
|
99
|
+
## Known Restrictions
|
100
|
+
### Limited number of events per hour per workspace
|
101
|
+
[Slack Events API](https://api.slack.com/apis/rate-limits#events) has a limit of 30,000 events sent per hour per workspace. When this limit is hit, Slack will send the message type `app_rate_limited`.
|
102
|
+
|
103
|
+
You can see an example of how this can get handled in the [EventTracer Middleware](lib/slack_bot/events/middleware/event_tracer.rb)
|
104
|
+
|
105
|
+
|
106
|
+
### 10 open Sockets per App
|
107
|
+
A Slack app can have at most 10 open sockets to Slack simultaneously. On WebSocket aquisition, it will first send the `open` type. This will reveal how many open connections there currently are.
|
108
|
+
|
109
|
+
In regards to SlackBot::Events, this limitation means that you can have at most 10 instances of SlackBot::Events running per bod.
|
110
|
+
|
111
|
+
For more information, Visit [Using Multiple Connections](https://api.slack.com/apis/socket-mode#connections) on Slack API page
|
112
|
+
|
113
|
+
### Message Acknowledgment
|
114
|
+
`SlackBot::Events` by default will handle message acknowledgment on your behalf. This can get taken care of before or after the handler is executed.
|
115
|
+
|
116
|
+
Slack expects an Aknowledgment within 3 seconds. If your Middleware combined with the handler execution takes longer than the expected 3 seconds, Slack will immediately attempt to send the same envelope package again. This will cause duplication in your application.
|
117
|
+
|
118
|
+
Retry attempts can occur on any open socket.
|
119
|
+
- Attempt 3 Seconds after no response
|
120
|
+
- Attempt 60 Seconds after no response
|
121
|
+
- Attempt 5 minutes after no response
|
122
|
+
|
123
|
+
Over the course of an hour, if you fail to send acknowledgement before the first retry, you will be rate limited and your app cordoned off
|
124
|
+
|
125
|
+
Ideally, your listener executes quickly and returns. This means your execution is quick or you ship the data off to an async job like Sidekiq or spawn a new thread.
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# Slack Bot Requirements:
|
2
|
+
SlackBot::Events gem utilizes the [Slack Events API](https://api.slack.com/apis/events-api) with Socket Mode. Events are pushed directly to any socket that is open and accepting requets.
|
3
|
+
|
4
|
+
**Warning** This Slack Bot requires the ability to connect to the events API using a WebSocket. This is only available in paid workspaces and development workspaces. Not available in free Workspaces.
|
5
|
+
|
6
|
+
You will need:
|
7
|
+
## Slack App created
|
8
|
+
To create a Slack App, checkout out [Slacks App Quickstart Guide](https://api.slack.com/quickstart). If you are familiar with Slack App Creation, you can go directly to the [Slack Apps Homepage](https://api.slack.com/apps)
|
9
|
+
|
10
|
+
## Slack App Socket Enable
|
11
|
+
SlackBot::Events is based on Socket mode. Socket mode must get enabled before you can subscribe to events without a `Request URL` public endpoint in your application.
|
12
|
+
|
13
|
+
Navigate to your app and select the `Socket Mode` tab on the left. Ensure the switch to `Enable Socket Mode` is toggled on before proceeding
|
14
|
+
|
15
|
+
You will be asked to create a new token. Name it whatever you would like. This will create a new token for you.
|
16
|
+
|
17
|
+
You will **NEED** to retain the token for this Gem. (But don't worry, you can create a new one using with [Slack App Level tokens](https://api.slack.com/concepts/token-types#app-level) later as well)
|
18
|
+
|
19
|
+
## Slack App Events received
|
20
|
+
Every workpace has a limitation on the number of events the entire workspace can receive. This means that you should choose carefully which events your App can recieve.
|
21
|
+
|
22
|
+
Navigate to your app and select the `Event Subscriptions` tab on the left.
|
23
|
+
|
24
|
+
Carefully pick the events to subscribe to under the `Subscribe to bot events`.
|
25
|
+
|
26
|
+
A good place to start is by subscribing to the following events:
|
27
|
+
```
|
28
|
+
message.channels
|
29
|
+
reaction_added
|
30
|
+
reaction_removed
|
31
|
+
```
|
32
|
+
*Note*: This will automatically add the correct OAuth permissions to the bot user. When you want to add additional subscriptions, come back here.
|
33
|
+
|
34
|
+
## Install the Slack app to your workspace
|
35
|
+
Navigate to your app and select the `Install App` tab on the left. Click on `Install to Workspace`. In some cases, you may need to get Workspace Admin approval before the app becomes available in the workspace.
|
36
|
+
|
37
|
+
## Add the Bot to specific Channels
|
38
|
+
Once the App is intalled into the workspace, invite the new bot to channels. Once the bot is in a channel, it will have the ability to send subscribed events to SlackBot::Events gem
|
39
|
+
|
data/changelog.md
ADDED
data/examples/README.md
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
# Examples
|
2
|
+
This is the root directory for examples. Provided you have the correct `SLACK_SOCKET_TOKEN` ENV variable created, these examples will work with your workspace.
|
3
|
+
|
4
|
+
## [Basic Example](/examples/basic)
|
5
|
+
```bash
|
6
|
+
cd basic
|
7
|
+
bundle i
|
8
|
+
ruby main.rb
|
9
|
+
```
|
10
|
+
|
11
|
+
## [Middleware Example](/examples/middleware)
|
12
|
+
```bash
|
13
|
+
cd middleware
|
14
|
+
bundle i
|
15
|
+
ruby main.rb
|
16
|
+
```
|
17
|
+
|
18
|
+
## [Middleware No Yield Example](/examples/middleware_no_yield)
|
19
|
+
```bash
|
20
|
+
cd middleware_no_yield
|
21
|
+
bundle i
|
22
|
+
ruby main.rb
|
23
|
+
```
|
24
|
+
|
25
|
+
## [Multi Listener Example](/examples/multi_listener)
|
26
|
+
```bash
|
27
|
+
cd multi_listener
|
28
|
+
bundle i
|
29
|
+
ruby main.rb
|
30
|
+
```
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'bundler/setup'
|
4
|
+
|
5
|
+
require "slack_bot-events"
|
6
|
+
require_relative "message_listener.rb"
|
7
|
+
|
8
|
+
# The `name` must match a Event subscription type found
|
9
|
+
# https://api.slack.com/events
|
10
|
+
|
11
|
+
# Register a listener for all reaction removed events
|
12
|
+
SlackBot::Events.register_listener(
|
13
|
+
name: "message",
|
14
|
+
# Handler must respond to call with schema: and raw_data: KWARGS
|
15
|
+
handler: MessageListener,
|
16
|
+
# on_success must respond to call with 1 arg of schema
|
17
|
+
on_success: MessageListener.method(:on_success),
|
18
|
+
# on_failure must respond to call with 2 args of schema and error
|
19
|
+
on_failure: MessageListener.method(:on_failure),
|
20
|
+
)
|
21
|
+
|
22
|
+
|
23
|
+
# This is a blocking way to start the Websocket client
|
24
|
+
# EventMachine is used to keep the socket open
|
25
|
+
# The process responds to all SigQuit/Term/Kill events as expected
|
26
|
+
SlackBot::Events::Client.new.start!
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module MessageListener
|
4
|
+
def self.call(schema:, raw_data:)
|
5
|
+
# Do some cool(quick returning) things here
|
6
|
+
# schema.payload.event will be a SlackBot::Events::Schemas::Type::Message
|
7
|
+
puts "Heya! I found a message! #{schema.payload.event.text}"
|
8
|
+
raise StandardError, "I Randomly decided to Barf" if rand > 0.9
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.on_success(schema)
|
12
|
+
# Send a metric maybe?
|
13
|
+
# Or a Log Message
|
14
|
+
puts "Congrats! You executed it succesfully"
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.on_failure(schema, error)
|
18
|
+
# Send job to sidekiq to try again?
|
19
|
+
# Or send a log message; but make sure to do it quick
|
20
|
+
puts "Yikes, You died a misreable death"
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'bundler/setup'
|
4
|
+
|
5
|
+
require "slack_bot-events"
|
6
|
+
require_relative "message_listener.rb"
|
7
|
+
require_relative "meddling_message_middleware.rb"
|
8
|
+
|
9
|
+
SlackBot::Events.configure do |c|
|
10
|
+
c.message_middleware.add(MeddlingMessageMiddleware)
|
11
|
+
c.print_tldr = false
|
12
|
+
end
|
13
|
+
|
14
|
+
SlackBot::Events.register_listener(
|
15
|
+
name: "message",
|
16
|
+
handler: MessageListener,
|
17
|
+
on_success: MessageListener.method(:on_success),
|
18
|
+
on_failure: MessageListener.method(:on_failure),
|
19
|
+
)
|
20
|
+
|
21
|
+
SlackBot::Events::Client.new.start!
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class MeddlingMessageMiddleware
|
4
|
+
# Message middlewares have the following KWargs available to them
|
5
|
+
|
6
|
+
# parsed_data => Raw JSON of schema
|
7
|
+
# schema => Schematized objected of data. schema.payload.event has much of the data you will want to mess with
|
8
|
+
# socket_event => The socket_event object that was given -- Unlikely you need to play with this
|
9
|
+
# listener => { handler:, on_success:, on_failure: } if the listener exists for the schema type; will be nil otherwise
|
10
|
+
# type => will be one of :message, :ope, :close
|
11
|
+
# websocket => The websocket client attached to Slack
|
12
|
+
def call(parsed_data:, schema:, socket_event:, listener:, type:, websocket:)
|
13
|
+
###
|
14
|
+
# Code to execute BEFORE the listener handler is called
|
15
|
+
###
|
16
|
+
puts "I get called BEFORE the Handler gets executed"
|
17
|
+
|
18
|
+
|
19
|
+
|
20
|
+
# The middleware chain is broken if yield is not called
|
21
|
+
# If provided, the listener handler will not get called either
|
22
|
+
# There may be occasions when you want to halt the middleware chain, but
|
23
|
+
# for the most part, ensure you always yield
|
24
|
+
yield
|
25
|
+
|
26
|
+
|
27
|
+
|
28
|
+
###
|
29
|
+
# Code to execute AFTER the listener handler is called
|
30
|
+
###
|
31
|
+
puts "I get called AFTER the Handler gets executed"
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module MessageListener
|
4
|
+
def self.call(schema:, raw_data:)
|
5
|
+
# Do some cool(quick returning) things here
|
6
|
+
# schema.payload.event will be a SlackBot::Events::Schemas::Type::Message
|
7
|
+
puts "Heya! I found a message! #{schema.payload.event.text}"
|
8
|
+
raise StandardError, "I Randomly decided to Barf" if rand > 0.9
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.on_success(schema)
|
12
|
+
# Send a metric maybe?
|
13
|
+
# Or a Log Message
|
14
|
+
puts "Congrats! You executed it succesfully"
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.on_failure(schema, error)
|
18
|
+
# Send job to sidekiq to try again?
|
19
|
+
# Or send a log message; but make sure to do it quick
|
20
|
+
puts "Yikes, You died a misreable death"
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'bundler/setup'
|
4
|
+
|
5
|
+
require "slack_bot-events"
|
6
|
+
require_relative "message_listener.rb"
|
7
|
+
require_relative "meddling_message_middleware.rb"
|
8
|
+
|
9
|
+
SlackBot::Events.configure do |c|
|
10
|
+
c.message_middleware.add(MeddlingMessageMiddleware)
|
11
|
+
c.print_tldr = false
|
12
|
+
end
|
13
|
+
|
14
|
+
SlackBot::Events.register_listener(
|
15
|
+
name: "message",
|
16
|
+
handler: MessageListener,
|
17
|
+
on_success: MessageListener.method(:on_success),
|
18
|
+
on_failure: MessageListener.method(:on_failure),
|
19
|
+
)
|
20
|
+
|
21
|
+
SlackBot::Events::Client.new.start!
|
@@ -0,0 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class MeddlingMessageMiddleware
|
4
|
+
# Message middlewares have the following KWargs available to them
|
5
|
+
def call(parsed_data:, schema:, socket_event:, listener:, type:, websocket:)
|
6
|
+
puts "I get called BEFORE the Handler gets executed"
|
7
|
+
|
8
|
+
puts "But wait! There is no yield, Message Handler never gets called"
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module MessageListener
|
4
|
+
|
5
|
+
def self.call(schema:, raw_data:)
|
6
|
+
raise "Its okay, It never actually makes it here"
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.on_success(schema)
|
10
|
+
# Send a metric maybe?
|
11
|
+
# Or a Log Message
|
12
|
+
puts "I did still make it to the on_success handler"
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.on_failure(schema, error)
|
16
|
+
# Send job to sidekiq to try again?
|
17
|
+
# Or send a log message; but make sure to do it quick
|
18
|
+
puts "Yikes, You died a misreable death"
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'bundler/setup'
|
4
|
+
|
5
|
+
require "slack_bot-events"
|
6
|
+
require_relative "message_listener.rb"
|
7
|
+
require_relative "reaction_removed_listener.rb"
|
8
|
+
|
9
|
+
# The `name` must match a Event subscription type found
|
10
|
+
# https://api.slack.com/events
|
11
|
+
|
12
|
+
###
|
13
|
+
# In the examples below, on_success and on_failure are methods
|
14
|
+
# They can be left empty or a be a proc
|
15
|
+
###
|
16
|
+
|
17
|
+
# Register a listener for all reaction removed events
|
18
|
+
SlackBot::Events.register_listener(
|
19
|
+
name: "reaction_removed",
|
20
|
+
# Handler must respond to call with schema: and raw_data: KWARGS
|
21
|
+
handler: ReactionRemovedListener,
|
22
|
+
# on_success must respond to call with 1 arg of schema
|
23
|
+
on_success: ReactionRemovedListener.method(:on_success),
|
24
|
+
# on_failure must respond to call with 2 args of schema and error
|
25
|
+
on_failure: ReactionRemovedListener.method(:on_failure),
|
26
|
+
)
|
27
|
+
|
28
|
+
# Register a listener for all messages sent to a channel the bot is added to
|
29
|
+
SlackBot::Events.register_listener(
|
30
|
+
name: "message",
|
31
|
+
# Handler must respond to call with schema: and raw_data: KWARGS
|
32
|
+
handler: MessageListener,
|
33
|
+
# on_success must respond to call with 1 arg of schema
|
34
|
+
on_success: MessageListener.method(:on_success),
|
35
|
+
# on_failure must respond to call with 2 args of schema and error
|
36
|
+
on_failure: MessageListener.method(:on_failure),
|
37
|
+
)
|
38
|
+
|
39
|
+
# This is a blocking way to start the Websocket client
|
40
|
+
# EventMachine is used to keep the socket open
|
41
|
+
# The process responds to all SigQuit/Term/Kill events as expected
|
42
|
+
SlackBot::Events::Client.new.start!
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module MessageListener
|
4
|
+
|
5
|
+
def self.call(schema:, raw_data:)
|
6
|
+
# Do some cool(quick returning) things here
|
7
|
+
# schema.payload.event will be a SlackBot::Events::Schemas::Type::Message
|
8
|
+
puts "Heya! I found a message! #{schema.payload.event.text}"
|
9
|
+
raise StandardError, "I Randomly decided to Barf" if rand > 0.9
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.on_success(schema)
|
13
|
+
# Send a metric maybe?
|
14
|
+
# Or a Log Message
|
15
|
+
puts "Congrats! You executed it succesfully"
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.on_failure(schema, error)
|
19
|
+
# Send job to sidekiq to try again?
|
20
|
+
# Or send a log message; but make sure to do it quick
|
21
|
+
puts "Yikes, You died a misreable death"
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ReactionRemovedListener
|
4
|
+
|
5
|
+
def self.call(schema:, raw_data:)
|
6
|
+
# Do some cool(quick returning) things here
|
7
|
+
# schema.payload.event will be a SlackBot::Events::Schemas::Type::ReactionModified
|
8
|
+
puts "Heya! I found a reaction! #{schema.payload.event.reaction}"
|
9
|
+
raise StandardError, "I Randomly decided to Barf" if rand > 0.9
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.on_success(schema)
|
13
|
+
# Send a metric maybe?
|
14
|
+
# Or a Log Message
|
15
|
+
puts "Congrats! You executed it succesfully"
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.on_failure(schema, error)
|
19
|
+
# Send job to sidekiq to try again?
|
20
|
+
# Or send a log message; but make sure to do it quick
|
21
|
+
puts "Yikes, You died a misreable death"
|
22
|
+
end
|
23
|
+
end
|
@@ -20,7 +20,7 @@ module SlackBot
|
|
20
20
|
process_message(socket_event: socket_event) do |listener:, parsed_data:, schema: nil|
|
21
21
|
case parsed_data["type"]
|
22
22
|
when "events_api"
|
23
|
-
events_api(handler: listener
|
23
|
+
events_api(handler: listener&.dig(:handler), schema: schema, parsed_data: parsed_data)
|
24
24
|
end
|
25
25
|
end
|
26
26
|
end
|
@@ -19,9 +19,12 @@ module SlackBot
|
|
19
19
|
attr_reader :type
|
20
20
|
|
21
21
|
DEFAULT_ENTRIES = {
|
22
|
-
message:
|
23
|
-
|
24
|
-
|
22
|
+
message: {
|
23
|
+
base: [Middleware::EventTracer, Middleware::MessageHandler],
|
24
|
+
immutable: [Middleware::MessageHandler]
|
25
|
+
},
|
26
|
+
open: { base: [Middleware::EventTracer] },
|
27
|
+
close: { base: [Middleware::EventTracer] },
|
25
28
|
}
|
26
29
|
|
27
30
|
def initialize(type:)
|
@@ -29,7 +32,7 @@ module SlackBot
|
|
29
32
|
end
|
30
33
|
|
31
34
|
def self.default_entry(type)
|
32
|
-
DEFAULT_ENTRIES[type].map { Entry.new(_1) }
|
35
|
+
DEFAULT_ENTRIES[type][:base].map { Entry.new(_1) }
|
33
36
|
end
|
34
37
|
|
35
38
|
def entries
|
@@ -37,7 +40,7 @@ module SlackBot
|
|
37
40
|
end
|
38
41
|
|
39
42
|
def remove(klass)
|
40
|
-
raise ArgumentError, "Unable to remove default Middleware #{klass}" if
|
43
|
+
raise ArgumentError, "Unable to remove default Middleware #{klass}" if Array(DEFAULT_ENTRIES[@type][:immutable]).include?(klass)
|
41
44
|
|
42
45
|
entries.delete_if { |entry| entry.klass == klass }
|
43
46
|
end
|
@@ -11,21 +11,23 @@ module SlackBot
|
|
11
11
|
when :close
|
12
12
|
additional_info = "code: #{socket_event.code} reason:#{socket_event.reason}"
|
13
13
|
when :message
|
14
|
-
|
15
|
-
|
16
|
-
parsed_data.dig("type"),
|
17
|
-
accurate_type
|
18
|
-
].compact.join(":")
|
19
|
-
case p_type
|
14
|
+
|
15
|
+
case parsed_data.dig("type")
|
20
16
|
when "app_rate_limited"
|
21
17
|
# https://api.slack.com/apis/rate-limits#events
|
22
18
|
# Total allowed workspace events are 30,000 per hour
|
23
19
|
# This message type is received once you have gone beyond that
|
24
|
-
temp_type += ":#{
|
20
|
+
temp_type += ":#{parsed_data.dig("type")}"
|
25
21
|
additional_info = "minute_rate_limited:#{parsed_data["minute_rate_limited"]} " \
|
26
22
|
"team_id:#{parsed_data["team_id"]} " \
|
27
23
|
"api_app_id:#{parsed_data["api_app_id"]}"
|
28
24
|
else
|
25
|
+
accurate_type = parsed_data.dig("payload","event","subtype") || parsed_data.dig("payload","event","type")
|
26
|
+
p_type = [
|
27
|
+
parsed_data.dig("type"),
|
28
|
+
accurate_type
|
29
|
+
].compact.join(":")
|
30
|
+
|
29
31
|
# Expected other types are `events_api` and `hello`
|
30
32
|
temp_type += ":#{p_type}"
|
31
33
|
end
|
@@ -17,8 +17,6 @@ module SlackBot
|
|
17
17
|
acknowledge!(websocket: websocket, schema: schema)
|
18
18
|
end
|
19
19
|
rescue StandardError => error
|
20
|
-
puts error.message
|
21
|
-
puts error.backtrace
|
22
20
|
Events.logger.error do
|
23
21
|
"#{listener[:handler]} returned #{error.class} => #{error.message}. #{error.backtrace[0...10]}"
|
24
22
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: slack_bot-events
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Matt Taylor
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-06-
|
11
|
+
date: 2024-06-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: faraday
|
@@ -129,7 +129,25 @@ files:
|
|
129
129
|
- bin/console
|
130
130
|
- bin/setup
|
131
131
|
- bin/start
|
132
|
+
- boring_slack_configuration.md
|
133
|
+
- changelog.md
|
132
134
|
- docker-compose.yml
|
135
|
+
- examples/README.md
|
136
|
+
- examples/basic/Gemfile
|
137
|
+
- examples/basic/main.rb
|
138
|
+
- examples/basic/message_listener.rb
|
139
|
+
- examples/middleware/Gemfile
|
140
|
+
- examples/middleware/main.rb
|
141
|
+
- examples/middleware/meddling_message_middleware.rb
|
142
|
+
- examples/middleware/message_listener.rb
|
143
|
+
- examples/middleware_no_yield/Gemfile
|
144
|
+
- examples/middleware_no_yield/main.rb
|
145
|
+
- examples/middleware_no_yield/meddling_message_middleware.rb
|
146
|
+
- examples/middleware_no_yield/message_listener.rb
|
147
|
+
- examples/multi_listener/Gemfile
|
148
|
+
- examples/multi_listener/main.rb
|
149
|
+
- examples/multi_listener/message_listener.rb
|
150
|
+
- examples/multi_listener/reaction_removed_listener.rb
|
133
151
|
- lib/slack_bot-events.rb
|
134
152
|
- lib/slack_bot/events.rb
|
135
153
|
- lib/slack_bot/events/client.rb
|