rubydium 0.1.0 → 0.2.1
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/.gitignore +2 -0
- data/.rspec +1 -0
- data/.rubocop.yml +55 -0
- data/.ruby-version +1 -1
- data/Gemfile +3 -2
- data/Gemfile.lock +28 -3
- data/README.md +85 -1
- data/example/example_bot.rb +35 -0
- data/lib/rubydium/bot.rb +70 -0
- data/lib/rubydium/config.rb +36 -0
- data/lib/rubydium/mixins/command_macros.rb +110 -0
- data/lib/rubydium/mixins/control_flow.rb +36 -0
- data/lib/rubydium/mixins/message_sending.rb +81 -0
- data/lib/rubydium/mixins.rb +17 -0
- data/lib/rubydium/version.rb +1 -1
- data/lib/rubydium.rb +8 -1
- data/rubydium.gemspec +7 -0
- metadata +40 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b77dd3488fec53db6e8af877924037be855a8e237fe1612de8f66394e418d3cb
|
4
|
+
data.tar.gz: cafc9b6f3bb0d05707594b40541cb93984fe9c95f69af524dc4a9619b05816d5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 895e9f3f019a273f54587dc754c8e7bc6a93be5f5b655b7bee391d818352ed1a672a933e8e26eb22bba6c55f1252397554b56a0e91d871c5249d6a7466641711
|
7
|
+
data.tar.gz: cfeb0b7f053ea952881521ed6a60a47341d0804529df2f20d184778772a316ec4064448e3eca3cfec453ad889442fc055b9f149e837162d0c36fb9252fed6949
|
data/.gitignore
CHANGED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--require spec_helper
|
data/.rubocop.yml
CHANGED
@@ -1,7 +1,62 @@
|
|
1
|
+
require: rubocop-rspec
|
2
|
+
|
1
3
|
AllCops:
|
2
4
|
TargetRubyVersion: 3.1.2
|
3
5
|
NewCops: enable
|
6
|
+
Exclude:
|
7
|
+
- test.rb
|
8
|
+
|
4
9
|
Layout/LineLength:
|
5
10
|
Max: 100
|
11
|
+
|
12
|
+
Layout/SpaceAroundEqualsInParameterDefault:
|
13
|
+
EnforcedStyle: no_space
|
14
|
+
|
15
|
+
Layout/SpaceInsideBlockBraces:
|
16
|
+
EnforcedStyleForEmptyBraces: space
|
17
|
+
|
18
|
+
Lint/EmptyBlock:
|
19
|
+
Exclude:
|
20
|
+
- spec/rubydium/mixins/command_macros_spec.rb
|
21
|
+
|
22
|
+
Metrics/BlockLength:
|
23
|
+
Exclude:
|
24
|
+
- spec/**/*
|
25
|
+
|
26
|
+
Metrics/MethodLength:
|
27
|
+
CountAsOne:
|
28
|
+
- array
|
29
|
+
- heredoc
|
30
|
+
- method_call
|
31
|
+
- hash
|
32
|
+
|
33
|
+
RSpec/BeNil:
|
34
|
+
EnforcedStyle: be
|
35
|
+
|
36
|
+
RSpec/ExampleLength:
|
37
|
+
Max: 10
|
38
|
+
|
39
|
+
RSpec/HookArgument:
|
40
|
+
EnforcedStyle: example
|
41
|
+
|
42
|
+
RSpec/MessageSpies:
|
43
|
+
EnforcedStyle: receive
|
44
|
+
|
45
|
+
RSpec/MultipleExpectations:
|
46
|
+
Max: 5
|
47
|
+
|
48
|
+
Style/BlockDelimiters:
|
49
|
+
EnforcedStyle: braces_for_chaining
|
50
|
+
|
51
|
+
Style/Documentation:
|
52
|
+
AllowedConstants:
|
53
|
+
- ClassMethods
|
54
|
+
|
55
|
+
Style/HashSyntax:
|
56
|
+
EnforcedShorthandSyntax: never
|
57
|
+
|
58
|
+
Style/IfUnlessModifier:
|
59
|
+
Enabled: false
|
60
|
+
|
6
61
|
Style/StringLiterals:
|
7
62
|
EnforcedStyle: double_quotes
|
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
3.
|
1
|
+
3.2.2
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -2,6 +2,10 @@ GEM
|
|
2
2
|
remote: https://rubygems.org/
|
3
3
|
specs:
|
4
4
|
ast (2.4.2)
|
5
|
+
async (2.3.1)
|
6
|
+
console (~> 1.10)
|
7
|
+
io-event (~> 1.1)
|
8
|
+
timers (~> 4.1)
|
5
9
|
axiom-types (0.1.1)
|
6
10
|
descendants_tracker (~> 0.0.4)
|
7
11
|
ice_nine (~> 0.11.0)
|
@@ -9,8 +13,11 @@ GEM
|
|
9
13
|
coderay (1.1.3)
|
10
14
|
coercible (1.0.0)
|
11
15
|
descendants_tracker (~> 0.0.1)
|
16
|
+
console (1.16.2)
|
17
|
+
fiber-local
|
12
18
|
descendants_tracker (0.0.4)
|
13
19
|
thread_safe (~> 0.3, >= 0.3.1)
|
20
|
+
diff-lcs (1.5.0)
|
14
21
|
dry-inflector (1.0.0)
|
15
22
|
faraday (2.7.2)
|
16
23
|
faraday-net_http (>= 2.0, < 3.1)
|
@@ -18,7 +25,9 @@ GEM
|
|
18
25
|
faraday-multipart (1.0.4)
|
19
26
|
multipart-post (~> 2)
|
20
27
|
faraday-net_http (3.0.2)
|
28
|
+
fiber-local (1.0.0)
|
21
29
|
ice_nine (0.11.2)
|
30
|
+
io-event (1.1.5)
|
22
31
|
json (2.6.3)
|
23
32
|
method_source (1.0.0)
|
24
33
|
multipart-post (2.2.3)
|
@@ -31,6 +40,19 @@ GEM
|
|
31
40
|
rainbow (3.1.1)
|
32
41
|
regexp_parser (2.6.1)
|
33
42
|
rexml (3.2.5)
|
43
|
+
rspec (3.12.0)
|
44
|
+
rspec-core (~> 3.12.0)
|
45
|
+
rspec-expectations (~> 3.12.0)
|
46
|
+
rspec-mocks (~> 3.12.0)
|
47
|
+
rspec-core (3.12.0)
|
48
|
+
rspec-support (~> 3.12.0)
|
49
|
+
rspec-expectations (3.12.1)
|
50
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
51
|
+
rspec-support (~> 3.12.0)
|
52
|
+
rspec-mocks (3.12.1)
|
53
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
54
|
+
rspec-support (~> 3.12.0)
|
55
|
+
rspec-support (3.12.0)
|
34
56
|
rubocop (1.41.1)
|
35
57
|
json (~> 2.3)
|
36
58
|
parallel (~> 1.10)
|
@@ -43,6 +65,8 @@ GEM
|
|
43
65
|
unicode-display_width (>= 1.4.0, < 3.0)
|
44
66
|
rubocop-ast (1.24.0)
|
45
67
|
parser (>= 3.1.1.0)
|
68
|
+
rubocop-rspec (2.16.0)
|
69
|
+
rubocop (~> 1.33)
|
46
70
|
ruby-progressbar (1.11.0)
|
47
71
|
ruby2_keywords (0.0.5)
|
48
72
|
telegram-bot-ruby (0.23.0)
|
@@ -51,6 +75,7 @@ GEM
|
|
51
75
|
faraday-multipart (~> 1.0)
|
52
76
|
virtus (~> 2.0)
|
53
77
|
thread_safe (0.3.6)
|
78
|
+
timers (4.3.5)
|
54
79
|
unicode-display_width (2.3.0)
|
55
80
|
virtus (2.0.0)
|
56
81
|
axiom-types (~> 0.1)
|
@@ -61,12 +86,12 @@ PLATFORMS
|
|
61
86
|
x86_64-linux
|
62
87
|
|
63
88
|
DEPENDENCIES
|
89
|
+
async
|
64
90
|
pry
|
91
|
+
rspec
|
65
92
|
rubocop
|
93
|
+
rubocop-rspec
|
66
94
|
telegram-bot-ruby
|
67
95
|
|
68
|
-
RUBY VERSION
|
69
|
-
ruby 3.1.2p20
|
70
|
-
|
71
96
|
BUNDLED WITH
|
72
97
|
2.3.26
|
data/README.md
CHANGED
@@ -1 +1,85 @@
|
|
1
|
-
|
1
|
+
# What it is
|
2
|
+
Rubydium is a framework for building Telegram bots.
|
3
|
+
Built on top of [telegram-bot-ruby](https://github.com/atipugin/telegram-bot-ruby) API wrapper, it aims to provide tools for building your bots with minimum boilerplate.
|
4
|
+
|
5
|
+
It's far from being done, but all the code in the [examples](example/) directory is functional and *mostly* covered with [specs](spec/rubydium/).
|
6
|
+
|
7
|
+
# Installation
|
8
|
+
CLI tool for creating and setting up new projects is planned. For now:
|
9
|
+
|
10
|
+
1. Create your project:
|
11
|
+
`mkdir example_bot && cd example_bot`
|
12
|
+
2. Install the gem:
|
13
|
+
- Add this gem to the Gemfile:
|
14
|
+
`bundle init && echo 'gem "rubydium"' >> Gemfile`
|
15
|
+
`bundle install`
|
16
|
+
- Or install system-wide:
|
17
|
+
`gem install rubydium`
|
18
|
+
3. Create your main file:
|
19
|
+
`touch example_bot.rb`
|
20
|
+
4. See the [examples](example/) directory for bot examples.
|
21
|
+
|
22
|
+
# Configuring the bot
|
23
|
+
There's two main ways to write your config. With a block:
|
24
|
+
```ruby
|
25
|
+
ExampleBot.configure do |config|
|
26
|
+
config.token = "1234567890:long_alphanumeric_string_goes_here"
|
27
|
+
config.bot_username = "ends_with_bot"
|
28
|
+
config.owner_username = "thats_you"
|
29
|
+
config.privileged_usernames = %w[
|
30
|
+
your_friend your_chat_moderator
|
31
|
+
]
|
32
|
+
end
|
33
|
+
```
|
34
|
+
Or with a hash:
|
35
|
+
```ruby
|
36
|
+
ExampleBot.config = {
|
37
|
+
token: "1234567890:long_alphanumeric_string_goes_here",
|
38
|
+
bot_username: "ends_with_bot",
|
39
|
+
owner_username: "thats_you",
|
40
|
+
privileged_usernames: %w[
|
41
|
+
your_friend your_chat_moderator
|
42
|
+
]
|
43
|
+
}
|
44
|
+
```
|
45
|
+
The hash variant also means you can pass in any valid Ruby hash, regardless of where it comes from. For example, you can set the same values, if you parse
|
46
|
+
<details>
|
47
|
+
<summary>a JSON file:</summary>
|
48
|
+
|
49
|
+
`example_bot/config.json`:
|
50
|
+
```json
|
51
|
+
{
|
52
|
+
"token": "1234567890:long_alphanumeric_string_goes_here",
|
53
|
+
"bot_username": "ends_with_bot",
|
54
|
+
"owner_username": "thats_you",
|
55
|
+
"privileged_usernames": [
|
56
|
+
"your_friend",
|
57
|
+
"your_chat_moderator"
|
58
|
+
]
|
59
|
+
}
|
60
|
+
```
|
61
|
+
`example_bot/example_bot.rb`:
|
62
|
+
```ruby
|
63
|
+
require "json"
|
64
|
+
ExampleBot.config = JSON.load_file("./config.json")
|
65
|
+
```
|
66
|
+
</details>
|
67
|
+
|
68
|
+
<details>
|
69
|
+
<summary>or a YAML:</summary>
|
70
|
+
|
71
|
+
`example_bot/config.yaml`
|
72
|
+
```yaml
|
73
|
+
token: 1234567890:long_alphanumeric_string_goes_here
|
74
|
+
bot_username: ends_with_bot
|
75
|
+
owner_username: thats_you
|
76
|
+
privileged_usernames:
|
77
|
+
- your_friend
|
78
|
+
- your_chat_moderator
|
79
|
+
```
|
80
|
+
`example_bot/example_bot.rb`:
|
81
|
+
```ruby
|
82
|
+
require "yaml"
|
83
|
+
ExampleBot.config = YAML.load_file("./config.yaml")
|
84
|
+
```
|
85
|
+
</details>
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "rubydium"
|
4
|
+
|
5
|
+
# Your actual logic of handling the updates goes here.
|
6
|
+
class ExampleBot < Rubydium::Bot
|
7
|
+
on_every_message :log_message
|
8
|
+
|
9
|
+
on_command "/help", description: "Show help message" do
|
10
|
+
text = help_message
|
11
|
+
send_message(text)
|
12
|
+
end
|
13
|
+
|
14
|
+
on_command "/start", :greet_user, description: "Say hello"
|
15
|
+
|
16
|
+
def log_message
|
17
|
+
puts "Got message from #{@user.first_name}, text: \n#{@text}"
|
18
|
+
end
|
19
|
+
|
20
|
+
def greet_user
|
21
|
+
text = "Hi hello"
|
22
|
+
reply(text)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
ExampleBot.configure do |config|
|
27
|
+
config.token = "1234567890:long_alphanumeric_string_goes_here"
|
28
|
+
config.bot_username = "ends_with_bot"
|
29
|
+
config.owner_username = "thats_you"
|
30
|
+
config.privileged_usernames = %w[
|
31
|
+
your_friend your_chat_moderator
|
32
|
+
]
|
33
|
+
end
|
34
|
+
|
35
|
+
ExampleBot.run
|
data/lib/rubydium/bot.rb
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Rubydium
|
4
|
+
# On every update a new instance of this class is created to handle it.
|
5
|
+
# This is a base class that's meant to be inherited by user's actual bot class,
|
6
|
+
# where actual logic of handling the updates is described.
|
7
|
+
class Bot
|
8
|
+
include Mixins
|
9
|
+
|
10
|
+
COMMAND_REGEXP = %r{\A/}
|
11
|
+
|
12
|
+
def self.run
|
13
|
+
Telegram::Bot::Client.run(config.token) do |client|
|
14
|
+
Async do |task|
|
15
|
+
client.listen do |update|
|
16
|
+
task.async do
|
17
|
+
# Not all `update`s here are messages (`listen` yields `Update#current_message`,
|
18
|
+
# which can be `ChatMemberUpdated` etc.)
|
19
|
+
# TODO: rework to allow for clean handling of other types.
|
20
|
+
if update.is_a? Telegram::Bot::Types::Message
|
21
|
+
new(client, update).handle_update
|
22
|
+
end
|
23
|
+
rescue => e
|
24
|
+
puts e.detailed_message, e.backtrace
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def initialize(client, update)
|
32
|
+
@client = client
|
33
|
+
@api = client.api
|
34
|
+
@msg = update
|
35
|
+
@user = @msg.from
|
36
|
+
@chat = @msg.chat
|
37
|
+
@replies_to = @msg.reply_to_message
|
38
|
+
@target = @replies_to&.from
|
39
|
+
@text = @msg.text.to_s
|
40
|
+
@message_id = @msg.message_id
|
41
|
+
@command = get_command(@msg.text)
|
42
|
+
@text_without_command = @text.gsub(@command.to_s, '').gsub(/@#{config.bot_username}\b/, '').strip
|
43
|
+
@text_without_bot_mentions = @text.gsub(/@#{config.bot_username}\b/, '')
|
44
|
+
end
|
45
|
+
|
46
|
+
def handle_update
|
47
|
+
execute_on_every_message
|
48
|
+
execute_on_mention if @text.split(/\s/).first == "@#{config.bot_username}"
|
49
|
+
# execute_on_reply if @target&.username == config.bot_username
|
50
|
+
execute_command
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
|
55
|
+
def help_message
|
56
|
+
self.class.registered_commands.map { |command, info|
|
57
|
+
"#{command} - #{info[:description]}"
|
58
|
+
}.join("\n")
|
59
|
+
end
|
60
|
+
|
61
|
+
# For example:
|
62
|
+
# "/start asdf", "/start@yourbot", "/start /another", "asdf /start" will all return "/start".
|
63
|
+
def get_command(text)
|
64
|
+
return unless text
|
65
|
+
|
66
|
+
@command = text.split.grep(%r{\A/}).first
|
67
|
+
@command&.delete_suffix("@#{config.bot_username}")
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Rubydium
|
4
|
+
class Bot # :nodoc:
|
5
|
+
def self.configure
|
6
|
+
yield config
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.config
|
10
|
+
@config ||= Config.new
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.config=(config_hash)
|
14
|
+
config_hash.each_pair do |key, value|
|
15
|
+
config.public_send("#{key}=", value)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def config
|
20
|
+
self.class.config
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
# Things that a full-fledged bot probably needs to know.
|
25
|
+
# Not necessary for basic functionality, though.
|
26
|
+
class Config
|
27
|
+
def method_missing(method, ...)
|
28
|
+
if method[-1] == '='
|
29
|
+
self.class.attr_accessor method[0..-2]
|
30
|
+
public_send(method, ...)
|
31
|
+
else
|
32
|
+
super(method, ...)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,110 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Rubydium
|
4
|
+
module Mixins
|
5
|
+
# Macro-like definitions that describe what actions bot takes
|
6
|
+
# in reaction to messages.
|
7
|
+
module CommandMacros
|
8
|
+
def self.included(base)
|
9
|
+
base.extend ClassMethods
|
10
|
+
end
|
11
|
+
|
12
|
+
module ClassMethods
|
13
|
+
def on_mention(method_name=nil, ignore_forwarded: true, &block)
|
14
|
+
@registered_on_mention ||= []
|
15
|
+
action = (method_name || block)
|
16
|
+
raise ArgumentError, "Provide either method name or a block" unless action
|
17
|
+
|
18
|
+
@registered_on_mention << {
|
19
|
+
action: action,
|
20
|
+
ignore_forwarded: ignore_forwarded
|
21
|
+
}
|
22
|
+
end
|
23
|
+
|
24
|
+
def registered_on_mention
|
25
|
+
@registered_on_mention ||= []
|
26
|
+
end
|
27
|
+
|
28
|
+
def on_every_message(method_name=nil, ignore_forwarded: true, &block)
|
29
|
+
@registered_on_every_message ||= []
|
30
|
+
action = (method_name || block)
|
31
|
+
raise ArgumentError, "Provide either method name or a block" unless action
|
32
|
+
|
33
|
+
@registered_on_every_message << {
|
34
|
+
action: action,
|
35
|
+
ignore_forwarded: ignore_forwarded
|
36
|
+
}
|
37
|
+
end
|
38
|
+
|
39
|
+
def registered_on_every_message
|
40
|
+
@registered_on_every_message ||= []
|
41
|
+
end
|
42
|
+
|
43
|
+
def on_command(command, method_name=nil, description: nil, ignore_forwarded: true, &block)
|
44
|
+
@registered_commands ||= {}
|
45
|
+
action = (method_name || block)
|
46
|
+
raise ArgumentError, "Provide either method name or a block" unless action
|
47
|
+
|
48
|
+
@registered_commands.merge!(
|
49
|
+
{
|
50
|
+
command => {
|
51
|
+
action: action,
|
52
|
+
description: description,
|
53
|
+
ignore_forwarded: ignore_forwarded
|
54
|
+
}
|
55
|
+
}
|
56
|
+
)
|
57
|
+
end
|
58
|
+
|
59
|
+
def registered_commands
|
60
|
+
@registered_commands ||= {}
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def skip_task(**kwargs)
|
65
|
+
kwargs.each_pair do |task_type, task_name|
|
66
|
+
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def execute_on_every_message
|
71
|
+
self.class.registered_on_every_message.each do |action|
|
72
|
+
next if action[:ignore_forwarded] && @msg.forward_date
|
73
|
+
execute_action(action[:action])
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def execute_on_mention
|
78
|
+
self.class.registered_on_mention.each do |action|
|
79
|
+
next if action[:ignore_forwarded] && @msg.forward_date
|
80
|
+
execute_action(action[:action])
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def execute_command
|
85
|
+
command = self.class.registered_commands[@command]
|
86
|
+
return unless command
|
87
|
+
return if command[:ignore_forwarded] && @msg.forward_date
|
88
|
+
|
89
|
+
action = command[:action]
|
90
|
+
|
91
|
+
execute_action(action)
|
92
|
+
end
|
93
|
+
|
94
|
+
def execute_action(action)
|
95
|
+
case action
|
96
|
+
when Symbol
|
97
|
+
public_send action
|
98
|
+
when Proc
|
99
|
+
instance_exec(&action)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
# # Implement @commands
|
104
|
+
# def execute_all_commands
|
105
|
+
# method_names = self.class.registered_commands.slice(*@commands).values
|
106
|
+
# method_name.each { |method| self.public_send(method) }
|
107
|
+
# end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Rubydium
|
4
|
+
module Mixins
|
5
|
+
# These methods encapsulate common logic in control flow structures
|
6
|
+
# a bot will probably have.
|
7
|
+
module ControlFlow
|
8
|
+
def must_be_owner
|
9
|
+
return not_from_owner unless @user.username == config.owner_username
|
10
|
+
|
11
|
+
yield
|
12
|
+
end
|
13
|
+
|
14
|
+
def must_be_reply
|
15
|
+
return not_a_reply unless @replies_to
|
16
|
+
|
17
|
+
yield
|
18
|
+
end
|
19
|
+
|
20
|
+
def must_be_privileged
|
21
|
+
return not_from_privileged unless config.privileged_usernames.include?(@user.username)
|
22
|
+
|
23
|
+
yield
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
# Overridable methods
|
29
|
+
def not_from_owner; end
|
30
|
+
|
31
|
+
def not_a_reply; end
|
32
|
+
|
33
|
+
def not_from_privileged; end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Rubydium
|
4
|
+
module Mixins
|
5
|
+
# Shorthand methods for sending messages in different ways.
|
6
|
+
module MessageSending
|
7
|
+
def send_message(text)
|
8
|
+
@api.send_message(
|
9
|
+
chat_id: @chat.id,
|
10
|
+
text: text
|
11
|
+
)
|
12
|
+
end
|
13
|
+
|
14
|
+
def send_sticker(sticker, action: nil, **kwargs)
|
15
|
+
chat_action_if_provided(action, :choose_sticker)
|
16
|
+
|
17
|
+
@api.send_sticker(
|
18
|
+
chat_id: @chat.id,
|
19
|
+
sticker: sticker,
|
20
|
+
**kwargs
|
21
|
+
)
|
22
|
+
end
|
23
|
+
|
24
|
+
def chat_action_if_provided(duration, action_name)
|
25
|
+
if duration
|
26
|
+
send_chat_action(action_name)
|
27
|
+
sleep duration if duration.is_a? Numeric
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def send_chat_action(action, **kwargs)
|
32
|
+
@api.send_chat_action(
|
33
|
+
chat_id: @chat.id,
|
34
|
+
action: action,
|
35
|
+
**kwargs
|
36
|
+
)
|
37
|
+
end
|
38
|
+
|
39
|
+
def send_video(video, action: nil, **kwargs)
|
40
|
+
chat_action_if_provided(action, :upload_video)
|
41
|
+
|
42
|
+
@api.send_video(
|
43
|
+
chat_id: @chat.id,
|
44
|
+
video: video,
|
45
|
+
**kwargs
|
46
|
+
)
|
47
|
+
end
|
48
|
+
|
49
|
+
def send_photo(photo, action: nil, **kwargs)
|
50
|
+
chat_action_if_provided(action, :upload_photo)
|
51
|
+
|
52
|
+
@api.send_photo(
|
53
|
+
chat_id: @chat.id,
|
54
|
+
photo: photo,
|
55
|
+
**kwargs
|
56
|
+
)
|
57
|
+
end
|
58
|
+
|
59
|
+
def reply(text, **args)
|
60
|
+
@api.send_message(
|
61
|
+
chat_id: @chat.id,
|
62
|
+
reply_to_message_id: @message_id,
|
63
|
+
text: text,
|
64
|
+
**args
|
65
|
+
)
|
66
|
+
end
|
67
|
+
|
68
|
+
def reply_code(text)
|
69
|
+
reply("```\n#{text}```", parse_mode: "Markdown")
|
70
|
+
end
|
71
|
+
|
72
|
+
def reply_to_target(text)
|
73
|
+
@api.send_message(
|
74
|
+
chat_id: @chat.id,
|
75
|
+
reply_to_message_id: @replies_to.message_id,
|
76
|
+
text: text
|
77
|
+
)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "mixins/message_sending"
|
4
|
+
require_relative "mixins/command_macros"
|
5
|
+
require_relative "mixins/control_flow"
|
6
|
+
|
7
|
+
module Rubydium
|
8
|
+
module Mixins # :nodoc:
|
9
|
+
def self.included(base)
|
10
|
+
base.include(
|
11
|
+
MessageSending,
|
12
|
+
CommandMacros,
|
13
|
+
ControlFlow
|
14
|
+
)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/lib/rubydium/version.rb
CHANGED
data/lib/rubydium.rb
CHANGED
@@ -1,4 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
3
|
+
require "telegram/bot"
|
4
|
+
require "async"
|
5
|
+
require_relative "rubydium/mixins"
|
6
|
+
require_relative "rubydium/bot"
|
7
|
+
require_relative "rubydium/config"
|
8
|
+
require_relative "rubydium/version"
|
9
|
+
|
10
|
+
module Rubydium # :nodoc:
|
4
11
|
end
|
data/rubydium.gemspec
CHANGED
@@ -32,4 +32,11 @@ Gem::Specification.new do |spec|
|
|
32
32
|
# For more information and examples about making a new gem, checkout our
|
33
33
|
# guide at: https://bundler.io/guides/creating_gem.html
|
34
34
|
spec.metadata["rubygems_mfa_required"] = "true"
|
35
|
+
|
36
|
+
{
|
37
|
+
"telegram-bot-ruby" => ['~> 0.23.0'],
|
38
|
+
"async" => ['~> 2.3']
|
39
|
+
}.each do |name, versions|
|
40
|
+
spec.add_dependency(name, *versions)
|
41
|
+
end
|
35
42
|
end
|
metadata
CHANGED
@@ -1,15 +1,43 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rubydium
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1
|
4
|
+
version: 0.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- bulgakke
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
12
|
-
dependencies:
|
11
|
+
date: 2023-09-14 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: telegram-bot-ruby
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 0.23.0
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 0.23.0
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: async
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '2.3'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '2.3'
|
13
41
|
description:
|
14
42
|
email:
|
15
43
|
- vvp835@yandex.ru
|
@@ -18,13 +46,21 @@ extensions: []
|
|
18
46
|
extra_rdoc_files: []
|
19
47
|
files:
|
20
48
|
- ".gitignore"
|
49
|
+
- ".rspec"
|
21
50
|
- ".rubocop.yml"
|
22
51
|
- ".ruby-version"
|
23
52
|
- Gemfile
|
24
53
|
- Gemfile.lock
|
25
54
|
- LICENSE
|
26
55
|
- README.md
|
56
|
+
- example/example_bot.rb
|
27
57
|
- lib/rubydium.rb
|
58
|
+
- lib/rubydium/bot.rb
|
59
|
+
- lib/rubydium/config.rb
|
60
|
+
- lib/rubydium/mixins.rb
|
61
|
+
- lib/rubydium/mixins/command_macros.rb
|
62
|
+
- lib/rubydium/mixins/control_flow.rb
|
63
|
+
- lib/rubydium/mixins/message_sending.rb
|
28
64
|
- lib/rubydium/version.rb
|
29
65
|
- rubydium.gemspec
|
30
66
|
homepage: https://github.com/bulgakke/rubydium
|
@@ -49,7 +85,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
49
85
|
- !ruby/object:Gem::Version
|
50
86
|
version: '0'
|
51
87
|
requirements: []
|
52
|
-
rubygems_version: 3.
|
88
|
+
rubygems_version: 3.4.10
|
53
89
|
signing_key:
|
54
90
|
specification_version: 4
|
55
91
|
summary: An OO framework for building Telegram bots. That's the plan, at least.
|