bas 1.4.1 → 1.4.2
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 +3 -0
- data/README.md +2 -136
- data/examples/serverless_example.md +132 -0
- data/lib/bas/bot/fetch_billing_from_digital_ocean.rb +16 -4
- data/lib/bas/bot/format_do_bill_alert.rb +14 -7
- data/lib/bas/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6956cdda4a4735a5eb0a3d4413d41a972ac8190bb8d7da920e298a71bbe41516
|
4
|
+
data.tar.gz: 27c071aa1a681fb0f657af8e21c46057e3eb11cb467b5dd715f28c2f691d6dda
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bb89f398a03c6c8bae97798d069772790f2bd80a3ef7db4956b86751c4ef5a2b04420184e76ed138685f45dee3b1a9cdb1994517ca585663d9998a40bcb07f83
|
7
|
+
data.tar.gz: 9a586528f93844ad4e68d34a938bb2cff62eec5cd58fd952d1b431c5641c7af9ba5933ed8803b7fda42086b258b167c3826d2b492546887155b47e563c080b1f
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -102,142 +102,8 @@ bot.execute
|
|
102
102
|
|
103
103
|
```
|
104
104
|
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
#### Configuring environment variables
|
109
|
-
Create the environment variables configuration file.
|
110
|
-
|
111
|
-
```bash
|
112
|
-
cp env.yml.example env.yml
|
113
|
-
```
|
114
|
-
|
115
|
-
And put the following env variables
|
116
|
-
```
|
117
|
-
dev:
|
118
|
-
BIRTHDAY_NOTION_DATABASE_ID: "BIRTHDAY_NOTION_DATABASE_ID"
|
119
|
-
BIRTHDAY_NOTION_SECRET: "BIRTHDAY_NOTION_SECRET"
|
120
|
-
prod:
|
121
|
-
BIRTHDAY_NOTION_DATABASE_ID: "BIRTHDAY_NOTION_DATABASE_ID"
|
122
|
-
BIRTHDAY_NOTION_SECRET: "BIRTHDAY_NOTION_SECRET"
|
123
|
-
|
124
|
-
```
|
125
|
-
|
126
|
-
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:
|
127
|
-
|
128
|
-
```bash
|
129
|
-
# Accessible by all the lambdas
|
130
|
-
custom:
|
131
|
-
settings:
|
132
|
-
api:
|
133
|
-
NOTION_DATABASE_ID: ${file(./env.yml):${env:STAGE}.NOTION_DATABASE_ID}
|
134
|
-
NOTION_SECRET: ${file(./env.yml):${env:STAGE}.NOTION_SECRET}}
|
135
|
-
|
136
|
-
# Accessible by the lambda
|
137
|
-
functions:
|
138
|
-
lambdaName:
|
139
|
-
environment:
|
140
|
-
NOTION_DATABASE_ID: ${file(./env.yml):${env:STAGE}.NOTION_DATABASE_ID}
|
141
|
-
NOTION_SECRET: ${file(./env.yml):${env:STAGE}.NOTION_SECRET}}
|
142
|
-
```
|
143
|
-
|
144
|
-
#### Schedule
|
145
|
-
the schedule is configured using an environment variable containing the cron configuration. For example:
|
146
|
-
```bash
|
147
|
-
# env.yml file
|
148
|
-
SCHEDULER: cron(0 13 ? * MON-FRI *)
|
149
|
-
|
150
|
-
# serverless.yml
|
151
|
-
functions:
|
152
|
-
lambdaName:
|
153
|
-
events:
|
154
|
-
- schedule:
|
155
|
-
rate: ${file(./env.yml):${env:STAGE}.SCHEDULER}
|
156
|
-
```
|
157
|
-
|
158
|
-
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)
|
159
|
-
|
160
|
-
#### Building your lambda
|
161
|
-
On your serverless configuration, create your lambda function, on your serverless `/src` folder.
|
162
|
-
|
163
|
-
```ruby
|
164
|
-
# frozen_string_literal: true
|
165
|
-
|
166
|
-
require 'bas/bot/fetch_birthdays_from_notion'
|
167
|
-
|
168
|
-
# Initialize the environment variables
|
169
|
-
NOTION_DATABASE_ID = ENV.fetch('NOTION_DATABASE_ID')
|
170
|
-
NOTION_SECRET = ENV.fetch('NOTION_SECRET')
|
171
|
-
|
172
|
-
module Notifier
|
173
|
-
# Service description
|
174
|
-
class UseCaseName
|
175
|
-
def self.notify(*)
|
176
|
-
options = { process_options: , write_options: }
|
177
|
-
|
178
|
-
begin
|
179
|
-
use_case = Bot::FetchBirthdaysFromNotion.new(options)
|
180
|
-
|
181
|
-
use_case.execute
|
182
|
-
rescue StandardError => e
|
183
|
-
{ body: { message: e.message } }
|
184
|
-
end
|
185
|
-
end
|
186
|
-
|
187
|
-
def self.process_options
|
188
|
-
{
|
189
|
-
database_id: NOTION_DATABASE_ID,
|
190
|
-
secret: NOTION_SECRET
|
191
|
-
}
|
192
|
-
end
|
193
|
-
|
194
|
-
def self.write_options
|
195
|
-
{
|
196
|
-
connection: {
|
197
|
-
host: "host",
|
198
|
-
port: 5432,
|
199
|
-
dbname: "bas",
|
200
|
-
user: "postgres",
|
201
|
-
password: "postgres"
|
202
|
-
},
|
203
|
-
db_table: "use_cases",
|
204
|
-
bot_name: "FetchBirthdaysFromNotion"
|
205
|
-
}
|
206
|
-
end
|
207
|
-
end
|
208
|
-
end
|
209
|
-
```
|
210
|
-
|
211
|
-
#### Configure the lambda
|
212
|
-
In the `serverless.yml` file, add a new instance in the `functions` block with this structure:
|
213
|
-
|
214
|
-
```bash
|
215
|
-
functions:
|
216
|
-
fetchBirthdayFromNotion:
|
217
|
-
handler: src/lambdas/birthday_fetch.Bot::Birthday.fetch
|
218
|
-
environment:
|
219
|
-
BIRTHDAY_NOTION_DATABASE_ID: ${file(./env.yml):${env:STAGE}.BIRTHDAY_NOTION_DATABASE_ID}
|
220
|
-
BIRTHDAY_NOTION_SECRET: ${file(./env.yml):${env:STAGE}.BIRTHDAY_NOTION_SECRET}
|
221
|
-
events:
|
222
|
-
- schedule:
|
223
|
-
name: birthday-fetch
|
224
|
-
description: "Fetch every 24 hours at 8:30 a.m (UTC-5) from monday to friday"
|
225
|
-
rate: cron(${file(./env.yml):${env:STAGE}.BIRTHDAY_FETCH_SCHEDULER})
|
226
|
-
enabled: true
|
227
|
-
```
|
228
|
-
|
229
|
-
#### Deploying
|
230
|
-
|
231
|
-
Configure the AWS keys:
|
232
|
-
|
233
|
-
```bash
|
234
|
-
serverless config credentials --provider aws --key YOUR_KEY --secret YOUR_SECRET
|
235
|
-
```
|
236
|
-
|
237
|
-
Deploy the project:
|
238
|
-
```bash
|
239
|
-
STAGE=prod sls deploy --verbose
|
240
|
-
```
|
105
|
+
## Real case usage
|
106
|
+
For implementation details, please refer to the examples folder in the repository. You can find an example of how to configure a Lambda function with a bot there.
|
241
107
|
|
242
108
|
## Development
|
243
109
|
|
@@ -0,0 +1,132 @@
|
|
1
|
+
### Serverless
|
2
|
+
We'll explain how to configure and deploy a bot with serverless.
|
3
|
+
|
4
|
+
#### Configuring environment variables
|
5
|
+
Create the environment variables configuration file (`env.yml`)
|
6
|
+
|
7
|
+
And put the following env variables
|
8
|
+
```
|
9
|
+
dev:
|
10
|
+
BIRTHDAY_NOTION_DATABASE_ID: "BIRTHDAY_NOTION_DATABASE_ID"
|
11
|
+
BIRTHDAY_NOTION_SECRET: "BIRTHDAY_NOTION_SECRET"
|
12
|
+
prod:
|
13
|
+
BIRTHDAY_NOTION_DATABASE_ID: "BIRTHDAY_NOTION_DATABASE_ID"
|
14
|
+
BIRTHDAY_NOTION_SECRET: "BIRTHDAY_NOTION_SECRET"
|
15
|
+
|
16
|
+
```
|
17
|
+
|
18
|
+
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:
|
19
|
+
|
20
|
+
```bash
|
21
|
+
# Accessible by all the lambdas
|
22
|
+
custom:
|
23
|
+
settings:
|
24
|
+
api:
|
25
|
+
NOTION_DATABASE_ID: ${file(./env.yml):${env:STAGE}.NOTION_DATABASE_ID}
|
26
|
+
NOTION_SECRET: ${file(./env.yml):${env:STAGE}.NOTION_SECRET}}
|
27
|
+
|
28
|
+
# Accessible by the lambda
|
29
|
+
functions:
|
30
|
+
lambdaName:
|
31
|
+
environment:
|
32
|
+
NOTION_DATABASE_ID: ${file(./env.yml):${env:STAGE}.NOTION_DATABASE_ID}
|
33
|
+
NOTION_SECRET: ${file(./env.yml):${env:STAGE}.NOTION_SECRET}}
|
34
|
+
```
|
35
|
+
|
36
|
+
#### Schedule
|
37
|
+
the schedule is configured using an environment variable containing the cron configuration. For example:
|
38
|
+
```bash
|
39
|
+
# env.yml file
|
40
|
+
SCHEDULER: cron(0 13 ? * MON-FRI *)
|
41
|
+
|
42
|
+
# serverless.yml
|
43
|
+
functions:
|
44
|
+
lambdaName:
|
45
|
+
events:
|
46
|
+
- schedule:
|
47
|
+
rate: ${file(./env.yml):${env:STAGE}.SCHEDULER}
|
48
|
+
```
|
49
|
+
|
50
|
+
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)
|
51
|
+
|
52
|
+
#### Building your lambda
|
53
|
+
On your serverless configuration, create your lambda function, on your serverless `/src` folder.
|
54
|
+
|
55
|
+
```ruby
|
56
|
+
# frozen_string_literal: true
|
57
|
+
|
58
|
+
require 'bas/bot/fetch_birthdays_from_notion'
|
59
|
+
|
60
|
+
# Initialize the environment variables
|
61
|
+
NOTION_DATABASE_ID = ENV.fetch('NOTION_DATABASE_ID')
|
62
|
+
NOTION_SECRET = ENV.fetch('NOTION_SECRET')
|
63
|
+
|
64
|
+
module Notifier
|
65
|
+
# Service description
|
66
|
+
class UseCaseName
|
67
|
+
def self.notify(*)
|
68
|
+
options = { process_options: , write_options: }
|
69
|
+
|
70
|
+
begin
|
71
|
+
use_case = Bot::FetchBirthdaysFromNotion.new(options)
|
72
|
+
|
73
|
+
use_case.execute
|
74
|
+
rescue StandardError => e
|
75
|
+
{ body: { message: e.message } }
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def self.process_options
|
80
|
+
{
|
81
|
+
database_id: NOTION_DATABASE_ID,
|
82
|
+
secret: NOTION_SECRET
|
83
|
+
}
|
84
|
+
end
|
85
|
+
|
86
|
+
def self.write_options
|
87
|
+
{
|
88
|
+
connection: {
|
89
|
+
host: "host",
|
90
|
+
port: 5432,
|
91
|
+
dbname: "bas",
|
92
|
+
user: "postgres",
|
93
|
+
password: "postgres"
|
94
|
+
},
|
95
|
+
db_table: "use_cases",
|
96
|
+
bot_name: "FetchBirthdaysFromNotion"
|
97
|
+
}
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
```
|
102
|
+
|
103
|
+
#### Configure the lambda
|
104
|
+
In the `serverless.yml` file, add a new instance in the `functions` block with this structure:
|
105
|
+
|
106
|
+
```bash
|
107
|
+
functions:
|
108
|
+
fetchBirthdayFromNotion:
|
109
|
+
handler: src/lambdas/birthday_fetch.Bot::Birthday.fetch
|
110
|
+
environment:
|
111
|
+
BIRTHDAY_NOTION_DATABASE_ID: ${file(./env.yml):${env:STAGE}.BIRTHDAY_NOTION_DATABASE_ID}
|
112
|
+
BIRTHDAY_NOTION_SECRET: ${file(./env.yml):${env:STAGE}.BIRTHDAY_NOTION_SECRET}
|
113
|
+
events:
|
114
|
+
- schedule:
|
115
|
+
name: birthday-fetch
|
116
|
+
description: "Fetch every 24 hours at 8:30 a.m (UTC-5) from monday to friday"
|
117
|
+
rate: cron(${file(./env.yml):${env:STAGE}.BIRTHDAY_FETCH_SCHEDULER})
|
118
|
+
enabled: true
|
119
|
+
```
|
120
|
+
|
121
|
+
#### Deploying
|
122
|
+
|
123
|
+
Configure the AWS keys:
|
124
|
+
|
125
|
+
```bash
|
126
|
+
serverless config credentials --provider aws --key YOUR_KEY --secret YOUR_SECRET
|
127
|
+
```
|
128
|
+
|
129
|
+
Deploy the project:
|
130
|
+
```bash
|
131
|
+
STAGE=prod sls deploy --verbose
|
132
|
+
```
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require_relative "./base"
|
4
|
-
require_relative "../read/
|
4
|
+
require_relative "../read/postgres"
|
5
5
|
require_relative "../utils/digital_ocean/request"
|
6
6
|
require_relative "../write/postgres"
|
7
7
|
|
@@ -37,7 +37,7 @@ module Bot
|
|
37
37
|
# Read function to execute the default Read component
|
38
38
|
#
|
39
39
|
def read
|
40
|
-
reader = Read::
|
40
|
+
reader = Read::Postgres.new(read_options.merge(conditions))
|
41
41
|
|
42
42
|
reader.execute
|
43
43
|
end
|
@@ -48,8 +48,7 @@ module Bot
|
|
48
48
|
response = Utils::DigitalOcean::Request.execute(params)
|
49
49
|
|
50
50
|
if response.code == 200
|
51
|
-
|
52
|
-
{ success: { billing: response.parsed_response } }
|
51
|
+
{ success: { billing: response.parsed_response, last_billing: } }
|
53
52
|
else
|
54
53
|
{ error: { message: response.parsed_response, status_code: response.code } }
|
55
54
|
end
|
@@ -65,6 +64,13 @@ module Bot
|
|
65
64
|
|
66
65
|
private
|
67
66
|
|
67
|
+
def conditions
|
68
|
+
{
|
69
|
+
where: "archived=$1 AND tag=$2 ORDER BY inserted_at DESC",
|
70
|
+
params: [false, read_options[:tag]]
|
71
|
+
}
|
72
|
+
end
|
73
|
+
|
68
74
|
def params
|
69
75
|
{
|
70
76
|
endpoint: "customers/my/balance",
|
@@ -73,5 +79,11 @@ module Bot
|
|
73
79
|
body: {}
|
74
80
|
}
|
75
81
|
end
|
82
|
+
|
83
|
+
def last_billing
|
84
|
+
return read_response.data["billing"] unless read_response.data.nil?
|
85
|
+
|
86
|
+
{ month_to_date_balance: 0 }
|
87
|
+
end
|
76
88
|
end
|
77
89
|
end
|
@@ -79,23 +79,30 @@ module Bot
|
|
79
79
|
end
|
80
80
|
|
81
81
|
def threshold_exceeded
|
82
|
-
|
82
|
+
return false if billing.zero?
|
83
|
+
|
84
|
+
usage > process_options[:threshold]
|
85
|
+
end
|
86
|
+
|
87
|
+
def usage
|
88
|
+
billing - last_billing
|
83
89
|
end
|
84
90
|
|
85
|
-
def
|
86
|
-
|
87
|
-
|
91
|
+
def billing
|
92
|
+
read_response.data["billing"]["month_to_date_balance"].to_f
|
93
|
+
end
|
88
94
|
|
89
|
-
|
95
|
+
def last_billing
|
96
|
+
read_response.data["last_billing"]["month_to_date_balance"].to_f
|
90
97
|
end
|
91
98
|
|
92
99
|
def message
|
93
|
-
balance =
|
100
|
+
balance = billing
|
94
101
|
threshold = process_options[:threshold]
|
95
102
|
|
96
103
|
":warning: The **DigitalOcean** daily usage was exceeded. \
|
97
104
|
Current balance: #{balance}, Threshold: #{threshold}, \
|
98
|
-
Current daily usage: #{
|
105
|
+
Current daily usage: #{usage.round(3)}"
|
99
106
|
end
|
100
107
|
end
|
101
108
|
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.
|
4
|
+
version: 1.4.2
|
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-08-
|
11
|
+
date: 2024-08-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: gmail_xoauth
|
@@ -184,6 +184,7 @@ files:
|
|
184
184
|
- README.md
|
185
185
|
- Rakefile
|
186
186
|
- SECURITY.md
|
187
|
+
- examples/serverless_example.md
|
187
188
|
- lib/bas.rb
|
188
189
|
- lib/bas/bot/base.rb
|
189
190
|
- lib/bas/bot/compare_wip_limit_count.rb
|