bas 0.3.1 → 0.4.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/.rubocop.yml +1 -1
- data/CHANGELOG.md +3 -0
- data/CONTRIBUTING.md +9 -0
- data/lib/bas/domain/notification.rb +23 -0
- data/lib/bas/formatter/notification.rb +34 -0
- data/lib/bas/process/discord/implementation.rb +1 -1
- data/lib/bas/process/openai/base.rb +72 -0
- data/lib/bas/process/openai/helper.rb +19 -0
- data/lib/bas/process/openai/types/response.rb +27 -0
- data/lib/bas/process/openai/use_case/humanize_pto.rb +53 -0
- data/lib/bas/process/slack/implementation.rb +1 -1
- data/lib/bas/read/github/types/response.rb +1 -1
- data/lib/bas/read/imap/types/response.rb +1 -1
- data/lib/bas/read/notion/base.rb +1 -1
- data/lib/bas/read/notion/helper.rb +1 -1
- data/lib/bas/read/notion/types/response.rb +1 -1
- data/lib/bas/read/notion/use_case/notification.rb +28 -0
- data/lib/bas/read/notion/use_case/pto_next_week.rb +2 -2
- data/lib/bas/read/postgres/helper.rb +1 -1
- data/lib/bas/read/postgres/types/response.rb +1 -1
- data/lib/bas/serialize/notion/notification.rb +56 -0
- data/lib/bas/use_cases/use_cases.rb +79 -3
- data/lib/bas/version.rb +1 -1
- data/lib/bas/write/notion/base.rb +36 -0
- data/lib/bas/write/notion/use_case/empty_notification.rb +38 -0
- data/lib/bas/write/notion/use_case/notification.rb +38 -0
- metadata +14 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5f5359b994975192b92fe8582bd37c23e9ce212bbe7d90bd9b93566421f88cd2
|
4
|
+
data.tar.gz: 3d8a0d0f9a8ea9529f3538600a471d32506fa865d45c8e1621d1d3851b6a5682
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d88b0b00ca6da83a2168051a685d60bea43766ec677285e129ced8e48dc55660203b8c7994e347f3e043e898838ed6e3910f9e5271f78e22e219a035929f85f9
|
7
|
+
data.tar.gz: 0a01df01e758f0b97931debeedc150045c1ba5f0978fe475ae775139fed7ed1d622cf66f17740f098ddfabf1d29a48511b83cffb67a97316b0dfeea51b2e5694
|
data/.rubocop.yml
CHANGED
data/CHANGELOG.md
CHANGED
data/CONTRIBUTING.md
CHANGED
@@ -42,6 +42,15 @@ At this point, you're waiting on us. We like to at least comment on pull request
|
|
42
42
|
business days (typically, one business day). We may suggest some changes, improvements or
|
43
43
|
alternatives.
|
44
44
|
|
45
|
+
# Stale issues
|
46
|
+
|
47
|
+
To ensure that our issue tracker remains organized and relevant, we have implemented a policy for handling Stale issues. Please review the following guidelines:
|
48
|
+
|
49
|
+
1. **Marking as Stale**: Issues will be automatically marked as **Stale** after 60 days of inactivity.
|
50
|
+
2. **Closing Stale Issues**: After an issue has been marked as Stale, a comment will be posted on the issue indicating that it will be closed if there is no further activity or information provided within a specified period.
|
51
|
+
|
52
|
+
Thank you for helping us maintain a clean and efficient issue tracker!
|
53
|
+
|
45
54
|
## Resources
|
46
55
|
|
47
56
|
- [How to Contribute to Open Source][oss-how-to]
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Domain
|
4
|
+
##
|
5
|
+
# The Domain::Notification class provides a domain-specific representation of a Notification object.
|
6
|
+
# It encapsulates the notification text.
|
7
|
+
#
|
8
|
+
class Notification
|
9
|
+
attr_reader :notification
|
10
|
+
|
11
|
+
ATTRIBUTES = %w[notification].freeze
|
12
|
+
|
13
|
+
# Initializes a Domain::Notification instance with the specified notification text.
|
14
|
+
#
|
15
|
+
# <br>
|
16
|
+
# <b>Params:</b>
|
17
|
+
# * <tt>String</tt> notification
|
18
|
+
#
|
19
|
+
def initialize(notification)
|
20
|
+
@notification = notification
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "../domain/notification"
|
4
|
+
require_relative "./exceptions/invalid_data"
|
5
|
+
require_relative "./base"
|
6
|
+
require_relative "./types/response"
|
7
|
+
|
8
|
+
module Formatter
|
9
|
+
##
|
10
|
+
# This class implements methods from the Formatter::Base module, tailored to format the
|
11
|
+
# Domain::Notification structure for a Process.
|
12
|
+
class Notification < Base
|
13
|
+
# Implements the logic for building a formatted notification message
|
14
|
+
#
|
15
|
+
# <br>
|
16
|
+
# <b>Params:</b>
|
17
|
+
# * <tt>List<Domain::Notification></tt> notifications_list: list of serialized notifications.
|
18
|
+
#
|
19
|
+
# <br>
|
20
|
+
# <b>raises</b> <tt>Formatter::Exceptions::InvalidData</tt> when invalid data is provided.
|
21
|
+
#
|
22
|
+
# <br>
|
23
|
+
# <b>returns</b> <tt>Formatter::Types::Response</tt> formatter response: standard output for
|
24
|
+
# the formatted payload suitable for a Process.
|
25
|
+
#
|
26
|
+
def format(notifications_list)
|
27
|
+
raise Formatter::Exceptions::InvalidData unless notifications_list.all? do |notification|
|
28
|
+
notification.is_a?(Domain::Notification)
|
29
|
+
end
|
30
|
+
|
31
|
+
Formatter::Types::Response.new(notifications_list[0].notification)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -41,7 +41,7 @@ module Process
|
|
41
41
|
|
42
42
|
body = post_body(response.data)
|
43
43
|
|
44
|
-
response = HTTParty.post(webhook, { body
|
44
|
+
response = HTTParty.post(webhook, { body:, headers: { "Content-Type" => "application/json" } })
|
45
45
|
|
46
46
|
discord_response = Process::Discord::Types::Response.new(response)
|
47
47
|
|
@@ -0,0 +1,72 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "httparty"
|
4
|
+
|
5
|
+
require_relative "../base"
|
6
|
+
require_relative "./types/response"
|
7
|
+
require_relative "./helper"
|
8
|
+
|
9
|
+
module Process
|
10
|
+
module OpenAI
|
11
|
+
##
|
12
|
+
# This class is an implementation of the Process::Base interface, specifically designed
|
13
|
+
# for requesting to the OpenAI API for chat completion.
|
14
|
+
#
|
15
|
+
class Base < Process::Base
|
16
|
+
OPENAI_BASE_URL = "https://api.openai.com"
|
17
|
+
DEFAULT_N_CHOICES = 1
|
18
|
+
|
19
|
+
# Initializes the process with essential configuration parameters.
|
20
|
+
#
|
21
|
+
def initialize(config = {})
|
22
|
+
super(config)
|
23
|
+
|
24
|
+
@n_choices = config[:n_choices] || DEFAULT_N_CHOICES
|
25
|
+
end
|
26
|
+
|
27
|
+
protected
|
28
|
+
|
29
|
+
# Implements the sending process logic for the OpenAI API. It sends a
|
30
|
+
# POST request to the OpenAI API for chat completion with the specified payload.
|
31
|
+
#
|
32
|
+
# <br>
|
33
|
+
# <b>Params:</b>
|
34
|
+
# * <tt>Formatter::Types::Response</tt> formatter response: standard formatter response
|
35
|
+
# with the data to be send to OpenAI.
|
36
|
+
# <br>
|
37
|
+
# <b>raises</b> <tt>StandardError</tt> if the API returns an error response
|
38
|
+
#
|
39
|
+
# <br>
|
40
|
+
# <b>returns</b> <tt>Process::Types::Response</tt>
|
41
|
+
#
|
42
|
+
def process(messages)
|
43
|
+
url = "#{OPENAI_BASE_URL}/v1/chat/completions"
|
44
|
+
|
45
|
+
httparty_response = HTTParty.post(url, { body: body(messages).to_json, headers: })
|
46
|
+
|
47
|
+
openai_response = Process::OpenAI::Types::Response.new(httparty_response)
|
48
|
+
|
49
|
+
response = Process::OpenAI::Helper.validate_response(openai_response)
|
50
|
+
|
51
|
+
Process::Types::Response.new(response)
|
52
|
+
end
|
53
|
+
|
54
|
+
private
|
55
|
+
|
56
|
+
def body(messages)
|
57
|
+
{
|
58
|
+
"model": config[:model],
|
59
|
+
"n": @n_choices,
|
60
|
+
"messages": messages
|
61
|
+
}
|
62
|
+
end
|
63
|
+
|
64
|
+
def headers
|
65
|
+
{
|
66
|
+
"Authorization" => "Bearer #{config[:secret]}",
|
67
|
+
"Content-Type" => "application/json"
|
68
|
+
}
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Process
|
4
|
+
module OpenAI
|
5
|
+
##
|
6
|
+
# Provides common fuctionalities along the Process::OpenAI domain.
|
7
|
+
#
|
8
|
+
module Helper
|
9
|
+
def self.validate_response(response)
|
10
|
+
case response.status_code
|
11
|
+
when 200
|
12
|
+
response
|
13
|
+
else
|
14
|
+
raise StandardError, response.message
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Process
|
4
|
+
module OpenAI
|
5
|
+
module Types
|
6
|
+
##
|
7
|
+
# Represents a response received from the OpenAI chat completion service API. It encapsulates
|
8
|
+
# essential information about the response, providing a structured way to handle and analyze
|
9
|
+
# its responses.
|
10
|
+
class Response
|
11
|
+
attr_reader :status_code, :message, :choices
|
12
|
+
|
13
|
+
def initialize(response)
|
14
|
+
if response["error"]
|
15
|
+
@status_code = response.code
|
16
|
+
@message = response["error"]
|
17
|
+
@choices = []
|
18
|
+
else
|
19
|
+
@status_code = 200
|
20
|
+
@message = "success"
|
21
|
+
@choices = response["choices"]
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "../base"
|
4
|
+
|
5
|
+
module Process
|
6
|
+
module OpenAI
|
7
|
+
##
|
8
|
+
# This class is an implementation of the Process::OpenAI::Base interface, specifically designed
|
9
|
+
# to humanize formatted PTO messages for better understanding.
|
10
|
+
#
|
11
|
+
class HumanizePto < OpenAI::Base
|
12
|
+
# Implements the data process to humanize formatted PTO messages.
|
13
|
+
#
|
14
|
+
def execute(format_response)
|
15
|
+
messages = [
|
16
|
+
{
|
17
|
+
"role": "user",
|
18
|
+
"content": content(format_response.data)
|
19
|
+
}
|
20
|
+
]
|
21
|
+
|
22
|
+
process(messages)
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def content(data)
|
28
|
+
<<~MESSAGE
|
29
|
+
The following message is too complex for a human to read since it has specific dates formatted as YYYY-MM-DD:
|
30
|
+
|
31
|
+
\"#{data}\"
|
32
|
+
|
33
|
+
Create a text that gives the same message in a more human-readable and context-valuable fashion for a human.
|
34
|
+
Use the current date (#{current_date}) to provide context.
|
35
|
+
Try grouping information and using bullet points to make it easier to read the information at a quick glance.
|
36
|
+
Additionally, keep in mind that we work from Monday to Friday - not weekends.
|
37
|
+
Please, just give the PTOs message and avoid the intro message such as \"Here is a reader-friendly message\".
|
38
|
+
Add emojis for a cool message, but keep it seriously.
|
39
|
+
|
40
|
+
For example:
|
41
|
+
The input "Jane Doe is on PTO from 2024-04-08 to 2024-04-26", means that Jane will be on PTO starting at 2024-04-08
|
42
|
+
and ending at 2024-04-26, i.e, she will be back the next work-day which is 2024-04-29.
|
43
|
+
MESSAGE
|
44
|
+
end
|
45
|
+
|
46
|
+
def current_date
|
47
|
+
utc_today = Time.now.utc
|
48
|
+
|
49
|
+
Time.at(utc_today, in: config[:timezone]).strftime("%A, %F").to_s
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -41,7 +41,7 @@ module Process
|
|
41
41
|
|
42
42
|
body = post_body(response.data)
|
43
43
|
|
44
|
-
response = HTTParty.post(webhook, { body
|
44
|
+
response = HTTParty.post(webhook, { body:, headers: { "Content-Type" => "application/json" } })
|
45
45
|
|
46
46
|
slack_response = Process::Discord::Types::Response.new(response)
|
47
47
|
|
@@ -6,7 +6,7 @@ module Read
|
|
6
6
|
##
|
7
7
|
# Represents a response received from the Octokit Github client. It encapsulates essential
|
8
8
|
# information about the response, providing a structured way to handle and analyze
|
9
|
-
#
|
9
|
+
# its responses.
|
10
10
|
class Response
|
11
11
|
attr_reader :status_code, :message, :results
|
12
12
|
|
@@ -6,7 +6,7 @@ module Read
|
|
6
6
|
##
|
7
7
|
# Represents a response received from the Imap client. It encapsulates essential
|
8
8
|
# information about the response, providing a structured way to handle and analyze
|
9
|
-
#
|
9
|
+
# its responses.
|
10
10
|
class Response
|
11
11
|
attr_reader :status_code, :message, :results
|
12
12
|
|
data/lib/bas/read/notion/base.rb
CHANGED
@@ -31,7 +31,7 @@ module Read
|
|
31
31
|
def read(filter)
|
32
32
|
url = "#{NOTION_BASE_URL}/v1/databases/#{config[:database_id]}/query"
|
33
33
|
|
34
|
-
httparty_response = HTTParty.post(url, { body: filter.to_json, headers:
|
34
|
+
httparty_response = HTTParty.post(url, { body: filter.to_json, headers: })
|
35
35
|
|
36
36
|
notion_response = Read::Notion::Types::Response.new(httparty_response)
|
37
37
|
|
@@ -5,7 +5,7 @@ module Read
|
|
5
5
|
module Types
|
6
6
|
##
|
7
7
|
# Represents a response received from the Notion API. It encapsulates essential information about the response,
|
8
|
-
# providing a structured way to handle and analyze
|
8
|
+
# providing a structured way to handle and analyze its responses.
|
9
9
|
class Response
|
10
10
|
attr_reader :status_code, :message, :results
|
11
11
|
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "../base"
|
4
|
+
|
5
|
+
module Read
|
6
|
+
module Notion
|
7
|
+
##
|
8
|
+
# This class is an implementation of the Read::Notion::Base interface, specifically designed
|
9
|
+
# for reading Notification data from Notion.
|
10
|
+
#
|
11
|
+
class Notification < Notion::Base
|
12
|
+
# Implements the reading filter for notification data from Notion.
|
13
|
+
#
|
14
|
+
def execute
|
15
|
+
filter = {
|
16
|
+
filter: {
|
17
|
+
property: "Use Case",
|
18
|
+
title: {
|
19
|
+
equals: config[:use_case_title]
|
20
|
+
}
|
21
|
+
}
|
22
|
+
}
|
23
|
+
|
24
|
+
read(filter)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -52,8 +52,8 @@ module Read
|
|
52
52
|
def belong_next_week(property, after_day, before_day)
|
53
53
|
{
|
54
54
|
and: [
|
55
|
-
{ property
|
56
|
-
{ property
|
55
|
+
{ property:, date: { on_or_after: after_day } },
|
56
|
+
{ property:, date: { on_or_before: before_day } }
|
57
57
|
]
|
58
58
|
}
|
59
59
|
end
|
@@ -5,7 +5,7 @@ module Read
|
|
5
5
|
module Types
|
6
6
|
##
|
7
7
|
# Represents a response received from the Postgres API. It encapsulates essential information about the response,
|
8
|
-
# providing a structured way to handle and analyze
|
8
|
+
# providing a structured way to handle and analyze its responses.
|
9
9
|
class Response
|
10
10
|
attr_reader :status, :message, :response, :fields, :records
|
11
11
|
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "../../domain/notification"
|
4
|
+
require_relative "../base"
|
5
|
+
|
6
|
+
module Serialize
|
7
|
+
module Notion
|
8
|
+
##
|
9
|
+
# This class implements the methods of the Serialize::Base module, specifically designed for preparing or
|
10
|
+
# shaping Notification's data coming from a Read::Base implementation.
|
11
|
+
#
|
12
|
+
class Notification
|
13
|
+
include Base
|
14
|
+
|
15
|
+
NOTIFICATION_PARAMS = ["Notification"].freeze
|
16
|
+
|
17
|
+
# Implements the logic for shaping the results from a reader response.
|
18
|
+
#
|
19
|
+
# <br>
|
20
|
+
# <b>Params:</b>
|
21
|
+
# * <tt>Read::Notion::Types::Response</tt> notion_response: Notion response object.
|
22
|
+
#
|
23
|
+
# <br>
|
24
|
+
# <b>returns</b> <tt>List<Domain::Notification></tt> notification_list, serialized
|
25
|
+
# notifications to be used by a Formatter::Base implementation.
|
26
|
+
#
|
27
|
+
def execute(notion_response)
|
28
|
+
return [] if notion_response.results.empty?
|
29
|
+
|
30
|
+
normalized_notion_data = normalize_response(notion_response.results)
|
31
|
+
|
32
|
+
normalized_notion_data.map do |notification|
|
33
|
+
Domain::Notification.new(notification["Notification"])
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def normalize_response(response)
|
40
|
+
return [] if response.nil?
|
41
|
+
|
42
|
+
response.map do |value|
|
43
|
+
notification_fields = value["properties"].slice(*NOTIFICATION_PARAMS)
|
44
|
+
|
45
|
+
{
|
46
|
+
"Notification" => extract_notification_field_value(notification_fields["Notification"])
|
47
|
+
}
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def extract_notification_field_value(notification)
|
52
|
+
notification["rich_text"][0]["plain_text"]
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -5,6 +5,7 @@ require_relative "../read/notion/use_case/birthday_today"
|
|
5
5
|
require_relative "../read/notion/use_case/birthday_next_week"
|
6
6
|
require_relative "../read/notion/use_case/pto_today"
|
7
7
|
require_relative "../read/notion/use_case/pto_next_week"
|
8
|
+
require_relative "../read/notion/use_case/notification"
|
8
9
|
require_relative "../read/notion/use_case/work_items_limit"
|
9
10
|
require_relative "../read/postgres/use_case/pto_today"
|
10
11
|
require_relative "../read/imap/use_case/support_emails"
|
@@ -14,6 +15,7 @@ require_relative "../read/github/use_case/repo_issues"
|
|
14
15
|
require_relative "../serialize/notion/birthday_today"
|
15
16
|
require_relative "../serialize/notion/pto_today"
|
16
17
|
require_relative "../serialize/notion/work_items_limit"
|
18
|
+
require_relative "../serialize/notion/notification"
|
17
19
|
require_relative "../serialize/postgres/pto_today"
|
18
20
|
require_relative "../serialize/imap/support_emails"
|
19
21
|
require_relative "../serialize/github/issues"
|
@@ -23,13 +25,17 @@ require_relative "../formatter/birthday"
|
|
23
25
|
require_relative "../formatter/pto"
|
24
26
|
require_relative "../formatter/work_items_limit"
|
25
27
|
require_relative "../formatter/support_emails"
|
28
|
+
require_relative "../formatter/notification"
|
26
29
|
|
27
30
|
# process
|
28
31
|
require_relative "../process/discord/implementation"
|
29
32
|
require_relative "../process/slack/implementation"
|
33
|
+
require_relative "../process/openai/use_case/humanize_pto"
|
30
34
|
|
31
35
|
# write
|
32
36
|
require_relative "../write/logs/use_case/console_log"
|
37
|
+
require_relative "../write/notion/use_case/notification"
|
38
|
+
require_relative "../write/notion/use_case/empty_notification"
|
33
39
|
|
34
40
|
require_relative "use_case"
|
35
41
|
require_relative "./types/config"
|
@@ -150,10 +156,19 @@ module UseCases
|
|
150
156
|
# read_options: {
|
151
157
|
# database_id: NOTION_DATABASE_ID,
|
152
158
|
# secret: NOTION_API_INTEGRATION_SECRET,
|
159
|
+
# use_case_title: "PTO"
|
160
|
+
# },
|
161
|
+
# format_options: {
|
162
|
+
# template: ":beach: individual_name is on PTO",
|
163
|
+
# timezone: "-05:00"
|
153
164
|
# },
|
154
165
|
# process_options: {
|
155
166
|
# webhook: "https://discord.com/api/webhooks/1199213527672565760/KmpoIzBet9xYG16oFh8W1RWHbpIqT7UtTBRrhfLcvWZdNiVZCTM-gpil2Qoy4eYEgpdf",
|
156
|
-
# name: "
|
167
|
+
# name: "notificationBOT"
|
168
|
+
# },
|
169
|
+
# write_options: {
|
170
|
+
# secret: NOTION_API_INTEGRATION_SECRET,
|
171
|
+
# page_id: WRITE_NOTION_PAGE_ID
|
157
172
|
# }
|
158
173
|
# }
|
159
174
|
#
|
@@ -172,6 +187,8 @@ module UseCases
|
|
172
187
|
# | Jane Doe | November 11, 2024 2:00 PM | November 11, 2024 6:00 PM |
|
173
188
|
# ---------------------------------------------------------------------------------------------------------
|
174
189
|
#
|
190
|
+
# * Write Notion page ID, from a page with a "Notification" text property.
|
191
|
+
# This property will be updated with the humanized notification.
|
175
192
|
# * A Notion secret, which can be obtained, by creating an integration here: `https://developers.notion.com/`,
|
176
193
|
# browsing on the <View my integations> option, and selecting the <New Integration> or <Create new>
|
177
194
|
# integration** buttons.
|
@@ -179,11 +196,70 @@ module UseCases
|
|
179
196
|
# https://support.discord.com/hc/en-us/articles/228383668-Intro-to-Webhooks
|
180
197
|
#
|
181
198
|
def self.notify_pto_from_notion_to_discord(options)
|
199
|
+
read = Read::Notion::Notification.new(options[:read_options])
|
200
|
+
serialize = Serialize::Notion::Notification.new
|
201
|
+
formatter = Formatter::Notification.new(options[:format_options])
|
202
|
+
process = Process::Discord::Implementation.new(options[:process_options])
|
203
|
+
write = Write::Notion::EmptyNotification.new(options[:write_options])
|
204
|
+
|
205
|
+
use_case_config = UseCases::Types::Config.new(read, serialize, formatter, process, write)
|
206
|
+
|
207
|
+
UseCases::UseCase.new(use_case_config)
|
208
|
+
end
|
209
|
+
|
210
|
+
# Provides an instance of the humanized PTO write from Notion to Notion use case implementation.
|
211
|
+
#
|
212
|
+
# <br>
|
213
|
+
# <b>Example</b>
|
214
|
+
#
|
215
|
+
# options = {
|
216
|
+
# read_options: {
|
217
|
+
# database_id: READ_NOTION_DATABASE_ID,
|
218
|
+
# secret: NOTION_API_INTEGRATION_SECRET
|
219
|
+
# },
|
220
|
+
# format_options: {
|
221
|
+
# template: ":beach: individual_name is on PTO",
|
222
|
+
# timezone: "-05:00"
|
223
|
+
# },
|
224
|
+
# process_options: {
|
225
|
+
# secret: OPENAI_API_SECRET_KEY,
|
226
|
+
# model: "gpt-4",
|
227
|
+
# timezone: "-05:00"
|
228
|
+
# },
|
229
|
+
# write_options: {
|
230
|
+
# secret: NOTION_API_INTEGRATION_SECRET,
|
231
|
+
# page_id: WRITE_NOTION_PAGE_ID,
|
232
|
+
# }
|
233
|
+
# }
|
234
|
+
#
|
235
|
+
# use_case = UseCases.write_humanized_pto_from_notion_to_notion(options)
|
236
|
+
# use_case.perform
|
237
|
+
#
|
238
|
+
# #################################################################################
|
239
|
+
#
|
240
|
+
# Requirements:
|
241
|
+
# * Read Notion database ID, from a database with the following structure:
|
242
|
+
#
|
243
|
+
# ________________________________________________________________________________________________________
|
244
|
+
# | Person (person) | Desde? (date) | Hasta? (date) |
|
245
|
+
# | -------------------- | --------------------------------------- | ------------------------------------ |
|
246
|
+
# | John Doe | January 24, 2024 | January 27, 2024 |
|
247
|
+
# | Jane Doe | November 11, 2024 2:00 PM | November 11, 2024 6:00 PM |
|
248
|
+
# ---------------------------------------------------------------------------------------------------------
|
249
|
+
#
|
250
|
+
# * Write Notion page ID, from a page with a "Notification" text property.
|
251
|
+
# This property will be updated with the humanized notification.
|
252
|
+
# * A Notion secret, which can be obtained, by creating an integration here: `https://developers.notion.com/`,
|
253
|
+
# browsing on the <View my integations> option, and selecting the <New Integration> or <Create new>
|
254
|
+
# integration** buttons. This should have permission to update.
|
255
|
+
#
|
256
|
+
def self.write_humanized_pto_from_notion_to_notion(options)
|
182
257
|
read = Read::Notion::PtoToday.new(options[:read_options])
|
183
258
|
serialize = Serialize::Notion::PtoToday.new
|
184
259
|
formatter = Formatter::Pto.new(options[:format_options])
|
185
|
-
process = Process::
|
186
|
-
write = Write::
|
260
|
+
process = Process::OpenAI::HumanizePto.new(options[:process_options])
|
261
|
+
write = Write::Notion::Notification.new(options[:write_options])
|
262
|
+
|
187
263
|
use_case_config = UseCases::Types::Config.new(read, serialize, formatter, process, write)
|
188
264
|
|
189
265
|
UseCases::UseCase.new(use_case_config)
|
data/lib/bas/version.rb
CHANGED
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "../base"
|
4
|
+
|
5
|
+
module Write
|
6
|
+
module Notion
|
7
|
+
##
|
8
|
+
# This class is an implementation of the Write::Base interface, specifically designed
|
9
|
+
# to create or update pages in a Notion database.
|
10
|
+
#
|
11
|
+
class Base < Write::Base
|
12
|
+
NOTION_BASE_URL = "https://api.notion.com"
|
13
|
+
|
14
|
+
protected
|
15
|
+
|
16
|
+
# Implements the writing logic to create or update pages in a Notion.database. It sends
|
17
|
+
# a request to the Notion API given the method (post, patch, etc), endpoint and body.
|
18
|
+
#
|
19
|
+
def write(method, endpoint, body)
|
20
|
+
url = "#{NOTION_BASE_URL}#{endpoint}"
|
21
|
+
|
22
|
+
HTTParty.send(method, url, { body: body.to_json, headers: })
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def headers
|
28
|
+
{
|
29
|
+
"Authorization" => "Bearer #{config[:secret]}",
|
30
|
+
"Content-Type" => "application/json",
|
31
|
+
"Notion-Version" => "2022-06-28"
|
32
|
+
}
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "../base"
|
4
|
+
|
5
|
+
module Write
|
6
|
+
module Notion
|
7
|
+
##
|
8
|
+
# This class is an implementation of the Write::Notion::Base interface, specifically designed
|
9
|
+
# to update an existing page in a Notion database to write an empty text.
|
10
|
+
class EmptyNotification < Notion::Base
|
11
|
+
# Implements the writting process logic for the Notification use case.
|
12
|
+
#
|
13
|
+
# <br>
|
14
|
+
# <b>Params:</b>
|
15
|
+
# * <tt>Process::Types::Response</tt> process response: standard process response.
|
16
|
+
#
|
17
|
+
def execute(_process_response)
|
18
|
+
endpoint = "/v1/pages/#{config[:page_id]}"
|
19
|
+
|
20
|
+
body = body("")
|
21
|
+
|
22
|
+
write("patch", endpoint, body)
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def body(content)
|
28
|
+
{
|
29
|
+
properties: {
|
30
|
+
Notification: {
|
31
|
+
rich_text: [{ text: { content: } }]
|
32
|
+
}
|
33
|
+
}
|
34
|
+
}
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "../base"
|
4
|
+
|
5
|
+
module Write
|
6
|
+
module Notion
|
7
|
+
##
|
8
|
+
# This class is an implementation of the Write::OpenAI::Base interface, specifically designed
|
9
|
+
# to update an existing page on a Notion database to write the notification text.
|
10
|
+
class Notification < Notion::Base
|
11
|
+
# Implements the writting process logic for the Notification use case.
|
12
|
+
#
|
13
|
+
# <br>
|
14
|
+
# <b>Params:</b>
|
15
|
+
# * <tt>Process::Types::Response</tt> process response: standard process response with the data to be updated.
|
16
|
+
#
|
17
|
+
def execute(process_response)
|
18
|
+
endpoint = "/v1/pages/#{config[:page_id]}"
|
19
|
+
|
20
|
+
body = body(process_response.data.choices[0]["message"]["content"])
|
21
|
+
|
22
|
+
write("patch", endpoint, body)
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def body(content)
|
28
|
+
{
|
29
|
+
properties: {
|
30
|
+
Notification: {
|
31
|
+
rich_text: [{ text: { content: } }]
|
32
|
+
}
|
33
|
+
}
|
34
|
+
}
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
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: 0.
|
4
|
+
version: 0.4.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-04-
|
11
|
+
date: 2024-04-19 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: A versatile business automation system offering key components for building
|
14
14
|
various use cases. It provides an easy-to-use tool for implementing automation
|
@@ -35,11 +35,13 @@ files:
|
|
35
35
|
- lib/bas/domain/email.rb
|
36
36
|
- lib/bas/domain/exceptions/function_not_implemented.rb
|
37
37
|
- lib/bas/domain/issue.rb
|
38
|
+
- lib/bas/domain/notification.rb
|
38
39
|
- lib/bas/domain/pto.rb
|
39
40
|
- lib/bas/domain/work_items_limit.rb
|
40
41
|
- lib/bas/formatter/base.rb
|
41
42
|
- lib/bas/formatter/birthday.rb
|
42
43
|
- lib/bas/formatter/exceptions/invalid_data.rb
|
44
|
+
- lib/bas/formatter/notification.rb
|
43
45
|
- lib/bas/formatter/pto.rb
|
44
46
|
- lib/bas/formatter/support_emails.rb
|
45
47
|
- lib/bas/formatter/types/response.rb
|
@@ -48,6 +50,10 @@ files:
|
|
48
50
|
- lib/bas/process/discord/exceptions/invalid_webhook_token.rb
|
49
51
|
- lib/bas/process/discord/implementation.rb
|
50
52
|
- lib/bas/process/discord/types/response.rb
|
53
|
+
- lib/bas/process/openai/base.rb
|
54
|
+
- lib/bas/process/openai/helper.rb
|
55
|
+
- lib/bas/process/openai/types/response.rb
|
56
|
+
- lib/bas/process/openai/use_case/humanize_pto.rb
|
51
57
|
- lib/bas/process/slack/exceptions/invalid_webhook_token.rb
|
52
58
|
- lib/bas/process/slack/implementation.rb
|
53
59
|
- lib/bas/process/slack/types/response.rb
|
@@ -66,6 +72,7 @@ files:
|
|
66
72
|
- lib/bas/read/notion/types/response.rb
|
67
73
|
- lib/bas/read/notion/use_case/birthday_next_week.rb
|
68
74
|
- lib/bas/read/notion/use_case/birthday_today.rb
|
75
|
+
- lib/bas/read/notion/use_case/notification.rb
|
69
76
|
- lib/bas/read/notion/use_case/pto_next_week.rb
|
70
77
|
- lib/bas/read/notion/use_case/pto_today.rb
|
71
78
|
- lib/bas/read/notion/use_case/work_items_limit.rb
|
@@ -77,6 +84,7 @@ files:
|
|
77
84
|
- lib/bas/serialize/github/issues.rb
|
78
85
|
- lib/bas/serialize/imap/support_emails.rb
|
79
86
|
- lib/bas/serialize/notion/birthday_today.rb
|
87
|
+
- lib/bas/serialize/notion/notification.rb
|
80
88
|
- lib/bas/serialize/notion/pto_today.rb
|
81
89
|
- lib/bas/serialize/notion/work_items_limit.rb
|
82
90
|
- lib/bas/serialize/postgres/pto_today.rb
|
@@ -87,6 +95,9 @@ files:
|
|
87
95
|
- lib/bas/write/base.rb
|
88
96
|
- lib/bas/write/logs/base.rb
|
89
97
|
- lib/bas/write/logs/use_case/console_log.rb
|
98
|
+
- lib/bas/write/notion/base.rb
|
99
|
+
- lib/bas/write/notion/use_case/empty_notification.rb
|
100
|
+
- lib/bas/write/notion/use_case/notification.rb
|
90
101
|
- renovate.json
|
91
102
|
- sig/business_automation_system.rbs
|
92
103
|
homepage: https://github.com/kommitters/bas
|
@@ -103,7 +114,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
103
114
|
requirements:
|
104
115
|
- - ">="
|
105
116
|
- !ruby/object:Gem::Version
|
106
|
-
version:
|
117
|
+
version: 3.1.0
|
107
118
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
108
119
|
requirements:
|
109
120
|
- - ">="
|