bas 1.5.3 → 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.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +3 -0
  3. data/README.md +92 -50
  4. data/lib/bas/bot/base.rb +37 -54
  5. data/lib/bas/shared_storage/base.rb +35 -0
  6. data/lib/bas/shared_storage/default.rb +18 -0
  7. data/lib/bas/shared_storage/postgres.rb +95 -0
  8. data/lib/bas/shared_storage/types/read.rb +22 -0
  9. data/lib/bas/utils/openai/run_assistant.rb +1 -0
  10. data/lib/bas/utils/postgres/request.rb +3 -1
  11. data/lib/bas/version.rb +1 -1
  12. metadata +8 -41
  13. data/lib/bas/bot/compare_wip_limit_count.rb +0 -92
  14. data/lib/bas/bot/create_work_item.rb +0 -142
  15. data/lib/bas/bot/fetch_billing_from_digital_ocean.rb +0 -87
  16. data/lib/bas/bot/fetch_birthdays_from_notion.rb +0 -128
  17. data/lib/bas/bot/fetch_domain_services_from_notion.rb +0 -93
  18. data/lib/bas/bot/fetch_domains_wip_counts_from_notion.rb +0 -121
  19. data/lib/bas/bot/fetch_domains_wip_limit_from_notion.rb +0 -134
  20. data/lib/bas/bot/fetch_emails_from_imap.rb +0 -99
  21. data/lib/bas/bot/fetch_github_issues.rb +0 -147
  22. data/lib/bas/bot/fetch_images_from_discord.rb +0 -78
  23. data/lib/bas/bot/fetch_media_from_notion.rb +0 -186
  24. data/lib/bas/bot/fetch_next_week_birthdays_from_notion.rb +0 -142
  25. data/lib/bas/bot/fetch_next_week_ptos_from_notion.rb +0 -197
  26. data/lib/bas/bot/fetch_ptos_from_notion.rb +0 -160
  27. data/lib/bas/bot/format_birthdays.rb +0 -97
  28. data/lib/bas/bot/format_do_bill_alert.rb +0 -108
  29. data/lib/bas/bot/format_emails.rb +0 -124
  30. data/lib/bas/bot/format_wip_limit_exceeded.rb +0 -97
  31. data/lib/bas/bot/garbage_collector.rb +0 -85
  32. data/lib/bas/bot/humanize_pto.rb +0 -117
  33. data/lib/bas/bot/notify_discord.rb +0 -96
  34. data/lib/bas/bot/notify_do_bill_alert_email.rb +0 -94
  35. data/lib/bas/bot/review_domain_availability.rb +0 -96
  36. data/lib/bas/bot/review_media.rb +0 -139
  37. data/lib/bas/bot/update_review_media_state.rb +0 -102
  38. data/lib/bas/bot/update_work_item.rb +0 -181
  39. data/lib/bas/bot/verify_issue_existance_in_notion.rb +0 -131
  40. data/lib/bas/bot/write_domain_review_requests.rb +0 -104
  41. data/lib/bas/bot/write_media_review_in_discord.rb +0 -98
  42. data/lib/bas/bot/write_media_review_requests.rb +0 -104
  43. data/lib/bas/read/base.rb +0 -30
  44. data/lib/bas/read/default.rb +0 -16
  45. data/lib/bas/read/postgres.rb +0 -44
  46. data/lib/bas/read/types/response.rb +0 -18
  47. data/lib/bas/write/base.rb +0 -31
  48. data/lib/bas/write/postgres.rb +0 -45
  49. data/lib/bas/write/postgres_update.rb +0 -49
