bas 1.5.2 → 1.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/CHANGELOG.md +6 -0
- data/README.md +92 -50
- data/lib/bas/bot/base.rb +37 -54
- data/lib/bas/shared_storage/base.rb +35 -0
- data/lib/bas/shared_storage/default.rb +18 -0
- data/lib/bas/shared_storage/postgres.rb +95 -0
- data/lib/bas/shared_storage/types/read.rb +22 -0
- data/lib/bas/utils/discord/request.rb +15 -2
- data/lib/bas/utils/openai/run_assistant.rb +1 -0
- data/lib/bas/utils/postgres/request.rb +3 -1
- data/lib/bas/version.rb +1 -1
- metadata +8 -41
- data/lib/bas/bot/compare_wip_limit_count.rb +0 -92
- data/lib/bas/bot/create_work_item.rb +0 -142
- data/lib/bas/bot/fetch_billing_from_digital_ocean.rb +0 -87
- data/lib/bas/bot/fetch_birthdays_from_notion.rb +0 -128
- data/lib/bas/bot/fetch_domain_services_from_notion.rb +0 -93
- data/lib/bas/bot/fetch_domains_wip_counts_from_notion.rb +0 -121
- data/lib/bas/bot/fetch_domains_wip_limit_from_notion.rb +0 -134
- data/lib/bas/bot/fetch_emails_from_imap.rb +0 -99
- data/lib/bas/bot/fetch_github_issues.rb +0 -147
- data/lib/bas/bot/fetch_images_from_discord.rb +0 -78
- data/lib/bas/bot/fetch_media_from_notion.rb +0 -186
- data/lib/bas/bot/fetch_next_week_birthdays_from_notion.rb +0 -142
- data/lib/bas/bot/fetch_next_week_ptos_from_notion.rb +0 -197
- data/lib/bas/bot/fetch_ptos_from_notion.rb +0 -160
- data/lib/bas/bot/format_birthdays.rb +0 -97
- data/lib/bas/bot/format_do_bill_alert.rb +0 -108
- data/lib/bas/bot/format_emails.rb +0 -124
- data/lib/bas/bot/format_wip_limit_exceeded.rb +0 -97
- data/lib/bas/bot/garbage_collector.rb +0 -85
- data/lib/bas/bot/humanize_pto.rb +0 -117
- data/lib/bas/bot/notify_discord.rb +0 -96
- data/lib/bas/bot/notify_do_bill_alert_email.rb +0 -94
- data/lib/bas/bot/review_domain_availability.rb +0 -96
- data/lib/bas/bot/review_media.rb +0 -139
- data/lib/bas/bot/update_review_media_state.rb +0 -102
- data/lib/bas/bot/update_work_item.rb +0 -181
- data/lib/bas/bot/verify_issue_existance_in_notion.rb +0 -131
- data/lib/bas/bot/write_domain_review_requests.rb +0 -104
- data/lib/bas/bot/write_media_review_in_discord.rb +0 -114
- data/lib/bas/bot/write_media_review_requests.rb +0 -104
- data/lib/bas/read/base.rb +0 -30
- data/lib/bas/read/default.rb +0 -16
- data/lib/bas/read/postgres.rb +0 -44
- data/lib/bas/read/types/response.rb +0 -18
- data/lib/bas/write/base.rb +0 -31
- data/lib/bas/write/postgres.rb +0 -45
- data/lib/bas/write/postgres_update.rb +0 -49
@@ -1,142 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative "./base"
|
4
|
-
require_relative "../read/postgres"
|
5
|
-
require_relative "../utils/notion/request"
|
6
|
-
require_relative "../write/postgres"
|
7
|
-
|
8
|
-
module Bot
|
9
|
-
##
|
10
|
-
# The Bot::FetchNextWeekBirthdaysFromNotion class serves as a bot implementation to read next
|
11
|
-
# week birthdays from a notion database and write them on a PostgresDB table with a specific format.
|
12
|
-
#
|
13
|
-
# <br>
|
14
|
-
# <b>Example</b>
|
15
|
-
#
|
16
|
-
# options = {
|
17
|
-
# process_options: {
|
18
|
-
# database_id: "notion database id",
|
19
|
-
# secret: "notion secret"
|
20
|
-
# },
|
21
|
-
# write_options: {
|
22
|
-
# connection: {
|
23
|
-
# host: "host",
|
24
|
-
# port: 5432,
|
25
|
-
# dbname: "bas",
|
26
|
-
# user: "postgres",
|
27
|
-
# password: "postgres"
|
28
|
-
# },
|
29
|
-
# db_table: "birthdays",
|
30
|
-
# tag: "FetchNextWeekBirthdaysFromNotion"
|
31
|
-
# }
|
32
|
-
# }
|
33
|
-
#
|
34
|
-
# bot = Bot::FetchNextWeekBirthdaysFromNotion.new(options)
|
35
|
-
# bot.execute
|
36
|
-
#
|
37
|
-
class FetchNextWeekBirthdaysFromNotion < Bot::Base
|
38
|
-
DAYS_BEFORE = 7
|
39
|
-
|
40
|
-
# read function to execute the PostgresDB Read component
|
41
|
-
#
|
42
|
-
def read
|
43
|
-
reader = Read::Postgres.new(read_options.merge(conditions))
|
44
|
-
|
45
|
-
reader.execute
|
46
|
-
end
|
47
|
-
|
48
|
-
# Process function to execute the Notion utility to fetch PTO's from the notion database
|
49
|
-
#
|
50
|
-
def process
|
51
|
-
response = Utils::Notion::Request.execute(params)
|
52
|
-
|
53
|
-
if response.code == 200
|
54
|
-
birthdays_list = normalize_response(response.parsed_response["results"])
|
55
|
-
|
56
|
-
{ success: { birthdays: birthdays_list } }
|
57
|
-
else
|
58
|
-
{ error: { message: response.parsed_response, status_code: response.code } }
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
# Write function to execute the PostgresDB write component
|
63
|
-
#
|
64
|
-
def write
|
65
|
-
write = Write::Postgres.new(write_options, process_response)
|
66
|
-
|
67
|
-
write.execute
|
68
|
-
end
|
69
|
-
|
70
|
-
private
|
71
|
-
|
72
|
-
def conditions
|
73
|
-
{
|
74
|
-
where: "archived=$1 AND tag=$2 AND stage=$3 ORDER BY inserted_at ASC",
|
75
|
-
params: [false, read_options[:tag], "unprocessed"]
|
76
|
-
}
|
77
|
-
end
|
78
|
-
|
79
|
-
def params
|
80
|
-
{
|
81
|
-
endpoint: "databases/#{process_options[:database_id]}/query",
|
82
|
-
secret: process_options[:secret],
|
83
|
-
method: "post",
|
84
|
-
body:
|
85
|
-
}
|
86
|
-
end
|
87
|
-
|
88
|
-
def body
|
89
|
-
{
|
90
|
-
filter: {
|
91
|
-
and: [{ property: "BD_this_year", date: { equals: n_days_from_now } }] + last_edited_condition
|
92
|
-
}
|
93
|
-
}
|
94
|
-
end
|
95
|
-
|
96
|
-
def last_edited_condition
|
97
|
-
return [] if read_response.inserted_at.nil?
|
98
|
-
|
99
|
-
[
|
100
|
-
{
|
101
|
-
timestamp: "last_edited_time",
|
102
|
-
last_edited_time: { on_or_after: read_response.inserted_at }
|
103
|
-
}
|
104
|
-
]
|
105
|
-
end
|
106
|
-
|
107
|
-
def n_days_from_now
|
108
|
-
date = Time.now.utc + days_in_second(days_before)
|
109
|
-
|
110
|
-
date.utc.strftime("%F").to_s
|
111
|
-
end
|
112
|
-
|
113
|
-
def days_before
|
114
|
-
process_options[:days_before] || DAYS_BEFORE
|
115
|
-
end
|
116
|
-
|
117
|
-
def days_in_second(days)
|
118
|
-
days * 24 * 60 * 60
|
119
|
-
end
|
120
|
-
|
121
|
-
def normalize_response(results)
|
122
|
-
return [] if results.nil?
|
123
|
-
|
124
|
-
results.map do |value|
|
125
|
-
birthday_fields = value["properties"]
|
126
|
-
|
127
|
-
{
|
128
|
-
"name" => extract_rich_text_field_value(birthday_fields["Complete Name"]),
|
129
|
-
"birthday_date" => extract_date_field_value(birthday_fields["BD_this_year"])
|
130
|
-
}
|
131
|
-
end
|
132
|
-
end
|
133
|
-
|
134
|
-
def extract_rich_text_field_value(data)
|
135
|
-
data["rich_text"][0]["plain_text"]
|
136
|
-
end
|
137
|
-
|
138
|
-
def extract_date_field_value(data)
|
139
|
-
data["formula"]["date"]["start"]
|
140
|
-
end
|
141
|
-
end
|
142
|
-
end
|
@@ -1,197 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "date"
|
4
|
-
|
5
|
-
require_relative "./base"
|
6
|
-
require_relative "../read/default"
|
7
|
-
require_relative "../utils/notion/request"
|
8
|
-
require_relative "../write/postgres"
|
9
|
-
|
10
|
-
module Bot
|
11
|
-
##
|
12
|
-
# The Bot::FetchNextWeekPtosFromNotion class serves as a bot implementation to read next week
|
13
|
-
# PTO's from a notion database and write them on a PostgresDB table with a specific format.
|
14
|
-
#
|
15
|
-
# <br>
|
16
|
-
# <b>Example</b>
|
17
|
-
#
|
18
|
-
# options = {
|
19
|
-
# process_options: {
|
20
|
-
# database_id: "notion database id",
|
21
|
-
# secret: "notion secret"
|
22
|
-
# },
|
23
|
-
# write_options: {
|
24
|
-
# connection: {
|
25
|
-
# host: "host",
|
26
|
-
# port: 5432,
|
27
|
-
# dbname: "bas",
|
28
|
-
# user: "postgres",
|
29
|
-
# password: "postgres"
|
30
|
-
# },
|
31
|
-
# db_table: "pto",
|
32
|
-
# tag: "FetchNextWeekPtosFromNotion"
|
33
|
-
# }
|
34
|
-
# }
|
35
|
-
#
|
36
|
-
# bot = Bot::FetchNextWeekPtosFromNotion.new(options)
|
37
|
-
# bot.execute
|
38
|
-
#
|
39
|
-
class FetchNextWeekPtosFromNotion < Bot::Base # rubocop:disable Metrics/ClassLength
|
40
|
-
# Read function to execute the default Read component
|
41
|
-
#
|
42
|
-
def read
|
43
|
-
reader = Read::Default.new
|
44
|
-
|
45
|
-
reader.execute
|
46
|
-
end
|
47
|
-
|
48
|
-
# Process function to execute the Notion utility to fetch next week PTO's from the notion database
|
49
|
-
#
|
50
|
-
def process
|
51
|
-
response = Utils::Notion::Request.execute(params)
|
52
|
-
|
53
|
-
if response.code == 200
|
54
|
-
ptos_list = normalize_response(response.parsed_response["results"])
|
55
|
-
|
56
|
-
{ success: { ptos: ptos_list } }
|
57
|
-
else
|
58
|
-
{ error: { message: response.parsed_response, status_code: response.code } }
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
# Write function to execute the PostgresDB write component
|
63
|
-
#
|
64
|
-
def write
|
65
|
-
write = Write::Postgres.new(write_options, process_response)
|
66
|
-
|
67
|
-
write.execute
|
68
|
-
end
|
69
|
-
|
70
|
-
private
|
71
|
-
|
72
|
-
def params
|
73
|
-
{
|
74
|
-
endpoint: "databases/#{process_options[:database_id]}/query",
|
75
|
-
secret: process_options[:secret],
|
76
|
-
method: "post",
|
77
|
-
body:
|
78
|
-
}
|
79
|
-
end
|
80
|
-
|
81
|
-
def body
|
82
|
-
monday, sunday = next_week_dates
|
83
|
-
|
84
|
-
{
|
85
|
-
filter: {
|
86
|
-
or: [
|
87
|
-
belong_next_week("StartDateTime", monday, sunday),
|
88
|
-
belong_next_week("EndDateTime", monday, sunday),
|
89
|
-
cover_next_week(monday, sunday)
|
90
|
-
]
|
91
|
-
}
|
92
|
-
}
|
93
|
-
end
|
94
|
-
|
95
|
-
def next_week_dates
|
96
|
-
monday = next_week_monday
|
97
|
-
sunday = monday + 6
|
98
|
-
|
99
|
-
[monday, sunday]
|
100
|
-
end
|
101
|
-
|
102
|
-
def next_week_monday
|
103
|
-
today = Date.today
|
104
|
-
week_day = today.wday
|
105
|
-
|
106
|
-
days = week_day.zero? ? 1 : 8 - week_day
|
107
|
-
|
108
|
-
today + days
|
109
|
-
end
|
110
|
-
|
111
|
-
def belong_next_week(property, after_day, before_day)
|
112
|
-
{
|
113
|
-
and: [
|
114
|
-
{ property:, date: { on_or_after: after_day } },
|
115
|
-
{ property:, date: { on_or_before: before_day } }
|
116
|
-
]
|
117
|
-
}
|
118
|
-
end
|
119
|
-
|
120
|
-
def cover_next_week(monday, sunday)
|
121
|
-
{
|
122
|
-
and: [
|
123
|
-
{ property: "EndDateTime", date: { on_or_after: sunday } },
|
124
|
-
{ property: "StartDateTime", date: { on_or_before: monday } }
|
125
|
-
]
|
126
|
-
}
|
127
|
-
end
|
128
|
-
|
129
|
-
def normalize_response(results)
|
130
|
-
return [] if results.nil?
|
131
|
-
|
132
|
-
results.map do |pto|
|
133
|
-
pto_fields = pto["properties"]
|
134
|
-
|
135
|
-
name = extract_description_field_value(pto_fields["Description"])
|
136
|
-
start_date = extract_date_field_value(pto_fields["StartDateTime"])
|
137
|
-
end_date = extract_date_field_value(pto_fields["EndDateTime"])
|
138
|
-
|
139
|
-
description(name, start_date, end_date)
|
140
|
-
end
|
141
|
-
end
|
142
|
-
|
143
|
-
def description(name, start_date, end_date)
|
144
|
-
start = start_description(start_date)
|
145
|
-
finish = end_description(end_date)
|
146
|
-
|
147
|
-
"#{name} will not be working between #{start} and #{finish}. And returns the #{returns(finish)}"
|
148
|
-
end
|
149
|
-
|
150
|
-
def start_description(date)
|
151
|
-
date[:from]
|
152
|
-
end
|
153
|
-
|
154
|
-
def end_description(date)
|
155
|
-
return date[:from] if date[:to].nil?
|
156
|
-
|
157
|
-
date[:to]
|
158
|
-
end
|
159
|
-
|
160
|
-
def returns(date)
|
161
|
-
date.include?("T12") ? "#{date} in the afternoon" : next_work_day(date)
|
162
|
-
end
|
163
|
-
|
164
|
-
def next_work_day(date)
|
165
|
-
datetime = DateTime.parse(date)
|
166
|
-
|
167
|
-
return_day = case datetime.wday
|
168
|
-
when 5 then datetime + 3
|
169
|
-
when 6 then datetime + 2
|
170
|
-
else datetime + 1
|
171
|
-
end
|
172
|
-
|
173
|
-
return_day.strftime("%A %B %d of %Y").to_s
|
174
|
-
end
|
175
|
-
|
176
|
-
def extract_description_field_value(data)
|
177
|
-
names = data["title"].map { |name| name["plain_text"] }
|
178
|
-
|
179
|
-
names.join(" ")
|
180
|
-
end
|
181
|
-
|
182
|
-
def extract_date_field_value(date)
|
183
|
-
{
|
184
|
-
from: extract_start_date(date),
|
185
|
-
to: extract_end_date(date)
|
186
|
-
}
|
187
|
-
end
|
188
|
-
|
189
|
-
def extract_start_date(data)
|
190
|
-
data["date"]["start"]
|
191
|
-
end
|
192
|
-
|
193
|
-
def extract_end_date(data)
|
194
|
-
data["date"]["end"]
|
195
|
-
end
|
196
|
-
end
|
197
|
-
end
|
@@ -1,160 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "date"
|
4
|
-
|
5
|
-
require_relative "./base"
|
6
|
-
require_relative "../read/default"
|
7
|
-
require_relative "../utils/notion/request"
|
8
|
-
require_relative "../write/postgres"
|
9
|
-
|
10
|
-
module Bot
|
11
|
-
##
|
12
|
-
# The Bot::FetchPtosFromNotion class serves as a bot implementation to read PTO's from a
|
13
|
-
# notion database and write them on a PostgresDB table with a specific format.
|
14
|
-
#
|
15
|
-
# <br>
|
16
|
-
# <b>Example</b>
|
17
|
-
#
|
18
|
-
# options = {
|
19
|
-
# process_options: {
|
20
|
-
# database_id: "notion database id",
|
21
|
-
# secret: "notion secret"
|
22
|
-
# },
|
23
|
-
# write_options: {
|
24
|
-
# connection: {
|
25
|
-
# host: "host",
|
26
|
-
# port: 5432,
|
27
|
-
# dbname: "bas",
|
28
|
-
# user: "postgres",
|
29
|
-
# password: "postgres"
|
30
|
-
# },
|
31
|
-
# db_table: "pto",
|
32
|
-
# tag: "FetchPtosFromNotion"
|
33
|
-
# }
|
34
|
-
# }
|
35
|
-
#
|
36
|
-
# bot = Bot::FetchPtosFromNotion.new(options)
|
37
|
-
# bot.execute
|
38
|
-
#
|
39
|
-
class FetchPtosFromNotion < Bot::Base
|
40
|
-
# Read function to execute the default Read component
|
41
|
-
#
|
42
|
-
def read
|
43
|
-
reader = Read::Default.new
|
44
|
-
|
45
|
-
reader.execute
|
46
|
-
end
|
47
|
-
|
48
|
-
# Process function to execute the Notion utility to fetch PTO's from the notion database
|
49
|
-
#
|
50
|
-
def process
|
51
|
-
response = Utils::Notion::Request.execute(params)
|
52
|
-
|
53
|
-
if response.code == 200
|
54
|
-
ptos_list = normalize_response(response.parsed_response["results"])
|
55
|
-
|
56
|
-
{ success: { ptos: ptos_list } }
|
57
|
-
else
|
58
|
-
{ error: { message: response.parsed_response, status_code: response.code } }
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
# Write function to execute the PostgresDB write component
|
63
|
-
#
|
64
|
-
def write
|
65
|
-
write = Write::Postgres.new(write_options, process_response)
|
66
|
-
|
67
|
-
write.execute
|
68
|
-
end
|
69
|
-
|
70
|
-
private
|
71
|
-
|
72
|
-
def params
|
73
|
-
{
|
74
|
-
endpoint: "databases/#{process_options[:database_id]}/query",
|
75
|
-
secret: process_options[:secret],
|
76
|
-
method: "post",
|
77
|
-
body: { filter: today_condition }
|
78
|
-
}
|
79
|
-
end
|
80
|
-
|
81
|
-
def today_condition
|
82
|
-
today = Time.now.utc.strftime("%F").to_s
|
83
|
-
|
84
|
-
{
|
85
|
-
"and": [
|
86
|
-
{ property: "StartDateTime", date: { on_or_before: today } },
|
87
|
-
{ property: "EndDateTime", date: { on_or_after: today } }
|
88
|
-
]
|
89
|
-
}
|
90
|
-
end
|
91
|
-
|
92
|
-
def normalize_response(results)
|
93
|
-
return [] if results.nil?
|
94
|
-
|
95
|
-
results.map do |pto|
|
96
|
-
pto_fields = pto["properties"]
|
97
|
-
|
98
|
-
name = extract_description_field_value(pto_fields["Description"])
|
99
|
-
start_date = extract_date_field_value(pto_fields["StartDateTime"])
|
100
|
-
end_date = extract_date_field_value(pto_fields["EndDateTime"])
|
101
|
-
|
102
|
-
description(name, start_date, end_date)
|
103
|
-
end
|
104
|
-
end
|
105
|
-
|
106
|
-
def description(name, start_date, end_date)
|
107
|
-
start = start_description(start_date)
|
108
|
-
finish = end_description(end_date)
|
109
|
-
|
110
|
-
"#{name} will not be working between #{start} and #{finish}. And returns the #{returns(finish)}"
|
111
|
-
end
|
112
|
-
|
113
|
-
def start_description(date)
|
114
|
-
date[:from]
|
115
|
-
end
|
116
|
-
|
117
|
-
def end_description(date)
|
118
|
-
return date[:from] if date[:to].nil?
|
119
|
-
|
120
|
-
date[:to]
|
121
|
-
end
|
122
|
-
|
123
|
-
def returns(date)
|
124
|
-
date.include?("T12") ? "#{date} in the afternoon" : next_work_day(date)
|
125
|
-
end
|
126
|
-
|
127
|
-
def next_work_day(date)
|
128
|
-
datetime = DateTime.parse(date)
|
129
|
-
|
130
|
-
return_day = case datetime.wday
|
131
|
-
when 5 then datetime + 3
|
132
|
-
when 6 then datetime + 2
|
133
|
-
else datetime + 1
|
134
|
-
end
|
135
|
-
|
136
|
-
return_day.strftime("%A %B %d of %Y").to_s
|
137
|
-
end
|
138
|
-
|
139
|
-
def extract_description_field_value(data)
|
140
|
-
names = data["title"].map { |name| name["plain_text"] }
|
141
|
-
|
142
|
-
names.join(" ")
|
143
|
-
end
|
144
|
-
|
145
|
-
def extract_date_field_value(date)
|
146
|
-
{
|
147
|
-
from: extract_start_date(date),
|
148
|
-
to: extract_end_date(date)
|
149
|
-
}
|
150
|
-
end
|
151
|
-
|
152
|
-
def extract_start_date(data)
|
153
|
-
data["date"]["start"]
|
154
|
-
end
|
155
|
-
|
156
|
-
def extract_end_date(data)
|
157
|
-
data["date"]["end"]
|
158
|
-
end
|
159
|
-
end
|
160
|
-
end
|
@@ -1,97 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative "./base"
|
4
|
-
require_relative "../read/postgres"
|
5
|
-
require_relative "../write/postgres"
|
6
|
-
|
7
|
-
module Bot
|
8
|
-
##
|
9
|
-
# The Bot::FormatBirthdays class serves as a bot implementation to read birthdays from a
|
10
|
-
# PostgresDB database, format them with a specific template, and write them on a PostgresDB
|
11
|
-
# table with a specific format.
|
12
|
-
#
|
13
|
-
# <br>
|
14
|
-
# <b>Example</b>
|
15
|
-
#
|
16
|
-
# options = {
|
17
|
-
# read_options: {
|
18
|
-
# connection: {
|
19
|
-
# host: "localhost",
|
20
|
-
# port: 5432,
|
21
|
-
# dbname: "bas",
|
22
|
-
# user: "postgres",
|
23
|
-
# password: "postgres"
|
24
|
-
# },
|
25
|
-
# db_table: "use_cases",
|
26
|
-
# tag: "FetchBirthdaysFromNotion"
|
27
|
-
# },
|
28
|
-
# process_options: {
|
29
|
-
# template: "birthday template message"
|
30
|
-
# },
|
31
|
-
# write_options: {
|
32
|
-
# connection: {
|
33
|
-
# host: "localhost",
|
34
|
-
# port: 5432,
|
35
|
-
# dbname: "bas",
|
36
|
-
# user: "postgres",
|
37
|
-
# password: "postgres"
|
38
|
-
# },
|
39
|
-
# db_table: "use_cases",
|
40
|
-
# tag: "FormatBirthdays"
|
41
|
-
# }
|
42
|
-
# }
|
43
|
-
#
|
44
|
-
# bot = Bot::FormatBirthdays.new(options)
|
45
|
-
# bot.execute
|
46
|
-
#
|
47
|
-
class FormatBirthdays < Bot::Base
|
48
|
-
BIRTHDAY_ATTRIBUTES = %w[name birthday_date].freeze
|
49
|
-
|
50
|
-
# read function to execute the PostgresDB Read component
|
51
|
-
#
|
52
|
-
def read
|
53
|
-
reader = Read::Postgres.new(read_options.merge(conditions))
|
54
|
-
|
55
|
-
reader.execute
|
56
|
-
end
|
57
|
-
|
58
|
-
# Process function to format the notification using a template
|
59
|
-
#
|
60
|
-
def process
|
61
|
-
return { success: { notification: "" } } if unprocessable_response
|
62
|
-
|
63
|
-
birthdays_list = read_response.data["birthdays"]
|
64
|
-
|
65
|
-
notification = birthdays_list.reduce("") do |payload, birthday|
|
66
|
-
"#{payload} #{build_template(BIRTHDAY_ATTRIBUTES, birthday)} \n"
|
67
|
-
end
|
68
|
-
|
69
|
-
{ success: { notification: } }
|
70
|
-
end
|
71
|
-
|
72
|
-
# Write function to execute the PostgresDB write component
|
73
|
-
#
|
74
|
-
def write
|
75
|
-
write = Write::Postgres.new(write_options, process_response)
|
76
|
-
|
77
|
-
write.execute
|
78
|
-
end
|
79
|
-
|
80
|
-
private
|
81
|
-
|
82
|
-
def conditions
|
83
|
-
{
|
84
|
-
where: "archived=$1 AND tag=$2 AND stage=$3 ORDER BY inserted_at ASC",
|
85
|
-
params: [false, read_options[:tag], "unprocessed"]
|
86
|
-
}
|
87
|
-
end
|
88
|
-
|
89
|
-
def build_template(attributes, instance)
|
90
|
-
template = process_options[:template]
|
91
|
-
|
92
|
-
attributes.reduce(template) do |formated_template, attribute|
|
93
|
-
formated_template.gsub("<#{attribute}>", instance[attribute].to_s)
|
94
|
-
end
|
95
|
-
end
|
96
|
-
end
|
97
|
-
end
|
@@ -1,108 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative "./base"
|
4
|
-
require_relative "../read/postgres"
|
5
|
-
require_relative "../write/postgres"
|
6
|
-
|
7
|
-
module Bot
|
8
|
-
##
|
9
|
-
# The Bot::FormatDoBillAlert class serves as a bot implementation to format DigitalOcean bill
|
10
|
-
# alerts from a PostgresDB database, format them with a specific template, and write them on a
|
11
|
-
# PostgresDB table with a specific format.
|
12
|
-
#
|
13
|
-
# <br>
|
14
|
-
# <b>Example</b>
|
15
|
-
#
|
16
|
-
# options = {
|
17
|
-
# read_options: {
|
18
|
-
# connection: {
|
19
|
-
# host: "localhost",
|
20
|
-
# port: 5432,
|
21
|
-
# dbname: "bas",
|
22
|
-
# user: "postgres",
|
23
|
-
# password: "postgres"
|
24
|
-
# },
|
25
|
-
# db_table: "do_billing",
|
26
|
-
# tag: "FetchBillingFromDigitalOcean"
|
27
|
-
# },
|
28
|
-
# process_options: {
|
29
|
-
# threshold: 7
|
30
|
-
# },
|
31
|
-
# write_options: {
|
32
|
-
# connection: {
|
33
|
-
# host: "localhost",
|
34
|
-
# port: 5432,
|
35
|
-
# dbname: "bas",
|
36
|
-
# user: "postgres",
|
37
|
-
# password: "postgres"
|
38
|
-
# },
|
39
|
-
# db_table: "do_billing",
|
40
|
-
# tag: "FormatDoBillAlert"
|
41
|
-
# }
|
42
|
-
# }
|
43
|
-
#
|
44
|
-
# bot = Bot::FormatDoBillAlert.new(options)
|
45
|
-
# bot.execute
|
46
|
-
#
|
47
|
-
class FormatDoBillAlert < Bot::Base
|
48
|
-
# read function to execute the PostgresDB Read component
|
49
|
-
#
|
50
|
-
def read
|
51
|
-
reader = Read::Postgres.new(read_options.merge(conditions))
|
52
|
-
|
53
|
-
reader.execute
|
54
|
-
end
|
55
|
-
|
56
|
-
# Process function to format the notification using a template
|
57
|
-
#
|
58
|
-
def process
|
59
|
-
return { success: { notification: "" } } if unprocessable_response || !threshold_exceeded
|
60
|
-
|
61
|
-
{ success: { notification: message } }
|
62
|
-
end
|
63
|
-
|
64
|
-
# Write function to execute the PostgresDB write component
|
65
|
-
#
|
66
|
-
def write
|
67
|
-
write = Write::Postgres.new(write_options, process_response)
|
68
|
-
|
69
|
-
write.execute
|
70
|
-
end
|
71
|
-
|
72
|
-
private
|
73
|
-
|
74
|
-
def conditions
|
75
|
-
{
|
76
|
-
where: "archived=$1 AND tag=$2 AND stage=$3 ORDER BY inserted_at ASC",
|
77
|
-
params: [false, read_options[:tag], "unprocessed"]
|
78
|
-
}
|
79
|
-
end
|
80
|
-
|
81
|
-
def threshold_exceeded
|
82
|
-
return false if billing.zero?
|
83
|
-
|
84
|
-
usage > process_options[:threshold]
|
85
|
-
end
|
86
|
-
|
87
|
-
def usage
|
88
|
-
billing - last_billing
|
89
|
-
end
|
90
|
-
|
91
|
-
def billing
|
92
|
-
read_response.data["billing"]["month_to_date_balance"].to_f
|
93
|
-
end
|
94
|
-
|
95
|
-
def last_billing
|
96
|
-
read_response.data["last_billing"]["month_to_date_balance"].to_f
|
97
|
-
end
|
98
|
-
|
99
|
-
def message
|
100
|
-
balance = billing
|
101
|
-
threshold = process_options[:threshold]
|
102
|
-
|
103
|
-
":warning: The **DigitalOcean** daily usage was exceeded. \
|
104
|
-
Current balance: #{balance}, Threshold: #{threshold}, \
|
105
|
-
Current daily usage: #{usage.round(3)}"
|
106
|
-
end
|
107
|
-
end
|
108
|
-
end
|