bas 0.2.0 → 0.3.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +9 -0
- data/README.md +25 -22
- data/lib/bas/formatter/base.rb +2 -2
- data/lib/bas/formatter/birthday.rb +8 -4
- data/lib/bas/formatter/pto.rb +8 -4
- data/lib/bas/formatter/support_emails.rb +7 -3
- data/lib/bas/formatter/types/response.rb +16 -0
- data/lib/bas/formatter/work_items_limit.rb +8 -4
- data/lib/bas/process/base.rb +39 -0
- data/lib/bas/{dispatcher → process}/discord/exceptions/invalid_webhook_token.rb +1 -1
- data/lib/bas/process/discord/implementation.rb +71 -0
- data/lib/bas/{dispatcher → process}/discord/types/response.rb +1 -1
- data/lib/bas/{dispatcher → process}/slack/exceptions/invalid_webhook_token.rb +1 -1
- data/lib/bas/process/slack/implementation.rb +70 -0
- data/lib/bas/{dispatcher → process}/slack/types/response.rb +1 -1
- data/lib/bas/process/types/response.rb +16 -0
- data/lib/bas/{fetcher → read}/base.rb +8 -8
- data/lib/bas/{fetcher → read}/github/base.rb +7 -7
- data/lib/bas/{fetcher → read}/github/types/response.rb +1 -1
- data/lib/bas/read/github/use_case/repo_issues.rb +17 -0
- data/lib/bas/{fetcher → read}/imap/base.rb +7 -7
- data/lib/bas/{fetcher → read}/imap/types/response.rb +1 -1
- data/lib/bas/read/imap/use_case/support_emails.rb +26 -0
- data/lib/bas/{fetcher → read}/notion/base.rb +8 -8
- data/lib/bas/{fetcher → read}/notion/helper.rb +1 -1
- data/lib/bas/{fetcher → read}/notion/types/response.rb +1 -1
- data/lib/bas/{fetcher → read}/notion/use_case/birthday_next_week.rb +6 -6
- data/lib/bas/{fetcher → read}/notion/use_case/birthday_today.rb +6 -6
- data/lib/bas/{fetcher → read}/notion/use_case/pto_next_week.rb +6 -6
- data/lib/bas/{fetcher → read}/notion/use_case/pto_today.rb +6 -6
- data/lib/bas/{fetcher → read}/notion/use_case/work_items_limit.rb +5 -5
- data/lib/bas/{fetcher → read}/postgres/base.rb +8 -8
- data/lib/bas/{fetcher → read}/postgres/helper.rb +1 -1
- data/lib/bas/{fetcher → read}/postgres/types/response.rb +1 -1
- data/lib/bas/{fetcher → read}/postgres/use_case/pto_today.rb +6 -6
- data/lib/bas/{mapper → serialize}/base.rb +7 -7
- data/lib/bas/{mapper → serialize}/github/issues.rb +7 -7
- data/lib/bas/{mapper → serialize}/imap/support_emails.rb +7 -7
- data/lib/bas/{mapper → serialize}/notion/birthday_today.rb +7 -7
- data/lib/bas/{mapper → serialize}/notion/pto_today.rb +14 -12
- data/lib/bas/{mapper → serialize}/notion/work_items_limit.rb +7 -7
- data/lib/bas/{mapper → serialize}/postgres/pto_today.rb +7 -7
- data/lib/bas/use_cases/types/config.rb +6 -5
- data/lib/bas/use_cases/use_case.rb +13 -10
- data/lib/bas/use_cases/use_cases.rb +71 -61
- data/lib/bas/version.rb +1 -1
- data/lib/bas/write/base.rb +36 -0
- data/lib/bas/write/logs/base.rb +33 -0
- data/lib/bas/write/logs/use_case/console_log.rb +22 -0
- metadata +42 -37
- data/lib/bas/dispatcher/base.rb +0 -31
- data/lib/bas/dispatcher/discord/implementation.rb +0 -51
- data/lib/bas/dispatcher/slack/implementation.rb +0 -51
- data/lib/bas/fetcher/github/use_case/repo_issues.rb +0 -17
- data/lib/bas/fetcher/imap/use_case/support_emails.rb +0 -26
- /data/lib/bas/{fetcher → read}/notion/exceptions/invalid_api_key.rb +0 -0
- /data/lib/bas/{fetcher → read}/notion/exceptions/invalid_database_id.rb +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: eb7e143b2fed334e1489ffe66e55c87a997f71b744eefa8aa3ef55d53b8a8659
|
4
|
+
data.tar.gz: 7bf4e381847d69f760d5beab142bae8d9fc378dabb0f03583759b00e8b8b4b97
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 38e5f2ff3e0c3f76f8d74a8cd8b3b25f2eae63dfe0d9595f9e97503bce057c45e24c21ea7f9625ec367c9851131bbe7b70824176e01da913d7209666840d3dd6
|
7
|
+
data.tar.gz: 5b993cfb181d61f647a48bdd2a38f39849068274aea4819cabd5e8691571fca4afd27205c6af862a7fc5b81789ba00a32a8afed291e40b71dbbc46ebc490f20b
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,14 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## 0.3.1 (16.04.2024)
|
4
|
+
- [Use case format error](https://github.com/kommitters/bas/issues/22)
|
5
|
+
|
6
|
+
## 0.3.0 (16.04.2024)
|
7
|
+
- [Rename the Fetcher to Read](https://github.com/kommitters/bas/issues/13)
|
8
|
+
- [Rename the Mapper to Serialize](https://github.com/kommitters/bas/issues/14)
|
9
|
+
- [Rename the Dispatcher to Process](https://github.com/kommitters/bas/issues/15)
|
10
|
+
- [Add the Writer Component](https://github.com/kommitters/bas/issues/16)
|
11
|
+
|
3
12
|
## 0.2.0 (04.04.2024)
|
4
13
|
- [Add a GitHub fetcher component](https://github.com/kommitters/bas/issues/6)
|
5
14
|
- [Allow daily hours pto for more than one day pto](https://github.com/kommitters/bas/issues/8)
|
data/README.md
CHANGED
@@ -39,27 +39,27 @@ There are 7 currently implemented use cases:
|
|
39
39
|
* WIP limit exceeded - from Notion to Discord
|
40
40
|
* Support email notification - from IMAP to Discord
|
41
41
|
|
42
|
-
For this example we'll analyze the birthday notification use case, bringing data from a notion database, and
|
42
|
+
For this example we'll analyze the birthday notification use case, bringing data from a notion database, and sending the
|
43
43
|
notifications to a Discord channel.
|
44
44
|
|
45
|
-
A *Use Case* object, consists on
|
45
|
+
A *Use Case* object, consists on 5 main components, having it's own responsibility:
|
46
46
|
|
47
|
-
### 1.
|
47
|
+
### 1. Read - Obtaining the data
|
48
48
|
|
49
|
-
Specifically, a
|
50
|
-
for building your own
|
49
|
+
Specifically, a reader is an object in charged of bringing data from a data source. The gem already provides the base interface
|
50
|
+
for building your own reader for your specific data source, or rely on already built classes if they match your purpose.
|
51
51
|
|
52
|
-
The base interface for a
|
52
|
+
The base interface for a reader can be found under the `bas/read/base.rb` class. Since this is a implementation of the `Read::Base`
|
53
53
|
for bringing data from a Notion database, it was created on a new namespace for that data source, it can be found under
|
54
|
-
`/bas/
|
54
|
+
`/bas/read/notion/use_case/birthday_today.rb`. It implements specific logic for reading the data and validating the response.
|
55
55
|
|
56
|
-
### 2.
|
56
|
+
### 2. Serialize - Shaping it
|
57
57
|
|
58
|
-
The **
|
58
|
+
The **Serializer** responsibility, is to shape the data using custom types from the app domain, bringing it into a
|
59
59
|
common structure understandable for other components, specifically the **Formatter**.
|
60
60
|
|
61
|
-
Because of the use case, the
|
62
|
-
under `/bas/
|
61
|
+
Because of the use case, the Serializer implementation for it, relies on specific types for representing a Birthday it self. It can be found
|
62
|
+
under `/bas/serialize/notion/birthday_today.rb`
|
63
63
|
|
64
64
|
### 3. Formatter - Preparing the message
|
65
65
|
|
@@ -67,11 +67,14 @@ The **Formatter**, is in charge of preparing the message to be sent in our notif
|
|
67
67
|
The template or 'format' to be used should be included in the use case configurations, which we'll review in a further step. It's
|
68
68
|
implementation can be found under `/bas/formatter/birthday.rb`.
|
69
69
|
|
70
|
-
### 4.
|
70
|
+
### 4. Process - Optional Data Process
|
71
71
|
|
72
|
-
Finally, the **
|
72
|
+
Finally, the **Process** basically, allow required data process depending on the use case like sending formatted messages into a destination. In this case, since the use case was implemented for
|
73
73
|
Discord, it implements specific logic to communicate with a Discord channel using a webhook. The webhook configuration and name for the 'Sender'
|
74
|
-
in the channel should be provided with the initial use case configurations. It can be found under `/bas/
|
74
|
+
in the channel should be provided with the initial use case configurations. It can be found under `/bas/process/discord/implementation.rb`
|
75
|
+
|
76
|
+
### 5. Write - Apply changes in a destination
|
77
|
+
Finally, the **Write** is in charge of creating or updating information in a destination. This is the last step in the pipeline, and it aims to allow the users to apply changes in a destination depending on the use case. These changes can be a transaction in a database, adding files in a cloud storage, or simply creating logs. For the Birthday use case, after the Process sends the notification, the Write creates a Log in the `$stdout`. It can be found under `lib/bas/write/logs/use_case/console_log.rb`
|
75
78
|
|
76
79
|
## Examples
|
77
80
|
|
@@ -113,7 +116,7 @@ today = Date.now
|
|
113
116
|
}
|
114
117
|
```
|
115
118
|
|
116
|
-
* A template for the formatter to be used for formatting the payload to
|
119
|
+
* A template for the formatter to be used for formatting the payload to be send to Discord. For this specific case, the format of the messages should be:
|
117
120
|
|
118
121
|
`"NAME, Wishing you a very happy birthday! Enjoy your special day! :birthday: :gift:"`
|
119
122
|
|
@@ -139,13 +142,13 @@ filter = {
|
|
139
142
|
}
|
140
143
|
|
141
144
|
options = {
|
142
|
-
|
145
|
+
read_options: {
|
143
146
|
base_url: "https://api.notion.com",
|
144
147
|
database_id: NOTION_DATABASE_ID,
|
145
148
|
secret: NOTION_API_INTEGRATION_SECRET,
|
146
149
|
filter: filter
|
147
150
|
},
|
148
|
-
|
151
|
+
process_options: {
|
149
152
|
webhook: "https://discord.com/api/webhooks/1199213527672565760/KmpoIzBet9xYG16oFh8W1RWHbpIqT7UtTBRrhfLcvWZdNiVZCTM-gpil2Qoy4eYEgpdf",
|
150
153
|
name: "Birthday Bot"
|
151
154
|
}
|
@@ -235,7 +238,7 @@ module Notifier
|
|
235
238
|
# Service description
|
236
239
|
class UseCaseName
|
237
240
|
def self.notify(*)
|
238
|
-
options = {
|
241
|
+
options = { read_options:, process_options: }
|
239
242
|
|
240
243
|
begin
|
241
244
|
use_case = UseCases.use_case_build_function(options)
|
@@ -246,18 +249,18 @@ module Notifier
|
|
246
249
|
end
|
247
250
|
end
|
248
251
|
|
249
|
-
def self.
|
252
|
+
def self.read_options
|
250
253
|
{
|
251
254
|
base_url: NOTION_BASE_URL,
|
252
255
|
database_id: NOTION_DATABASE_ID,
|
253
256
|
secret: NOTION_SECRET,
|
254
257
|
filter: {
|
255
|
-
filter: { "and":
|
258
|
+
filter: { "and": read_filter }
|
256
259
|
}
|
257
260
|
}
|
258
261
|
end
|
259
262
|
|
260
|
-
def self.
|
263
|
+
def self.read_filter
|
261
264
|
today = Common::TimeZone.set_colombia_time_zone.strftime('%F').to_s
|
262
265
|
|
263
266
|
[
|
@@ -266,7 +269,7 @@ module Notifier
|
|
266
269
|
]
|
267
270
|
end
|
268
271
|
|
269
|
-
def self.
|
272
|
+
def self.process_options
|
270
273
|
{
|
271
274
|
webhook: DISCORD_WEBHOOK,
|
272
275
|
name: DISCORD_BOT_NAME
|
data/lib/bas/formatter/base.rb
CHANGED
@@ -20,7 +20,7 @@ module Formatter
|
|
20
20
|
end
|
21
21
|
|
22
22
|
# This method is designed to provide a specified format for data from any implementation of
|
23
|
-
# the
|
23
|
+
# the Serialize::Base interface.
|
24
24
|
# Must be overridden by subclasses, with specific logic based on the use case.
|
25
25
|
#
|
26
26
|
# <br>
|
@@ -30,7 +30,7 @@ module Formatter
|
|
30
30
|
# <br>
|
31
31
|
# <b>raises</b> <tt>Domain::Exceptions::FunctionNotImplemented</tt> when missing implementation.
|
32
32
|
#
|
33
|
-
# <b>returns</b> <tt>String</tt> Formatted payload suitable for a
|
33
|
+
# <b>returns</b> <tt>String</tt> Formatted payload suitable for a Process::Base implementation.
|
34
34
|
#
|
35
35
|
def format(_domain_data)
|
36
36
|
raise Domain::Exceptions::FunctionNotImplemented
|
@@ -3,32 +3,36 @@
|
|
3
3
|
require_relative "../domain/birthday"
|
4
4
|
require_relative "./exceptions/invalid_data"
|
5
5
|
require_relative "./base"
|
6
|
+
require_relative "./types/response"
|
6
7
|
|
7
8
|
module Formatter
|
8
9
|
##
|
9
10
|
# This class implements methods from the Formatter::Base module, tailored to format the
|
10
|
-
# Domain::Birthday structure for a
|
11
|
+
# Domain::Birthday structure for a Process.
|
11
12
|
class Birthday < Base
|
12
13
|
# Implements the logic for building a formatted payload with the given template for birthdays.
|
13
14
|
#
|
14
15
|
# <br>
|
15
16
|
# <b>Params:</b>
|
16
|
-
# * <tt>List<Domain::Birthday></tt> birthdays_list: list of
|
17
|
+
# * <tt>List<Domain::Birthday></tt> birthdays_list: list of serialized birthdays.
|
17
18
|
#
|
18
19
|
# <br>
|
19
20
|
# <b>raises</b> <tt>Formatter::Exceptions::InvalidData</tt> when invalid data is provided.
|
20
21
|
#
|
21
22
|
# <br>
|
22
|
-
# <b>returns</b> <tt>
|
23
|
+
# <b>returns</b> <tt>Formatter::Types::Response</tt> formatter response: standard output for
|
24
|
+
# the formatted payload suitable for a Process.
|
23
25
|
#
|
24
26
|
def format(birthdays_list)
|
25
27
|
raise Formatter::Exceptions::InvalidData unless birthdays_list.all? do |brithday|
|
26
28
|
brithday.is_a?(Domain::Birthday)
|
27
29
|
end
|
28
30
|
|
29
|
-
birthdays_list.reduce("") do |payload, birthday|
|
31
|
+
response = birthdays_list.reduce("") do |payload, birthday|
|
30
32
|
payload + build_template(Domain::Birthday::ATTRIBUTES, birthday)
|
31
33
|
end
|
34
|
+
|
35
|
+
Formatter::Types::Response.new(response)
|
32
36
|
end
|
33
37
|
end
|
34
38
|
end
|
data/lib/bas/formatter/pto.rb
CHANGED
@@ -5,11 +5,12 @@ require "date"
|
|
5
5
|
require_relative "../domain/pto"
|
6
6
|
require_relative "./exceptions/invalid_data"
|
7
7
|
require_relative "./base"
|
8
|
+
require_relative "./types/response"
|
8
9
|
|
9
10
|
module Formatter
|
10
11
|
##
|
11
12
|
# This class implements methods from the Formatter::Base module, tailored to format the
|
12
|
-
# Domain::Pto structure for a
|
13
|
+
# Domain::Pto structure for a Process.
|
13
14
|
class Pto < Base
|
14
15
|
DEFAULT_TIME_ZONE = "+00:00"
|
15
16
|
|
@@ -26,13 +27,14 @@ module Formatter
|
|
26
27
|
#
|
27
28
|
# <br>
|
28
29
|
# <b>Params:</b>
|
29
|
-
# * <tt>List<Domain::Pto></tt> pto_list: List of
|
30
|
+
# * <tt>List<Domain::Pto></tt> pto_list: List of serialized PTO's.
|
30
31
|
#
|
31
32
|
# <br>
|
32
33
|
# <b>raises</b> <tt>Formatter::Exceptions::InvalidData</tt> when invalid data is provided.
|
33
34
|
#
|
34
35
|
# <br>
|
35
|
-
# <b>returns</b> <tt>
|
36
|
+
# <b>returns</b> <tt>Formatter::Types::Response</tt> formatter response: standard output for
|
37
|
+
# the formatted payload suitable for a Process.
|
36
38
|
#
|
37
39
|
|
38
40
|
def format(ptos_list)
|
@@ -40,10 +42,12 @@ module Formatter
|
|
40
42
|
|
41
43
|
ptos_list.each { |pto| pto.format_timezone(@timezone) }
|
42
44
|
|
43
|
-
ptos_list.reduce("") do |payload, pto|
|
45
|
+
response = ptos_list.reduce("") do |payload, pto|
|
44
46
|
built_template = build_template(Domain::Pto::ATTRIBUTES, pto)
|
45
47
|
payload + format_message_by_case(built_template.gsub("\n", ""), pto)
|
46
48
|
end
|
49
|
+
|
50
|
+
Formatter::Types::Response.new(response)
|
47
51
|
end
|
48
52
|
|
49
53
|
private
|
@@ -3,11 +3,12 @@
|
|
3
3
|
require_relative "../domain/email"
|
4
4
|
require_relative "./exceptions/invalid_data"
|
5
5
|
require_relative "./base"
|
6
|
+
require_relative "./types/response"
|
6
7
|
|
7
8
|
module Formatter
|
8
9
|
##
|
9
10
|
# This class implements methods from the Formatter::Base module, tailored to format the
|
10
|
-
# Domain::Email structure for a
|
11
|
+
# Domain::Email structure for a Process.
|
11
12
|
class SupportEmails < Base
|
12
13
|
DEFAULT_TIME_ZONE = "+00:00"
|
13
14
|
|
@@ -31,16 +32,19 @@ module Formatter
|
|
31
32
|
# <b>raises</b> <tt>Formatter::Exceptions::InvalidData</tt> when invalid data is provided.
|
32
33
|
#
|
33
34
|
# <br>
|
34
|
-
# <b>returns</b> <tt>
|
35
|
+
# <b>returns</b> <tt>Formatter::Types::Response</tt> formatter response: standard output for
|
36
|
+
# the formatted payload suitable for a Process.
|
35
37
|
#
|
36
38
|
def format(support_emails_list)
|
37
39
|
raise Formatter::Exceptions::InvalidData unless support_emails_list.all? do |support_email|
|
38
40
|
support_email.is_a?(Domain::Email)
|
39
41
|
end
|
40
42
|
|
41
|
-
process_emails(support_emails_list).reduce("") do |payload, support_email|
|
43
|
+
response = process_emails(support_emails_list).reduce("") do |payload, support_email|
|
42
44
|
payload + build_template(Domain::Email::ATTRIBUTES, support_email)
|
43
45
|
end
|
46
|
+
|
47
|
+
Formatter::Types::Response.new(response)
|
44
48
|
end
|
45
49
|
|
46
50
|
private
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Formatter
|
4
|
+
module Types
|
5
|
+
##
|
6
|
+
# Represents a response received from a Formatter. It encapsulates the formatted data to be used by
|
7
|
+
# a Process or a Write component.
|
8
|
+
class Response
|
9
|
+
attr_reader :data
|
10
|
+
|
11
|
+
def initialize(response)
|
12
|
+
@data = response
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -3,11 +3,12 @@
|
|
3
3
|
require_relative "../domain/work_items_limit"
|
4
4
|
require_relative "./exceptions/invalid_data"
|
5
5
|
require_relative "./base"
|
6
|
+
require_relative "./types/response"
|
6
7
|
|
7
8
|
module Formatter
|
8
9
|
##
|
9
10
|
# This class implements methods from the Formatter::Base module, tailored to format the
|
10
|
-
# Domain::WorkItemsLimit structure for a
|
11
|
+
# Domain::WorkItemsLimit structure for a Process.
|
11
12
|
class WorkItemsLimit < Base
|
12
13
|
DEFAULT_DOMAIN_LIMIT = 6
|
13
14
|
|
@@ -24,13 +25,14 @@ module Formatter
|
|
24
25
|
#
|
25
26
|
# <br>
|
26
27
|
# <b>Params:</b>
|
27
|
-
# * <tt>List<Domain::WorkItemsLimit></tt> work_items_list: List of
|
28
|
+
# * <tt>List<Domain::WorkItemsLimit></tt> work_items_list: List of serialized work items limits.
|
28
29
|
#
|
29
30
|
# <br>
|
30
31
|
# <b>raises</b> <tt>Formatter::Exceptions::InvalidData</tt> when invalid data is provided.
|
31
32
|
#
|
32
33
|
# <br>
|
33
|
-
# <b>returns</b> <tt>
|
34
|
+
# <b>returns</b> <tt>Formatter::Types::Response</tt> formatter response: standard output for
|
35
|
+
# the formatted payload suitable for a Process.
|
34
36
|
#
|
35
37
|
|
36
38
|
def format(work_items_list)
|
@@ -38,10 +40,12 @@ module Formatter
|
|
38
40
|
work_item.is_a?(Domain::WorkItemsLimit)
|
39
41
|
end
|
40
42
|
|
41
|
-
exceeded_domains(work_items_list).reduce("") do |payload, work_items_limit|
|
43
|
+
response = exceeded_domains(work_items_list).reduce("") do |payload, work_items_limit|
|
42
44
|
built_template = build_template(Domain::WorkItemsLimit::ATTRIBUTES, work_items_limit)
|
43
45
|
payload + format_message_by_case(built_template.gsub("\n", ""), work_items_limit)
|
44
46
|
end
|
47
|
+
|
48
|
+
Formatter::Types::Response.new(response)
|
45
49
|
end
|
46
50
|
|
47
51
|
private
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "../domain/exceptions/function_not_implemented"
|
4
|
+
require_relative "./types/response"
|
5
|
+
|
6
|
+
module Process
|
7
|
+
##
|
8
|
+
# Serves as a foundational structure for implementing specific process. Acting as an interface,
|
9
|
+
# this class defines essential attributes and methods, providing a blueprint for creating custom
|
10
|
+
# process tailored to different platforms or services.
|
11
|
+
#
|
12
|
+
class Base
|
13
|
+
attr_reader :config
|
14
|
+
|
15
|
+
# Initializes the process with essential configuration parameters.
|
16
|
+
#
|
17
|
+
def initialize(config = {})
|
18
|
+
@config = config
|
19
|
+
end
|
20
|
+
|
21
|
+
# A method meant to send messages to an specific destination depending on the implementation.
|
22
|
+
# Must be overridden by subclasses, with specific logic based on the use case.
|
23
|
+
#
|
24
|
+
# <br>
|
25
|
+
# <b>returns</b> a <tt>Process::Types::Response</tt>: standard output for a process
|
26
|
+
#
|
27
|
+
def execute(format_response)
|
28
|
+
Process::Types::Response.new(format_response.data)
|
29
|
+
end
|
30
|
+
|
31
|
+
protected
|
32
|
+
|
33
|
+
def valid_format_response(format_response)
|
34
|
+
return format_response if format_response.is_a?(Formatter::Types::Response)
|
35
|
+
|
36
|
+
raise Formatter::Exceptions::InvalidData
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "../base"
|
4
|
+
require_relative "./exceptions/invalid_webhook_token"
|
5
|
+
require_relative "./types/response"
|
6
|
+
|
7
|
+
module Process
|
8
|
+
module Discord
|
9
|
+
##
|
10
|
+
# This class is an implementation of the Process::Base interface, specifically designed
|
11
|
+
# for sending messages to Discord.
|
12
|
+
#
|
13
|
+
class Implementation < Base
|
14
|
+
attr_reader :webhook, :name
|
15
|
+
|
16
|
+
# Initializes the process with essential configuration parameters.
|
17
|
+
#
|
18
|
+
def initialize(config = {})
|
19
|
+
super(config)
|
20
|
+
|
21
|
+
@webhook = config[:webhook]
|
22
|
+
@name = config[:name]
|
23
|
+
end
|
24
|
+
|
25
|
+
# Implements the sending process logic for the Discord use case. It sends a POST request to
|
26
|
+
# the Discord webhook with the specified payload.
|
27
|
+
#
|
28
|
+
# <br>
|
29
|
+
# <b>Params:</b>
|
30
|
+
# * <tt>Formatter::Types::Response</tt> formatter response: standard formatter response
|
31
|
+
# with the Payload to be send to discord.
|
32
|
+
# <br>
|
33
|
+
# <b>raises</b> <tt>Exceptions::Discord::InvalidWebookToken</tt> if the provided webhook
|
34
|
+
# token is invalid.
|
35
|
+
#
|
36
|
+
# <br>
|
37
|
+
# <b>returns</b> <tt>Process::Types::Response</tt>
|
38
|
+
#
|
39
|
+
def execute(format_response)
|
40
|
+
response = valid_format_response(format_response)
|
41
|
+
|
42
|
+
body = post_body(response.data)
|
43
|
+
|
44
|
+
response = HTTParty.post(webhook, { body: body, headers: { "Content-Type" => "application/json" } })
|
45
|
+
|
46
|
+
discord_response = Process::Discord::Types::Response.new(response)
|
47
|
+
|
48
|
+
validate_response(discord_response)
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
def post_body(payload)
|
54
|
+
{
|
55
|
+
username: name,
|
56
|
+
avatar_url: "",
|
57
|
+
content: payload
|
58
|
+
}.to_json
|
59
|
+
end
|
60
|
+
|
61
|
+
def validate_response(response)
|
62
|
+
case response.code
|
63
|
+
when 50_027
|
64
|
+
raise Discord::Exceptions::InvalidWebookToken, response.message
|
65
|
+
else
|
66
|
+
Process::Types::Response.new(response)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "../base"
|
4
|
+
require_relative "./exceptions/invalid_webhook_token"
|
5
|
+
require_relative "./types/response"
|
6
|
+
|
7
|
+
module Process
|
8
|
+
module Slack
|
9
|
+
##
|
10
|
+
# This class is an implementation of the Process::Base interface, specifically designed
|
11
|
+
# for sending messages to Slack.
|
12
|
+
#
|
13
|
+
class Implementation < Base
|
14
|
+
attr_reader :webhook, :name
|
15
|
+
|
16
|
+
# Initializes the process with essential configuration parameters.
|
17
|
+
#
|
18
|
+
def initialize(config = {})
|
19
|
+
super(config)
|
20
|
+
|
21
|
+
@webhook = config[:webhook]
|
22
|
+
@name = config[:name]
|
23
|
+
end
|
24
|
+
|
25
|
+
# Implements the sending process logic for the Slack use case. It sends a POST request to
|
26
|
+
# the Slack webhook with the specified payload.
|
27
|
+
#
|
28
|
+
# <br>
|
29
|
+
# <b>Params:</b>
|
30
|
+
# * <tt>Formatter::Types::Response</tt> formatter response: standard formatter response
|
31
|
+
# with the Payload to be send to slack.
|
32
|
+
# <br>
|
33
|
+
# <b>raises</b> <tt>Exceptions::Slack::InvalidWebookToken</tt> if the provided webhook
|
34
|
+
# token is invalid.
|
35
|
+
#
|
36
|
+
# <br>
|
37
|
+
# <b>returns</b> <tt>Process::Types::Response</tt>
|
38
|
+
#
|
39
|
+
def execute(format_response)
|
40
|
+
response = valid_format_response(format_response)
|
41
|
+
|
42
|
+
body = post_body(response.data)
|
43
|
+
|
44
|
+
response = HTTParty.post(webhook, { body: body, headers: { "Content-Type" => "application/json" } })
|
45
|
+
|
46
|
+
slack_response = Process::Discord::Types::Response.new(response)
|
47
|
+
|
48
|
+
validate_response(slack_response)
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
def post_body(payload)
|
54
|
+
{
|
55
|
+
username: name,
|
56
|
+
text: payload
|
57
|
+
}.to_json
|
58
|
+
end
|
59
|
+
|
60
|
+
def validate_response(response)
|
61
|
+
case response.http_code
|
62
|
+
when 403
|
63
|
+
raise Process::Slack::Exceptions::InvalidWebookToken, response.message
|
64
|
+
else
|
65
|
+
Process::Types::Response.new(response)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Process
|
4
|
+
module Types
|
5
|
+
##
|
6
|
+
# Represents a response received from a Process. It encapsulates the formatted data to be used by
|
7
|
+
# a Write component.
|
8
|
+
class Response
|
9
|
+
attr_reader :data
|
10
|
+
|
11
|
+
def initialize(response)
|
12
|
+
@data = response
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -2,41 +2,41 @@
|
|
2
2
|
|
3
3
|
require_relative "../domain/exceptions/function_not_implemented"
|
4
4
|
|
5
|
-
module
|
5
|
+
module Read
|
6
6
|
##
|
7
|
-
# The
|
7
|
+
# The Read::Base class serves as the foundation for implementing specific data readers within the Read module.
|
8
8
|
# Operating as an interface, this class defines essential attributes and methods, providing a blueprint for creating
|
9
|
-
# custom
|
9
|
+
# custom readers tailored to different data sources.
|
10
10
|
#
|
11
11
|
class Base
|
12
12
|
attr_reader :config
|
13
13
|
|
14
|
-
# Initializes the
|
14
|
+
# Initializes the reader with essential configuration parameters.
|
15
15
|
#
|
16
16
|
def initialize(config)
|
17
17
|
@config = config
|
18
18
|
end
|
19
19
|
|
20
|
-
# A method meant to
|
20
|
+
# A method meant to execute the read request from an specific source depending on the implementation.
|
21
21
|
# Must be overridden by subclasses, with specific logic based on the use case.
|
22
22
|
#
|
23
23
|
# <br>
|
24
24
|
# <b>raises</b> <tt>Domain::Exceptions::FunctionNotImplemented</tt> when missing implementation.
|
25
25
|
#
|
26
|
-
def
|
26
|
+
def execute
|
27
27
|
raise Domain::Exceptions::FunctionNotImplemented
|
28
28
|
end
|
29
29
|
|
30
30
|
protected
|
31
31
|
|
32
|
-
# A method meant to
|
32
|
+
# A method meant to read from the source, retrieven the required data
|
33
33
|
# from an specific filter configuration depending on the use case implementation.
|
34
34
|
# Must be overridden by subclasses, with specific logic based on the use case.
|
35
35
|
#
|
36
36
|
# <br>
|
37
37
|
# <b>raises</b> <tt>Domain::Exceptions::FunctionNotImplemented</tt> when missing implementation.
|
38
38
|
#
|
39
|
-
def
|
39
|
+
def read(*_filters)
|
40
40
|
raise Domain::Exceptions::FunctionNotImplemented
|
41
41
|
end
|
42
42
|
end
|