mos-eisley-lambda 0.4.1 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +18 -32
- data/lib/handler.rb +27 -10
- data/lib/mos-eisley-lambda.rb +108 -84
- data/lib/s3po/blockkit.rb +26 -0
- data/lib/s3po/s3po.rb +4 -0
- data/lib/slack.rb +68 -10
- data/mos-eisley-lambda.gemspec +2 -2
- metadata +5 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4e38c9c1ecdcab343fc118677a1f7b515d4fe4ce19a0b4a056b50f515f81f87b
|
4
|
+
data.tar.gz: a0b90f7bfb4c67bf383ce059fab48a7ce93d0588bd0766603dc879ea14783789
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 31a6c405c9b10616063c4c7d99579d16bbfbd816ba1476640662a9123aa631d8d51886ee39a1f1007ff7fa1b2b7c46ecf10cbf24dd7f6b45629bbc102c47f43f
|
7
|
+
data.tar.gz: 3dca76f821c4d4be95544eccdc599be61eef6715cdf0f7083649b3ac8ac8cc934d138c7757a31d2d3461491070d6327f8444abc143028f8d438b14a3b3540606
|
data/README.md
CHANGED
@@ -4,13 +4,12 @@
|
|
4
4
|
|
5
5
|
“You will never find a more wretched hive of scum and villainy.” – Obi-Wan Kenobi
|
6
6
|
|
7
|
-
Episode 2 of the Ruby based [Slack app](https://api.slack.com/) framework, this time for [AWS Lambda](https://aws.amazon.com/lambda/). Pure
|
7
|
+
Episode 2 of the Ruby based [Slack app](https://api.slack.com/) framework, this time for [AWS Lambda](https://aws.amazon.com/lambda/). Pure Ruby, no external gem/library dependency.
|
8
8
|
|
9
9
|
## Setup
|
10
10
|
|
11
11
|
### AWS
|
12
12
|
|
13
|
-
1. Create an SQS queue for MosEisley
|
14
13
|
1. Create an IAM role for MosEisley Lambda function
|
15
14
|
1. Create a Lambda function for MosEisley
|
16
15
|
- You can install this gem using [Lambda Layer](#using-with-lambda-layers) or just copy the `lib` directory to your Lambda code.
|
@@ -20,10 +19,11 @@ Episode 2 of the Ruby based [Slack app](https://api.slack.com/) framework, this
|
|
20
19
|
|
21
20
|
Configure Lambda environment variable.
|
22
21
|
|
23
|
-
- `
|
24
|
-
- `
|
25
|
-
- `
|
26
|
-
- `MOSEISLEY_LOG_LEVEL
|
22
|
+
- `SLACK_CREDENTIALS_SSMPS_PATH`: hierarchy path to System Managers Parameter Store; e.g., `/slack/credentials/` would reference two parameters:
|
23
|
+
- `/slack/credetials/signing_secret`
|
24
|
+
- `/slack/credetials/bot_access_token`
|
25
|
+
- `MOSEISLEY_LOG_LEVEL`: _optional_, could be `DEBUG`, `INFO`, `WARN`, or `ERROR`
|
26
|
+
- `SLACK_LOG_CHANNEL_ID`: _optional_, if you want to use `ME::SlackWeb.post_log()`
|
27
27
|
|
28
28
|
Configure Lambda code in your `lambda_function.rb` file.
|
29
29
|
|
@@ -37,7 +37,7 @@ MosEisley::Handler.import
|
|
37
37
|
# MosEisley::Handler.import_from_path('./my-handlers')
|
38
38
|
|
39
39
|
def lambda_handler(event:, context:)
|
40
|
-
MosEisley::lambda_event(event)
|
40
|
+
MosEisley::lambda_event(event, context)
|
41
41
|
end
|
42
42
|
```
|
43
43
|
|
@@ -85,50 +85,36 @@ ME::Handler.add(:command, 'A Slack command') do |event, myself|
|
|
85
85
|
end
|
86
86
|
```
|
87
87
|
|
88
|
-
## Protocols
|
89
|
-
|
90
|
-
### SQS
|
91
|
-
|
92
|
-
- Attributes
|
93
|
-
- `source`: `slack`, `moseisley`, or other
|
94
|
-
- `endpoint`: if source is `slack`, which endpoint it arrived at
|
95
|
-
- `destination`: `slack` or `moseisley`
|
96
|
-
- `api`: if destination is `slack`
|
97
|
-
- Message (JSON)
|
98
|
-
- `params`: object, meant to be passed to Slack API
|
99
|
-
- `payload`: the data/payload itself
|
100
|
-
|
101
88
|
### Helpers
|
102
89
|
|
103
|
-
`ME::S3PO` – collection of helpers to analyze/create Slack messages.
|
104
|
-
`ME::SlackWeb` – methods for sending payloads to Slack Web API calls.
|
90
|
+
- `ME::S3PO` – collection of helpers to analyze/create Slack messages.
|
91
|
+
- `ME::SlackWeb` – methods for sending payloads to Slack Web API calls.
|
105
92
|
|
106
93
|
## Event Lifecycle
|
107
94
|
|
108
95
|
### Inbound
|
109
96
|
|
110
97
|
1. Slack event is sent to Mos Eisley Lambda function via API Gateway
|
111
|
-
1. Slack event is verified and
|
98
|
+
1. Slack event is verified and produces a parsed object
|
112
99
|
1. If it's a slash command, MosEisley::Handler.command_acks is referenced and immediate response is sent
|
113
|
-
1. The original Slack event JSON is sent to
|
100
|
+
1. The original Slack event JSON is sent to the function in a recursive fashion (this is to return the inital response ASAP)
|
114
101
|
|
115
102
|
### Event Processing
|
116
103
|
|
117
|
-
1.
|
104
|
+
1. Lambda function is invoked by itself with the original Slack event
|
118
105
|
1. Handlers are called and processed according to original endpoint the event was sent to; actions, commands, events, menus
|
119
|
-
1.
|
106
|
+
1. Send a Slack message as necessary and the Slack event cycle is complete
|
120
107
|
|
121
|
-
<!-- ###
|
108
|
+
<!-- ### Outbound, Messaging Only
|
122
109
|
|
123
|
-
|
110
|
+
Invoke the function from another app to send a Slack message
|
124
111
|
|
125
|
-
1. Create a Slack message packaged to be sent to the API and
|
126
|
-
1. Message
|
127
|
-
1. Message is sent to Slack API -->
|
112
|
+
1. Create a Slack message packaged to be sent to the API and invoke the function
|
113
|
+
1. Message is received, then sent to Slack API according to payload-->
|
128
114
|
|
129
115
|
## Using with Lambda Layers
|
130
116
|
|
131
|
-
Used the Makefile to create a zip file which can be uploaded
|
117
|
+
Used the Makefile to create a zip file which can be uploaded to a Lambda Layer.
|
132
118
|
|
133
119
|
```sh
|
134
120
|
make
|
data/lib/handler.rb
CHANGED
@@ -19,17 +19,26 @@ module MosEisley
|
|
19
19
|
end
|
20
20
|
|
21
21
|
# Call as often as necessary to add handlers with blocks; each call creates a MosEisley::Handler object
|
22
|
-
# @param type [Symbol] :action | :command | :event | :menu
|
23
|
-
# @param name [String]
|
22
|
+
# @param type [Symbol] :action | :command_response | :command | :event | :menu
|
23
|
+
# @param name [String] required for type = :command_response, otherwise optional
|
24
24
|
def self.add(type, name = nil, &block)
|
25
|
+
if type == :command_response && name.nil?
|
26
|
+
raise ArgumentError.new('Name required for :command_response.')
|
27
|
+
end
|
25
28
|
@handlers ||= {
|
26
29
|
action: [],
|
30
|
+
command_response: {},
|
27
31
|
command: [],
|
28
32
|
event: [],
|
29
33
|
menu: [],
|
30
34
|
}
|
31
|
-
|
32
|
-
|
35
|
+
h = MosEisley::Handler.new(type, name, &block)
|
36
|
+
if type == :command_response
|
37
|
+
@handlers[type][name] = h
|
38
|
+
else
|
39
|
+
@handlers[type] << h
|
40
|
+
end
|
41
|
+
MosEisley.logger.debug("Added #{type} handler: #{h}")
|
33
42
|
end
|
34
43
|
|
35
44
|
# Example: {'/command' => {response_type: 'ephemeral', text: nil}}
|
@@ -48,14 +57,22 @@ module MosEisley
|
|
48
57
|
def self.run(type, event)
|
49
58
|
logger = MosEisley.logger
|
50
59
|
response = nil
|
51
|
-
|
52
|
-
|
53
|
-
if h
|
54
|
-
|
55
|
-
|
60
|
+
if type == :command_response
|
61
|
+
h = @handlers[type][event[:command]]
|
62
|
+
if h
|
63
|
+
response = h.run(event)
|
64
|
+
logger.info("Done running #{type} handlers.")
|
65
|
+
end
|
66
|
+
else
|
67
|
+
@handlers[type].each do |h|
|
68
|
+
response = h.run(event)
|
69
|
+
if h.stopped?
|
70
|
+
logger.debug('Handler stop was requested.')
|
71
|
+
break
|
72
|
+
end
|
56
73
|
end
|
74
|
+
logger.info("Done running #{type} handlers.")
|
57
75
|
end
|
58
|
-
logger.info("Done running #{type} handlers.")
|
59
76
|
response
|
60
77
|
end
|
61
78
|
|
data/lib/mos-eisley-lambda.rb
CHANGED
@@ -2,52 +2,88 @@ require_relative './logger'
|
|
2
2
|
require_relative './slack'
|
3
3
|
require_relative './s3po/s3po'
|
4
4
|
require_relative './handler'
|
5
|
-
require 'aws-sdk-
|
5
|
+
require 'aws-sdk-lambda'
|
6
|
+
require 'aws-sdk-ssm'
|
6
7
|
require 'base64'
|
7
8
|
require 'json'
|
8
9
|
|
9
10
|
ME = MosEisley
|
10
|
-
SQS = Aws::SQS::Client.new
|
11
11
|
|
12
12
|
module MosEisley
|
13
|
-
def self.
|
14
|
-
|
15
|
-
|
16
|
-
|
13
|
+
def self.config
|
14
|
+
@config ||= {}
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.lambda_event(event, context)
|
18
|
+
raise 'Pre-flight check failed!' unless preflightcheck
|
19
|
+
case
|
20
|
+
when event['routeKey']
|
21
|
+
# Inbound Slack event (via API GW)
|
17
22
|
MosEisley.logger.info('API GW event')
|
18
|
-
return apigw_event(event)
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
MosEisley.logger.
|
23
|
-
return
|
23
|
+
return apigw_event(event, context)
|
24
|
+
when event.dig('Records',0,'eventSource') == 'MosEisley:Slack_event'
|
25
|
+
# Internal event (via invoke)
|
26
|
+
MosEisley.logger.info('Invoke event')
|
27
|
+
MosEisley.logger.debug("#{event}")
|
28
|
+
return invoke_event(event)
|
29
|
+
else
|
30
|
+
# Unknown event
|
31
|
+
MosEisley.logger.info('Unknown event')
|
32
|
+
return unknown_event(event)
|
24
33
|
end
|
25
34
|
end
|
26
35
|
|
27
36
|
def self.preflightcheck
|
28
|
-
|
29
|
-
|
30
|
-
|
37
|
+
if config[:timestamp]
|
38
|
+
MosEisley.logger.debug("Confing already loaded at: #{config[:timestamp]}")
|
39
|
+
return true
|
31
40
|
end
|
32
41
|
env_required = [
|
33
|
-
'
|
34
|
-
'SLACK_SIGNING_SECRET',
|
35
|
-
'SLACK_BOT_ACCESS_TOKEN',
|
42
|
+
'SLACK_CREDENTIALS_SSMPS_PATH',
|
36
43
|
]
|
37
44
|
env_optional = [
|
38
45
|
'MOSEISLEY_LOG_LEVEL',
|
46
|
+
'SLACK_LOG_CHANNEL_ID',
|
39
47
|
]
|
40
|
-
|
41
|
-
|
42
|
-
|
48
|
+
config_required = [
|
49
|
+
:signing_secret,
|
50
|
+
:bot_access_token,
|
51
|
+
]
|
52
|
+
l = ENV['MOSEISLEY_LOG_LEVEL']
|
53
|
+
if String === l && ['DEBUG', 'INFO', 'WARN', 'ERROR'].include?(l.upcase)
|
54
|
+
MosEisley.logger.level = eval("Logger::#{l.upcase}")
|
55
|
+
end
|
56
|
+
env_required.each do |v|
|
57
|
+
if ENV[v].nil?
|
58
|
+
MosEisley.logger.error("Missing environment variable: #{v}")
|
43
59
|
return false
|
44
60
|
end
|
61
|
+
case v
|
62
|
+
when 'SLACK_CREDENTIALS_SSMPS_PATH'
|
63
|
+
ssm = Aws::SSM::Client.new
|
64
|
+
rparams = {
|
65
|
+
path: ENV['SLACK_CREDENTIALS_SSMPS_PATH'],
|
66
|
+
with_decryption: true,
|
67
|
+
}
|
68
|
+
ssm.get_parameters_by_path(rparams).parameters.each do |prm|
|
69
|
+
k = prm[:name].split('/').last.to_sym
|
70
|
+
config[k] = prm[:value]
|
71
|
+
config_required.delete(k)
|
72
|
+
end
|
73
|
+
end
|
45
74
|
end
|
75
|
+
unless config_required.empty?
|
76
|
+
t = "Missing config values: #{config_required.join(', ')}"
|
77
|
+
MosEisley.logger.error(t)
|
78
|
+
return false
|
79
|
+
end
|
80
|
+
config[:timestamp] = Time.now
|
81
|
+
MosEisley.logger.info('Config loaded')
|
46
82
|
return true
|
47
83
|
end
|
48
84
|
|
49
|
-
def self.apigw_event(event)
|
50
|
-
se =
|
85
|
+
def self.apigw_event(event, context)
|
86
|
+
se = MosEisley::SlackEvent.validate(event)
|
51
87
|
unless se[:valid?]
|
52
88
|
MosEisley.logger.warn("#{se[:msg]}")
|
53
89
|
return {statusCode: 401}
|
@@ -57,23 +93,21 @@ module MosEisley
|
|
57
93
|
MosEisley.logger.debug("Inbound Slack request to: #{ep}")
|
58
94
|
case ep
|
59
95
|
when '/actions'
|
60
|
-
|
96
|
+
## Slack Interactivity & Shortcuts
|
97
|
+
# Nothing to do, through-pass data
|
61
98
|
when '/commands'
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
else
|
70
|
-
text = sep[:text].empty? ? '' : " #{se[:event][:text]}"
|
71
|
-
"Received: `#{se[:event][:command]}#{text}`"
|
72
|
-
end
|
99
|
+
## Slack Slash Commands
|
100
|
+
MosEisley.logger.debug("Slash command event:\n#{se[:event]}")
|
101
|
+
r = MosEisley::Handler.run(:command_response, se[:event])
|
102
|
+
if String === r
|
103
|
+
r = {text: r}
|
104
|
+
end
|
105
|
+
if Hash === r
|
73
106
|
# AWS sets status code and headers by passing JSON string
|
74
|
-
resp = JSON.fast_generate(
|
107
|
+
resp = JSON.fast_generate(r)
|
75
108
|
end
|
76
109
|
when '/events'
|
110
|
+
## Slack Event Subscriptions
|
77
111
|
# Respond to Slack challenge request
|
78
112
|
if se[:event][:type] == 'url_verification'
|
79
113
|
c = se[:event][:challenge]
|
@@ -81,65 +115,55 @@ module MosEisley
|
|
81
115
|
return "{\"challenge\": \"#{c}\"}"
|
82
116
|
end
|
83
117
|
when '/menus'
|
84
|
-
#
|
118
|
+
# MosEisley::Handler.run(:menu, se)
|
85
119
|
# TODO to be implemented
|
86
120
|
return "{\"options\": []}"
|
87
121
|
else
|
88
122
|
MosEisley.logger.warn('Unknown request, ignored.')
|
89
123
|
return {statusCode: 400}
|
90
124
|
end
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
}
|
98
|
-
|
99
|
-
data_type: 'String',
|
100
|
-
string_value: 'moseisley',
|
101
|
-
},
|
102
|
-
'endpoint' => {
|
103
|
-
data_type: 'String',
|
104
|
-
string_value: ep,
|
105
|
-
},
|
106
|
-
},
|
107
|
-
message_body: "{\"payload\":#{se[:json]}}",
|
125
|
+
pl = {
|
126
|
+
Records: [
|
127
|
+
{
|
128
|
+
eventSource: 'MosEisley:Slack_event',
|
129
|
+
endpoint: ep,
|
130
|
+
body: se[:json],
|
131
|
+
}
|
132
|
+
]
|
108
133
|
}
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
134
|
+
lc = Aws::Lambda::Client.new
|
135
|
+
params = {
|
136
|
+
function_name: context.function_name,
|
137
|
+
invocation_type: 'Event',
|
138
|
+
payload: JSON.fast_generate(pl),
|
139
|
+
}
|
140
|
+
r = lc.invoke(params)
|
141
|
+
if r.status_code >= 200 && r.status_code < 300
|
142
|
+
MosEisley.logger.debug("Successfullly invoked with playload size: #{params[:payload].length}")
|
143
|
+
else
|
144
|
+
MosEisley.logger.warn("Problem with invoke, status code: #{r.status_code}")
|
145
|
+
end
|
146
|
+
resp
|
113
147
|
end
|
114
148
|
|
115
|
-
def self.
|
116
|
-
|
117
|
-
src = a.dig('source','stringValue')
|
118
|
-
dst = a.dig('destination','stringValue')
|
119
|
-
ep = a.dig('endpoint','stringValue')
|
149
|
+
def self.invoke_event(event)
|
150
|
+
ep = event.dig('Records',0,'endpoint')
|
120
151
|
se = JSON.parse(event.dig('Records',0,'body'), {symbolize_names: true})
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
when '/events'
|
131
|
-
ME::Handler.run(:event, se)
|
132
|
-
when '/menus'
|
133
|
-
MosEisley.logger.warn('Menu request cannot be processed here.')
|
134
|
-
else
|
135
|
-
MosEisley.logger.warn("Unknown request: #{ep}")
|
136
|
-
end
|
137
|
-
elsif dst == 'slack'
|
138
|
-
# An event to be sent to Slack
|
139
|
-
MosEisley.logger.debug a.dig('api','stringValue')
|
152
|
+
case ep
|
153
|
+
when '/actions'
|
154
|
+
MosEisley::Handler.run(:action, se)
|
155
|
+
when '/commands'
|
156
|
+
MosEisley::Handler.run(:command, se)
|
157
|
+
when '/events'
|
158
|
+
MosEisley::Handler.run(:event, se)
|
159
|
+
when '/menus'
|
160
|
+
MosEisley.logger.warn('Menu request cannot be processed here.')
|
140
161
|
else
|
141
|
-
MosEisley.logger.warn(
|
162
|
+
MosEisley.logger.warn("Unknown request: #{ep}")
|
142
163
|
end
|
143
|
-
|
164
|
+
end
|
165
|
+
|
166
|
+
def self.unknown_event(event)
|
167
|
+
# TODO hand off to a handler
|
144
168
|
end
|
145
169
|
end
|
data/lib/s3po/blockkit.rb
CHANGED
@@ -1,6 +1,32 @@
|
|
1
|
+
# S3PO - Slack protocol droid in Mos Eisley
|
2
|
+
# ::BlockKit - Block Kit tools
|
3
|
+
#
|
4
|
+
# v.20220201
|
5
|
+
|
1
6
|
module MosEisley
|
2
7
|
module S3PO
|
3
8
|
module BlockKit
|
9
|
+
# @param txt [String]
|
10
|
+
# @param type [Symbol] :plain | :emoji | :mrkdwn
|
11
|
+
# @return [Hash] Block Kit section object
|
12
|
+
def self.con_text(txt, type = :mrkdwn)
|
13
|
+
{
|
14
|
+
type: :context,
|
15
|
+
elements: [
|
16
|
+
text(txt, type),
|
17
|
+
]
|
18
|
+
}
|
19
|
+
end
|
20
|
+
|
21
|
+
# @param txt [String]
|
22
|
+
# @return [Hash] Block Kit header object
|
23
|
+
def self.header(txt)
|
24
|
+
{
|
25
|
+
type: :header,
|
26
|
+
text: text(txt, :emoji),
|
27
|
+
}
|
28
|
+
end
|
29
|
+
|
4
30
|
# @param txt [String]
|
5
31
|
# @param type [Symbol] :plain | :emoji | :mrkdwn
|
6
32
|
# @return [Hash] Block Kit section object
|
data/lib/s3po/s3po.rb
CHANGED
data/lib/slack.rb
CHANGED
@@ -15,7 +15,7 @@ module MosEisley
|
|
15
15
|
end
|
16
16
|
b = e['isBase64Encoded'] ? Base64.decode64(e['body']) : e['body']
|
17
17
|
s = "v0:#{t}:#{b}"
|
18
|
-
k =
|
18
|
+
k = MosEisley.config[:signing_secret]
|
19
19
|
sig = "v0=#{OpenSSL::HMAC.hexdigest('sha256', k, s)}"
|
20
20
|
if e.dig('headers', 'x-slack-signature') != sig
|
21
21
|
return {valid?: false, msg: 'Invalid signature.'}
|
@@ -48,11 +48,23 @@ module MosEisley
|
|
48
48
|
post_to_slack('chat.meMessage', data)
|
49
49
|
end
|
50
50
|
|
51
|
-
def self.chat_postephemeral()
|
51
|
+
def self.chat_postephemeral(channel:, blocks: nil, text: nil, thread_ts: nil)
|
52
|
+
chat_send(:postEphemeral, channel, blocks, text, thread_ts)
|
52
53
|
end
|
53
54
|
|
54
55
|
def self.chat_postmessage(channel:, blocks: nil, text: nil, thread_ts: nil)
|
56
|
+
chat_send(:postMessage, channel, blocks, text, thread_ts)
|
57
|
+
end
|
58
|
+
|
59
|
+
def self.chat_schedulemessage(channel:, post_at:, blocks: nil, text: nil, thread_ts: nil)
|
60
|
+
chat_send(:scheduleMessage, channel, blocks, text, thread_ts, post_at)
|
61
|
+
end
|
62
|
+
|
63
|
+
def self.chat_send(m, channel, blocks, text, thread_ts, post_at = nil)
|
55
64
|
data = {channel: channel}
|
65
|
+
if m == :scheduleMessage
|
66
|
+
post_at ? data[:post_at] = post_at : raise
|
67
|
+
end
|
56
68
|
if blocks
|
57
69
|
data[:blocks] = blocks
|
58
70
|
data[:text] = text if text
|
@@ -60,10 +72,7 @@ module MosEisley
|
|
60
72
|
text ? data[:text] = text : raise
|
61
73
|
end
|
62
74
|
data[:thread_ts] = thread_ts if thread_ts
|
63
|
-
post_to_slack(
|
64
|
-
end
|
65
|
-
|
66
|
-
def self.chat_schedulemessage()
|
75
|
+
post_to_slack("chat.#{m}", data)
|
67
76
|
end
|
68
77
|
|
69
78
|
def self.post_response_url(url, payload)
|
@@ -111,16 +120,65 @@ module MosEisley
|
|
111
120
|
def self.views_push(trigger_id:, view:)
|
112
121
|
end
|
113
122
|
|
114
|
-
|
115
|
-
|
116
|
-
|
123
|
+
def self.conversations_members(channel:, cursor: nil, limit: nil)
|
124
|
+
params = {channel: channel}
|
125
|
+
params[:cursor] = cursor if cursor
|
126
|
+
params[:limit] = limit if limit
|
127
|
+
get_from_slack('conversations.members', params)
|
128
|
+
end
|
129
|
+
|
130
|
+
def self.users_info(user)
|
131
|
+
get_from_slack('users.info', {user: user})
|
132
|
+
end
|
133
|
+
|
134
|
+
def self.users_list(cursor: nil, limit: nil)
|
135
|
+
params = {include_locale: true}
|
136
|
+
params[:cursor] = cursor if cursor
|
137
|
+
params[:limit] = limit if limit
|
138
|
+
get_from_slack('users.list', params)
|
139
|
+
end
|
140
|
+
|
141
|
+
def self.users_lookupbyemail(email)
|
142
|
+
get_from_slack('users.lookupByEmail', {email: email})
|
143
|
+
end
|
144
|
+
|
145
|
+
def self.users_profile_get(user)
|
146
|
+
get_from_slack('users.profile.get', {user: user})
|
147
|
+
end
|
148
|
+
|
149
|
+
def self.auth_test
|
150
|
+
post_to_slack('auth.test', '')
|
151
|
+
end
|
117
152
|
|
118
153
|
private
|
119
154
|
|
155
|
+
def self.get_from_slack(m, params)
|
156
|
+
l = MosEisley.logger
|
157
|
+
url ||= BASE_URL + m
|
158
|
+
head = {authorization: "Bearer #{MosEisley.config[:bot_access_token]}"}
|
159
|
+
r = Neko::HTTP.get(url, params, head)
|
160
|
+
if r[:code] != 200
|
161
|
+
l.warn("#{m} HTTP failed: #{r[:message]}")
|
162
|
+
return nil
|
163
|
+
end
|
164
|
+
begin
|
165
|
+
h = JSON.parse(r[:body], {symbolize_names: true})
|
166
|
+
if h[:ok]
|
167
|
+
return h
|
168
|
+
else
|
169
|
+
l.warn("#{m} Slack failed: #{h[:error]}")
|
170
|
+
l.debug("#{h[:response_metadata]}")
|
171
|
+
return nil
|
172
|
+
end
|
173
|
+
rescue
|
174
|
+
return {body: r[:body]}
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
120
178
|
def self.post_to_slack(method, data, url = nil)
|
121
179
|
l = MosEisley.logger
|
122
180
|
url ||= BASE_URL + method
|
123
|
-
head = {authorization: "Bearer #{
|
181
|
+
head = {authorization: "Bearer #{MosEisley.config[:bot_access_token]}"}
|
124
182
|
r = Neko::HTTP.post_json(url, data, head)
|
125
183
|
if r[:code] != 200
|
126
184
|
l.warn("post_to_slack HTTP failed: #{r[:message]}")
|
data/mos-eisley-lambda.gemspec
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = 'mos-eisley-lambda'
|
3
|
-
s.version = '0.
|
3
|
+
s.version = '0.6.0'
|
4
4
|
s.authors = ['Ken J.']
|
5
5
|
s.email = ['kenjij@gmail.com']
|
6
6
|
s.summary = %q{Ruby based Slack bot framework, for AWS Lambda use}
|
7
|
-
s.description = %q{Ruby based Slack bot framework, for AWS Lambda
|
7
|
+
s.description = %q{Ruby based Slack bot framework, for AWS Lambda; event queue based. Also provides Block Kit helper.}
|
8
8
|
s.homepage = 'https://github.com/kenjij/mos-eisley-lambda'
|
9
9
|
s.license = 'MIT'
|
10
10
|
|
metadata
CHANGED
@@ -1,17 +1,17 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mos-eisley-lambda
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ken J.
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-02-24 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
|
-
description: Ruby based Slack bot framework, for AWS Lambda
|
14
|
-
|
13
|
+
description: Ruby based Slack bot framework, for AWS Lambda; event queue based. Also
|
14
|
+
provides Block Kit helper.
|
15
15
|
email:
|
16
16
|
- kenjij@gmail.com
|
17
17
|
executables: []
|
@@ -49,7 +49,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
49
49
|
- !ruby/object:Gem::Version
|
50
50
|
version: '0'
|
51
51
|
requirements: []
|
52
|
-
rubygems_version: 3.1.
|
52
|
+
rubygems_version: 3.1.4
|
53
53
|
signing_key:
|
54
54
|
specification_version: 4
|
55
55
|
summary: Ruby based Slack bot framework, for AWS Lambda use
|