bas 1.1.2 → 1.2.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/Gemfile +3 -0
- data/lib/bas/bot/fetch_billing_from_digital_ocean.rb +77 -0
- data/lib/bas/bot/format_do_bill_alert.rb +103 -0
- data/lib/bas/bot/notify_do_bill_alert_email.rb +94 -0
- data/lib/bas/bot/write_media_review_in_notion.rb +15 -1
- data/lib/bas/bot/write_media_review_requests.rb +16 -0
- data/lib/bas/utils/digital_ocean/request.rb +43 -0
- data/lib/bas/utils/google/send_email.rb +72 -0
- data/lib/bas/utils/notion/update_db_state.rb +45 -0
- data/lib/bas/version.rb +1 -1
- metadata +38 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 595076237d4e4862f9aa5c615bae73312ba412f953549d2e426b3166c36608cc
|
4
|
+
data.tar.gz: 221686b0a213c00a3bf1973963c2b3871ad24861f8f90f6095fb498c51de287c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: '083d7414310b342bdc27c5be5bd44fa7ba347e070081c47bd784c92bbb8a524181aa086b1912ef876bd90c6679203e7818b5a58205ca352a5f127e85435e75e9'
|
7
|
+
data.tar.gz: d1f183178454b2b2a8883862a1dbaff9a6be69f83520d45ae02f0a35ae9027647118f89cbff85287c4597639b1942b7454b45c9e4b2efc84085de53990b8893a
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,11 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
# 1.2.0 (12.07.2024)
|
4
|
+
- [Add bots to process digital ocean billing checker](https://github.com/kommitters/bas/issues/78)
|
5
|
+
|
6
|
+
# 1.1.3 (08.07.2024)
|
7
|
+
- [Update write media request to set in process](https://github.com/kommitters/bas/issues/76)
|
8
|
+
|
3
9
|
# 1.1.2 (03.07.2024)
|
4
10
|
- [Add gem dependencies to the specification file](https://github.com/kommitters/bas/issues/72)
|
5
11
|
|
data/Gemfile
CHANGED
@@ -0,0 +1,77 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "./base"
|
4
|
+
require_relative "../read/default"
|
5
|
+
require_relative "../utils/digital_ocean/request"
|
6
|
+
require_relative "../write/postgres"
|
7
|
+
|
8
|
+
module Bot
|
9
|
+
##
|
10
|
+
# The Bot::FetchBillingFromDigitalOcean class serves as a bot implementation to read digital
|
11
|
+
# ocean current billing using the DigitalOcean API
|
12
|
+
#
|
13
|
+
# <br>
|
14
|
+
# <b>Example</b>
|
15
|
+
#
|
16
|
+
# options = {
|
17
|
+
# process_options: {
|
18
|
+
# secret: "digital_ocean_secret_key"
|
19
|
+
# },
|
20
|
+
# write_options: {
|
21
|
+
# connection: {
|
22
|
+
# host: "host",
|
23
|
+
# port: 5432,
|
24
|
+
# dbname: "bas",
|
25
|
+
# user: "postgres",
|
26
|
+
# password: "postgres"
|
27
|
+
# },
|
28
|
+
# db_table: "use_cases",
|
29
|
+
# tag: "FetchBillingFromDigitalOcean"
|
30
|
+
# }
|
31
|
+
# }
|
32
|
+
#
|
33
|
+
# bot = Bot::FetchBillingFromDigitalOcean.new(options)
|
34
|
+
# bot.execute
|
35
|
+
#
|
36
|
+
class FetchBillingFromDigitalOcean < Bot::Base
|
37
|
+
# Read function to execute the default Read component
|
38
|
+
#
|
39
|
+
def read
|
40
|
+
reader = Read::Default.new
|
41
|
+
|
42
|
+
reader.execute
|
43
|
+
end
|
44
|
+
|
45
|
+
# Process function to execute the DigitalOcean utility to fetch bills
|
46
|
+
#
|
47
|
+
def process
|
48
|
+
response = Utils::DigitalOcean::Request.execute(params)
|
49
|
+
|
50
|
+
if response.code == 200
|
51
|
+
|
52
|
+
{ success: { billing: response.parsed_response } }
|
53
|
+
else
|
54
|
+
{ error: { message: response.parsed_response, status_code: response.code } }
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
# Write function to execute the PostgresDB write component
|
59
|
+
#
|
60
|
+
def write
|
61
|
+
write = Write::Postgres.new(write_options, process_response)
|
62
|
+
|
63
|
+
write.execute
|
64
|
+
end
|
65
|
+
|
66
|
+
private
|
67
|
+
|
68
|
+
def params
|
69
|
+
{
|
70
|
+
endpoint: "customers/my/balance",
|
71
|
+
secret: process_options[:secret],
|
72
|
+
method: "get",
|
73
|
+
body: {}
|
74
|
+
}
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,103 @@
|
|
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
|
+
daily_usage > process_options[:threshold]
|
83
|
+
end
|
84
|
+
|
85
|
+
def daily_usage
|
86
|
+
balance = read_response.data["billing"]["month_to_date_balance"].to_f
|
87
|
+
day_of_month = Time.now.utc.mday
|
88
|
+
|
89
|
+
balance / day_of_month
|
90
|
+
end
|
91
|
+
|
92
|
+
def message
|
93
|
+
balance = read_response.data["billing"]["month_to_date_balance"]
|
94
|
+
threshold = process_options[:threshold]
|
95
|
+
|
96
|
+
"""The daily usage was exceeded.
|
97
|
+
Current balance: #{balance}
|
98
|
+
Threshold: #{threshold}
|
99
|
+
Expected daily usage: #{daily_usage.round(3)}
|
100
|
+
"""
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
@@ -0,0 +1,94 @@
|
|
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
|
@@ -5,6 +5,7 @@ require "json"
|
|
5
5
|
require_relative "./base"
|
6
6
|
require_relative "../read/postgres"
|
7
7
|
require_relative "../utils/notion/request"
|
8
|
+
require_relative "../utils/notion/update_db_state"
|
8
9
|
require_relative "../write/postgres"
|
9
10
|
|
10
11
|
module Bot
|
@@ -47,7 +48,7 @@ module Bot
|
|
47
48
|
# bot.execute
|
48
49
|
#
|
49
50
|
class WriteMediaReviewInNotion < Bot::Base
|
50
|
-
|
51
|
+
READY_STATE = "ready"
|
51
52
|
|
52
53
|
# read function to execute the PostgresDB Read component
|
53
54
|
#
|
@@ -65,6 +66,8 @@ module Bot
|
|
65
66
|
response = Utils::Notion::Request.execute(params)
|
66
67
|
|
67
68
|
if response.code == 200
|
69
|
+
update_state
|
70
|
+
|
68
71
|
{ success: { page_id: read_response.data["page_id"], property: read_response.data["property"] } }
|
69
72
|
else
|
70
73
|
{ error: { message: response.parsed_response, status_code: response.code } }
|
@@ -128,5 +131,16 @@ module Bot
|
|
128
131
|
when "paragraph" then "Text review results/"
|
129
132
|
end
|
130
133
|
end
|
134
|
+
|
135
|
+
def update_state
|
136
|
+
data = {
|
137
|
+
property: read_response.data["property"],
|
138
|
+
page_id: read_response.data["page_id"],
|
139
|
+
state: READY_STATE,
|
140
|
+
secret: process_options[:secret]
|
141
|
+
}
|
142
|
+
|
143
|
+
Utils::Notion::UpdateDbState.execute(data)
|
144
|
+
end
|
131
145
|
end
|
132
146
|
end
|
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
require_relative "./base"
|
4
4
|
require_relative "../read/postgres"
|
5
|
+
require_relative "../utils/notion/update_db_state"
|
5
6
|
require_relative "../write/postgres"
|
6
7
|
|
7
8
|
module Bot
|
@@ -53,6 +54,8 @@ module Bot
|
|
53
54
|
# bot.execute
|
54
55
|
#
|
55
56
|
class WriteMediaReviewRequests < Bot::Base
|
57
|
+
IN_PROCESS_STATE = "in process"
|
58
|
+
|
56
59
|
# read function to execute the PostgresDB Read component
|
57
60
|
#
|
58
61
|
def read
|
@@ -97,7 +100,20 @@ module Bot
|
|
97
100
|
def write_request(request)
|
98
101
|
return { error: request } if request["media"].empty? || !request["error"].nil?
|
99
102
|
|
103
|
+
update_state(request)
|
104
|
+
|
100
105
|
{ success: request }
|
101
106
|
end
|
107
|
+
|
108
|
+
def update_state(request)
|
109
|
+
data = {
|
110
|
+
property: request["property"],
|
111
|
+
page_id: request["page_id"],
|
112
|
+
state: IN_PROCESS_STATE,
|
113
|
+
secret: process_options[:secret]
|
114
|
+
}
|
115
|
+
|
116
|
+
Utils::Notion::UpdateDbState.execute(data)
|
117
|
+
end
|
102
118
|
end
|
103
119
|
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "httparty"
|
4
|
+
require "json"
|
5
|
+
|
6
|
+
module Utils
|
7
|
+
module DigitalOcean
|
8
|
+
##
|
9
|
+
# This module is a Notion utility for sending request to create, update, or delete
|
10
|
+
# Notion resources.
|
11
|
+
#
|
12
|
+
module Request
|
13
|
+
DIGITAL_OCEAN_BASE_URL = "https://api.digitalocean.com/v2"
|
14
|
+
|
15
|
+
# Implements the request process logic to Notion.
|
16
|
+
#
|
17
|
+
# <br>
|
18
|
+
# <b>Params:</b>
|
19
|
+
# * <tt>method</tt> HTTP request method: post, get, put, etc.
|
20
|
+
# * <tt>body</tt> Request body (Hash).
|
21
|
+
# * <tt>endpoint</tt> Notion resource endpoint.
|
22
|
+
# * <tt>secret</tt> Notion secret.
|
23
|
+
#
|
24
|
+
# <br>
|
25
|
+
# <b>returns</b> <tt>HTTParty::Response</tt>
|
26
|
+
#
|
27
|
+
def self.execute(params)
|
28
|
+
url = "#{DIGITAL_OCEAN_BASE_URL}/#{params[:endpoint]}"
|
29
|
+
|
30
|
+
headers = headers(params[:secret])
|
31
|
+
|
32
|
+
HTTParty.send(params[:method], url, { body: params[:body].to_json, headers: })
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.headers(secret)
|
36
|
+
{
|
37
|
+
"Authorization" => "Bearer #{secret}",
|
38
|
+
"Content-Type" => "application/json"
|
39
|
+
}
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "google/apis/gmail_v1"
|
4
|
+
require "googleauth"
|
5
|
+
|
6
|
+
module Utils
|
7
|
+
module GoogleService
|
8
|
+
##
|
9
|
+
# This module is a Google service utility to send emails from a google account
|
10
|
+
#
|
11
|
+
class SendEmail
|
12
|
+
SCOPES = ["https://mail.google.com/", "https://www.googleapis.com/auth/gmail.send"].freeze
|
13
|
+
CONTENT_TYPE = "message/rfc822"
|
14
|
+
|
15
|
+
def initialize(params)
|
16
|
+
@refresh_token = params[:refresh_token]
|
17
|
+
@client_id = params[:client_id]
|
18
|
+
@client_secret = params[:client_secret]
|
19
|
+
@user_email = params[:user_email]
|
20
|
+
@recipient_email = params[:recipient_email]
|
21
|
+
@subject = params[:subject]
|
22
|
+
@message = params[:message]
|
23
|
+
end
|
24
|
+
|
25
|
+
def execute
|
26
|
+
{ send_email: }
|
27
|
+
rescue StandardError => e
|
28
|
+
{ error: e.to_s }
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def send_email
|
34
|
+
service = Google::Apis::GmailV1::GmailService.new
|
35
|
+
|
36
|
+
service.authorization = access_token
|
37
|
+
|
38
|
+
service.send_user_message(@user_email, upload_source:, content_type: CONTENT_TYPE)
|
39
|
+
end
|
40
|
+
|
41
|
+
def upload_source
|
42
|
+
message = <<~END_OF_MESSAGE
|
43
|
+
From: me
|
44
|
+
To: #{@recipient_email.join(",")}
|
45
|
+
Subject: #{@subject}
|
46
|
+
MIME-Version: 1.0
|
47
|
+
Content-Type: text/plain; charset=UTF-8
|
48
|
+
|
49
|
+
#{@message}
|
50
|
+
END_OF_MESSAGE
|
51
|
+
|
52
|
+
StringIO.new(message)
|
53
|
+
end
|
54
|
+
|
55
|
+
def access_token
|
56
|
+
client = Google::Auth::UserRefreshCredentials.new(auth_params)
|
57
|
+
|
58
|
+
client.fetch_access_token!
|
59
|
+
client.access_token
|
60
|
+
end
|
61
|
+
|
62
|
+
def auth_params
|
63
|
+
{
|
64
|
+
client_id: @client_id,
|
65
|
+
client_secret: @client_secret,
|
66
|
+
refresh_token: @refresh_token,
|
67
|
+
scope: SCOPES
|
68
|
+
}
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "httparty"
|
4
|
+
require_relative "request"
|
5
|
+
|
6
|
+
module Utils
|
7
|
+
module Notion
|
8
|
+
##
|
9
|
+
# This module is a Notion utility for sending update status to notion databases.
|
10
|
+
#
|
11
|
+
module UpdateDbState
|
12
|
+
# Implements the request process logic to Notion.
|
13
|
+
#
|
14
|
+
# <br>
|
15
|
+
# <b>Params:</b>
|
16
|
+
# * <tt>property</tt> Name of the db property to be updated.
|
17
|
+
# * <tt>page_id</tt> Id of the page to be updated.
|
18
|
+
# * <tt>state</tt> State to be updated
|
19
|
+
# * <tt>secret</tt> Notion secret.
|
20
|
+
#
|
21
|
+
# <br>
|
22
|
+
# <b>returns</b> <tt>HTTParty::Response</tt>
|
23
|
+
#
|
24
|
+
|
25
|
+
def self.execute(data)
|
26
|
+
params = build_params(data)
|
27
|
+
|
28
|
+
Utils::Notion::Request.execute(params)
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.build_params(data)
|
32
|
+
{
|
33
|
+
endpoint: "pages/#{data[:page_id]}",
|
34
|
+
secret: data[:secret],
|
35
|
+
method: "patch",
|
36
|
+
body: body(data)
|
37
|
+
}
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.body(data)
|
41
|
+
{ properties: { data[:property] => { select: { name: data[:state] } } } }
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
data/lib/bas/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bas
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.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-07-
|
11
|
+
date: 2024-07-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: gmail_xoauth
|
@@ -16,14 +16,42 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 0.4.
|
19
|
+
version: 0.4.1
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 0.4.
|
26
|
+
version: 0.4.1
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: google-api-client
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0.53'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0.53'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: googleauth
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.11'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.11'
|
27
55
|
- !ruby/object:Gem::Dependency
|
28
56
|
name: httparty
|
29
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -159,6 +187,7 @@ files:
|
|
159
187
|
- lib/bas.rb
|
160
188
|
- lib/bas/bot/base.rb
|
161
189
|
- lib/bas/bot/compare_wip_limit_count.rb
|
190
|
+
- lib/bas/bot/fetch_billing_from_digital_ocean.rb
|
162
191
|
- lib/bas/bot/fetch_birthdays_from_notion.rb
|
163
192
|
- lib/bas/bot/fetch_domains_wip_counts_from_notion.rb
|
164
193
|
- lib/bas/bot/fetch_domains_wip_limit_from_notion.rb
|
@@ -168,11 +197,13 @@ files:
|
|
168
197
|
- lib/bas/bot/fetch_next_week_ptos_from_notion.rb
|
169
198
|
- lib/bas/bot/fetch_ptos_from_notion.rb
|
170
199
|
- lib/bas/bot/format_birthdays.rb
|
200
|
+
- lib/bas/bot/format_do_bill_alert.rb
|
171
201
|
- lib/bas/bot/format_emails.rb
|
172
202
|
- lib/bas/bot/format_wip_limit_exceeded.rb
|
173
203
|
- lib/bas/bot/garbage_collector.rb
|
174
204
|
- lib/bas/bot/humanize_pto.rb
|
175
205
|
- lib/bas/bot/notify_discord.rb
|
206
|
+
- lib/bas/bot/notify_do_bill_alert_email.rb
|
176
207
|
- lib/bas/bot/review_media.rb
|
177
208
|
- lib/bas/bot/update_review_media_state.rb
|
178
209
|
- lib/bas/bot/write_media_review_in_notion.rb
|
@@ -181,11 +212,14 @@ files:
|
|
181
212
|
- lib/bas/read/default.rb
|
182
213
|
- lib/bas/read/postgres.rb
|
183
214
|
- lib/bas/read/types/response.rb
|
215
|
+
- lib/bas/utils/digital_ocean/request.rb
|
184
216
|
- lib/bas/utils/discord/integration.rb
|
185
217
|
- lib/bas/utils/exceptions/function_not_implemented.rb
|
186
218
|
- lib/bas/utils/exceptions/invalid_process_response.rb
|
219
|
+
- lib/bas/utils/google/send_email.rb
|
187
220
|
- lib/bas/utils/imap/request.rb
|
188
221
|
- lib/bas/utils/notion/request.rb
|
222
|
+
- lib/bas/utils/notion/update_db_state.rb
|
189
223
|
- lib/bas/utils/openai/run_assistant.rb
|
190
224
|
- lib/bas/utils/postgres/request.rb
|
191
225
|
- lib/bas/version.rb
|