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,124 +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::FormatEmails class serves as a bot implementation to read emails 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: "FetchEmailsFromImap"
|
27
|
-
# },
|
28
|
-
# process_options: {
|
29
|
-
# template: "emails 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: "FormatEmails"
|
41
|
-
# }
|
42
|
-
# }
|
43
|
-
#
|
44
|
-
# bot = Bot::FormatEmails.new(options)
|
45
|
-
# bot.execute
|
46
|
-
#
|
47
|
-
class FormatEmails < Bot::Base
|
48
|
-
EMAIL_ATTRIBUTES = %w[subject sender date].freeze
|
49
|
-
DEFAULT_TIME_ZONE = "+00:00"
|
50
|
-
|
51
|
-
# read function to execute the PostgresDB Read component
|
52
|
-
#
|
53
|
-
def read
|
54
|
-
reader = Read::Postgres.new(read_options.merge(conditions))
|
55
|
-
|
56
|
-
reader.execute
|
57
|
-
end
|
58
|
-
|
59
|
-
# Process function to format the notification using a template
|
60
|
-
#
|
61
|
-
def process
|
62
|
-
return { success: { notification: "" } } if unprocessable_response
|
63
|
-
|
64
|
-
emails_list = read_response.data["emails"]
|
65
|
-
|
66
|
-
notification = process_emails(emails_list).reduce("") do |payload, email|
|
67
|
-
"#{payload} #{build_template(EMAIL_ATTRIBUTES, email)} \n"
|
68
|
-
end
|
69
|
-
|
70
|
-
{ success: { notification: } }
|
71
|
-
end
|
72
|
-
|
73
|
-
# Write function to execute the PostgresDB write component
|
74
|
-
#
|
75
|
-
def write
|
76
|
-
write = Write::Postgres.new(write_options, process_response)
|
77
|
-
|
78
|
-
write.execute
|
79
|
-
end
|
80
|
-
|
81
|
-
private
|
82
|
-
|
83
|
-
def conditions
|
84
|
-
{
|
85
|
-
where: "archived=$1 AND tag=$2 AND stage=$3 ORDER BY inserted_at ASC",
|
86
|
-
params: [false, read_options[:tag], "unprocessed"]
|
87
|
-
}
|
88
|
-
end
|
89
|
-
|
90
|
-
def process_emails(emails)
|
91
|
-
emails.each do |email|
|
92
|
-
date = DateTime.parse(email["date"]).to_time
|
93
|
-
email["date"] = at_timezone(date)
|
94
|
-
end
|
95
|
-
emails.filter! { |email| email["date"] > time_window } unless process_options[:frequency].nil?
|
96
|
-
|
97
|
-
format_timestamp(emails)
|
98
|
-
end
|
99
|
-
|
100
|
-
def format_timestamp(emails)
|
101
|
-
emails.each { |email| email["date"] = email["date"].strftime("%F %r") }
|
102
|
-
end
|
103
|
-
|
104
|
-
def time_window
|
105
|
-
date_time = Time.now - (60 * 60 * process_options[:frequency])
|
106
|
-
|
107
|
-
at_timezone(date_time)
|
108
|
-
end
|
109
|
-
|
110
|
-
def at_timezone(date)
|
111
|
-
timezone = process_options[:timezone] || DEFAULT_TIME_ZONE
|
112
|
-
|
113
|
-
Time.at(date, in: timezone)
|
114
|
-
end
|
115
|
-
|
116
|
-
def build_template(attributes, instance)
|
117
|
-
template = process_options[:template]
|
118
|
-
|
119
|
-
attributes.reduce(template) do |formated_template, attribute|
|
120
|
-
formated_template.gsub("<#{attribute}>", instance[attribute].to_s)
|
121
|
-
end
|
122
|
-
end
|
123
|
-
end
|
124
|
-
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::FormatWipLimitExceeded class serves as a bot implementation to read exceeded domain wip
|
10
|
-
# counts by limits from a PostgresDB database, format them with a specific template, and write them
|
11
|
-
# on a 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: "use_cases",
|
26
|
-
# tag: "CompareWipLimitCount"
|
27
|
-
# },
|
28
|
-
# process_options: {
|
29
|
-
# template: "exceeded wip limit 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: "FormatWipLimitExceeded"
|
41
|
-
# }
|
42
|
-
# }
|
43
|
-
#
|
44
|
-
# bot = Bot::FormatWipLimitExceeded.new(options)
|
45
|
-
# bot.execute
|
46
|
-
#
|
47
|
-
class FormatWipLimitExceeded < Bot::Base
|
48
|
-
WIP_LIMIT_ATTRIBUTES = %w[domain exceeded].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
|
-
exceedded_limits_list = read_response.data["exceeded_domain_count"]
|
64
|
-
|
65
|
-
notification = exceedded_limits_list.reduce("") do |payload, exceedded_limit|
|
66
|
-
"#{payload} #{build_template(WIP_LIMIT_ATTRIBUTES, exceedded_limit)} \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,85 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative "./base"
|
4
|
-
require_relative "../read/default"
|
5
|
-
require_relative "../write/postgres"
|
6
|
-
|
7
|
-
module Bot
|
8
|
-
##
|
9
|
-
# The Bot::GarbageCollector class serves as a bot implementation to archive bot records from a
|
10
|
-
# PostgresDB database table and write a response on a PostgresDB table with a specific format.
|
11
|
-
#
|
12
|
-
# <br>
|
13
|
-
# <b>Example</b>
|
14
|
-
#
|
15
|
-
# options = {
|
16
|
-
# process_options: {
|
17
|
-
# connection: {
|
18
|
-
# host: "localhost",
|
19
|
-
# port: 5432,
|
20
|
-
# dbname: "bas",
|
21
|
-
# user: "postgres",
|
22
|
-
# password: "postgres"
|
23
|
-
# },
|
24
|
-
# db_table: "use_cases"
|
25
|
-
# },
|
26
|
-
# write_options: {
|
27
|
-
# connection: {
|
28
|
-
# host: "localhost",
|
29
|
-
# port: 5432,
|
30
|
-
# dbname: "bas",
|
31
|
-
# user: "postgres",
|
32
|
-
# password: "postgres"
|
33
|
-
# },
|
34
|
-
# db_table: "use_cases"
|
35
|
-
# }
|
36
|
-
# }
|
37
|
-
#
|
38
|
-
# bot = Bot::GarbageCollector.new(options)
|
39
|
-
# bot.execute
|
40
|
-
#
|
41
|
-
class GarbageCollector < Bot::Base
|
42
|
-
SUCCESS_STATUS = "PGRES_COMMAND_OK"
|
43
|
-
|
44
|
-
# Read function to execute the default Read component
|
45
|
-
#
|
46
|
-
def read
|
47
|
-
reader = Read::Default.new
|
48
|
-
|
49
|
-
reader.execute
|
50
|
-
end
|
51
|
-
|
52
|
-
# Process function to update records in a PostgresDB database table
|
53
|
-
#
|
54
|
-
def process
|
55
|
-
response = Utils::Postgres::Request.execute(params)
|
56
|
-
|
57
|
-
if response.res_status == SUCCESS_STATUS
|
58
|
-
{ success: { archived: true } }
|
59
|
-
else
|
60
|
-
{ error: { message: response.result_error_message, status_code: response.res_status } }
|
61
|
-
end
|
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 params
|
75
|
-
{
|
76
|
-
connection: process_options[:connection],
|
77
|
-
query:
|
78
|
-
}
|
79
|
-
end
|
80
|
-
|
81
|
-
def query
|
82
|
-
"UPDATE #{process_options[:db_table]} SET archived=true WHERE archived=false"
|
83
|
-
end
|
84
|
-
end
|
85
|
-
end
|
data/lib/bas/bot/humanize_pto.rb
DELETED
@@ -1,117 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative "./base"
|
4
|
-
require_relative "../read/postgres"
|
5
|
-
require_relative "../write/postgres"
|
6
|
-
require_relative "../utils/openai/run_assistant"
|
7
|
-
|
8
|
-
module Bot
|
9
|
-
##
|
10
|
-
# The Bot::HumanizePto class serves as a bot implementation to read PTO's from a
|
11
|
-
# PostgresDb table, format them using an OpenAI Assistant with the OpenAI API, and
|
12
|
-
# write the response as a notification on a PostgresDB table.
|
13
|
-
#
|
14
|
-
# <br>
|
15
|
-
# <b>Example</b>
|
16
|
-
#
|
17
|
-
# options = {
|
18
|
-
# read_options: {
|
19
|
-
# connection: {
|
20
|
-
# host: "host",
|
21
|
-
# port: 5432,
|
22
|
-
# dbname: "bas",
|
23
|
-
# user: "postgres",
|
24
|
-
# password: "postgres"
|
25
|
-
# },
|
26
|
-
# db_table: "pto",
|
27
|
-
# tag: "FetchPtosFromNotion"
|
28
|
-
# },
|
29
|
-
# process_options: {
|
30
|
-
# secret: "openai secret key",
|
31
|
-
# assistant_id: "assistant_id",
|
32
|
-
# prompt: "optional additional prompt"
|
33
|
-
# },
|
34
|
-
# write_options: {
|
35
|
-
# connection: {
|
36
|
-
# host: "host",
|
37
|
-
# port: 5432,
|
38
|
-
# dbname: "bas",
|
39
|
-
# user: "postgres",
|
40
|
-
# password: "postgres"
|
41
|
-
# },
|
42
|
-
# db_table: "pto",
|
43
|
-
# tag: "HumanizePto"
|
44
|
-
# }
|
45
|
-
# }
|
46
|
-
#
|
47
|
-
# bot = Bot::HumanizePto.new(options)
|
48
|
-
# bot.execute
|
49
|
-
#
|
50
|
-
class HumanizePto < Bot::Base
|
51
|
-
DEFAULT_PROMPT = "{data}"
|
52
|
-
|
53
|
-
# read function to execute the PostgresDB Read component
|
54
|
-
#
|
55
|
-
def read
|
56
|
-
reader = Read::Postgres.new(read_options.merge(conditions))
|
57
|
-
|
58
|
-
reader.execute
|
59
|
-
end
|
60
|
-
|
61
|
-
# process function to execute the OpenaAI utility to process the PTO's
|
62
|
-
#
|
63
|
-
def process
|
64
|
-
return { success: { notification: "" } } if unprocessable_response
|
65
|
-
|
66
|
-
response = Utils::OpenAI::RunAssitant.execute(params)
|
67
|
-
|
68
|
-
if response.code != 200 || (!response["status"].nil? && response["status"] != "completed")
|
69
|
-
return error_response(response)
|
70
|
-
end
|
71
|
-
|
72
|
-
sucess_response(response)
|
73
|
-
end
|
74
|
-
|
75
|
-
# write function to execute the PostgresDB write component
|
76
|
-
#
|
77
|
-
def write
|
78
|
-
write = Write::Postgres.new(write_options, process_response)
|
79
|
-
|
80
|
-
write.execute
|
81
|
-
end
|
82
|
-
|
83
|
-
private
|
84
|
-
|
85
|
-
def conditions
|
86
|
-
{
|
87
|
-
where: "archived=$1 AND tag=$2 AND stage=$3 ORDER BY inserted_at ASC",
|
88
|
-
params: [false, read_options[:tag], "unprocessed"]
|
89
|
-
}
|
90
|
-
end
|
91
|
-
|
92
|
-
def params
|
93
|
-
{
|
94
|
-
assistant_id: process_options[:assistant_id],
|
95
|
-
secret: process_options[:secret],
|
96
|
-
prompt: build_prompt
|
97
|
-
}
|
98
|
-
end
|
99
|
-
|
100
|
-
def build_prompt
|
101
|
-
prompt = process_options[:prompt] || DEFAULT_PROMPT
|
102
|
-
ptos_list = read_response.data["ptos"]
|
103
|
-
|
104
|
-
ptos_list_formatted_string = ptos_list.join("\n")
|
105
|
-
|
106
|
-
prompt.gsub("{data}", ptos_list_formatted_string)
|
107
|
-
end
|
108
|
-
|
109
|
-
def sucess_response(response)
|
110
|
-
{ success: { notification: response.parsed_response["data"].first["content"].first["text"]["value"] } }
|
111
|
-
end
|
112
|
-
|
113
|
-
def error_response(response)
|
114
|
-
{ error: { message: response.parsed_response, status_code: response.code } }
|
115
|
-
end
|
116
|
-
end
|
117
|
-
end
|
@@ -1,96 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative "./base"
|
4
|
-
require_relative "../read/postgres"
|
5
|
-
require_relative "../write/postgres"
|
6
|
-
require_relative "../utils/discord/integration"
|
7
|
-
|
8
|
-
module Bot
|
9
|
-
##
|
10
|
-
# The Bot::NotifyDiscord class serves as a bot implementation to send messages to a
|
11
|
-
# Discord readed from a PostgresDB table.
|
12
|
-
#
|
13
|
-
# <br>
|
14
|
-
# <b>Example</b>
|
15
|
-
#
|
16
|
-
# options = {
|
17
|
-
# read_options: {
|
18
|
-
# connection: {
|
19
|
-
# host: "host",
|
20
|
-
# port: 5432,
|
21
|
-
# dbname: "bas",
|
22
|
-
# user: "postgres",
|
23
|
-
# password: "postgres"
|
24
|
-
# },
|
25
|
-
# db_table: "pto",
|
26
|
-
# tag: "HumanizePto"
|
27
|
-
# },
|
28
|
-
# process_options: {
|
29
|
-
# name: "bot name to be shown on discord",
|
30
|
-
# webhook: "discord webhook"
|
31
|
-
# },
|
32
|
-
# write_options: {
|
33
|
-
# connection: {
|
34
|
-
# host: "host",
|
35
|
-
# port: 5432,
|
36
|
-
# dbname: "bas",
|
37
|
-
# user: "postgres",
|
38
|
-
# password: "postgres"
|
39
|
-
# },
|
40
|
-
# db_table: "pto",
|
41
|
-
# tag: "NotifyDiscord"
|
42
|
-
# }
|
43
|
-
# }
|
44
|
-
#
|
45
|
-
# bot = Bot::NotifyDiscord.new(options)
|
46
|
-
# bot.execute
|
47
|
-
#
|
48
|
-
class NotifyDiscord < Bot::Base
|
49
|
-
# read function to execute the PostgresDB Read component
|
50
|
-
#
|
51
|
-
def read
|
52
|
-
reader = Read::Postgres.new(read_options.merge(conditions))
|
53
|
-
|
54
|
-
reader.execute
|
55
|
-
end
|
56
|
-
|
57
|
-
# process function to execute the Discord utility to send the PTO's notification
|
58
|
-
#
|
59
|
-
def process
|
60
|
-
return { success: {} } if unprocessable_response
|
61
|
-
|
62
|
-
response = Utils::Discord::Integration.execute(params)
|
63
|
-
|
64
|
-
if response.code == 204
|
65
|
-
{ success: {} }
|
66
|
-
else
|
67
|
-
{ error: { message: response.parsed_response, status_code: response.code } }
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
|
-
# write function to execute the PostgresDB write component
|
72
|
-
#
|
73
|
-
def write
|
74
|
-
write = Write::Postgres.new(write_options, process_response)
|
75
|
-
|
76
|
-
write.execute
|
77
|
-
end
|
78
|
-
|
79
|
-
private
|
80
|
-
|
81
|
-
def conditions
|
82
|
-
{
|
83
|
-
where: "archived=$1 AND tag=$2 AND stage=$3 ORDER BY inserted_at ASC",
|
84
|
-
params: [false, read_options[:tag], "unprocessed"]
|
85
|
-
}
|
86
|
-
end
|
87
|
-
|
88
|
-
def params
|
89
|
-
{
|
90
|
-
name: process_options[:name],
|
91
|
-
notification: read_response.data["notification"],
|
92
|
-
webhook: process_options[:webhook]
|
93
|
-
}
|
94
|
-
end
|
95
|
-
end
|
96
|
-
end
|
@@ -1,94 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative "./base"
|
4
|
-
require_relative "../read/postgres"
|
5
|
-
require_relative "../write/postgres"
|
6
|
-
require_relative "../utils/google/send_email"
|
7
|
-
|
8
|
-
module Bot
|
9
|
-
##
|
10
|
-
# The Bot::NotifyDoBillAlertEmail class serves as a bot implementation to send digital
|
11
|
-
# ocean daily bill exceeded alert emails to a recipient using a google account
|
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
|
-
# refresh_token: "email server refresh token",
|
30
|
-
# client_id: "email server client it",
|
31
|
-
# client_secret: "email server client secret",
|
32
|
-
# user_email: "sender@mail.com",
|
33
|
-
# recipient_email: "recipient@mail.com",
|
34
|
-
# threshold: "THRESHOLD"
|
35
|
-
# },
|
36
|
-
# write_options: {
|
37
|
-
# connection: {
|
38
|
-
# host: "localhost",
|
39
|
-
# port: 5432,
|
40
|
-
# dbname: "bas",
|
41
|
-
# user: "postgres",
|
42
|
-
# password: "postgres"
|
43
|
-
# },
|
44
|
-
# db_table: "do_billing",
|
45
|
-
# tag: "NotifyDoBillAlertEmail"
|
46
|
-
# }
|
47
|
-
# }
|
48
|
-
#
|
49
|
-
# bot = Bot::NotifyDoBillAlertEmail.new(options)
|
50
|
-
# bot.execute
|
51
|
-
#
|
52
|
-
class NotifyDoBillAlertEmail < Bot::Base
|
53
|
-
SUBJECT = "Digital Ocean Daily Threshold Alert"
|
54
|
-
|
55
|
-
# read function to execute the PostgresDB Read component
|
56
|
-
#
|
57
|
-
def read
|
58
|
-
reader = Read::Postgres.new(read_options.merge(conditions))
|
59
|
-
|
60
|
-
reader.execute
|
61
|
-
end
|
62
|
-
|
63
|
-
# process function to execute the Google send email utility
|
64
|
-
#
|
65
|
-
def process
|
66
|
-
return { success: {} } if unprocessable_response
|
67
|
-
|
68
|
-
response = Utils::GoogleService::SendEmail.new(params).execute
|
69
|
-
|
70
|
-
response[:error].nil? ? { success: {} } : { error: response }
|
71
|
-
end
|
72
|
-
|
73
|
-
# write function to execute the PostgresDB write component
|
74
|
-
#
|
75
|
-
def write
|
76
|
-
write = Write::Postgres.new(write_options, process_response)
|
77
|
-
|
78
|
-
write.execute
|
79
|
-
end
|
80
|
-
|
81
|
-
private
|
82
|
-
|
83
|
-
def conditions
|
84
|
-
{
|
85
|
-
where: "archived=$1 AND tag=$2 AND stage=$3 ORDER BY inserted_at ASC",
|
86
|
-
params: [false, read_options[:tag], "unprocessed"]
|
87
|
-
}
|
88
|
-
end
|
89
|
-
|
90
|
-
def params
|
91
|
-
process_options.merge({ subject: SUBJECT, message: read_response.data["notification"] })
|
92
|
-
end
|
93
|
-
end
|
94
|
-
end
|
@@ -1,96 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "httparty"
|
4
|
-
|
5
|
-
require_relative "./base"
|
6
|
-
require_relative "../read/postgres"
|
7
|
-
require_relative "../write/postgres"
|
8
|
-
require_relative "../utils/openai/run_assistant"
|
9
|
-
|
10
|
-
module Bot
|
11
|
-
##
|
12
|
-
# The Bot::ReviewDomainAvailability class serves as a bot implementation to read from a postgres
|
13
|
-
# shared storage a domain requests and review its availability.
|
14
|
-
#
|
15
|
-
# <br>
|
16
|
-
# <b>Example</b>
|
17
|
-
#
|
18
|
-
# options = {
|
19
|
-
# read_options: {
|
20
|
-
# connection: {
|
21
|
-
# host: "localhost",
|
22
|
-
# port: 5432,
|
23
|
-
# dbname: "bas",
|
24
|
-
# user: "postgres",
|
25
|
-
# password: "postgres"
|
26
|
-
# },
|
27
|
-
# db_table: "web_availability",
|
28
|
-
# tag: "ReviewDomainRequest"
|
29
|
-
# },
|
30
|
-
# write_options: {
|
31
|
-
# connection: {
|
32
|
-
# host: "localhost",
|
33
|
-
# port: 5432,
|
34
|
-
# dbname: "bas",
|
35
|
-
# user: "postgres",
|
36
|
-
# password: "postgres"
|
37
|
-
# },
|
38
|
-
# db_table: "web_availability",
|
39
|
-
# tag: "ReviewDomainAvailability"
|
40
|
-
# }
|
41
|
-
# }
|
42
|
-
#
|
43
|
-
# bot = Bot::ReviewDomainAvailability.new(options)
|
44
|
-
# bot.execute
|
45
|
-
#
|
46
|
-
class ReviewDomainAvailability < Bot::Base
|
47
|
-
# read function to execute the PostgresDB Read component
|
48
|
-
#
|
49
|
-
def read
|
50
|
-
reader = Read::Postgres.new(read_options.merge(conditions))
|
51
|
-
|
52
|
-
reader.execute
|
53
|
-
end
|
54
|
-
|
55
|
-
# process function to make a http request to the domain and check the status
|
56
|
-
#
|
57
|
-
def process
|
58
|
-
return { success: { review: nil } } if unprocessable_response
|
59
|
-
|
60
|
-
response = availability
|
61
|
-
|
62
|
-
if response.code == 200
|
63
|
-
{ success: { review: nil } }
|
64
|
-
else
|
65
|
-
{ success: { notification: notification(response) } }
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
# write function to execute the PostgresDB write component
|
70
|
-
#
|
71
|
-
def write
|
72
|
-
write = Write::Postgres.new(write_options, process_response)
|
73
|
-
|
74
|
-
write.execute
|
75
|
-
end
|
76
|
-
|
77
|
-
private
|
78
|
-
|
79
|
-
def conditions
|
80
|
-
{
|
81
|
-
where: "archived=$1 AND tag=$2 AND stage=$3 ORDER BY inserted_at ASC",
|
82
|
-
params: [false, read_options[:tag], "unprocessed"]
|
83
|
-
}
|
84
|
-
end
|
85
|
-
|
86
|
-
def availability
|
87
|
-
url = read_response.data["url"]
|
88
|
-
|
89
|
-
HTTParty.get(url, {})
|
90
|
-
end
|
91
|
-
|
92
|
-
def notification(response)
|
93
|
-
":warning: The Domain #{read_response.data["url"]} is down with an error code of #{response.code}"
|
94
|
-
end
|
95
|
-
end
|
96
|
-
end
|