bns 0.1.0 → 0.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/._.rspec_status +0 -0
- data/CHANGELOG.md +13 -0
- data/Gemfile +2 -0
- data/README.md +163 -4
- data/SECURITY.md +13 -0
- data/lib/bns/dispatcher/discord/exceptions/invalid_webhook_token.rb +2 -2
- data/lib/bns/dispatcher/discord/implementation.rb +1 -1
- data/lib/bns/dispatcher/slack/exceptions/invalid_webhook_token.rb +16 -0
- data/lib/bns/dispatcher/slack/implementation.rb +51 -0
- data/lib/bns/dispatcher/slack/types/response.rb +21 -0
- data/lib/bns/domain/birthday.rb +2 -0
- data/lib/bns/domain/pto.rb +2 -0
- data/lib/bns/domain/work_items_limit.rb +39 -0
- data/lib/bns/fetcher/base.rb +13 -0
- data/lib/bns/fetcher/notion/{pto.rb → base.rb} +11 -7
- data/lib/bns/fetcher/notion/types/response.rb +1 -1
- data/lib/bns/fetcher/notion/use_case/birthday_next_week.rb +41 -0
- data/lib/bns/fetcher/notion/use_case/birthday_today.rb +29 -0
- data/lib/bns/fetcher/notion/use_case/pto_next_week.rb +71 -0
- data/lib/bns/fetcher/notion/use_case/pto_today.rb +30 -0
- data/lib/bns/fetcher/notion/use_case/work_items_limit.rb +37 -0
- data/lib/bns/fetcher/postgres/base.rb +46 -0
- data/lib/bns/fetcher/postgres/helper.rb +16 -0
- data/lib/bns/fetcher/postgres/types/response.rb +42 -0
- data/lib/bns/fetcher/postgres/use_case/pto_today.rb +32 -0
- data/lib/bns/formatter/base.rb +27 -3
- data/lib/bns/formatter/birthday.rb +34 -0
- data/lib/bns/formatter/exceptions/invalid_data.rb +15 -0
- data/lib/bns/formatter/pto.rb +76 -0
- data/lib/bns/formatter/work_items_limit.rb +43 -0
- data/lib/bns/mapper/notion/{birthday.rb → birthday_today.rb} +13 -21
- data/lib/bns/mapper/notion/{pto.rb → pto_today.rb} +15 -41
- data/lib/bns/mapper/notion/work_items_limit.rb +65 -0
- data/lib/bns/mapper/postgres/pto_today.rb +47 -0
- data/lib/bns/use_cases/use_cases.rb +227 -49
- data/lib/bns/version.rb +1 -1
- data/renovate.json +6 -0
- metadata +27 -10
- data/Gemfile.lock +0 -91
- data/lib/bns/fetcher/notion/birthday.rb +0 -53
- data/lib/bns/formatter/discord/birthday.rb +0 -43
- data/lib/bns/formatter/discord/exceptions/invalid_data.rb +0 -17
- data/lib/bns/formatter/discord/pto.rb +0 -52
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7f27d7368a358fcf6dea96e51922690ff399670b5582387b70f56db0d5b25feb
|
4
|
+
data.tar.gz: a46adf0a088dd65740c85aadc5d3005654f3654e2f12cecf345700be7f44f2b1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bfa9c1394d5fe161f90fe86e29a44acace8b2a7809ee8bd233ee12d0be082b11a0081e3fb98efefcdfe22c64a50f27335a95ac24f9c8baeec10c5a9f8d381754
|
7
|
+
data.tar.gz: a13978067c0c9ad5a96c8abc8ae2f7781674a0f4b3accc9b2229a11dde525f706a52ee448effad8570c34b2141a5e9c3ad0a3457f29dea2f5d60d42c6ba7bd4e
|
data/._.rspec_status
ADDED
Binary file
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,18 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## 0.2.0 (29.02.2024)
|
4
|
+
- [Add a Postgres fetcher component](https://github.com/kommitters/bns/issues/28)
|
5
|
+
- [Use case - PTO's Postgres-Slack implementation](https://github.com/kommitters/bns/issues/30)
|
6
|
+
- [Slack dispatcher](https://github.com/kommitters/bns/issues/32)
|
7
|
+
- [Refactor fetcher components](https://github.com/kommitters/bns/issues/34)
|
8
|
+
- [Add Use Case - Boards WI alerts](https://github.com/kommitters/bns/issues/36)
|
9
|
+
- [Add Use Case - Next Week Birthday](https://github.com/kommitters/bns/issues/38)
|
10
|
+
- [Add Use Case - Next Week PTO's](https://github.com/kommitters/bns/issues/39)
|
11
|
+
|
12
|
+
## 0.1.1 (07.02.2024)
|
13
|
+
- [Add custom templates option](https://github.com/kommitters/bns/issues/25)
|
14
|
+
- [PTO's formatting use cases](https://github.com/kommitters/bns/issues/24)
|
15
|
+
|
3
16
|
## 0.1.0 (06.02.2024)
|
4
17
|
|
5
18
|
- [Build initial codebase](https://github.com/kommitters/bns/issues/6)
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,11 +1,16 @@
|
|
1
1
|
# BNS - Business Notification System
|
2
2
|
|
3
|
-
|
3
|
+
Many organizations and individuals rely on automatic notifications across various contexts in their daily operations. With BNS, we aim to provide an open-source platform that empowers users to create customized notification systems tailored to their unique requirements. BNS consists of a series of abstract components designed to facilitate the creation of diverse use cases, regardless of context.
|
4
4
|
|
5
|
+
The underlying idea is to develop generic components that can serve a wide range of needs, this approach ensures that all members of the community can leverage the platform's evolving suite of components and use cases to their advantage.
|
6
|
+
|
7
|
+

|
8
|
+

|
5
9
|

|
6
10
|
[](https://coveralls.io/github/kommitters/bns?branch=main)
|
7
|
-
[](https://api.securityscorecards.dev/projects/github.com/kommitters/bns)
|
8
11
|

|
12
|
+
[](https://api.securityscorecards.dev/projects/github.com/kommitters/bns)
|
13
|
+
[](https://bestpractices.coreinfrastructure.org/projects/8383)
|
9
14
|
|
10
15
|
## Installation
|
11
16
|
|
@@ -147,9 +152,163 @@ use_case.perform
|
|
147
152
|
|
148
153
|
```
|
149
154
|
|
150
|
-
|
155
|
+
### Serverless
|
156
|
+
We'll explain how to configure and deploy a use case with serverless, this example will cover the PTO's notifications use case.
|
157
|
+
|
158
|
+
#### Configuring environment variables
|
159
|
+
Create the environment variables configuration file.
|
160
|
+
|
161
|
+
```bash
|
162
|
+
cp env.yml.example env.yml
|
163
|
+
```
|
151
164
|
|
152
|
-
|
165
|
+
And put the following env variables
|
166
|
+
```
|
167
|
+
dev:
|
168
|
+
NOTION_DATABASE_ID: NOTION_DATABASE_ID
|
169
|
+
NOTION_SECRET: NOTION_SECRET
|
170
|
+
DISCORD_WEBHOOK: DISCORD_WEBHOOK
|
171
|
+
DISCORD_BOT_NAME: DISCORD_BOT_NAME
|
172
|
+
prod:
|
173
|
+
NOTION_DATABASE_ID: NOTION_DATABASE_ID
|
174
|
+
NOTION_SECRET: NOTION_SECRET
|
175
|
+
DISCORD_WEBHOOK: DISCORD_WEBHOOK
|
176
|
+
DISCORD_BOT_NAME: DISCORD_BOT_NAME
|
177
|
+
|
178
|
+
```
|
179
|
+
|
180
|
+
The variables should be defined either in the custom settings section within the `serverless.yml` file to ensure accessibility by all lambdas, or in the environment configuration option for each lambda respectively. For example:
|
181
|
+
|
182
|
+
```bash
|
183
|
+
# Accessible by all the lambdas
|
184
|
+
custom:
|
185
|
+
settings:
|
186
|
+
api:
|
187
|
+
NOTION_DATABASE_ID: ${file(./env.yml):${env:STAGE}.NOTION_DATABASE_ID}
|
188
|
+
NOTION_SECRET: ${file(./env.yml):${env:STAGE}.NOTION_SECRET}}
|
189
|
+
|
190
|
+
# Accessible by the lambda
|
191
|
+
functions:
|
192
|
+
lambdaName:
|
193
|
+
environment:
|
194
|
+
NOTION_DATABASE_ID: ${file(./env.yml):${env:STAGE}.NOTION_DATABASE_ID}
|
195
|
+
NOTION_SECRET: ${file(./env.yml):${env:STAGE}.NOTION_SECRET}}
|
196
|
+
```
|
197
|
+
|
198
|
+
#### Schedule
|
199
|
+
the schedule is configured using an environment variable containing the cron configuration. For example:
|
200
|
+
```bash
|
201
|
+
# env.yml file
|
202
|
+
SCHEDULER: cron(0 13 ? * MON-FRI *)
|
203
|
+
|
204
|
+
# serverless.yml
|
205
|
+
functions:
|
206
|
+
lambdaName:
|
207
|
+
events:
|
208
|
+
- schedule:
|
209
|
+
rate: ${file(./env.yml):${env:STAGE}.SCHEDULER}
|
210
|
+
```
|
211
|
+
|
212
|
+
To learn how to modify the cron configuration follow this guide: [Schedule expressions using rate or cron](https://docs.aws.amazon.com/lambda/latest/dg/services-cloudwatchevents-expressions.html)
|
213
|
+
|
214
|
+
#### Building your lambda
|
215
|
+
On your serverless configuration, create your lambda function, on your serverless `/src` folder.
|
216
|
+
|
217
|
+
```ruby
|
218
|
+
# frozen_string_literal: true
|
219
|
+
|
220
|
+
require 'bns'
|
221
|
+
|
222
|
+
# Initialize the environment variables
|
223
|
+
NOTION_BASE_URL = 'https://api.notion.com'
|
224
|
+
NOTION_DATABASE_ID = ENV.fetch('PTO_NOTION_DATABASE_ID')
|
225
|
+
NOTION_SECRET = ENV.fetch('PTO_NOTION_SECRET')
|
226
|
+
DISCORD_WEBHOOK = ENV.fetch('PTO_DISCORD_WEBHOOK')
|
227
|
+
DISCORD_BOT_NAME = ENV.fetch('PTO_DISCORD_BOT_NAME')
|
228
|
+
|
229
|
+
module Notifier
|
230
|
+
# Service description
|
231
|
+
class UseCaseName
|
232
|
+
def self.notify(*)
|
233
|
+
options = { fetch_options:, dispatch_options: }
|
234
|
+
|
235
|
+
begin
|
236
|
+
use_case = UseCases.use_case_build_function(options)
|
237
|
+
|
238
|
+
use_case.perform
|
239
|
+
rescue StandardError => e
|
240
|
+
{ body: { message: e.message } }
|
241
|
+
end
|
242
|
+
end
|
243
|
+
|
244
|
+
def self.fetch_options
|
245
|
+
{
|
246
|
+
base_url: NOTION_BASE_URL,
|
247
|
+
database_id: NOTION_DATABASE_ID,
|
248
|
+
secret: NOTION_SECRET,
|
249
|
+
filter: {
|
250
|
+
filter: { "and": fetch_filter }
|
251
|
+
}
|
252
|
+
}
|
253
|
+
end
|
254
|
+
|
255
|
+
def self.fetch_filter
|
256
|
+
today = Common::TimeZone.set_colombia_time_zone.strftime('%F').to_s
|
257
|
+
|
258
|
+
[
|
259
|
+
{ property: 'Desde?', date: { on_or_before: today } },
|
260
|
+
{ property: 'Hasta?', date: { on_or_after: today } }
|
261
|
+
]
|
262
|
+
end
|
263
|
+
|
264
|
+
def self.dispatch_options
|
265
|
+
{
|
266
|
+
webhook: DISCORD_WEBHOOK,
|
267
|
+
name: DISCORD_BOT_NAME
|
268
|
+
}
|
269
|
+
end
|
270
|
+
|
271
|
+
def self.format_options
|
272
|
+
{
|
273
|
+
template: ':beach: individual_name is on PTO'
|
274
|
+
}
|
275
|
+
end
|
276
|
+
end
|
277
|
+
end
|
278
|
+
```
|
279
|
+
|
280
|
+
#### Configure the lambda
|
281
|
+
In the `serverless.yml` file, add a new instance in the `functions` block with this structure:
|
282
|
+
|
283
|
+
```bash
|
284
|
+
functions:
|
285
|
+
ptoNotification:
|
286
|
+
handler: src/lambdas/pto_notification.Notifier::PTO.notify
|
287
|
+
environment:
|
288
|
+
PTO_NOTION_DATABASE_ID: ${file(./env.yml):${env:STAGE}.PTO_NOTION_DATABASE_ID}
|
289
|
+
PTO_NOTION_SECRET: ${file(./env.yml):${env:STAGE}.PTO_NOTION_SECRET}
|
290
|
+
PTO_DISCORD_WEBHOOK: ${file(./env.yml):${env:STAGE}.PTO_DISCORD_WEBHOOK}
|
291
|
+
PTO_DISCORD_BOT_NAME: ${file(./env.yml):${env:STAGE}.DISCORD_BOT_NAME}
|
292
|
+
events:
|
293
|
+
- schedule:
|
294
|
+
name: pto-daily-notification
|
295
|
+
description: "Notify every 24 hours at 8:30 a.m (UTC-5) from monday to friday"
|
296
|
+
rate: cron(${file(./env.yml):${env:STAGE}.PTO_SCHEDULER})
|
297
|
+
enabled: true
|
298
|
+
```
|
299
|
+
|
300
|
+
#### Deploying
|
301
|
+
|
302
|
+
Configure the AWS keys:
|
303
|
+
|
304
|
+
```bash
|
305
|
+
serverless config credentials --provider aws --key YOUR_KEY --secret YOUR_SECRET
|
306
|
+
```
|
307
|
+
|
308
|
+
Deploy the project:
|
309
|
+
```bash
|
310
|
+
STAGE=prod sls deploy --verbose
|
311
|
+
```
|
153
312
|
|
154
313
|
## Development
|
155
314
|
|
data/SECURITY.md
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
# Security Policy
|
2
|
+
|
3
|
+
## Reporting Security Issues
|
4
|
+
|
5
|
+
To report a security issue, you can either:
|
6
|
+
- Privately report a vulnerability through repository's Security tab by clicking "Report a vulnerability".
|
7
|
+
- Email us at [oss@kommit.co](mailto:oss@kommit.co).
|
8
|
+
|
9
|
+
Please, make sure to provide a description of the issue, the steps you took to create the issue, affected versions, and, if known, mitigations for the issue.
|
10
|
+
|
11
|
+
## Responsible Disclosure
|
12
|
+
|
13
|
+
If the issue is confirmed as a vulnerability, we will open a Security Advisory and acknowledge your contributions as part of it.
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Dispatcher
|
4
|
+
module Slack
|
5
|
+
module Exceptions
|
6
|
+
##
|
7
|
+
# Domain specific representation when an invalid webhook token is provided to Slack.
|
8
|
+
#
|
9
|
+
class InvalidWebookToken < StandardError
|
10
|
+
def initialize(message = "The provided Webhook token is invalid.")
|
11
|
+
super(message)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "../base"
|
4
|
+
require_relative "./exceptions/invalid_webhook_token"
|
5
|
+
require_relative "./types/response"
|
6
|
+
|
7
|
+
module Dispatcher
|
8
|
+
module Slack
|
9
|
+
##
|
10
|
+
# This class is an implementation of the Dispatcher::Base interface, specifically designed
|
11
|
+
# for dispatching messages to Slack.
|
12
|
+
#
|
13
|
+
class Implementation < Base
|
14
|
+
# Implements the dispatching logic for the Slack use case. It sends a POST request to
|
15
|
+
# the Slack webhook with the specified payload.
|
16
|
+
#
|
17
|
+
# <br>
|
18
|
+
# <b>Params:</b>
|
19
|
+
# * <tt>String</tt> payload: Payload to be dispatched to slack.
|
20
|
+
# <br>
|
21
|
+
# <b>raises</b> <tt>Exceptions::Slack::InvalidWebookToken</tt> if the provided webhook token is invalid.
|
22
|
+
#
|
23
|
+
# <br>
|
24
|
+
# <b>returns</b> <tt>Dispatcher::Slack::Types::Response</tt>
|
25
|
+
#
|
26
|
+
def dispatch(payload)
|
27
|
+
body = {
|
28
|
+
username: name,
|
29
|
+
text: payload
|
30
|
+
}.to_json
|
31
|
+
|
32
|
+
response = HTTParty.post(webhook, { body: body, headers: { "Content-Type" => "application/json" } })
|
33
|
+
|
34
|
+
slack_response = Dispatcher::Discord::Types::Response.new(response)
|
35
|
+
|
36
|
+
validate_response(slack_response)
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def validate_response(response)
|
42
|
+
case response.http_code
|
43
|
+
when 403
|
44
|
+
raise Dispatcher::Slack::Exceptions::InvalidWebookToken, response.message
|
45
|
+
else
|
46
|
+
response
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Dispatcher
|
4
|
+
module Slack
|
5
|
+
module Types
|
6
|
+
##
|
7
|
+
# Represents a response received from Slack. It encapsulates essential information about the response,
|
8
|
+
# providing a structured way to handle and analyze Slack server responses.
|
9
|
+
#
|
10
|
+
class Response
|
11
|
+
attr_reader :body, :http_code, :message
|
12
|
+
|
13
|
+
def initialize(response)
|
14
|
+
@http_code = response.code
|
15
|
+
@message = response.message
|
16
|
+
@body = response.body
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/lib/bns/domain/birthday.rb
CHANGED
data/lib/bns/domain/pto.rb
CHANGED
@@ -9,6 +9,8 @@ module Domain
|
|
9
9
|
class Pto
|
10
10
|
attr_reader :individual_name, :start_date, :end_date
|
11
11
|
|
12
|
+
ATTRIBUTES = %w[individual_name start_date end_date].freeze
|
13
|
+
|
12
14
|
# Initializes a Domain::Pto instance with the specified individual name, start date, and end date.
|
13
15
|
#
|
14
16
|
# <br>
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Domain
|
4
|
+
##
|
5
|
+
# The Domain::WorkItemsLimit class provides a domain-specific representation of a Work Item object.
|
6
|
+
# It encapsulates information about a work items limit, including the domain, total, and wip_limit.
|
7
|
+
#
|
8
|
+
class WorkItemsLimit
|
9
|
+
attr_reader :domain, :total, :wip_limit
|
10
|
+
|
11
|
+
ATTRIBUTES = %w[domain total wip_limit].freeze
|
12
|
+
|
13
|
+
# Initializes a Domain::WorkItemsLimit instance with the specified domain, total and wip_limit.
|
14
|
+
#
|
15
|
+
# <br>
|
16
|
+
# <b>Params:</b>
|
17
|
+
# * <tt>String</tt> 'domain' responsible domain of the work items.
|
18
|
+
# * <tt>String</tt> 'total' total 'in progress' work items.
|
19
|
+
# * <tt>String</tt> 'wip_limit' maximum 'in progress' work items for the domain
|
20
|
+
#
|
21
|
+
def initialize(domain, total)
|
22
|
+
@domain = domain
|
23
|
+
@total = total
|
24
|
+
@wip_limit = domain_wip_limit(domain)
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def domain_wip_limit(domain)
|
30
|
+
case domain
|
31
|
+
when "kommit.ops" then 5
|
32
|
+
when "kommit.sales" then 3
|
33
|
+
when "kommit.marketing" then 4
|
34
|
+
when "kommit.engineering" then 12
|
35
|
+
else 6
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
data/lib/bns/fetcher/base.rb
CHANGED
@@ -26,5 +26,18 @@ module Fetcher
|
|
26
26
|
def fetch
|
27
27
|
raise Domain::Exceptions::FunctionNotImplemented
|
28
28
|
end
|
29
|
+
|
30
|
+
protected
|
31
|
+
|
32
|
+
# A method meant to execute the fetch request, retrieven the required data
|
33
|
+
# from an specific filter configuration depending on the use case implementation.
|
34
|
+
# Must be overridden by subclasses, with specific logic based on the use case.
|
35
|
+
#
|
36
|
+
# <br>
|
37
|
+
# <b>raises</b> <tt>Domain::Exceptions::FunctionNotImplemented</tt> when missing implementation.
|
38
|
+
#
|
39
|
+
def execute
|
40
|
+
raise Domain::Exceptions::FunctionNotImplemented
|
41
|
+
end
|
29
42
|
end
|
30
43
|
end
|
@@ -1,21 +1,25 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "httparty"
|
4
|
-
require "date"
|
5
4
|
|
6
5
|
require_relative "../base"
|
7
6
|
require_relative "./exceptions/invalid_api_key"
|
8
7
|
require_relative "./exceptions/invalid_database_id"
|
9
8
|
require_relative "./types/response"
|
9
|
+
require_relative "./helper"
|
10
10
|
|
11
11
|
module Fetcher
|
12
12
|
module Notion
|
13
13
|
##
|
14
14
|
# This class is an implementation of the Fetcher::Base interface, specifically designed
|
15
|
-
# for fetching
|
15
|
+
# for fetching data from Notion.
|
16
16
|
#
|
17
|
-
class
|
18
|
-
|
17
|
+
class Base < Fetcher::Base
|
18
|
+
NOTION_BASE_URL = "https://api.notion.com"
|
19
|
+
|
20
|
+
protected
|
21
|
+
|
22
|
+
# Implements the data fetching logic for data from Notion. It sends a POST
|
19
23
|
# request to the Notion API to query the specified database and returns a validated response.
|
20
24
|
#
|
21
25
|
# <br>
|
@@ -24,10 +28,10 @@ module Fetcher
|
|
24
28
|
# <b>raises</b> <tt>Exceptions::Notion::InvalidDatabaseId</tt> if the Database id provided is incorrect
|
25
29
|
# or invalid.
|
26
30
|
#
|
27
|
-
def
|
28
|
-
url = "#{
|
31
|
+
def execute(filter)
|
32
|
+
url = "#{NOTION_BASE_URL}/v1/databases/#{config[:database_id]}/query"
|
29
33
|
|
30
|
-
httparty_response = HTTParty.post(url, { body:
|
34
|
+
httparty_response = HTTParty.post(url, { body: filter.to_json, headers: headers })
|
31
35
|
|
32
36
|
notion_response = Fetcher::Notion::Types::Response.new(httparty_response)
|
33
37
|
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "../base"
|
4
|
+
|
5
|
+
module Fetcher
|
6
|
+
module Notion
|
7
|
+
##
|
8
|
+
# This class is an implementation of the Fetcher::Notion::Base interface, specifically designed
|
9
|
+
# for fetching next week birthdays data from Notion.
|
10
|
+
#
|
11
|
+
class BirthdayNextWeek < Notion::Base
|
12
|
+
DAYS_BEFORE_NOTIFY = 8
|
13
|
+
|
14
|
+
# Implements the data fetching filter for next week Birthdays data from Notion.
|
15
|
+
#
|
16
|
+
def fetch
|
17
|
+
filter = {
|
18
|
+
filter: {
|
19
|
+
or: [
|
20
|
+
{ property: "BD_this_year", date: { equals: eight_days_from_now } }
|
21
|
+
]
|
22
|
+
}
|
23
|
+
}
|
24
|
+
|
25
|
+
execute(filter)
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def eight_days_from_now
|
31
|
+
date = Time.now.utc + days_in_second(DAYS_BEFORE_NOTIFY)
|
32
|
+
|
33
|
+
date.utc.strftime("%F").to_s
|
34
|
+
end
|
35
|
+
|
36
|
+
def days_in_second(days)
|
37
|
+
days * 24 * 60 * 60
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "../base"
|
4
|
+
|
5
|
+
module Fetcher
|
6
|
+
module Notion
|
7
|
+
##
|
8
|
+
# This class is an implementation of the Fetcher::Notion::Base interface, specifically designed
|
9
|
+
# for fetching birthday data from Notion.
|
10
|
+
#
|
11
|
+
class BirthdayToday < Notion::Base
|
12
|
+
# Implements the data fetching filter for todays Birthdays data from Notion.
|
13
|
+
#
|
14
|
+
def fetch
|
15
|
+
today = Time.now.utc.strftime("%F").to_s
|
16
|
+
|
17
|
+
filter = {
|
18
|
+
filter: {
|
19
|
+
or: [
|
20
|
+
{ property: "BD_this_year", date: { equals: today } }
|
21
|
+
]
|
22
|
+
}
|
23
|
+
}
|
24
|
+
|
25
|
+
execute(filter)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "../base"
|
4
|
+
|
5
|
+
module Fetcher
|
6
|
+
module Notion
|
7
|
+
##
|
8
|
+
# This class is an implementation of the Fetcher::Notion::Base interface, specifically designed
|
9
|
+
# for fetching next week Paid Time Off (PTO) data from Notion.
|
10
|
+
#
|
11
|
+
class PtoNextWeek < Notion::Base
|
12
|
+
# Implements the data fetching filter for next week PTO's data from Notion.
|
13
|
+
#
|
14
|
+
def fetch
|
15
|
+
filter = build_filter
|
16
|
+
|
17
|
+
execute(filter)
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def next_week_dates
|
23
|
+
monday = next_week_monday
|
24
|
+
sunday = monday + 6
|
25
|
+
|
26
|
+
[monday, sunday]
|
27
|
+
end
|
28
|
+
|
29
|
+
def next_week_monday
|
30
|
+
today = Date.today
|
31
|
+
week_day = today.wday
|
32
|
+
|
33
|
+
days = week_day.zero? ? 1 : 8 - week_day
|
34
|
+
|
35
|
+
today + days
|
36
|
+
end
|
37
|
+
|
38
|
+
def build_filter
|
39
|
+
monday, sunday = next_week_dates
|
40
|
+
|
41
|
+
{
|
42
|
+
filter: {
|
43
|
+
or: [
|
44
|
+
belong_next_week("Desde?", monday, sunday),
|
45
|
+
belong_next_week("Hasta?", monday, sunday),
|
46
|
+
cover_next_week(monday, sunday)
|
47
|
+
]
|
48
|
+
}
|
49
|
+
}
|
50
|
+
end
|
51
|
+
|
52
|
+
def belong_next_week(property, after_day, before_day)
|
53
|
+
{
|
54
|
+
and: [
|
55
|
+
{ property: property, date: { on_or_after: after_day } },
|
56
|
+
{ property: property, date: { on_or_before: before_day } }
|
57
|
+
]
|
58
|
+
}
|
59
|
+
end
|
60
|
+
|
61
|
+
def cover_next_week(monday, sunday)
|
62
|
+
{
|
63
|
+
and: [
|
64
|
+
{ property: "Hasta?", date: { on_or_after: sunday } },
|
65
|
+
{ property: "Desde?", date: { on_or_before: monday } }
|
66
|
+
]
|
67
|
+
}
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "../base"
|
4
|
+
|
5
|
+
module Fetcher
|
6
|
+
module Notion
|
7
|
+
##
|
8
|
+
# This class is an implementation of the Fetcher::Notion::Base interface, specifically designed
|
9
|
+
# for fetching Paid Time Off (PTO) data from Notion.
|
10
|
+
#
|
11
|
+
class PtoToday < Notion::Base
|
12
|
+
# Implements the data fetching filter for todays PTO's data from Notion.
|
13
|
+
#
|
14
|
+
def fetch
|
15
|
+
today = Time.now.utc.strftime("%F").to_s
|
16
|
+
|
17
|
+
filter = {
|
18
|
+
filter: {
|
19
|
+
"and": [
|
20
|
+
{ property: "Desde?", date: { on_or_before: today } },
|
21
|
+
{ property: "Hasta?", date: { on_or_after: today } }
|
22
|
+
]
|
23
|
+
}
|
24
|
+
}
|
25
|
+
|
26
|
+
execute(filter)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|