@@ -1,139 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "json"
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::ReviewMedia class serves as a bot implementation to read from a postgres
13
- # shared storage a images hash with a specific format and create single request
14
- # on the shared storage to be processed one by one.
15
- #
16
- # <br>
17
- # <b>Example</b>
18
- #
19
- # options = {
20
- # read_options: {
21
- # connection: {
22
- # host: "localhost",
23
- # port: 5432,
24
- # dbname: "bas",
25
- # user: "postgres",
26
- # password: "postgres"
27
- # },
28
- # db_table: "review_media",
29
- # tag: "ReviewMediaRequest"
30
- # },
31
- # process_options: {
32
- # secret: "openai_secret",
33
- # assistant_id: "openai_assistant_id",
34
- # media_type: "images"
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: "review_media",
45
- # tag: "ReviewText"
46
- # }
47
- # }
48
- #
49
- # bot = Bot::ReviewMedia.new(options)
50
- # bot.execute
51
- #
52
- class ReviewMedia < Bot::Base
53
- DETAIL = "low"
54
- # read function to execute the PostgresDB Read component
55
- #
56
- def read
57
- reader = Read::Postgres.new(read_options.merge(conditions))
58
-
59
- reader.execute
60
- end
61
-
62
- # process function to execute the OpenaAI utility to process the media reviews
63
- #
64
- def process
65
- return { success: { review: nil } } if unprocessable_response
66
-
67
- response = Utils::OpenAI::RunAssitant.execute(params)
68
-
69
- if response.code != 200 || (!response["status"].nil? && response["status"] != "completed")
70
- return error_response(response)
71
- end
72
-
73
- success_response(response)
74
- end
75
-
76
- # write function to execute the PostgresDB write component
77
- #
78
- def write
79
- write = Write::Postgres.new(write_options, process_response)
80
-
81
- write.execute
82
- end
83
-
84
- private
85
-
86
- def conditions
87
- {
88
- where: "archived=$1 AND tag=$2 AND stage=$3 ORDER BY inserted_at ASC",
89
- params: [false, read_options[:tag], "unprocessed"]
90
- }
91
- end
92
-
93
- def params
94
- {
95
- assistant_id: process_options[:assistant_id],
96
- secret: process_options[:secret],
97
- prompt: build_prompt
98
- }
99
- end
100
-
101
- def build_prompt
102
- case process_options[:media_type]
103
- when "images" then images_media
104
- when "paragraph" then text_media
105
- end
106
- end
107
-
108
- def images_media
109
- read_response.data["media"].map { |url| { type: "image_url", image_url: { url:, detail: DETAIL } } }
110
- end
111
-
112
- def text_media
113
- read_response.data["media"]
114
- end
115
-
116
- def success_response(response)
117
- review = get_review(response)
118
- { success: media_hash.merge({ review: }) }
119
- end
120
-
121
- def get_review(response)
122
- response.parsed_response["data"].first["content"].first["text"]["value"]
123
- end
124
-
125
- def media_hash
126
- {
127
- message_id: read_response.data["message_id"],
128
- channel_id: read_response.data["channel_id"],
129
- property: read_response.data["property"],
130
- author: read_response.data["author"],
131
- media_type: process_options[:media_type]
132
- }
133
- end
134
-
135
- def error_response(response)
136
- { error: { message: response.parsed_response, status_code: response.code } }
137
- end
138
- end
139
- end
@@ -1,102 +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::UpdateReviewMediaStatus class serves as a bot implementation to read from a postgres
11
- # shared storage updated status and update a parameter on a Notion database.
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: "review_media",
26
- # tag: "WriteMediaReviewInNotion"
27
- # },
28
- # process_options: {
29
- # secret: "notion_secret"
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: "review_media",
40
- # tag: "UpdateReviewMediaStatus"
41
- # }
42
- # }
43
- #
44
- # bot = Bot::UpdateReviewMediaStatus.new(options)
45
- # bot.execute
46
- #
47
- class UpdateReviewMediaStatus < Bot::Base
48
- READY_STATE = "ready"
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 execute the Notion utility to update a Notion database property
59
- #
60
- def process
61
- return { success: { status_updated: nil } } if unprocessable_response
62
-
63
- response = Utils::Notion::Request.execute(params)
64
-
65
- if response.code == 200
66
- { success: { status_updated: true } }
67
- else
68
- { error: { message: response.parsed_response, status_code: response.code } }
69
- end
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 params
90
- {
91
- endpoint: "pages/#{read_response.data["page_id"]}",
92
- secret: process_options[:secret],
93
- method: "patch",
94
- body:
95
- }
96
- end
97
-
98
- def body
99
- { properties: { read_response.data["property"] => { select: { name: READY_STATE } } } }
100
- end
101
- end
102
- end
@@ -1,181 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "json"
4
- require "md_to_notion"
5
-
6
- require_relative "./base"
7
- require_relative "../read/postgres"
8
- require_relative "../utils/notion/request"
9
- require_relative "../utils/notion/types"
10
- require_relative "../utils/notion/delete_page_blocks"
11
- require_relative "../utils/notion/fetch_database_record"
12
- require_relative "../utils/notion/update_db_page"
13
- require_relative "../write/postgres"
14
-
15
- module Bot
16
- ##
17
- # The Bot::UpdateWorkItem class serves as a bot implementation to update "work items" on a
18
- # notion database using information of a GitHub issue.
19
- #
20
- # <br>
21
- # <b>Example</b>
22
- #
23
- # options = {
24
- # read_options: {
25
- # connection: {
26
- # host: "localhost",
27
- # port: 5432,
28
- # dbname: "bas",
29
- # user: "postgres",
30
- # password: "postgres"
31
- # },
32
- # db_table: "github_issues",
33
- # tag: "UpdateWorkItemRequest"
34
- # },
35
- # process_options: {
36
- # secret: "notion secret"
37
- # },
38
- # write_options: {
39
- # connection: {
40
- # host: "localhost",
41
- # port: 5432,
42
- # dbname: "bas",
43
- # user: "postgres",
44
- # password: "postgres"
45
- # },
46
- # db_table: "github_issues",
47
- # tag: "UpdateWorkItem"
48
- # }
49
- # }
50
- #
51
- # bot = Bot::UpdateWorkItem.new(options)
52
- # bot.execute
53
- #
54
- class UpdateWorkItem < Bot::Base
55
- include Utils::Notion::Types
56
-
57
- DESCRIPTION = "Issue Description"
58
- GITHUB_COLUMN = "Username"
59
-
60
- # read function to execute the PostgresDB Read component
61
- #
62
- def read
63
- reader = Read::Postgres.new(read_options.merge(conditions))
64
-
65
- reader.execute
66
- end
67
-
68
- # process function to execute the Notion utility to update work items on a notion
69
- # database
70
- def process
71
- return { success: { updated: nil } } if unprocessable_response
72
-
73
- response = process_wi
74
-
75
- if response.code == 200
76
- update_assigness
77
-
78
- { success: { issue: read_response.data["issue"] } }
79
- else
80
- { error: { message: response.parsed_response, status_code: response.code } }
81
- end
82
- end
83
-
84
- # write function to execute the PostgresDB write component
85
- #
86
- def write
87
- write = Write::Postgres.new(write_options, process_response)
88
-
89
- write.execute
90
- end
91
-
92
- private
93
-
94
- def conditions
95
- {
96
- where: "archived=$1 AND tag=$2 AND stage=$3 ORDER BY inserted_at ASC",
97
- params: [false, read_options[:tag], "unprocessed"]
98
- }
99
- end
100
-
101
- def process_wi
102
- delete_wi
103
-
104
- Utils::Notion::Request.execute(params)
105
- end
106
-
107
- def params
108
- {
109
- endpoint: "blocks/#{read_response.data["notion_wi"]}/children",
110
- secret: process_options[:secret],
111
- method: "patch",
112
- body:
113
- }
114
- end
115
-
116
- def body
117
- { children: description + [issue_reference] }
118
- end
119
-
120
- def description
121
- MdToNotion::Parser.markdown_to_notion_blocks(read_response.data["issue"]["body"])
122
- end
123
-
124
- def issue_reference
125
- {
126
- object: "block",
127
- type: "paragraph",
128
- paragraph: rich_text("issue", read_response.data["issue"]["html_url"])
129
- }
130
- end
131
-
132
- def delete_wi
133
- options = {
134
- page_id: read_response.data["notion_wi"],
135
- secret: process_options[:secret]
136
- }
137
-
138
- Utils::Notion::DeletePageBlocks.new(options).execute
139
- end
140
-
141
- def update_assigness
142
- relation = users.map { |user| user_id(user) }
143
-
144
- options = {
145
- page_id: read_response.data["notion_wi"],
146
- secret: process_options[:secret],
147
- body: { properties: { People: { relation: } }.merge(status) }
148
- }
149
-
150
- Utils::Notion::UpdateDatabasePage.new(options).execute
151
- end
152
-
153
- def users
154
- options = {
155
- database_id: process_options[:users_database_id],
156
- secret: process_options[:secret],
157
- body: { filter: { or: github_usernames } }
158
- }
159
-
160
- Utils::Notion::FetchDatabaseRecord.new(options).execute
161
- end
162
-
163
- def github_usernames
164
- read_response.data["issue"]["assignees"].map do |username|
165
- { property: GITHUB_COLUMN, rich_text: { equals: username } }
166
- end
167
- end
168
-
169
- def user_id(user)
170
- relation = user.dig("properties", "People", "relation")
171
-
172
- relation.nil? ? {} : relation.first
173
- end
174
-
175
- def status
176
- return {} unless read_response.data["issue"]["state"] == "closed"
177
-
178
- { Status: { status: { name: "Done" } } }
179
- end
180
- end
181
- end
@@ -1,131 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "json"
4
-
5
- require_relative "./base"
6
- require_relative "../read/postgres"
7
- require_relative "../utils/notion/request"
8
- require_relative "../utils/notion/update_db_state"
9
- require_relative "../write/postgres"
10
-
11
- module Bot
12
- ##
13
- # The Bot::VerifyIssueExistanceInNotion class serves as a bot implementation to verify if a
14
- # GitHub issue was already created on a notion database base on a column with the issue id.
15
- #
16
- # <br>
17
- # <b>Example</b>
18
- #
19
- # options = {
20
- # read_options: {
21
- # connection: {
22
- # host: "localhost",
23
- # port: 5432,
24
- # dbname: "bas",
25
- # user: "postgres",
26
- # password: "postgres"
27
- # },
28
- # db_table: "github_issues",
29
- # tag: "GithubIssueRequest"
30
- # },
31
- # process_options: {
32
- # database_id: "notion database id",
33
- # secret: "notion secret"
34
- # },
35
- # write_options: {
36
- # connection: {
37
- # host: "localhost",
38
- # port: 5432,
39
- # dbname: "bas",
40
- # user: "postgres",
41
- # password: "postgres"
42
- # },
43
- # db_table: "github_issues",
44
- # tag: "VerifyIssueExistanceInNotio"
45
- # }
46
- # }
47
- #
48
- # bot = Bot::VerifyIssueExistanceInNotion.new(options)
49
- # bot.execute
50
- #
51
- class VerifyIssueExistanceInNotion < Bot::Base
52
- NOT_FOUND = "not found"
53
- NOTION_PROPERTY = "Github Issue Id"
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 Notion utility to verify GitHub issues existance
64
- # on a notion database
65
- #
66
- def process
67
- return { success: { issue: nil } } if unprocessable_response
68
-
69
- response = Utils::Notion::Request.execute(params)
70
-
71
- if response.code == 200
72
- result = response.parsed_response["results"].first
73
-
74
- { success: read_response.data.merge({ notion_wi: notion_wi_id(result) }) }
75
- else
76
- { error: { message: response.parsed_response, status_code: response.code } }
77
- end
78
- end
79
-
80
- # write function to execute the PostgresDB write component
81
- #
82
- def write
83
- options = write_options.merge({ tag: })
84
-
85
- write = Write::Postgres.new(options, process_response)
86
-
87
- write.execute
88
- end
89
-
90
- private
91
-
92
- def conditions
93
- {
94
- where: "archived=$1 AND tag=$2 AND stage=$3 ORDER BY inserted_at ASC",
95
- params: [false, read_options[:tag], "unprocessed"]
96
- }
97
- end
98
-
99
- def params
100
- {
101
- endpoint: "databases/#{process_options[:database_id]}/query",
102
- secret: process_options[:secret],
103
- method: "post",
104
- body:
105
- }
106
- end
107
-
108
- def body
109
- {
110
- filter: {
111
- property: NOTION_PROPERTY,
112
- rich_text: { equals: read_response.data["issue"]["id"].to_s }
113
- }
114
- }
115
- end
116
-
117
- def notion_wi_id(result)
118
- return NOT_FOUND if result.nil?
119
-
120
- result["id"]
121
- end
122
-
123
- def tag
124
- issue = process_response[:success]
125
-
126
- return write_options[:tag] if issue.nil? || issue[:notion_wi].nil?
127
-
128
- issue[:notion_wi].eql?(NOT_FOUND) ? "CreateWorkItemRequest" : "UpdateWorkItemRequest"
129
- end
130
- end
131
- end
@@ -1,104 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative "./base"
4
- require_relative "../read/postgres"
5
- require_relative "../utils/notion/update_db_state"
6
- require_relative "../write/postgres"
7
-
8
- module Bot
9
- ##
10
- # The Bot::WriteDomainReviewRequests class serves as a bot implementation to read from a postgres
11
- # shared storage a set of review domain requests and create single request on the shared storage to
12
- # be processed one by one.
13
- #
14
- # <br>
15
- # <b>Example</b>
16
- #
17
- # options = {
18
- # read_options: {
19
- # connection: {
20
- # host: "localhost",
21
- # port: 5432,
22
- # dbname: "bas",
23
- # user: "postgres",
24
- # password: "postgres"
25
- # },
26
- # db_table: "web_availability",
27
- # tag: "FetchDomainServicesFromNotion"
28
- # },
29
- # process_options: {
30
- # connection: {
31
- # host: "localhost",
32
- # port: 5432,
33
- # dbname: "bas",
34
- # user: "postgres",
35
- # password: "postgres"
36
- # },
37
- # db_table: "web_availability",
38
- # tag: "ReviewDomainRequest"
39
- # },
40
- # write_options: {
41
- # connection: {
42
- # host: "localhost",
43
- # port: 5432,
44
- # dbname: "bas",
45
- # user: "postgres",
46
- # password: "postgres"
47
- # },
48
- # db_table: "web_availability",
49
- # tag: "WriteDomainReviewRequests"
50
- # }
51
- # }
52
- #
53
- # bot = Bot::WriteDomainReviewRequests.new(options)
54
- # bot.execute
55
- #
56
- class WriteDomainReviewRequests < Bot::Base
57
- # read function to execute the PostgresDB Read component
58
- #
59
- def read
60
- reader = Read::Postgres.new(read_options.merge(conditions))
61
-
62
- reader.execute
63
- end
64
-
65
- # Process function to execute the Notion utility create single review requests
66
- #
67
- def process
68
- return { success: { created: nil } } if unprocessable_response
69
-
70
- read_response.data["urls"].each { |request| create_request(request) }
71
-
72
- { success: { created: true } }
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 create_request(request)
93
- write_data = write_request(request)
94
-
95
- Write::Postgres.new(process_options, write_data).execute
96
- end
97
-
98
- def write_request(request)
99
- return { error: request } if request["url"].empty? || !request["error"].nil?
100
-
101
- { success: request }
102
- end
103
- end
104
- end