rodbot 0.4.1 → 0.4.3
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/CHANGELOG.md +10 -0
- data/README.md +25 -21
- data/checksums/rodbot-0.4.2.gem.sha512 +1 -0
- data/checksums/rodbot-0.4.3.gem.sha512 +1 -0
- data/lib/rodbot/plugins/word_of_the_day/README.word_of_the_day.md +27 -0
- data/lib/rodbot/plugins/word_of_the_day/adapter.rb +22 -0
- data/lib/rodbot/plugins/word_of_the_day/adapters/base.rb +27 -0
- data/lib/rodbot/plugins/word_of_the_day/adapters/merriam_webster.rb +34 -0
- data/lib/rodbot/plugins/word_of_the_day/adapters/transparent.rb +54 -0
- data/lib/rodbot/plugins/word_of_the_day/schedule.rb +7 -26
- data/lib/rodbot/services/schedule.rb +4 -1
- data/lib/rodbot/version.rb +1 -1
- data.tar.gz.sig +3 -1
- metadata +8 -2
- metadata.gz.sig +1 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 63507ad988e8bc39e627cfe154e6713be7e64026e50d222bafc828cb3063825b
|
|
4
|
+
data.tar.gz: cbb4dd2628412ea4b2672e4dfe1f313ff758124a07dfd41082f38e655d5a4ee7
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 0cb3f6d314ffedd6e8e25f33abb967a03837512f3ba35b0cc4d14746fa19ac8b491e53bb6653fa3d4f2a6158764fb377eaa7c94b625fa86b5294fc23f921f1e7
|
|
7
|
+
data.tar.gz: cd5d8bc13b3d52f40231b5bb57a0872b340e962caf062e5dab80167d2a5cc35afc57619d36359ebdf5bda133296a608ce603039759bd99e3d4a8ccb0bc6be6ed
|
checksums.yaml.gz.sig
CHANGED
|
Binary file
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
|
@@ -17,21 +17,21 @@ Minimalistic yet polyglot framework to build chat bots on top of a Roda backend
|
|
|
17
17
|
|
|
18
18
|
## Table of Contents
|
|
19
19
|
|
|
20
|
-
[Install](#
|
|
21
|
-
[Anatomy](#
|
|
22
|
-
   [App Service](#
|
|
23
|
-
   [Relay Services](#
|
|
24
|
-
   [Schedule Service](#
|
|
25
|
-
[CLI](#
|
|
20
|
+
[Install](#install) <br>
|
|
21
|
+
[Anatomy](#anatomy) <br>
|
|
22
|
+
   [App Service](#app-service) <br>
|
|
23
|
+
   [Relay Services](#relay-services) <br>
|
|
24
|
+
   [Schedule Service](#schedule-service) <br>
|
|
25
|
+
[CLI](#CLI) <br>
|
|
26
26
|
[Request](#request)<br>
|
|
27
27
|
[Say](#say)<br>
|
|
28
|
-
[Routes and Commands](#
|
|
29
|
-
[Database](#
|
|
28
|
+
[Routes and Commands](#routes-and-commands) <br>
|
|
29
|
+
[Database](#database) <br>
|
|
30
30
|
[Environments](#environments) <br>
|
|
31
31
|
[Credentials](#credentials) <br>
|
|
32
|
-
[Plugins](#
|
|
33
|
-
[Environment Variables](#
|
|
34
|
-
[Development](#
|
|
32
|
+
[Plugins](#plugins) <br>
|
|
33
|
+
[Environment Variables](#environment-variables) <br>
|
|
34
|
+
[Development](#development) <br>
|
|
35
35
|
|
|
36
36
|
## Install
|
|
37
37
|
|
|
@@ -53,7 +53,7 @@ rodbot new my_bot
|
|
|
53
53
|
cd my_bot
|
|
54
54
|
```
|
|
55
55
|
|
|
56
|
-
For the bot to be useful at all, you should choose one of the supported [relay service plugins](#
|
|
56
|
+
For the bot to be useful at all, you should choose one of the supported [relay service plugins](#plugins). Say, you'd like to interact via Matrix:
|
|
57
57
|
|
|
58
58
|
```
|
|
59
59
|
bundle config set --local with matrix
|
|
@@ -137,7 +137,7 @@ It loads the following Roda plugins:
|
|
|
137
137
|
* [unescape_path](http://roda.jeremyevans.net/rdoc/classes/Roda/RodaPlugins/UnescapePath.html)
|
|
138
138
|
* [render](http://roda.jeremyevans.net/rdoc/classes/Roda/RodaPlugins/Render.html)
|
|
139
139
|
|
|
140
|
-
It loads the following Roda
|
|
140
|
+
It also loads the following Roda extension provided by Rodbot:
|
|
141
141
|
|
|
142
142
|
* Shortcut `r.arguments` for `r.params['arguments']`
|
|
143
143
|
|
|
@@ -159,7 +159,7 @@ port 12345
|
|
|
159
159
|
|
|
160
160
|
#### Commands
|
|
161
161
|
|
|
162
|
-
All top level GET requests such as `GET /foobar` are commands and therefore
|
|
162
|
+
All top level GET requests such as `GET /foobar` are commands and therefore accessible by relays, for instance using `!foobar` on Matrix.
|
|
163
163
|
|
|
164
164
|
Responses have to be either of the following content types:
|
|
165
165
|
|
|
@@ -168,7 +168,7 @@ Responses have to be either of the following content types:
|
|
|
168
168
|
|
|
169
169
|
Please note that the Markdown might get stripped on communication networks which feature only limited or no support for Markdown.
|
|
170
170
|
|
|
171
|
-
The response may contain special tags which have to be
|
|
171
|
+
The response may contain special tags which have to be replaced appropriately by the corresponding **relay service**:
|
|
172
172
|
|
|
173
173
|
Tag | Replaced with
|
|
174
174
|
----|--------------
|
|
@@ -211,7 +211,11 @@ The **schedule service** is a [Clockwork process](https://github.com/Rykian/cloc
|
|
|
211
211
|
|
|
212
212
|
It's a good idea to have the **app service** do the heavy lifting while the schedule simply fires the corresponding HTTP request.
|
|
213
213
|
|
|
214
|
-
A word on time zones since they are particularly important for schedules:
|
|
214
|
+
A word or two on time zones since they are particularly important for schedules:
|
|
215
|
+
|
|
216
|
+
Automatic discovery of the local time zone and DST status is rather unreliable. Therefore, Rodbot expects you to set the time zone in `config/rodbot.rb` using `time_zone`. See `ls /usr/share/zoneinfo` for valid values. To correctly handle DST, you should use geographical zones like `Europe/Paris` rather than technical zones like `CET`. If `time_zone` is not defined, the environment variable `TZ` is read instead. And if `TZ` isn't set neither, Rodbot falls back to `Etc/UTC`.
|
|
217
|
+
|
|
218
|
+
Also, make sure the [time zone data is available](https://tzinfo.github.io) where you deploy your bot to. The [official Alpine-based Ruby images](https://hub.docker.com/_/ruby) for instance doesn't come with it preinstalled, so you either have to `RUN apk add --no-cache tzdata` in the Dockerfile or add the [tzinfo-data gem](https://rubygems.org/gems/tzinfo-data) to the bundle for `TZ` to have any effect at all.
|
|
215
219
|
|
|
216
220
|
## CLI
|
|
217
221
|
|
|
@@ -478,10 +482,10 @@ Name | Dependencies | Description
|
|
|
478
482
|
-----|--------------|------------
|
|
479
483
|
[:matrix](https://rubydoc.info/github/svoop/rodbot/file/lib/rodbot/plugins/matrix/README.matrix.md) | yes | relay service for the [Matrix communication network](https://matrix.org)
|
|
480
484
|
[:otp](https://rubydoc.info/github/svoop/rodbot/file/lib/rodbot/plugins/otp/README.otp.md) | yes | guard commands with one-time passwords
|
|
481
|
-
[:gitlab_webhook](
|
|
482
|
-
[:github_webhook](
|
|
485
|
+
[:gitlab_webhook](https://rubydoc.info/github/svoop/rodbot/file/lib/rodbot/plugins/gitlab_webhook/README.gitlab_webhook.md) | no | event announcements from [GitLab](https://gitlab.com)
|
|
486
|
+
[:github_webhook](https://rubydoc.info/github/svoop/rodbot/file/lib/rodbot/plugins/github_webhook/README.github_webhook.md) | no | event announcements from [GitHub](https://github.com)
|
|
483
487
|
[:hal](https://rubydoc.info/github/svoop/rodbot/file/lib/rodbot/plugins/hal/README.hal.md) | no | feel like Dave (demo)
|
|
484
|
-
[:word_of_the_day](
|
|
488
|
+
[:word_of_the_day](https://rubydoc.info/github/svoop/rodbot/file/lib/rodbot/plugins/word_of_the_day/README.word_of_the_day.md) | no | word of the day announcements (demo)
|
|
485
489
|
|
|
486
490
|
You have to install the corresponding Bundler group in case the plugin depends on extra gems. Here's an example for the `:otp` plugin listed above:
|
|
487
491
|
|
|
@@ -597,7 +601,7 @@ end
|
|
|
597
601
|
|
|
598
602
|
The `loops` method must returns an array of callables (e.g. a Proc or Method) which will be called when this relay service is started. The loops must trap the `INT` signal.
|
|
599
603
|
|
|
600
|
-
Proactive
|
|
604
|
+
Proactive messages require other parts of Rodbot to forward a message directly. To do so, the relay has to implement a TCP socket. This socket must bind to the IP and port you get from the `bind` method which returns an array like `["localhost", 7201]`.
|
|
601
605
|
|
|
602
606
|
For an example, take a look at the [:matrix plugin](https://github.com/svoop/rodbot/tree/main/lib/rodbot/plugins/matrix).
|
|
603
607
|
|
|
@@ -633,7 +637,7 @@ For an example, take a look at the [:word_of_the_day plugin](https://github.com/
|
|
|
633
637
|
|
|
634
638
|
#### Toolbox
|
|
635
639
|
|
|
636
|
-
Before you write a plugin,
|
|
640
|
+
Before you write a plugin, familiarise yourself with the following bundled helpers:
|
|
637
641
|
|
|
638
642
|
* [Rodbot::Refinements](https://www.rubydoc.info/gems/rodbot/Rodbot/Refinements.html) – just a few handy extensions to Ruby core classes
|
|
639
643
|
* [Rodbot::Memoize](https://www.rubydoc.info/gems/rodbot/Rodbot/Memoize.html) – environment-aware memoization for method return values
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
f6c9c9fd62c5b0c22400fc958198c6d34b8d9b01242b8f7d028fe8622c8c2e8ba955fce7071e05ef0ea3a49e1559954856e21113b1a623c0efd7ed884400a4cc
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
909cbacb1a78772d5da56bfb4f1ed391fd43e5c9d2abfb347332e7d5933b3cf1afc4ee11cb6fdc1cc5cb61e2f187d3e700f7a66648f8c1facd78201c68e553e2
|
|
@@ -11,3 +11,30 @@ plugin :word_of_the_day do
|
|
|
11
11
|
time '10:00'
|
|
12
12
|
end
|
|
13
13
|
```
|
|
14
|
+
|
|
15
|
+
By default, the English word of the day from Merriam-Webster is used, but you can [select another language from Transparent](https://www.transparent.com/word-of-the-day/):
|
|
16
|
+
|
|
17
|
+
```ruby
|
|
18
|
+
plugin :word_of_the_day do
|
|
19
|
+
time '10:00'
|
|
20
|
+
languages %w(French)
|
|
21
|
+
end
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
You can also select more than one language:
|
|
25
|
+
|
|
26
|
+
```ruby
|
|
27
|
+
plugin :word_of_the_day do
|
|
28
|
+
time '10:00'
|
|
29
|
+
languages %w(English French Swedish)
|
|
30
|
+
end
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Given the above, the word of the day for any given day might look something like this:
|
|
34
|
+
|
|
35
|
+
```
|
|
36
|
+
Word of the day: foobar (English) / foobâr (French) / foobår (Swedish)
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
In case the word of the day is not available, the message will contain the missing language struck through.
|
|
40
|
+
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'adapters/base'
|
|
4
|
+
require_relative 'adapters/merriam_webster'
|
|
5
|
+
require_relative 'adapters/transparent'
|
|
6
|
+
|
|
7
|
+
module Rodbot
|
|
8
|
+
class Plugins
|
|
9
|
+
class WordOfTheDay
|
|
10
|
+
class Adapter
|
|
11
|
+
extend Forwardable
|
|
12
|
+
|
|
13
|
+
def_delegator :@adapter, :message, :message
|
|
14
|
+
|
|
15
|
+
def initialize(language)
|
|
16
|
+
@language = language
|
|
17
|
+
@adapter = (language == 'English' ? MerriamWebster : Transparent).new(language)
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'httpx'
|
|
4
|
+
|
|
5
|
+
module Rodbot
|
|
6
|
+
class Plugins
|
|
7
|
+
class WordOfTheDay
|
|
8
|
+
class Adapter
|
|
9
|
+
class Base
|
|
10
|
+
attr_reader :language
|
|
11
|
+
|
|
12
|
+
def initialize(language)
|
|
13
|
+
@language = language.downcase
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def message
|
|
17
|
+
if word
|
|
18
|
+
"[#{word}](#{url}) (#{language.capitalize})"
|
|
19
|
+
else
|
|
20
|
+
"~~#{language.capitalize}~~"
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Rodbot
|
|
4
|
+
class Plugins
|
|
5
|
+
class WordOfTheDay
|
|
6
|
+
class Adapter
|
|
7
|
+
class MerriamWebster < Base
|
|
8
|
+
private
|
|
9
|
+
|
|
10
|
+
def word
|
|
11
|
+
html.match(/<h2 class="word-header-txt">(.+?)</)&.captures&.first
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def url
|
|
15
|
+
"https://www.merriam-webster.com/word-of-the-day/#{today}"
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
private
|
|
19
|
+
|
|
20
|
+
def today
|
|
21
|
+
Time.now.strftime('%F')
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def html
|
|
25
|
+
case (response = HTTPX.get(url))
|
|
26
|
+
in { status: 200 } then response.body.to_s
|
|
27
|
+
else ''
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Rodbot
|
|
4
|
+
class Plugins
|
|
5
|
+
class WordOfTheDay
|
|
6
|
+
class Adapter
|
|
7
|
+
class Transparent < Base
|
|
8
|
+
LANGUAGE_CODES = {
|
|
9
|
+
'arabic' => 'ar',
|
|
10
|
+
'chinese' => 'zh',
|
|
11
|
+
'dutch' => 'nl',
|
|
12
|
+
'esperanto' => 'esp',
|
|
13
|
+
'french' => 'fr',
|
|
14
|
+
'german' => 'de',
|
|
15
|
+
'irish' => 'ga',
|
|
16
|
+
'italian' => 'it',
|
|
17
|
+
'japanese' => 'ja',
|
|
18
|
+
'latin' => 'la',
|
|
19
|
+
'polish' => 'pl',
|
|
20
|
+
'portuguese' => 'pt',
|
|
21
|
+
'russian' => 'ru',
|
|
22
|
+
'spanish' => 'es'
|
|
23
|
+
}.freeze
|
|
24
|
+
|
|
25
|
+
def word
|
|
26
|
+
xml.match(/<word>(.+?)</)&.captures&.first
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def url
|
|
30
|
+
"https://wotd.transparent.com/widget/?lang=#{language}&date=#{today}"
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
private
|
|
34
|
+
|
|
35
|
+
def today
|
|
36
|
+
Time.now.strftime('%m-%d-%Y')
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def language_code
|
|
40
|
+
LANGUAGE_CODES.fetch(language, language)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def xml
|
|
44
|
+
xml_url = "https://wotd.transparent.com/rss/#{today}-#{language_code}-widget.xml"
|
|
45
|
+
case (response = HTTPX.get(xml_url))
|
|
46
|
+
in { status: 200 } then response.body.to_s
|
|
47
|
+
else ''
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
@@ -2,12 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
require 'httpx'
|
|
4
4
|
|
|
5
|
+
require_relative 'adapter'
|
|
6
|
+
|
|
5
7
|
module Rodbot
|
|
6
8
|
class Plugins
|
|
7
9
|
class WordOfTheDay
|
|
8
10
|
class Schedule
|
|
9
11
|
def initialize
|
|
10
|
-
Clockwork.every(1.day, -> { Rodbot.say message }, at: time)
|
|
12
|
+
Clockwork.every(1.day, -> { Rodbot.say "Word of the day: #{message}" }, at: time)
|
|
11
13
|
end
|
|
12
14
|
|
|
13
15
|
private
|
|
@@ -16,36 +18,15 @@ module Rodbot
|
|
|
16
18
|
Rodbot.config(:plugin, :word_of_the_day, :time) || '12:00'
|
|
17
19
|
end
|
|
18
20
|
|
|
19
|
-
def
|
|
20
|
-
Rodbot
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
class Today
|
|
26
|
-
def initialize
|
|
27
|
-
@response = HTTPX.with(timeout: { request_timeout: 60 }).get('https://www.merriam-webster.com/word-of-the-day')
|
|
21
|
+
def languages
|
|
22
|
+
Rodbot.config(:plugin, :word_of_the_day, :languages) || %w(english)
|
|
28
23
|
end
|
|
29
24
|
|
|
30
25
|
def message
|
|
31
|
-
|
|
32
|
-
"Word of the day: [#{word}](#{url})"
|
|
33
|
-
else
|
|
34
|
-
"Sorry, there was a problem fetching the word of the day."
|
|
35
|
-
end
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
private
|
|
39
|
-
|
|
40
|
-
def word
|
|
41
|
-
@response.body.to_s.match(/<h2 class="word-header-txt">(.+?)</).captures.first
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
def url
|
|
45
|
-
@response.body.to_s.match(/<meta property="og:url" content="(.+?)"/).captures.first
|
|
26
|
+
languages.map { Adapter.new(_1).message }.compact.join(' / ')
|
|
46
27
|
end
|
|
47
28
|
end
|
|
48
|
-
|
|
49
29
|
end
|
|
50
30
|
end
|
|
51
31
|
end
|
|
32
|
+
|
|
@@ -16,7 +16,10 @@ module Rodbot
|
|
|
16
16
|
|
|
17
17
|
def run
|
|
18
18
|
Clockwork.instance_eval do
|
|
19
|
-
configure
|
|
19
|
+
configure do |config|
|
|
20
|
+
config[:tz] = Rodbot.config[:time_zone]
|
|
21
|
+
config[:logger] = Rodbot::Log.logger('schedule')
|
|
22
|
+
end
|
|
20
23
|
handler { Rodbot::Async.perform(&_1) }
|
|
21
24
|
end
|
|
22
25
|
Rodbot.plugins.extend_schedule
|
data/lib/rodbot/version.rb
CHANGED
data.tar.gz.sig
CHANGED
|
@@ -1 +1,3 @@
|
|
|
1
|
-
|
|
1
|
+
Q{<��scB�stV?�=��@�f�����d3)���9]�2����U�Z���;Q܄�q
|
|
2
|
+
^���=�Ҹ��kDB��uC�WvL�<���O�6)]q/Q�{q`�Ry�T��&�g�&u?�,'�6%��.�r�_��YԊ�F�\����H���$�I�����1bd̸�w�o��G��h%��
|
|
3
|
+
����8 �-�?�no)+������*ۤ�]`7:Z��=� �V9Ohð�o�ڱ�xpb�
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rodbot
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.4.
|
|
4
|
+
version: 0.4.3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Sven Schwyn
|
|
@@ -27,7 +27,7 @@ cert_chain:
|
|
|
27
27
|
k/QvZU05f6HMYBrPogJgIzHC/C5N/yeE4BVEuBDn+10Zb1iu3aDk8sd0uMgukCY8
|
|
28
28
|
TUmlP5A6NeGdeDJIoLgromAKs+nvI7TWzhQq9ODs51XhxgUFRCvBqUTpjTQigw==
|
|
29
29
|
-----END CERTIFICATE-----
|
|
30
|
-
date: 2023-
|
|
30
|
+
date: 2023-12-13 00:00:00.000000000 Z
|
|
31
31
|
dependencies:
|
|
32
32
|
- !ruby/object:Gem::Dependency
|
|
33
33
|
name: zeitwerk
|
|
@@ -454,6 +454,8 @@ files:
|
|
|
454
454
|
- checksums/rodbot-0.3.4.gem.sha512
|
|
455
455
|
- checksums/rodbot-0.4.0.gem.sha512
|
|
456
456
|
- checksums/rodbot-0.4.1.gem.sha512
|
|
457
|
+
- checksums/rodbot-0.4.2.gem.sha512
|
|
458
|
+
- checksums/rodbot-0.4.3.gem.sha512
|
|
457
459
|
- doc/rodbot.afphoto
|
|
458
460
|
- doc/rodbot.avif
|
|
459
461
|
- exe/rodbot
|
|
@@ -499,6 +501,10 @@ files:
|
|
|
499
501
|
- lib/rodbot/plugins/slack/README.slack.md
|
|
500
502
|
- lib/rodbot/plugins/slack/relay.rb
|
|
501
503
|
- lib/rodbot/plugins/word_of_the_day/README.word_of_the_day.md
|
|
504
|
+
- lib/rodbot/plugins/word_of_the_day/adapter.rb
|
|
505
|
+
- lib/rodbot/plugins/word_of_the_day/adapters/base.rb
|
|
506
|
+
- lib/rodbot/plugins/word_of_the_day/adapters/merriam_webster.rb
|
|
507
|
+
- lib/rodbot/plugins/word_of_the_day/adapters/transparent.rb
|
|
502
508
|
- lib/rodbot/plugins/word_of_the_day/schedule.rb
|
|
503
509
|
- lib/rodbot/rack.rb
|
|
504
510
|
- lib/rodbot/refinements.rb
|
metadata.gz.sig
CHANGED