bns 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +5 -0
- data/Gemfile +4 -0
- data/lib/bns/domain/email.rb +34 -0
- data/lib/bns/domain/work_items_limit.rb +4 -18
- data/lib/bns/fetcher/imap/base.rb +70 -0
- data/lib/bns/fetcher/imap/types/response.rb +27 -0
- data/lib/bns/fetcher/imap/use_case/support_emails.rb +26 -0
- data/lib/bns/formatter/pto.rb +14 -2
- data/lib/bns/formatter/support_emails.rb +69 -0
- data/lib/bns/formatter/work_items_limit.rb +24 -3
- data/lib/bns/mapper/imap/support_emails.rb +56 -0
- data/lib/bns/use_cases/use_cases.rb +49 -0
- data/lib/bns/version.rb +1 -1
- metadata +8 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f45452ff8e3569ad4ffed2d32d8cc7801cd5a4379205ca70d7d401814abb7d50
|
4
|
+
data.tar.gz: 64cd26aaa2269270f77f50ec5b1d4371272d4f53d280bed5b0ccd727b0e628b7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a61ce154f73bcf97b76828f437cf4cbd0af1809458532de9ec232343e9a92c85ec118d336a5f13b4eb95cb8e792e2b10bd941c90c79c720c2ae7b4fd5272543f
|
7
|
+
data.tar.gz: '088fc7b072e971ebc37259cc2e017bcc22aa69d9c8d2f035958bb33b578108235686f889c1faccdb6a6566e39b44cddacc6a356c737a81924cebd10d6379d057'
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,10 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## 0.3.0 (19.03.2024)
|
4
|
+
- [Add Component - Email fetcher](https://github.com/kommitters/bns/issues/40)
|
5
|
+
- [Use case - Email based notifications](https://github.com/kommitters/bns/issues/45)
|
6
|
+
- [Dynamic WIP limit value](https://github.com/kommitters/bns/issues/48)
|
7
|
+
|
3
8
|
## 0.2.0 (29.02.2024)
|
4
9
|
- [Add a Postgres fetcher component](https://github.com/kommitters/bns/issues/28)
|
5
10
|
- [Use case - PTO's Postgres-Slack implementation](https://github.com/kommitters/bns/issues/30)
|
data/Gemfile
CHANGED
@@ -7,6 +7,8 @@ gemspec
|
|
7
7
|
|
8
8
|
gem "rake", "~> 13.0"
|
9
9
|
|
10
|
+
gem "net-imap", "~> 0.4.10"
|
11
|
+
gem "net-smtp", "~> 0.4.0.1"
|
10
12
|
gem "rspec", "~> 3.0"
|
11
13
|
gem "rubocop", "~> 1.21"
|
12
14
|
gem "simplecov", require: false, group: :test
|
@@ -18,3 +20,5 @@ gem "webmock"
|
|
18
20
|
gem "httparty"
|
19
21
|
|
20
22
|
gem "pg", "~> 1.5", ">= 1.5.4"
|
23
|
+
|
24
|
+
gem "gmail_xoauth"
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Domain
|
4
|
+
##
|
5
|
+
# The Domain::Email class provides a domain-specific representation of an Email object.
|
6
|
+
# It encapsulates information about an email, including the subject, the sender, and the date.
|
7
|
+
#
|
8
|
+
class Email
|
9
|
+
attr_reader :subject, :sender
|
10
|
+
attr_accessor :date
|
11
|
+
|
12
|
+
ATTRIBUTES = %w[subject sender date].freeze
|
13
|
+
|
14
|
+
# Initializes a Domain::Email instance with the specified subject, sender, and date.
|
15
|
+
#
|
16
|
+
# <br>
|
17
|
+
# <b>Params:</b>
|
18
|
+
# * <tt>String</tt> email subject.
|
19
|
+
# * <tt>String</tt> Email of the sender.
|
20
|
+
# * <tt>String</tt> Reception date
|
21
|
+
#
|
22
|
+
def initialize(subject, sender, date)
|
23
|
+
@subject = subject
|
24
|
+
@sender = sender
|
25
|
+
@date = parse_to_datetime(date)
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def parse_to_datetime(date)
|
31
|
+
DateTime.parse(date).to_time
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -3,37 +3,23 @@
|
|
3
3
|
module Domain
|
4
4
|
##
|
5
5
|
# The Domain::WorkItemsLimit class provides a domain-specific representation of a Work Item object.
|
6
|
-
# It encapsulates information about a work items limit, including the domain
|
6
|
+
# It encapsulates information about a work items limit, including the domain and total.
|
7
7
|
#
|
8
8
|
class WorkItemsLimit
|
9
|
-
attr_reader :domain, :total
|
9
|
+
attr_reader :domain, :total
|
10
10
|
|
11
|
-
ATTRIBUTES = %w[domain total
|
11
|
+
ATTRIBUTES = %w[domain total].freeze
|
12
12
|
|
13
|
-
# Initializes a Domain::WorkItemsLimit instance with the specified domain
|
13
|
+
# Initializes a Domain::WorkItemsLimit instance with the specified domain and total.
|
14
14
|
#
|
15
15
|
# <br>
|
16
16
|
# <b>Params:</b>
|
17
17
|
# * <tt>String</tt> 'domain' responsible domain of the work items.
|
18
18
|
# * <tt>String</tt> 'total' total 'in progress' work items.
|
19
|
-
# * <tt>String</tt> 'wip_limit' maximum 'in progress' work items for the domain
|
20
19
|
#
|
21
20
|
def initialize(domain, total)
|
22
21
|
@domain = domain
|
23
22
|
@total = total
|
24
|
-
@wip_limit = domain_wip_limit(domain)
|
25
|
-
end
|
26
|
-
|
27
|
-
private
|
28
|
-
|
29
|
-
def domain_wip_limit(domain)
|
30
|
-
case domain
|
31
|
-
when "kommit.ops" then 5
|
32
|
-
when "kommit.sales" then 3
|
33
|
-
when "kommit.marketing" then 4
|
34
|
-
when "kommit.engineering" then 12
|
35
|
-
else 6
|
36
|
-
end
|
37
23
|
end
|
38
24
|
end
|
39
25
|
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "net/imap"
|
4
|
+
require "gmail_xoauth"
|
5
|
+
|
6
|
+
require_relative "../base"
|
7
|
+
require_relative "./types/response"
|
8
|
+
|
9
|
+
module Fetcher
|
10
|
+
module Imap
|
11
|
+
##
|
12
|
+
# This class is an implementation of the Fetcher::Base interface, specifically designed
|
13
|
+
# for fetching data from an IMAP server.
|
14
|
+
#
|
15
|
+
class Base < Fetcher::Base
|
16
|
+
protected
|
17
|
+
|
18
|
+
# Implements the data fetching logic for emails data from an IMAP server.
|
19
|
+
# It connects to an IMAP server inbox, request emails base on a filter,
|
20
|
+
# and returns a validated response.
|
21
|
+
#
|
22
|
+
def execute(email_domain, email_port, token_uri, query)
|
23
|
+
access_token = refresh_token(token_uri)
|
24
|
+
|
25
|
+
imap_fetch(email_domain, email_port, query, access_token)
|
26
|
+
|
27
|
+
Fetcher::Imap::Types::Response.new(@emails)
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def imap_fetch(email_domain, email_port, query, access_token)
|
33
|
+
imap = Net::IMAP.new(email_domain, port: email_port, ssl: true)
|
34
|
+
|
35
|
+
imap.authenticate("XOAUTH2", config[:user], access_token)
|
36
|
+
|
37
|
+
imap.examine(config[:inbox])
|
38
|
+
|
39
|
+
@emails = fetch_emails(imap, query)
|
40
|
+
|
41
|
+
imap.logout
|
42
|
+
imap.disconnect
|
43
|
+
end
|
44
|
+
|
45
|
+
def fetch_emails(imap, query)
|
46
|
+
imap.search(query).map do |message_id|
|
47
|
+
imap.fetch(message_id, "ENVELOPE")[0].attr["ENVELOPE"]
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def refresh_token(token_uri)
|
52
|
+
uri = URI.parse(token_uri)
|
53
|
+
|
54
|
+
response = Net::HTTP.post_form(uri, params)
|
55
|
+
token_data = JSON.parse(response.body)
|
56
|
+
|
57
|
+
token_data["access_token"]
|
58
|
+
end
|
59
|
+
|
60
|
+
def params
|
61
|
+
{
|
62
|
+
"grant_type" => "refresh_token",
|
63
|
+
"refresh_token" => config[:refresh_token],
|
64
|
+
"client_id" => config[:client_id],
|
65
|
+
"client_secret" => config[:client_secret]
|
66
|
+
}
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Fetcher
|
4
|
+
module Imap
|
5
|
+
module Types
|
6
|
+
##
|
7
|
+
# Represents a response received from the Imap client. It encapsulates essential
|
8
|
+
# information about the response, providing a structured way to handle and analyze
|
9
|
+
# it's responses.
|
10
|
+
class Response
|
11
|
+
attr_reader :status_code, :message, :results
|
12
|
+
|
13
|
+
def initialize(response)
|
14
|
+
if response.empty?
|
15
|
+
@status_code = 404
|
16
|
+
@message = "no result were found"
|
17
|
+
@results = []
|
18
|
+
else
|
19
|
+
@status_code = 200
|
20
|
+
@message = "success"
|
21
|
+
@results = response
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "../base"
|
4
|
+
|
5
|
+
module Fetcher
|
6
|
+
module Imap
|
7
|
+
##
|
8
|
+
# This class is an implementation of the Fetcher::Imap::Base interface, specifically designed
|
9
|
+
# for fetching support email from a Google Gmail account.
|
10
|
+
#
|
11
|
+
class SupportEmails < Imap::Base
|
12
|
+
TOKEN_URI = "https://oauth2.googleapis.com/token"
|
13
|
+
EMAIL_DOMAIN = "imap.gmail.com"
|
14
|
+
EMAIL_PORT = 993
|
15
|
+
|
16
|
+
# Implements the data fetching filter for support emails from Google Gmail.
|
17
|
+
#
|
18
|
+
def fetch
|
19
|
+
yesterday = (Time.now - (60 * 60 * 24)).strftime("%e-%b-%Y")
|
20
|
+
query = ["TO", config[:search_email], "SINCE", yesterday]
|
21
|
+
|
22
|
+
execute(EMAIL_DOMAIN, EMAIL_PORT, TOKEN_URI, query)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
data/lib/bns/formatter/pto.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "date"
|
4
|
+
|
3
5
|
require_relative "../domain/pto"
|
4
6
|
require_relative "./exceptions/invalid_data"
|
5
7
|
require_relative "./base"
|
@@ -9,13 +11,15 @@ module Formatter
|
|
9
11
|
# This class implements methods from the Formatter::Base module, tailored to format the
|
10
12
|
# Domain::Pto structure for a dispatcher.
|
11
13
|
class Pto < Base
|
14
|
+
DEFAULT_TIME_ZONE = "+00:00"
|
15
|
+
|
12
16
|
# Initializes the Slack formatter with essential configuration parameters.
|
13
17
|
#
|
14
18
|
# <b>timezone</b> : expect an string with the time difference relative to the UTC. Example: "-05:00"
|
15
19
|
def initialize(config = {})
|
16
20
|
super(config)
|
17
21
|
|
18
|
-
@timezone = config[:timezone]
|
22
|
+
@timezone = config[:timezone] || DEFAULT_TIME_ZONE
|
19
23
|
end
|
20
24
|
|
21
25
|
# Implements the logic for building a formatted payload with the given template for PTO's.
|
@@ -64,7 +68,9 @@ module Formatter
|
|
64
68
|
end
|
65
69
|
|
66
70
|
def format_timezone(date)
|
67
|
-
|
71
|
+
date_time = build_date(date)
|
72
|
+
|
73
|
+
Time.at(date_time, in: @timezone)
|
68
74
|
end
|
69
75
|
|
70
76
|
def today?(date)
|
@@ -72,5 +78,11 @@ module Formatter
|
|
72
78
|
|
73
79
|
date == format_timezone(time_now).strftime("%F")
|
74
80
|
end
|
81
|
+
|
82
|
+
def build_date(date)
|
83
|
+
date_time = date.include?("T") ? date : "#{date}T00:00:00.000#{@timezone}"
|
84
|
+
|
85
|
+
DateTime.parse(date_time).to_time
|
86
|
+
end
|
75
87
|
end
|
76
88
|
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "../domain/email"
|
4
|
+
require_relative "./exceptions/invalid_data"
|
5
|
+
require_relative "./base"
|
6
|
+
|
7
|
+
module Formatter
|
8
|
+
##
|
9
|
+
# This class implements methods from the Formatter::Base module, tailored to format the
|
10
|
+
# Domain::Email structure for a dispatcher.
|
11
|
+
class SupportEmails < Base
|
12
|
+
DEFAULT_TIME_ZONE = "+00:00"
|
13
|
+
|
14
|
+
# Initializes the formatter with essential configuration parameters.
|
15
|
+
#
|
16
|
+
# <b>timezone</b> : expect an string with the time difference relative to the UTC. Example: "-05:00"
|
17
|
+
def initialize(config = {})
|
18
|
+
super(config)
|
19
|
+
|
20
|
+
@timezone = config[:timezone] || DEFAULT_TIME_ZONE
|
21
|
+
@frecuency = config[:frecuency]
|
22
|
+
end
|
23
|
+
|
24
|
+
# Implements the logic for building a formatted payload with the given template for support emails.
|
25
|
+
#
|
26
|
+
# <br>
|
27
|
+
# <b>Params:</b>
|
28
|
+
# * <tt>List<Domain::Email></tt> support_emails_list: list of support emails.
|
29
|
+
#
|
30
|
+
# <br>
|
31
|
+
# <b>raises</b> <tt>Formatter::Exceptions::InvalidData</tt> when invalid data is provided.
|
32
|
+
#
|
33
|
+
# <br>
|
34
|
+
# <b>returns</b> <tt>String</tt> payload: formatted payload suitable for a Dispatcher.
|
35
|
+
#
|
36
|
+
def format(support_emails_list)
|
37
|
+
raise Formatter::Exceptions::InvalidData unless support_emails_list.all? do |support_email|
|
38
|
+
support_email.is_a?(Domain::Email)
|
39
|
+
end
|
40
|
+
|
41
|
+
process_emails(support_emails_list).reduce("") do |payload, support_email|
|
42
|
+
payload + build_template(Domain::Email::ATTRIBUTES, support_email)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
def process_emails(emails)
|
49
|
+
emails.each { |email| email.date = at_timezone(email.date) }
|
50
|
+
emails.filter! { |email| email.date > time_window } unless @frecuency.nil?
|
51
|
+
|
52
|
+
format_timestamp(emails)
|
53
|
+
end
|
54
|
+
|
55
|
+
def format_timestamp(emails)
|
56
|
+
emails.each { |email| email.date = email.date.strftime("%F %r") }
|
57
|
+
end
|
58
|
+
|
59
|
+
def time_window
|
60
|
+
date_time = Time.now - (60 * 60 * @frecuency)
|
61
|
+
|
62
|
+
at_timezone(date_time)
|
63
|
+
end
|
64
|
+
|
65
|
+
def at_timezone(date)
|
66
|
+
Time.at(date, in: @timezone)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -9,7 +9,16 @@ module Formatter
|
|
9
9
|
# This class implements methods from the Formatter::Base module, tailored to format the
|
10
10
|
# Domain::WorkItemsLimit structure for a dispatcher.
|
11
11
|
class WorkItemsLimit < Base
|
12
|
-
|
12
|
+
DEFAULT_DOMAIN_LIMIT = 6
|
13
|
+
|
14
|
+
# Initializes the formatter with essential configuration parameters.
|
15
|
+
#
|
16
|
+
# <b>limits</b> : expect a map with the wip limits by domain. Example: { "ops": 5 }
|
17
|
+
def initialize(config = {})
|
18
|
+
super(config)
|
19
|
+
|
20
|
+
@limits = config[:limits]
|
21
|
+
end
|
13
22
|
|
14
23
|
# Implements the logic for building a formatted payload with the given template for wip limits.
|
15
24
|
#
|
@@ -30,14 +39,26 @@ module Formatter
|
|
30
39
|
end
|
31
40
|
|
32
41
|
exceeded_domains(work_items_list).reduce("") do |payload, work_items_limit|
|
33
|
-
|
42
|
+
built_template = build_template(Domain::WorkItemsLimit::ATTRIBUTES, work_items_limit)
|
43
|
+
payload + format_message_by_case(built_template.gsub("\n", ""), work_items_limit)
|
34
44
|
end
|
35
45
|
end
|
36
46
|
|
37
47
|
private
|
38
48
|
|
49
|
+
def format_message_by_case(template, work_items_limit)
|
50
|
+
total_items = work_items_limit.total
|
51
|
+
limit = domain_limit(work_items_limit.domain)
|
52
|
+
|
53
|
+
template + ", #{total_items} of #{limit}\n"
|
54
|
+
end
|
55
|
+
|
39
56
|
def exceeded_domains(work_items_list)
|
40
|
-
work_items_list.filter { |work_item| work_item.total > work_item.
|
57
|
+
work_items_list.filter { |work_item| work_item.total > domain_limit(work_item.domain) }
|
58
|
+
end
|
59
|
+
|
60
|
+
def domain_limit(domain)
|
61
|
+
@limits[domain.to_sym] || DEFAULT_DOMAIN_LIMIT
|
41
62
|
end
|
42
63
|
end
|
43
64
|
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "../../domain/email"
|
4
|
+
require_relative "../base"
|
5
|
+
|
6
|
+
module Mapper
|
7
|
+
module Imap
|
8
|
+
##
|
9
|
+
# This class implementats the methods of the Mapper::Base module, specifically designed for
|
10
|
+
# preparing or shaping support emails data coming from a Fetcher::Base implementation.
|
11
|
+
class SupportEmails
|
12
|
+
include Base
|
13
|
+
|
14
|
+
# Implements the logic for shaping the results from a fetcher response.
|
15
|
+
#
|
16
|
+
# <br>
|
17
|
+
# <b>Params:</b>
|
18
|
+
# * <tt>Fetcher::Imap::Types::Response</tt> imap_response: Array of imap emails data.
|
19
|
+
#
|
20
|
+
# <br>
|
21
|
+
# <b>return</b> <tt>List<Domain::Email></tt> support_emails_list, mapped support emails to be used by a
|
22
|
+
# Formatter::Base implementation.
|
23
|
+
#
|
24
|
+
def map(imap_response)
|
25
|
+
return [] if imap_response.results.empty?
|
26
|
+
|
27
|
+
normalized_email_data = normalize_response(imap_response.results)
|
28
|
+
|
29
|
+
normalized_email_data.map do |email|
|
30
|
+
Domain::Email.new(email["subject"], email["sender"], email["date"])
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def normalize_response(results)
|
37
|
+
return [] if results.nil?
|
38
|
+
|
39
|
+
results.map do |value|
|
40
|
+
{
|
41
|
+
"sender" => extract_sender(value),
|
42
|
+
"date" => value.date,
|
43
|
+
"subject" => value.subject
|
44
|
+
}
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def extract_sender(value)
|
49
|
+
mailbox = value.sender[0]["mailbox"]
|
50
|
+
host = value.sender[0]["host"]
|
51
|
+
|
52
|
+
"#{mailbox}@#{host}"
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -1,21 +1,28 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# fetcher
|
3
4
|
require_relative "../fetcher/notion/use_case/birthday_today"
|
4
5
|
require_relative "../fetcher/notion/use_case/birthday_next_week"
|
5
6
|
require_relative "../fetcher/notion/use_case/pto_today"
|
6
7
|
require_relative "../fetcher/notion/use_case/pto_next_week"
|
7
8
|
require_relative "../fetcher/notion/use_case/work_items_limit"
|
8
9
|
require_relative "../fetcher/postgres/use_case/pto_today"
|
10
|
+
require_relative "../fetcher/imap/use_case/support_emails"
|
9
11
|
|
12
|
+
# mapper
|
10
13
|
require_relative "../mapper/notion/birthday_today"
|
11
14
|
require_relative "../mapper/notion/pto_today"
|
12
15
|
require_relative "../mapper/notion/work_items_limit"
|
13
16
|
require_relative "../mapper/postgres/pto_today"
|
17
|
+
require_relative "../mapper/imap/support_emails"
|
14
18
|
|
19
|
+
# formatter
|
15
20
|
require_relative "../formatter/birthday"
|
16
21
|
require_relative "../formatter/pto"
|
17
22
|
require_relative "../formatter/work_items_limit"
|
23
|
+
require_relative "../formatter/support_emails"
|
18
24
|
|
25
|
+
# dispatcher
|
19
26
|
require_relative "../dispatcher/discord/implementation"
|
20
27
|
require_relative "../dispatcher/slack/implementation"
|
21
28
|
|
@@ -325,4 +332,46 @@ module UseCases
|
|
325
332
|
|
326
333
|
UseCases::UseCase.new(use_case_config)
|
327
334
|
end
|
335
|
+
|
336
|
+
# Provides an instance of the support emails from an google IMAP server to Discord use case implementation.
|
337
|
+
#
|
338
|
+
# <br>
|
339
|
+
# <b>Example</b>
|
340
|
+
#
|
341
|
+
# options = {
|
342
|
+
# fetch_options: {
|
343
|
+
# user: 'info@email.co',
|
344
|
+
# refresh_token: REFRESH_TOKEN,
|
345
|
+
# client_id: CLIENT_ID,
|
346
|
+
# client_secret: CLIENT_SECRET,
|
347
|
+
# inbox: 'INBOX',
|
348
|
+
# search_email: 'support@email.co'
|
349
|
+
# },
|
350
|
+
# dispatch_options: {
|
351
|
+
# webhook: "https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX",
|
352
|
+
# name: "emailSupport"
|
353
|
+
# }
|
354
|
+
# }
|
355
|
+
#
|
356
|
+
# use_case = UseCases.notify_support_email_from_imap_to_discord(options)
|
357
|
+
# use_case.perform
|
358
|
+
#
|
359
|
+
# #################################################################################
|
360
|
+
#
|
361
|
+
# Requirements:
|
362
|
+
# * A google gmail account with IMAP support activated.
|
363
|
+
# * A set of authorization parameters like a client_id, client_secret, and a resfresh_token. To
|
364
|
+
# generate them, follow this instructions: https://developers.google.com/identity/protocols/oauth2
|
365
|
+
# * A webhook key, which can be generated directly on discrod on the desired channel, following this instructions:
|
366
|
+
# https://support.discord.com/hc/en-us/articles/228383668-Intro-to-Webhooks
|
367
|
+
#
|
368
|
+
def self.notify_support_email_from_imap_to_discord(options)
|
369
|
+
fetcher = Fetcher::Imap::SupportEmails.new(options[:fetch_options])
|
370
|
+
mapper = Mapper::Imap::SupportEmails.new
|
371
|
+
formatter = Formatter::SupportEmails.new(options[:format_options])
|
372
|
+
dispatcher = Dispatcher::Discord::Implementation.new(options[:dispatch_options])
|
373
|
+
use_case_config = UseCases::Types::Config.new(fetcher, mapper, formatter, dispatcher)
|
374
|
+
|
375
|
+
UseCases::UseCase.new(use_case_config)
|
376
|
+
end
|
328
377
|
end
|
data/lib/bns/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bns
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- kommitters Open Source
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-03-20 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: A versatile business notification system offering key components for
|
14
14
|
building various use cases. It provides an easy-to-use tool for implementing
|
@@ -39,10 +39,14 @@ files:
|
|
39
39
|
- lib/bns/dispatcher/slack/implementation.rb
|
40
40
|
- lib/bns/dispatcher/slack/types/response.rb
|
41
41
|
- lib/bns/domain/birthday.rb
|
42
|
+
- lib/bns/domain/email.rb
|
42
43
|
- lib/bns/domain/exceptions/function_not_implemented.rb
|
43
44
|
- lib/bns/domain/pto.rb
|
44
45
|
- lib/bns/domain/work_items_limit.rb
|
45
46
|
- lib/bns/fetcher/base.rb
|
47
|
+
- lib/bns/fetcher/imap/base.rb
|
48
|
+
- lib/bns/fetcher/imap/types/response.rb
|
49
|
+
- lib/bns/fetcher/imap/use_case/support_emails.rb
|
46
50
|
- lib/bns/fetcher/notion/base.rb
|
47
51
|
- lib/bns/fetcher/notion/exceptions/invalid_api_key.rb
|
48
52
|
- lib/bns/fetcher/notion/exceptions/invalid_database_id.rb
|
@@ -61,8 +65,10 @@ files:
|
|
61
65
|
- lib/bns/formatter/birthday.rb
|
62
66
|
- lib/bns/formatter/exceptions/invalid_data.rb
|
63
67
|
- lib/bns/formatter/pto.rb
|
68
|
+
- lib/bns/formatter/support_emails.rb
|
64
69
|
- lib/bns/formatter/work_items_limit.rb
|
65
70
|
- lib/bns/mapper/base.rb
|
71
|
+
- lib/bns/mapper/imap/support_emails.rb
|
66
72
|
- lib/bns/mapper/notion/birthday_today.rb
|
67
73
|
- lib/bns/mapper/notion/pto_today.rb
|
68
74
|
- lib/bns/mapper/notion/work_items_limit.rb
|