rodbot 0.4.4 → 0.5.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
- checksums.yaml.gz.sig +0 -0
- data/.github/FUNDING.yml +2 -0
- data/.github/workflows/test.yml +1 -1
- data/.ruby-version +1 -1
- data/CHANGELOG.md +10 -0
- data/README.md +25 -24
- data/checksums/rodbot-0.4.5.gem.sha512 +1 -0
- data/checksums/rodbot-0.5.0.gem.sha512 +1 -0
- data/guardfile.rb +2 -0
- data/lib/roda/plugins/rodbot.rb +2 -0
- data/lib/rodbot/async.rb +1 -1
- data/lib/rodbot/cli/command.rb +1 -1
- data/lib/rodbot/cli/commands/console.rb +1 -1
- data/lib/rodbot/cli/commands/credentials.rb +1 -1
- data/lib/rodbot/cli/commands/deploy.rb +1 -1
- data/lib/rodbot/cli/commands/new.rb +1 -1
- data/lib/rodbot/cli/commands/simulator.rb +1 -1
- data/lib/rodbot/cli/commands/start.rb +1 -1
- data/lib/rodbot/cli/commands/stop.rb +1 -1
- data/lib/rodbot/cli/commands/version.rb +1 -1
- data/lib/rodbot/cli/commands.rb +1 -1
- data/lib/rodbot/cli.rb +1 -2
- data/lib/rodbot/config.rb +3 -1
- data/lib/rodbot/constants.rb +1 -1
- data/lib/rodbot/dispatcher.rb +1 -1
- data/lib/rodbot/env.rb +1 -1
- data/lib/rodbot/error.rb +1 -1
- data/lib/rodbot/generator.rb +1 -1
- data/lib/rodbot/log.rb +1 -1
- data/lib/rodbot/memoize.rb +1 -2
- data/lib/rodbot/message.rb +2 -2
- data/lib/rodbot/plugins/github_webhook/README.github_webhook.md +29 -5
- data/lib/rodbot/plugins/github_webhook/app.rb +26 -16
- data/lib/rodbot/plugins/gitlab_webhook/README.gitlab_webhook.md +29 -6
- data/lib/rodbot/plugins/gitlab_webhook/app.rb +25 -15
- data/lib/rodbot/plugins/hal/README.hal.md +1 -1
- data/lib/rodbot/plugins/matrix/README.matrix.md +1 -1
- data/lib/rodbot/plugins/otp/README.otp.md +1 -1
- data/lib/rodbot/plugins/slack/README.slack.md +1 -1
- data/lib/rodbot/plugins/word_of_the_day/README.word_of_the_day.md +1 -2
- data/lib/rodbot/plugins.rb +1 -1
- data/lib/rodbot/rack.rb +1 -1
- data/lib/rodbot/refinements.rb +2 -2
- data/lib/rodbot/relay.rb +1 -1
- data/lib/rodbot/serializer.rb +1 -1
- data/lib/rodbot/services/app.rb +1 -1
- data/lib/rodbot/services/relay.rb +1 -1
- data/lib/rodbot/services/schedule.rb +1 -1
- data/lib/rodbot/services.rb +1 -1
- data/lib/rodbot/simulator.rb +1 -1
- data/lib/rodbot/version.rb +1 -1
- data/lib/templates/new/app/app.rb +2 -0
- data/lib/templates/new/app/routes/healthz.rb +2 -0
- data/lib/templates/new/app/routes/help.rb +2 -0
- data/lib/templates/new/config/rodbot.rb +2 -0
- data/lib/templates/new/config/schedule.rb +2 -0
- data/lib/templates/new/gems.rb +2 -0
- data/lib/templates/new/guardfile.rb +2 -0
- data/lib/templates/new/rakefile.rb +2 -0
- data/rakefile.rb +2 -0
- data/rodbot.gemspec +3 -0
- data.tar.gz.sig +0 -0
- metadata +60 -16
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 0ef0e8aac1acb78dff6f468e08dcb92661ae7c4a4c95e98e40f19588a423939d
|
|
4
|
+
data.tar.gz: 6c16909cb0ce8808379483c45a88f932573740c43ecf569fc52e45a23230a9a7
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 91b12ad2a3a2bbda920c4f7de33481c990e686302a86de5c9e9366bee11d416550690afafcb1586f38ec9831dbfdca743801280c956617693f25746300557fae
|
|
7
|
+
data.tar.gz: 57a5d280e4e536d36ca2d044ecd17a9aba62b53cc10d3466904697916c55bc06dc0faafb572c4e4c3e4c065868f7d440c3966f0d67ca0287f34a75f5a49eeaba
|
checksums.yaml.gz.sig
CHANGED
|
Binary file
|
data/.github/FUNDING.yml
ADDED
data/.github/workflows/test.yml
CHANGED
data/.ruby-version
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
3.
|
|
1
|
+
3.4
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
[](https://rubygems.org/gems/rodbot)
|
|
2
2
|
[](https://github.com/svoop/rodbot/actions?workflow=Test)
|
|
3
3
|
[](https://codeclimate.com/github/svoop/rodbot/)
|
|
4
|
-
[](https://github.com/sponsors/svoop)
|
|
5
5
|
|
|
6
6
|
<img src="https://github.com/svoop/rodbot/raw/main/doc/rodbot.avif" alt="Rodbot" height="125" align="left">
|
|
7
7
|
|
|
@@ -15,22 +15,24 @@ Minimalistic yet polyglot framework to build chat bots on top of a Roda backend
|
|
|
15
15
|
* [API](https://rubydoc.info/gems/rodbot)
|
|
16
16
|
* Author: [Sven Schwyn - Bitcetera](https://bitcetera.com)
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
Thank you for supporting free and open-source software by sponsoring on [GitHub](https://github.com/sponsors/svoop) or on [Donorbox](https://donorbox.com/bitcetera). Any gesture is appreciated, from a single Euro for a ☕️ cup of coffee to 🍹 early retirement.
|
|
19
|
+
|
|
20
|
+
## Table of contents
|
|
19
21
|
|
|
20
22
|
[Install](#install) <br>
|
|
21
23
|
[Anatomy](#anatomy) <br>
|
|
22
|
-
   [App
|
|
23
|
-
   [Relay
|
|
24
|
-
   [Schedule
|
|
24
|
+
   [App service](#app-service) <br>
|
|
25
|
+
   [Relay services](#relay-services) <br>
|
|
26
|
+
   [Schedule service](#schedule-service) <br>
|
|
25
27
|
[CLI](#CLI) <br>
|
|
26
28
|
[Request](#request)<br>
|
|
27
29
|
[Say](#say)<br>
|
|
28
|
-
[Routes and
|
|
30
|
+
[Routes and commands](#routes-and-commands) <br>
|
|
29
31
|
[Database](#database) <br>
|
|
30
32
|
[Environments](#environments) <br>
|
|
31
33
|
[Credentials](#credentials) <br>
|
|
32
34
|
[Plugins](#plugins) <br>
|
|
33
|
-
[Environment
|
|
35
|
+
[Environment variables](#environment-variables) <br>
|
|
34
36
|
[Development](#development) <br>
|
|
35
37
|
|
|
36
38
|
## Install
|
|
@@ -43,7 +45,7 @@ This gem is [cryptographically signed](https://guides.rubygems.org/security/#usi
|
|
|
43
45
|
gem cert --add <(curl -Ls https://raw.github.com/svoop/rodbot/main/certs/svoop.pem)
|
|
44
46
|
```
|
|
45
47
|
|
|
46
|
-
### Generate
|
|
48
|
+
### Generate new bot
|
|
47
49
|
|
|
48
50
|
Similar to other frameworks, generate the files for your new bot as follows:
|
|
49
51
|
|
|
@@ -104,7 +106,7 @@ RODBOT EXTERNAL
|
|
|
104
106
|
╰╴ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╶╯
|
|
105
107
|
```
|
|
106
108
|
|
|
107
|
-
### App
|
|
109
|
+
### App service
|
|
108
110
|
|
|
109
111
|
The **app service** is a [Roda app](https://roda.jeremyevans.net) where the real action happens. It acts on and responds to HTTP requests from:
|
|
110
112
|
|
|
@@ -175,11 +177,11 @@ Tag | Replaced with
|
|
|
175
177
|
`[[SENDER]]` | Mention the sender of the command.
|
|
176
178
|
`[[EVERYBODY]]` | Mention everybody.
|
|
177
179
|
|
|
178
|
-
#### Other
|
|
180
|
+
#### Other routes
|
|
179
181
|
|
|
180
182
|
All higher level requests such as `GET /foo/bar` are not accessible by relays. Use them to implement other aspects of your bot such as webhooks or schedule tasks.
|
|
181
183
|
|
|
182
|
-
### Relay
|
|
184
|
+
### Relay services
|
|
183
185
|
|
|
184
186
|
The **relay service** act as glue between the **app service** and external communication networks such as Matrix.
|
|
185
187
|
|
|
@@ -197,7 +199,7 @@ rodbot simulator
|
|
|
197
199
|
|
|
198
200
|
Enter the command `!pay EUR 123` and you see the request `GET /pay?argument=EUR+123` hitting the **app service**.
|
|
199
201
|
|
|
200
|
-
#### TCP
|
|
202
|
+
#### TCP socket
|
|
201
203
|
|
|
202
204
|
The TCP socket is primarily used by other Rodbot services to forward messages to the corresponding external communication network. However, you can use these sockets for non-Rodbot processes as well e.g. to issue notifications when events happen on the host running Rodbot.
|
|
203
205
|
|
|
@@ -205,7 +207,7 @@ Simply connect to a socket and submit the message as plain text or Markdown in U
|
|
|
205
207
|
|
|
206
208
|
Such simple messages are always posted to the primary room (aka: channel, group etc) of the communication network. For more complex scenarios, please take a look at [message objects](https://www.rubydoc.info/gems/rodbot/Rodbot/Message) which may contain meta information as well.
|
|
207
209
|
|
|
208
|
-
### Schedule
|
|
210
|
+
### Schedule service
|
|
209
211
|
|
|
210
212
|
The **schedule service** is a [Clockwork process](https://github.com/Rykian/clockwork) which triggers Ruby code asynchronously as configured in `config/schedule.rb`.
|
|
211
213
|
|
|
@@ -225,7 +227,7 @@ The `rodbot` CLI is the main tool to manage your bot. For a full list of functio
|
|
|
225
227
|
rodbot --help
|
|
226
228
|
```
|
|
227
229
|
|
|
228
|
-
### Starting and
|
|
230
|
+
### Starting and stopping services
|
|
229
231
|
|
|
230
232
|
While working on the app service, you certainly want to try routes:
|
|
231
233
|
|
|
@@ -362,7 +364,7 @@ You can further narrow where to post the message if you specify the relay plugin
|
|
|
362
364
|
say("Hello, Slack!", on: :slack)
|
|
363
365
|
```
|
|
364
366
|
|
|
365
|
-
## Routes and
|
|
367
|
+
## Routes and commands
|
|
366
368
|
|
|
367
369
|
Adding new tricks to your bot boils down to adding routes to the app service which is powered by Roda, a simple yet very powerful framework for web applications: Easy to learn (like Sinatra) but really fast and efficient. Take a minute and [get familiar with the basics of Roda](http://roda.jeremyevans.net/).
|
|
368
370
|
|
|
@@ -428,7 +430,7 @@ The Hash backend is not thread-safe and therefore shouldn't be used in productio
|
|
|
428
430
|
db 'hash'
|
|
429
431
|
```
|
|
430
432
|
|
|
431
|
-
### Write and
|
|
433
|
+
### Write and read data
|
|
432
434
|
|
|
433
435
|
With this in place, you can access the database with `Rodbot.db`:
|
|
434
436
|
|
|
@@ -478,7 +480,7 @@ In order not to commit secrets to repositories or environment variables, Rodbot
|
|
|
478
480
|
|
|
479
481
|
Rodbot aims to keep its core small and add features via plugins, either built-in or provided by gems.
|
|
480
482
|
|
|
481
|
-
### Built-
|
|
483
|
+
### Built-in plugins
|
|
482
484
|
|
|
483
485
|
Name | Dependencies | Description
|
|
484
486
|
-----|--------------|------------
|
|
@@ -497,7 +499,7 @@ bundle config set --local with otp
|
|
|
497
499
|
bundle install
|
|
498
500
|
```
|
|
499
501
|
|
|
500
|
-
### How
|
|
502
|
+
### How plugins work
|
|
501
503
|
|
|
502
504
|
Given the following `config/rodbot.rb`:
|
|
503
505
|
|
|
@@ -517,7 +519,7 @@ Whenever a service boots, the corresponding file is required.
|
|
|
517
519
|
|
|
518
520
|
In order to keep these plugin files slim, you should extract functionality into service classes. Just put them into `rodbot/plugins/my_plugin/lib/` and use `require_relative` where you need them.
|
|
519
521
|
|
|
520
|
-
### Create
|
|
522
|
+
### Create plugins
|
|
521
523
|
|
|
522
524
|
You can create plugins in any of the following places:
|
|
523
525
|
|
|
@@ -527,7 +529,7 @@ You can create plugins in any of the following places:
|
|
|
527
529
|
|
|
528
530
|
Please adhere to common naming conventions and use the dashed prefix `rodbot-` (and Module `Rodbot`), however, underscores in case the remaining gem name consists of several words.
|
|
529
531
|
|
|
530
|
-
#### App
|
|
532
|
+
#### App extension
|
|
531
533
|
|
|
532
534
|
An app extension `rodbot/plugins/my_plugin/app.rb` defines the module `App` and looks something like this:
|
|
533
535
|
|
|
@@ -567,7 +569,7 @@ The `App` module can be used to [extend all aspects of Roda](https://github.com/
|
|
|
567
569
|
|
|
568
570
|
For an example, take a look at the [:hal plugin](https://github.com/svoop/rodbot/tree/main/lib/rodbot/plugins/hal).
|
|
569
571
|
|
|
570
|
-
#### Relay
|
|
572
|
+
#### Relay extension
|
|
571
573
|
|
|
572
574
|
A relay extension `rodbot/plugins/my_plugin/relay.rb` defines the class `Relay` and looks something like this:
|
|
573
575
|
|
|
@@ -608,7 +610,7 @@ Proactive messages require other parts of Rodbot to forward a message directly.
|
|
|
608
610
|
|
|
609
611
|
For an example, take a look at the [:matrix plugin](https://github.com/svoop/rodbot/tree/main/lib/rodbot/plugins/matrix).
|
|
610
612
|
|
|
611
|
-
#### Schedule
|
|
613
|
+
#### Schedule extension
|
|
612
614
|
|
|
613
615
|
A schedule extension `rodbot/plugins/my_plugin/schedule.rb` defines the class `Schedule` and looks something like this:
|
|
614
616
|
|
|
@@ -645,7 +647,7 @@ Before you write a plugin, familiarise yourself with the following bundled helpe
|
|
|
645
647
|
* [Rodbot::Refinements](https://www.rubydoc.info/gems/rodbot/Rodbot/Refinements.html) – just a few handy extensions to Ruby core classes
|
|
646
648
|
* [Rodbot::Memoize](https://www.rubydoc.info/gems/rodbot/Rodbot/Memoize.html) – environment-aware memoization for method return values
|
|
647
649
|
|
|
648
|
-
## Environment
|
|
650
|
+
## Environment variables
|
|
649
651
|
|
|
650
652
|
Environment variables are used for the configuration bits which cannot or should not be part of `config/rodbot.rb` mainly because they have to be set on the infrastructure level.
|
|
651
653
|
|
|
@@ -675,4 +677,3 @@ export RODBOT_SPEC_REDIS_URL=redis://localhost:6379/10
|
|
|
675
677
|
```
|
|
676
678
|
|
|
677
679
|
You're welcome to join the [discussion forum](https://github.com/svoop/rodbot/discussions) to ask questions or drop feature ideas, [submit issues](https://github.com/svoop/rodbot/issues) you may encounter or contribute code by [forking this project and submitting pull requests](https://docs.github.com/en/get-started/quickstart/fork-a-repo).
|
|
678
|
-
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
1542bea80fbfefefd7e4ce2e9a982a4384a023bd7a80a8e1353237070a6bccd56de7394bcdebb1fb6cba43ba4e6d1e11ed6cd3d6c23064f7ced81aadf08bd1f1
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
d48b784395edc8f74c84bd058cb67ff471a7d24023fff0a25b085ef15886820d4623f8f4a1c8023a0850b1b31f857960747df54f457bb9f96c06d7f781ede150
|
data/guardfile.rb
CHANGED
data/lib/roda/plugins/rodbot.rb
CHANGED
data/lib/rodbot/async.rb
CHANGED
data/lib/rodbot/cli/command.rb
CHANGED
data/lib/rodbot/cli/commands.rb
CHANGED
data/lib/rodbot/cli.rb
CHANGED
data/lib/rodbot/config.rb
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#
|
|
1
|
+
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Rodbot
|
|
4
4
|
|
|
@@ -115,6 +115,8 @@ module Rodbot
|
|
|
115
115
|
# @param strings [String, nil] one or more strings to evaluate
|
|
116
116
|
# @return [self]
|
|
117
117
|
def eval_strings(*strings)
|
|
118
|
+
# TODO: filter magic comment until they are no longer requred to prevent warning
|
|
119
|
+
strings = strings.map { _1&.sub(/# frozen_string_literal: true/, '') }
|
|
118
120
|
instance_eval(strings.compact.join("\n"))
|
|
119
121
|
self
|
|
120
122
|
end
|
data/lib/rodbot/constants.rb
CHANGED
data/lib/rodbot/dispatcher.rb
CHANGED
data/lib/rodbot/env.rb
CHANGED
data/lib/rodbot/error.rb
CHANGED
data/lib/rodbot/generator.rb
CHANGED
data/lib/rodbot/log.rb
CHANGED
data/lib/rodbot/memoize.rb
CHANGED
data/lib/rodbot/message.rb
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#
|
|
1
|
+
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Rodbot
|
|
4
4
|
|
|
@@ -58,7 +58,7 @@ module Rodbot
|
|
|
58
58
|
fail(ArgumentError, "not a dumped message") unless hash['class'] == self.class.to_s
|
|
59
59
|
initialize(hash['text'], room: room || hash['room'])
|
|
60
60
|
else
|
|
61
|
-
initialize(string.
|
|
61
|
+
initialize(string.encode('UTF-8'), room: room)
|
|
62
62
|
end
|
|
63
63
|
self
|
|
64
64
|
end
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Rodbot
|
|
1
|
+
# Rodbot plugin – GitHub webhook
|
|
2
2
|
|
|
3
3
|
Pipeline event announcements from GitHub
|
|
4
4
|
|
|
@@ -18,9 +18,7 @@ To authenticate the webhook calls from GitHub, create a new random secret token:
|
|
|
18
18
|
ruby -r securerandom -e "puts SecureRandom.alphanumeric(20)"
|
|
19
19
|
```
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
Activate and configure this plugin in `config/rodbot.rb`:
|
|
21
|
+
Configure this plugin in `config/rodbot.rb`:
|
|
24
22
|
|
|
25
23
|
```ruby
|
|
26
24
|
plugin :github_webhook do
|
|
@@ -30,7 +28,7 @@ end
|
|
|
30
28
|
|
|
31
29
|
You can set any number of secure tokens here separated with colons.
|
|
32
30
|
|
|
33
|
-
##
|
|
31
|
+
## Activation
|
|
34
32
|
|
|
35
33
|
Add a webhook to every GitHub repository you'd like to see pipeline event announcements for. Go to `https://github.com/<USER>/<REPO>/settings/hooks` and create a new webhook with the following properties:
|
|
36
34
|
|
|
@@ -40,3 +38,29 @@ Add a webhook to every GitHub repository you'd like to see pipeline event announ
|
|
|
40
38
|
* SSL verification: (o) Enable SSL verification
|
|
41
39
|
* Which events? (o) Let me select individual events: [x] Workflow runs
|
|
42
40
|
* And... [x] Active
|
|
41
|
+
|
|
42
|
+
Use the test tool to verify your setup and to see what the JSON payloads look like in case you'd like to customize the handler.
|
|
43
|
+
|
|
44
|
+
## Customization
|
|
45
|
+
|
|
46
|
+
You can change how the plugin reacts to which webhook requests by configuring a custom handler proc. Here's the default one:
|
|
47
|
+
|
|
48
|
+
```ruby
|
|
49
|
+
plugin :github_webhook do
|
|
50
|
+
handler: ->(request) do
|
|
51
|
+
if request.env['HTTP_X_GITHUB_EVENT'] == 'workflow_run'
|
|
52
|
+
json = JSON.parse(request.body.read)
|
|
53
|
+
project = json.dig('repository', 'full_name')
|
|
54
|
+
status = json.dig('workflow_run', 'status')
|
|
55
|
+
status = json.dig('workflow_run', 'conclusion') if status == 'completed'
|
|
56
|
+
emoji = case status
|
|
57
|
+
when 'requested' then '🟡'
|
|
58
|
+
when 'success' then '🟢'
|
|
59
|
+
when 'failure' then '🔴'
|
|
60
|
+
else '⚪️'
|
|
61
|
+
end
|
|
62
|
+
[emoji, project, status.gsub('_', ' ')].join(' ')
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
```
|
|
@@ -6,18 +6,37 @@ module Rodbot
|
|
|
6
6
|
module App
|
|
7
7
|
|
|
8
8
|
class Routes < ::App
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
r.halt 200 if request.env['HTTP_X_GITHUB_EVENT'] == 'ping'
|
|
12
|
-
r.halt 400 unless request.env['HTTP_X_GITHUB_EVENT'] == 'workflow_run'
|
|
13
|
-
r.halt 401 unless authorized?
|
|
9
|
+
DEFAULT_HANDLER = ->(request) do
|
|
10
|
+
if request.env['HTTP_X_GITHUB_EVENT'] == 'workflow_run'
|
|
14
11
|
json = JSON.parse(request.body.read)
|
|
15
12
|
project = json.dig('repository', 'full_name')
|
|
16
13
|
status = json.dig('workflow_run', 'status')
|
|
17
14
|
status = json.dig('workflow_run', 'conclusion') if status == 'completed'
|
|
18
|
-
|
|
19
|
-
|
|
15
|
+
emoji = case status
|
|
16
|
+
when 'requested' then '🟡'
|
|
17
|
+
when 'success' then '🟢'
|
|
18
|
+
when 'failure' then '🔴'
|
|
19
|
+
else '⚪️'
|
|
20
|
+
end
|
|
21
|
+
[emoji, project, status.gsub('_', ' ')].join(' ')
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
route do |r|
|
|
26
|
+
r.post '' do
|
|
27
|
+
r.halt 200 if request.env['HTTP_X_GITHUB_EVENT'] == 'ping'
|
|
28
|
+
r.halt 401 unless authorized?
|
|
29
|
+
handler = Rodbot.config(:plugin, :github_webhook, :handler) || DEFAULT_HANDLER
|
|
30
|
+
message = handler.call(r)
|
|
31
|
+
if message&.empty?
|
|
32
|
+
r.halt 204
|
|
33
|
+
else
|
|
34
|
+
Rodbot.say message
|
|
35
|
+
r.halt 200
|
|
36
|
+
end
|
|
20
37
|
end
|
|
38
|
+
rescue => error
|
|
39
|
+
r.halt 500, error.message
|
|
21
40
|
end
|
|
22
41
|
|
|
23
42
|
private
|
|
@@ -30,15 +49,6 @@ module Rodbot
|
|
|
30
49
|
end
|
|
31
50
|
end
|
|
32
51
|
|
|
33
|
-
def emoji_for(status)
|
|
34
|
-
case status
|
|
35
|
-
when 'requested' then '🟡'
|
|
36
|
-
when 'success' then '🟢'
|
|
37
|
-
when 'failure' then '🔴'
|
|
38
|
-
else '⚪️'
|
|
39
|
-
end
|
|
40
|
-
end
|
|
41
|
-
|
|
42
52
|
end
|
|
43
53
|
end
|
|
44
54
|
end
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Rodbot
|
|
1
|
+
# Rodbot plugin – GitLab webhook
|
|
2
2
|
|
|
3
3
|
Pipeline event announcements from GitLab
|
|
4
4
|
|
|
@@ -18,9 +18,7 @@ To authenticate the webhook calls from GitLab, create a new random secret token:
|
|
|
18
18
|
ruby -r securerandom -e "puts SecureRandom.alphanumeric(20)"
|
|
19
19
|
```
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
Activate and configure this plugin in `config/rodbot.rb`:
|
|
21
|
+
Configure this plugin in `config/rodbot.rb`:
|
|
24
22
|
|
|
25
23
|
```ruby
|
|
26
24
|
plugin :gitlab_webhook do
|
|
@@ -30,11 +28,36 @@ end
|
|
|
30
28
|
|
|
31
29
|
You can set any number of secure tokens here separated with colons.
|
|
32
30
|
|
|
33
|
-
##
|
|
31
|
+
## Activation
|
|
34
32
|
|
|
35
|
-
|
|
33
|
+
Set up a webhook to every GitLab repository you'd like to see pipeline event announcements for. Go to `https://gitlab.com/<USER>/<REPO>/-/hooks` and create a new webhook with the following properties:
|
|
36
34
|
|
|
37
35
|
* URL: `https://<RODBOT-APP>/gitlab_webhook`
|
|
38
36
|
* Secret token: `<TOKEN>`
|
|
39
37
|
* Trigger: [x] Pipeline events
|
|
40
38
|
* SSL verification: [x] Enable SSL verification
|
|
39
|
+
|
|
40
|
+
Use the test tool to verify your setup and to see what the JSON payloads look like in case you'd like to customize the handler.
|
|
41
|
+
|
|
42
|
+
## Customization
|
|
43
|
+
|
|
44
|
+
You can change how the plugin reacts to which webhook requests by configuring a custom handler proc. Here's the default one:
|
|
45
|
+
|
|
46
|
+
```ruby
|
|
47
|
+
plugin :gitlab_webhook do
|
|
48
|
+
handler: ->(request) do
|
|
49
|
+
json = JSON.parse(request.body.read)
|
|
50
|
+
if json['object_kind'] == 'pipeline'
|
|
51
|
+
project = json.dig('project', 'path_with_namespace')
|
|
52
|
+
status = json.dig('object_attributes', 'detailed_status')
|
|
53
|
+
emoji = case status
|
|
54
|
+
when 'running' then '🟡'
|
|
55
|
+
when 'passed' then '🟢'
|
|
56
|
+
when 'failed' then '🔴'
|
|
57
|
+
else '⚪️'
|
|
58
|
+
end
|
|
59
|
+
[emoji, project, status.gsub('_', ' ')].join(' ')
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
```
|
|
@@ -6,16 +6,35 @@ module Rodbot
|
|
|
6
6
|
module App
|
|
7
7
|
|
|
8
8
|
class Routes < ::App
|
|
9
|
+
DEFAULT_HANDLER = ->(request) do
|
|
10
|
+
json = JSON.parse(request.body.read)
|
|
11
|
+
if json['object_kind'] == 'pipeline'
|
|
12
|
+
project = json.dig('project', 'path_with_namespace')
|
|
13
|
+
status = json.dig('object_attributes', 'detailed_status')
|
|
14
|
+
emoji = case status
|
|
15
|
+
when 'running' then '🟡'
|
|
16
|
+
when 'passed' then '🟢'
|
|
17
|
+
when 'failed' then '🔴'
|
|
18
|
+
else '⚪️'
|
|
19
|
+
end
|
|
20
|
+
[emoji, project, status.gsub('_', ' ')].join(' ')
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
9
24
|
route do |r|
|
|
10
25
|
r.post '' do
|
|
11
26
|
r.halt 401 unless authorized?
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
27
|
+
handler = Rodbot.config(:plugin, :gitlab_webhook, :handler) || DEFAULT_HANDLER
|
|
28
|
+
message = handler.call(r)
|
|
29
|
+
if message&.empty?
|
|
30
|
+
r.halt 204
|
|
31
|
+
else
|
|
32
|
+
Rodbot.say message
|
|
33
|
+
r.halt 200
|
|
34
|
+
end
|
|
18
35
|
end
|
|
36
|
+
rescue => error
|
|
37
|
+
r.halt 500, error.message
|
|
19
38
|
end
|
|
20
39
|
|
|
21
40
|
private
|
|
@@ -24,15 +43,6 @@ module Rodbot
|
|
|
24
43
|
Rodbot.config(:plugin, :gitlab_webhook, :secret_tokens).to_s.split(':').include?(request.env['HTTP_X_GITLAB_TOKEN'])
|
|
25
44
|
end
|
|
26
45
|
|
|
27
|
-
def emoji_for(status)
|
|
28
|
-
case status
|
|
29
|
-
when 'running' then '🟡'
|
|
30
|
-
when 'passed' then '🟢'
|
|
31
|
-
when 'failed' then '🔴'
|
|
32
|
-
else '⚪️'
|
|
33
|
-
end
|
|
34
|
-
end
|
|
35
|
-
|
|
36
46
|
end
|
|
37
47
|
end
|
|
38
48
|
end
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Rodbot
|
|
1
|
+
# Rodbot plugin – word of the day
|
|
2
2
|
|
|
3
3
|
Word of the day announcements
|
|
4
4
|
|
|
@@ -37,4 +37,3 @@ Word of the day: foobar (English) / foobâr (French) / foobår (Swedish)
|
|
|
37
37
|
```
|
|
38
38
|
|
|
39
39
|
In case the word of the day is not available, the message will contain the missing language struck through.
|
|
40
|
-
|
data/lib/rodbot/plugins.rb
CHANGED
data/lib/rodbot/rack.rb
CHANGED
data/lib/rodbot/refinements.rb
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#
|
|
1
|
+
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require 'uri'
|
|
4
4
|
require 'kramdown'
|
|
@@ -52,7 +52,7 @@ module Rodbot
|
|
|
52
52
|
# @return [String] concatted URI
|
|
53
53
|
refine String do
|
|
54
54
|
def uri_concat(*segments)
|
|
55
|
-
parser = URI::
|
|
55
|
+
parser = URI::RFC2396_PARSER
|
|
56
56
|
segments.inject(URI(self)) do |uri, segment|
|
|
57
57
|
uri + parser.escape(segment)
|
|
58
58
|
end.to_s
|
data/lib/rodbot/relay.rb
CHANGED
data/lib/rodbot/serializer.rb
CHANGED
data/lib/rodbot/services/app.rb
CHANGED
data/lib/rodbot/services.rb
CHANGED
data/lib/rodbot/simulator.rb
CHANGED
data/lib/rodbot/version.rb
CHANGED
data/lib/templates/new/gems.rb
CHANGED
data/rakefile.rb
CHANGED
data/rodbot.gemspec
CHANGED
|
@@ -42,6 +42,9 @@ Gem::Specification.new do |spec|
|
|
|
42
42
|
spec.required_ruby_version = '>= 3.0.0'
|
|
43
43
|
|
|
44
44
|
spec.add_runtime_dependency 'zeitwerk', '~> 2'
|
|
45
|
+
spec.add_runtime_dependency 'ostruct'
|
|
46
|
+
spec.add_runtime_dependency 'fiddle'
|
|
47
|
+
spec.add_runtime_dependency 'logger'
|
|
45
48
|
spec.add_runtime_dependency 'dry-cli', '~> 1'
|
|
46
49
|
spec.add_runtime_dependency 'dry-credentials', '~> 0'
|
|
47
50
|
spec.add_runtime_dependency 'tty-markdown', '~> 0'
|
data.tar.gz.sig
CHANGED
|
Binary file
|
metadata
CHANGED
|
@@ -1,33 +1,34 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rodbot
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.5.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Sven Schwyn
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: exe
|
|
10
9
|
cert_chain:
|
|
11
10
|
- |
|
|
12
11
|
-----BEGIN CERTIFICATE-----
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
12
|
+
MIIDODCCAiCgAwIBAgIBATANBgkqhkiG9w0BAQsFADAjMSEwHwYDVQQDDBhydWJ5
|
|
13
|
+
L0RDPWJpdGNldGVyYS9EQz1jb20wHhcNMjQxMTIwMjExMDIwWhcNMjUxMTIwMjEx
|
|
14
|
+
MDIwWjAjMSEwHwYDVQQDDBhydWJ5L0RDPWJpdGNldGVyYS9EQz1jb20wggEiMA0G
|
|
16
15
|
CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDcLg+IHjXYaUlTSU7R235lQKD8ZhEe
|
|
17
16
|
KMhoGlSUonZ/zo1OT3KXcqTCP1iMX743xYs6upEGALCWWwq+nxvlDdnWRjF3AAv7
|
|
18
17
|
ikC+Z2BEowjyeCCT/0gvn4ohKcR0JOzzRaIlFUVInlGSAHx2QHZ2N8ntf54lu7nd
|
|
19
18
|
L8CiDK8rClsY4JBNGOgH9UC81f+m61UUQuTLxyM2CXfAYkj/sGNTvFRJcNX+nfdC
|
|
20
19
|
hM9r2kH1+7wsa8yG7wJ2IkrzNACD8v84oE6qVusN8OLEMUI/NaEPVPbw2LUM149H
|
|
21
20
|
PVa0i729A4IhroNnFNmw4wOC93ARNbM1+LW36PLMmKjKudf5Exg8VmDVAgMBAAGj
|
|
22
|
-
|
|
23
|
-
yoX/
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
21
|
+
dzB1MAkGA1UdEwQCMAAwCwYDVR0PBAQDAgSwMB0GA1UdDgQWBBSfK8MtR62mQ6oN
|
|
22
|
+
yoX/VKJzFjLSVDAdBgNVHREEFjAUgRJydWJ5QGJpdGNldGVyYS5jb20wHQYDVR0S
|
|
23
|
+
BBYwFIEScnVieUBiaXRjZXRlcmEuY29tMA0GCSqGSIb3DQEBCwUAA4IBAQDSeB1x
|
|
24
|
+
8QK8F/ML37isgvwGiQxovDUqu6Sq14cQ1qE9y5prUBmL2AsDuCBpXXctcvamFqNC
|
|
25
|
+
PgfJtj7ZZcXmY0SfKCog7T1btkr6zYxPXpxwUqB45n0I6v5qc0UCNvMEfBzxlak5
|
|
26
|
+
VW7UMNlKD9qukeN55hxuLF2F/sLldMcHUo/ATgdV4zk1t3sK6A9+02wz5K5qfWdM
|
|
27
|
+
Mi+XWXmGd57uojk3RcIXNwBRRP4DTKcKgVXhuyHb7q1vjTXrS6bw1Ortu0KmWOIk
|
|
28
|
+
jTyRsT1gymASS2KHe+BaCTwD74GqO8q4woYLZgXnJ/PvgcFgY2FEi2Kn/sXLp4JE
|
|
29
|
+
boIgxQCMT+nxBHCD
|
|
29
30
|
-----END CERTIFICATE-----
|
|
30
|
-
date:
|
|
31
|
+
date: 2025-01-25 00:00:00.000000000 Z
|
|
31
32
|
dependencies:
|
|
32
33
|
- !ruby/object:Gem::Dependency
|
|
33
34
|
name: zeitwerk
|
|
@@ -43,6 +44,48 @@ dependencies:
|
|
|
43
44
|
- - "~>"
|
|
44
45
|
- !ruby/object:Gem::Version
|
|
45
46
|
version: '2'
|
|
47
|
+
- !ruby/object:Gem::Dependency
|
|
48
|
+
name: ostruct
|
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
|
50
|
+
requirements:
|
|
51
|
+
- - ">="
|
|
52
|
+
- !ruby/object:Gem::Version
|
|
53
|
+
version: '0'
|
|
54
|
+
type: :runtime
|
|
55
|
+
prerelease: false
|
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
57
|
+
requirements:
|
|
58
|
+
- - ">="
|
|
59
|
+
- !ruby/object:Gem::Version
|
|
60
|
+
version: '0'
|
|
61
|
+
- !ruby/object:Gem::Dependency
|
|
62
|
+
name: fiddle
|
|
63
|
+
requirement: !ruby/object:Gem::Requirement
|
|
64
|
+
requirements:
|
|
65
|
+
- - ">="
|
|
66
|
+
- !ruby/object:Gem::Version
|
|
67
|
+
version: '0'
|
|
68
|
+
type: :runtime
|
|
69
|
+
prerelease: false
|
|
70
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
71
|
+
requirements:
|
|
72
|
+
- - ">="
|
|
73
|
+
- !ruby/object:Gem::Version
|
|
74
|
+
version: '0'
|
|
75
|
+
- !ruby/object:Gem::Dependency
|
|
76
|
+
name: logger
|
|
77
|
+
requirement: !ruby/object:Gem::Requirement
|
|
78
|
+
requirements:
|
|
79
|
+
- - ">="
|
|
80
|
+
- !ruby/object:Gem::Version
|
|
81
|
+
version: '0'
|
|
82
|
+
type: :runtime
|
|
83
|
+
prerelease: false
|
|
84
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
85
|
+
requirements:
|
|
86
|
+
- - ">="
|
|
87
|
+
- !ruby/object:Gem::Version
|
|
88
|
+
version: '0'
|
|
46
89
|
- !ruby/object:Gem::Dependency
|
|
47
90
|
name: dry-cli
|
|
48
91
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -426,6 +469,7 @@ extra_rdoc_files:
|
|
|
426
469
|
- CHANGELOG.md
|
|
427
470
|
- LICENSE.txt
|
|
428
471
|
files:
|
|
472
|
+
- ".github/FUNDING.yml"
|
|
429
473
|
- ".github/workflows/test.yml"
|
|
430
474
|
- ".gitignore"
|
|
431
475
|
- ".ruby-version"
|
|
@@ -457,6 +501,8 @@ files:
|
|
|
457
501
|
- checksums/rodbot-0.4.2.gem.sha512
|
|
458
502
|
- checksums/rodbot-0.4.3.gem.sha512
|
|
459
503
|
- checksums/rodbot-0.4.4.gem.sha512
|
|
504
|
+
- checksums/rodbot-0.4.5.gem.sha512
|
|
505
|
+
- checksums/rodbot-0.5.0.gem.sha512
|
|
460
506
|
- doc/rodbot.afphoto
|
|
461
507
|
- doc/rodbot.avif
|
|
462
508
|
- exe/rodbot
|
|
@@ -558,7 +604,6 @@ metadata:
|
|
|
558
604
|
source_code_uri: https://github.com/svoop/rodbot
|
|
559
605
|
documentation_uri: https://www.rubydoc.info/gems/rodbot
|
|
560
606
|
bug_tracker_uri: https://github.com/svoop/rodbot/issues
|
|
561
|
-
post_install_message:
|
|
562
607
|
rdoc_options:
|
|
563
608
|
- "--title"
|
|
564
609
|
- Rodbot
|
|
@@ -580,8 +625,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
580
625
|
- !ruby/object:Gem::Version
|
|
581
626
|
version: '0'
|
|
582
627
|
requirements: []
|
|
583
|
-
rubygems_version: 3.
|
|
584
|
-
signing_key:
|
|
628
|
+
rubygems_version: 3.6.3
|
|
585
629
|
specification_version: 4
|
|
586
630
|
summary: Minimalistic framework to build chat bots on top of a Roda backend
|
|
587
631
|
test_files: []
|
metadata.gz.sig
CHANGED
|
Binary file
|