telepost 0.8.0 → 0.9.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/Gemfile +1 -0
- data/Gemfile.lock +25 -27
- data/README.md +11 -1
- data/Rakefile +1 -1
- data/lib/telepost.rb +69 -28
- data/telepost.gemspec +3 -3
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 847510fbfea002fc65ee0a20dbc39dd2c5ede53aab590c5a8aa2ed66f2bdc50e
|
|
4
|
+
data.tar.gz: '086d01f73bff093ef51dbbcb67757d48d21a37211131ca6522e5b2f25901345b'
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 77b5815fcaa702a9a0c422b7633e4992cb7824d79e0c0eb0a77ce03bd4e58464463eab5a3a154e47c4aad0704601d9fc7fa43c1c3fb2656401e88d1d4bd4df04
|
|
7
|
+
data.tar.gz: 4e9334873a9a5e0e9e7c92828b657fbc00b9f822e6c471f6c57bc7b582e3a54b6c6dde6a3c332de43614cffe7c31485678f8206f8fff7ee185ba9c6dc1f65142
|
data/Gemfile
CHANGED
|
@@ -10,6 +10,7 @@ gem 'minitest', '~>6.0', require: false
|
|
|
10
10
|
gem 'minitest-reporters', '~>1.7', require: false
|
|
11
11
|
gem 'rake', '~>13.2', require: false
|
|
12
12
|
gem 'rubocop', '~>1.71', require: false
|
|
13
|
+
gem 'rubocop-elegant', '>=0.0.20', require: false
|
|
13
14
|
gem 'rubocop-minitest', '~>0.38', require: false
|
|
14
15
|
gem 'rubocop-performance', '~>1.25', require: false
|
|
15
16
|
gem 'rubocop-rake', '~>0.7', require: false
|
data/Gemfile.lock
CHANGED
|
@@ -11,25 +11,25 @@ GEM
|
|
|
11
11
|
public_suffix (>= 2.0.2, < 8.0)
|
|
12
12
|
ansi (1.6.0)
|
|
13
13
|
ast (2.4.3)
|
|
14
|
-
bigdecimal (4.1.
|
|
14
|
+
bigdecimal (4.1.2)
|
|
15
15
|
builder (3.3.0)
|
|
16
|
-
concurrent-ruby (1.3.
|
|
16
|
+
concurrent-ruby (1.3.6)
|
|
17
17
|
crack (1.0.1)
|
|
18
18
|
bigdecimal
|
|
19
19
|
rexml
|
|
20
20
|
docile (1.4.1)
|
|
21
21
|
drb (2.2.3)
|
|
22
|
-
dry-core (1.
|
|
22
|
+
dry-core (1.2.0)
|
|
23
23
|
concurrent-ruby (~> 1.0)
|
|
24
24
|
logger
|
|
25
25
|
zeitwerk (~> 2.6)
|
|
26
|
-
dry-inflector (1.
|
|
26
|
+
dry-inflector (1.3.1)
|
|
27
27
|
dry-logic (1.6.0)
|
|
28
28
|
bigdecimal
|
|
29
29
|
concurrent-ruby (~> 1.0)
|
|
30
30
|
dry-core (~> 1.1)
|
|
31
31
|
zeitwerk (~> 2.6)
|
|
32
|
-
dry-struct (1.8.
|
|
32
|
+
dry-struct (1.8.1)
|
|
33
33
|
dry-core (~> 1.1)
|
|
34
34
|
dry-types (~> 1.8, >= 1.8.2)
|
|
35
35
|
ice_nine (~> 0.11)
|
|
@@ -41,26 +41,21 @@ GEM
|
|
|
41
41
|
dry-inflector (~> 1.0)
|
|
42
42
|
dry-logic (~> 1.4)
|
|
43
43
|
zeitwerk (~> 2.6)
|
|
44
|
-
faraday (2.
|
|
44
|
+
faraday (2.14.2)
|
|
45
45
|
faraday-net_http (>= 2.0, < 3.5)
|
|
46
46
|
json
|
|
47
47
|
logger
|
|
48
|
-
faraday-multipart (1.
|
|
48
|
+
faraday-multipart (1.2.0)
|
|
49
49
|
multipart-post (~> 2.0)
|
|
50
|
-
faraday-net_http (3.4.
|
|
51
|
-
net-http (
|
|
50
|
+
faraday-net_http (3.4.3)
|
|
51
|
+
net-http (~> 0.5)
|
|
52
52
|
hashdiff (1.2.1)
|
|
53
53
|
ice_nine (0.11.2)
|
|
54
|
-
json (2.19.
|
|
55
|
-
json-schema (6.2.0)
|
|
56
|
-
addressable (~> 2.8)
|
|
57
|
-
bigdecimal (>= 3.1, < 5)
|
|
54
|
+
json (2.19.5)
|
|
58
55
|
language_server-protocol (3.17.0.5)
|
|
59
56
|
lint_roller (1.1.0)
|
|
60
57
|
logger (1.7.0)
|
|
61
|
-
|
|
62
|
-
json-schema (>= 4.1)
|
|
63
|
-
minitest (6.0.5)
|
|
58
|
+
minitest (6.0.6)
|
|
64
59
|
drb (~> 2.0)
|
|
65
60
|
prism (~> 1.5)
|
|
66
61
|
minitest-reporters (1.8.0)
|
|
@@ -69,10 +64,10 @@ GEM
|
|
|
69
64
|
minitest (>= 5.0, < 7)
|
|
70
65
|
ruby-progressbar
|
|
71
66
|
multipart-post (2.4.1)
|
|
72
|
-
net-http (0.
|
|
73
|
-
uri
|
|
74
|
-
parallel (1.
|
|
75
|
-
parser (3.3.
|
|
67
|
+
net-http (0.9.1)
|
|
68
|
+
uri (>= 0.11.1)
|
|
69
|
+
parallel (2.1.0)
|
|
70
|
+
parser (3.3.11.1)
|
|
76
71
|
ast (~> 2.4.1)
|
|
77
72
|
racc
|
|
78
73
|
prism (1.9.0)
|
|
@@ -80,14 +75,13 @@ GEM
|
|
|
80
75
|
racc (1.8.1)
|
|
81
76
|
rainbow (3.1.1)
|
|
82
77
|
rake (13.4.2)
|
|
83
|
-
regexp_parser (2.
|
|
78
|
+
regexp_parser (2.12.0)
|
|
84
79
|
rexml (3.4.4)
|
|
85
|
-
rubocop (1.
|
|
80
|
+
rubocop (1.86.2)
|
|
86
81
|
json (~> 2.3)
|
|
87
82
|
language_server-protocol (~> 3.17.0.2)
|
|
88
83
|
lint_roller (~> 1.1.0)
|
|
89
|
-
|
|
90
|
-
parallel (~> 1.10)
|
|
84
|
+
parallel (>= 1.10)
|
|
91
85
|
parser (>= 3.3.0.2)
|
|
92
86
|
rainbow (>= 2.2.2, < 4.0)
|
|
93
87
|
regexp_parser (>= 2.9.3, < 3.0)
|
|
@@ -97,6 +91,9 @@ GEM
|
|
|
97
91
|
rubocop-ast (1.49.1)
|
|
98
92
|
parser (>= 3.3.7.2)
|
|
99
93
|
prism (~> 1.7)
|
|
94
|
+
rubocop-elegant (0.5.1)
|
|
95
|
+
lint_roller (~> 1.1)
|
|
96
|
+
rubocop (~> 1.75)
|
|
100
97
|
rubocop-minitest (0.39.1)
|
|
101
98
|
lint_roller (~> 1.1)
|
|
102
99
|
rubocop (>= 1.75.0, < 2.0)
|
|
@@ -126,13 +123,13 @@ GEM
|
|
|
126
123
|
unicode-display_width (3.2.0)
|
|
127
124
|
unicode-emoji (~> 4.1)
|
|
128
125
|
unicode-emoji (4.2.0)
|
|
129
|
-
uri (1.
|
|
126
|
+
uri (1.1.1)
|
|
130
127
|
webmock (3.26.2)
|
|
131
128
|
addressable (>= 2.8.0)
|
|
132
129
|
crack (>= 0.3.2)
|
|
133
130
|
hashdiff (>= 0.4.0, < 2.0.0)
|
|
134
|
-
yard (0.9.
|
|
135
|
-
zeitwerk (2.
|
|
131
|
+
yard (0.9.44)
|
|
132
|
+
zeitwerk (2.8.2)
|
|
136
133
|
|
|
137
134
|
PLATFORMS
|
|
138
135
|
arm64-darwin-22
|
|
@@ -146,6 +143,7 @@ DEPENDENCIES
|
|
|
146
143
|
minitest-reporters (~> 1.7)
|
|
147
144
|
rake (~> 13.2)
|
|
148
145
|
rubocop (~> 1.71)
|
|
146
|
+
rubocop-elegant (>= 0.0.20)
|
|
149
147
|
rubocop-minitest (~> 0.38)
|
|
150
148
|
rubocop-performance (~> 1.25)
|
|
151
149
|
rubocop-rake (~> 0.7)
|
data/README.md
CHANGED
|
@@ -37,7 +37,7 @@ tp.post(12345, 'How are you?', 'How are you doing?')
|
|
|
37
37
|
All lines you provide to the `post()` method will be concatenated
|
|
38
38
|
with a space between them.
|
|
39
39
|
|
|
40
|
-
Or you can pre-configure it to talk to certain list of chats.
|
|
40
|
+
Or you can pre-configure it to talk to a certain list of chats.
|
|
41
41
|
Your bot has to be an admin of the channel, in order to post there.
|
|
42
42
|
Here is how you "spam":
|
|
43
43
|
|
|
@@ -55,6 +55,16 @@ tp = Telepost.new('..token..')
|
|
|
55
55
|
tp.attach(12345, '/tmp/dump.sql', caption: 'Today is dump')
|
|
56
56
|
```
|
|
57
57
|
|
|
58
|
+
You can also pass an array of files, to post them all as a single
|
|
59
|
+
grouped message (a Telegram "album"). Files with an image extension
|
|
60
|
+
are sent as photos, the rest as documents, and the `caption:` is
|
|
61
|
+
shown once, on the first item:
|
|
62
|
+
|
|
63
|
+
```ruby
|
|
64
|
+
tp = Telepost.new('..token..')
|
|
65
|
+
tp.attach(12345, ['/tmp/a.png', '/tmp/b.png'], caption: 'Two shots')
|
|
66
|
+
```
|
|
67
|
+
|
|
58
68
|
That's it.
|
|
59
69
|
|
|
60
70
|
## How to contribute
|
data/Rakefile
CHANGED
data/lib/telepost.rb
CHANGED
|
@@ -31,9 +31,7 @@ class Telepost
|
|
|
31
31
|
@sent = []
|
|
32
32
|
end
|
|
33
33
|
|
|
34
|
-
def run
|
|
35
|
-
# Nothing to do here
|
|
36
|
-
end
|
|
34
|
+
def run; end
|
|
37
35
|
|
|
38
36
|
def spam(*lines)
|
|
39
37
|
post(0, lines)
|
|
@@ -44,9 +42,22 @@ class Telepost
|
|
|
44
42
|
end
|
|
45
43
|
|
|
46
44
|
def attach(chat, file, caption: nil)
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
45
|
+
@sent <<
|
|
46
|
+
if file.is_a?(Array)
|
|
47
|
+
"#{chat}: [attach-group:#{names(file)}#{cap(caption)}]"
|
|
48
|
+
else
|
|
49
|
+
"#{chat}: [attach:#{names([file])}#{cap(caption)}]"
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
private
|
|
54
|
+
|
|
55
|
+
def names(files)
|
|
56
|
+
files.map { |f| File.basename(f.is_a?(String) ? f : f.path) }.join(',')
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def cap(caption)
|
|
60
|
+
caption.nil? ? '' : " caption=#{caption}"
|
|
50
61
|
end
|
|
51
62
|
end
|
|
52
63
|
|
|
@@ -55,9 +66,6 @@ class Telepost
|
|
|
55
66
|
# @note Raised when message posting fails
|
|
56
67
|
class CantPost < StandardError; end
|
|
57
68
|
|
|
58
|
-
# To make it possible to get the client.
|
|
59
|
-
#
|
|
60
|
-
# @return [Telegram::Bot::Client] The Telegram bot client
|
|
61
69
|
attr_reader :client
|
|
62
70
|
|
|
63
71
|
# Makes a new object. To obtain a token you should talk
|
|
@@ -78,8 +86,10 @@ class Telepost
|
|
|
78
86
|
# @return [void]
|
|
79
87
|
# @raise [RuntimeError] If no block is given
|
|
80
88
|
def run
|
|
81
|
-
raise 'Block must be given' unless block_given?
|
|
89
|
+
raise(RuntimeError, 'Block must be given') unless block_given?
|
|
82
90
|
@bot.listen do |message|
|
|
91
|
+
next unless message.respond_to?(:chat)
|
|
92
|
+
next if message.chat.nil?
|
|
83
93
|
yield(message.chat.id, message.respond_to?(:text) ? message.text : '')
|
|
84
94
|
end
|
|
85
95
|
rescue Net::OpenTimeout
|
|
@@ -108,35 +118,66 @@ class Telepost
|
|
|
108
118
|
# @param lines [Array<String>] Message lines to send
|
|
109
119
|
# @return [Telegram::Bot::Types::Message] The sent message object
|
|
110
120
|
def post(chat, *lines, parse_mode: 'Markdown')
|
|
111
|
-
@bot.api.send_message(
|
|
112
|
-
chat_id: chat,
|
|
113
|
-
parse_mode:,
|
|
114
|
-
disable_web_page_preview: true,
|
|
115
|
-
text: lines.join(' ')
|
|
116
|
-
)
|
|
121
|
+
@bot.api.send_message(chat_id: chat, parse_mode:, disable_web_page_preview: true, text: lines.join(' '))
|
|
117
122
|
end
|
|
118
123
|
|
|
119
124
|
# Attach a file (as a Telegram document) to the chat. The file
|
|
120
125
|
# argument can either be a path (String) or an open IO/File. The
|
|
121
126
|
# filename shown in Telegram comes from the basename of the path.
|
|
122
127
|
#
|
|
128
|
+
# When +file+ is an +Array+, all of its items are posted as a single
|
|
129
|
+
# grouped message (a Telegram "album") via +sendMediaGroup+. Items
|
|
130
|
+
# with an image extension are wrapped in +InputMediaPhoto+, the rest
|
|
131
|
+
# in +InputMediaDocument+. The +caption+ is attached to the first
|
|
132
|
+
# item only, so the album shows one caption.
|
|
133
|
+
#
|
|
123
134
|
# @param chat [Integer, String] Chat ID or channel name
|
|
124
|
-
# @param file [String, File, IO]
|
|
135
|
+
# @param file [String, File, IO, Array] File (or array of files) to attach
|
|
125
136
|
# @param caption [String, nil] Optional caption for the attachment
|
|
126
137
|
# @param parse_mode [String] Parse mode used for the caption
|
|
127
138
|
# @return [Telegram::Bot::Types::Message] The sent message object
|
|
128
139
|
def attach(chat, file, caption: nil, parse_mode: 'Markdown')
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
140
|
+
return album(chat, file, caption:, parse_mode:) if file.is_a?(Array)
|
|
141
|
+
io = upload(file)
|
|
142
|
+
@bot.api.send_document(chat_id: chat, document: io, caption:, parse_mode:)
|
|
143
|
+
ensure
|
|
144
|
+
io.close if file.is_a?(String) && io.respond_to?(:close)
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
PHOTO_EXTENSIONS = %w[.jpg .jpeg .png .gif .webp].freeze
|
|
148
|
+
|
|
149
|
+
private
|
|
150
|
+
|
|
151
|
+
def album(chat, files, caption: nil, parse_mode: 'Markdown')
|
|
152
|
+
opened = []
|
|
153
|
+
params = { chat_id: chat }
|
|
154
|
+
params[:media] =
|
|
155
|
+
files.each_with_index.map do |file, idx|
|
|
156
|
+
io = upload(file)
|
|
157
|
+
opened << io if file.is_a?(String)
|
|
158
|
+
params[:"file#{idx}"] = io
|
|
159
|
+
attrs = { media: "attach://file#{idx}" }
|
|
160
|
+
if idx.zero? && !caption.nil?
|
|
161
|
+
attrs[:caption] = caption
|
|
162
|
+
attrs[:parse_mode] = parse_mode
|
|
163
|
+
end
|
|
164
|
+
klass(file).new(**attrs)
|
|
134
165
|
end
|
|
135
|
-
@bot.api.
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
166
|
+
@bot.api.send_media_group(**params)
|
|
167
|
+
ensure
|
|
168
|
+
opened.each(&:close)
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
def upload(file)
|
|
172
|
+
return file unless file.is_a?(String)
|
|
173
|
+
Faraday::UploadIO.new(file, 'application/octet-stream', File.basename(file))
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
def klass(file)
|
|
177
|
+
photo?(file) ? Telegram::Bot::Types::InputMediaPhoto : Telegram::Bot::Types::InputMediaDocument
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
def photo?(file)
|
|
181
|
+
PHOTO_EXTENSIONS.include?(File.extname(file.is_a?(String) ? file : file.path).downcase)
|
|
141
182
|
end
|
|
142
183
|
end
|
data/telepost.gemspec
CHANGED
|
@@ -6,10 +6,10 @@
|
|
|
6
6
|
require 'English'
|
|
7
7
|
|
|
8
8
|
Gem::Specification.new do |s|
|
|
9
|
-
s.required_rubygems_version = Gem::Requirement.new('>= 0') if s.respond_to?
|
|
9
|
+
s.required_rubygems_version = Gem::Requirement.new('>= 0') if s.respond_to?(:required_rubygems_version=)
|
|
10
10
|
s.required_ruby_version = '>=3.2'
|
|
11
11
|
s.name = 'telepost'
|
|
12
|
-
s.version = '0.
|
|
12
|
+
s.version = '0.9.0'
|
|
13
13
|
s.license = 'MIT'
|
|
14
14
|
s.summary = 'Simple Telegram posting Ruby gem'
|
|
15
15
|
s.description = 'Simple Telegram posting Ruby gem'
|
|
@@ -19,6 +19,6 @@ Gem::Specification.new do |s|
|
|
|
19
19
|
s.files = `git ls-files | grep -v -E '^(test/|\\.|renovate)'`.split($RS)
|
|
20
20
|
s.rdoc_options = ['--charset=UTF-8']
|
|
21
21
|
s.extra_rdoc_files = ['README.md']
|
|
22
|
-
s.add_dependency
|
|
22
|
+
s.add_dependency('telegram-bot-ruby', '~> 1.0')
|
|
23
23
|
s.metadata['rubygems_mfa_required'] = 'true'
|
|
24
24
|
end
|