telepost 0.8.1 → 0.10.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.lock +29 -35
- data/README.md +16 -4
- data/lib/telepost.rb +73 -13
- data/telepost.gemspec +1 -1
- 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: bb2f082807cb2bf827333ccbaf2dbe286b46edd1ddd8518df9628c7507822dc3
|
|
4
|
+
data.tar.gz: bcd93a98a219b978a7673c49746b54dd8240bbbfa51c2a1749fd17d129a96455
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 6a96040340518bec226b2ff447ac0d784e23785050de3c518c84369f64e265eba8225459d04405de64e2b877529d594f04597f8617689af6331f6d76f56c1d14
|
|
7
|
+
data.tar.gz: a1278e354d65fe8fbc9ae8adcea25ae851e6f10223ccfd735de47b8d39331982191b01b6abf76e79d593f235423d52f591715c3d28b828b78e46f243b3d53de0
|
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.7)
|
|
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.3)
|
|
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.4)
|
|
51
|
+
net-http (~> 0.5)
|
|
52
52
|
hashdiff (1.2.1)
|
|
53
53
|
ice_nine (0.11.2)
|
|
54
|
-
json (2.
|
|
55
|
-
|
|
56
|
-
addressable (~> 2.8)
|
|
57
|
-
bigdecimal (>= 3.1, < 5)
|
|
58
|
-
language_server-protocol (3.17.0.5)
|
|
54
|
+
json (2.21.2)
|
|
55
|
+
language_server-protocol (3.17.0.6)
|
|
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.12.0)
|
|
76
71
|
ast (~> 2.4.1)
|
|
77
72
|
racc
|
|
78
73
|
prism (1.9.0)
|
|
@@ -80,33 +75,32 @@ 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.
|
|
86
|
-
json (
|
|
80
|
+
rubocop (1.90.0)
|
|
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)
|
|
94
88
|
rubocop-ast (>= 1.49.0, < 2.0)
|
|
95
89
|
ruby-progressbar (~> 1.7)
|
|
96
90
|
unicode-display_width (>= 2.4.0, < 4.0)
|
|
97
|
-
rubocop-ast (1.
|
|
91
|
+
rubocop-ast (1.50.0)
|
|
98
92
|
parser (>= 3.3.7.2)
|
|
99
93
|
prism (~> 1.7)
|
|
100
|
-
rubocop-elegant (0.
|
|
94
|
+
rubocop-elegant (0.5.1)
|
|
101
95
|
lint_roller (~> 1.1)
|
|
102
96
|
rubocop (~> 1.75)
|
|
103
|
-
rubocop-minitest (0.
|
|
97
|
+
rubocop-minitest (0.40.0)
|
|
104
98
|
lint_roller (~> 1.1)
|
|
105
99
|
rubocop (>= 1.75.0, < 2.0)
|
|
106
100
|
rubocop-ast (>= 1.38.0, < 2.0)
|
|
107
|
-
rubocop-performance (1.
|
|
101
|
+
rubocop-performance (1.27.0)
|
|
108
102
|
lint_roller (~> 1.1)
|
|
109
|
-
rubocop (>= 1.
|
|
103
|
+
rubocop (>= 1.89.0, < 2.0)
|
|
110
104
|
rubocop-ast (>= 1.47.1, < 2.0)
|
|
111
105
|
rubocop-rake (0.7.1)
|
|
112
106
|
lint_roller (~> 1.1)
|
|
@@ -129,13 +123,13 @@ GEM
|
|
|
129
123
|
unicode-display_width (3.2.0)
|
|
130
124
|
unicode-emoji (~> 4.1)
|
|
131
125
|
unicode-emoji (4.2.0)
|
|
132
|
-
uri (1.
|
|
133
|
-
webmock (3.26.
|
|
126
|
+
uri (1.1.1)
|
|
127
|
+
webmock (3.26.3)
|
|
134
128
|
addressable (>= 2.8.0)
|
|
135
129
|
crack (>= 0.3.2)
|
|
136
130
|
hashdiff (>= 0.4.0, < 2.0.0)
|
|
137
|
-
yard (0.9.
|
|
138
|
-
zeitwerk (2.
|
|
131
|
+
yard (0.9.45)
|
|
132
|
+
zeitwerk (2.8.2)
|
|
139
133
|
|
|
140
134
|
PLATFORMS
|
|
141
135
|
arm64-darwin-22
|
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
|
|
|
@@ -46,13 +46,25 @@ tp = Telepost.new('..token..', chats: [12345])
|
|
|
46
46
|
tp.spam('How are you?')
|
|
47
47
|
```
|
|
48
48
|
|
|
49
|
-
You can also attach a file
|
|
50
|
-
|
|
51
|
-
|
|
49
|
+
You can also attach a file. The `file` argument accepts a path or
|
|
50
|
+
an already-open `IO`/`File`, and `caption:` is optional. A file with
|
|
51
|
+
an image extension goes out as a photo, which Telegram shows inline,
|
|
52
|
+
while everything else goes out as a document:
|
|
52
53
|
|
|
53
54
|
```ruby
|
|
54
55
|
tp = Telepost.new('..token..')
|
|
55
56
|
tp.attach(12345, '/tmp/dump.sql', caption: 'Today is dump')
|
|
57
|
+
tp.attach(12345, '/tmp/chart.png', caption: 'Today is chart')
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
You can also pass an array of files, to post them all as a single
|
|
61
|
+
grouped message (a Telegram "album"). Files with an image extension
|
|
62
|
+
are sent as photos, the rest as documents, and the `caption:` is
|
|
63
|
+
shown once, on the first item:
|
|
64
|
+
|
|
65
|
+
```ruby
|
|
66
|
+
tp = Telepost.new('..token..')
|
|
67
|
+
tp.attach(12345, ['/tmp/a.png', '/tmp/b.png'], caption: 'Two shots')
|
|
56
68
|
```
|
|
57
69
|
|
|
58
70
|
That's it.
|
data/lib/telepost.rb
CHANGED
|
@@ -42,9 +42,22 @@ class Telepost
|
|
|
42
42
|
end
|
|
43
43
|
|
|
44
44
|
def attach(chat, file, caption: nil)
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
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}"
|
|
48
61
|
end
|
|
49
62
|
end
|
|
50
63
|
|
|
@@ -108,22 +121,69 @@ class Telepost
|
|
|
108
121
|
@bot.api.send_message(chat_id: chat, parse_mode:, disable_web_page_preview: true, text: lines.join(' '))
|
|
109
122
|
end
|
|
110
123
|
|
|
111
|
-
# Attach a file
|
|
112
|
-
#
|
|
113
|
-
#
|
|
124
|
+
# Attach a file to the chat. The file argument can either be a
|
|
125
|
+
# path (String) or an open IO/File. The filename shown in Telegram
|
|
126
|
+
# comes from the basename of the path. A file with an image
|
|
127
|
+
# extension goes out as a photo via +sendPhoto+, so Telegram shows
|
|
128
|
+
# it inline, and everything else as a document via +sendDocument+.
|
|
129
|
+
#
|
|
130
|
+
# When +file+ is an +Array+, all of its items are posted as a single
|
|
131
|
+
# grouped message (a Telegram "album") via +sendMediaGroup+. Items
|
|
132
|
+
# with an image extension are wrapped in +InputMediaPhoto+, the rest
|
|
133
|
+
# in +InputMediaDocument+. The +caption+ is attached to the first
|
|
134
|
+
# item only, so the album shows one caption.
|
|
114
135
|
#
|
|
115
136
|
# @param chat [Integer, String] Chat ID or channel name
|
|
116
|
-
# @param file [String, File, IO]
|
|
137
|
+
# @param file [String, File, IO, Array] File (or array of files) to attach
|
|
117
138
|
# @param caption [String, nil] Optional caption for the attachment
|
|
118
139
|
# @param parse_mode [String] Parse mode used for the caption
|
|
119
140
|
# @return [Telegram::Bot::Types::Message] The sent message object
|
|
120
141
|
def attach(chat, file, caption: nil, parse_mode: 'Markdown')
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
142
|
+
return album(chat, file, caption:, parse_mode:) if file.is_a?(Array)
|
|
143
|
+
io = upload(file)
|
|
144
|
+
if photo?(file)
|
|
145
|
+
@bot.api.send_photo(chat_id: chat, photo: io, caption:, parse_mode:)
|
|
146
|
+
else
|
|
147
|
+
@bot.api.send_document(chat_id: chat, document: io, caption:, parse_mode:)
|
|
148
|
+
end
|
|
149
|
+
ensure
|
|
150
|
+
io.close if file.is_a?(String) && io.respond_to?(:close)
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
PHOTO_EXTENSIONS = %w[.jpg .jpeg .png .gif .webp].freeze
|
|
154
|
+
|
|
155
|
+
private
|
|
156
|
+
|
|
157
|
+
def album(chat, files, caption: nil, parse_mode: 'Markdown')
|
|
158
|
+
opened = []
|
|
159
|
+
params = { chat_id: chat }
|
|
160
|
+
params[:media] =
|
|
161
|
+
files.each_with_index.map do |file, idx|
|
|
162
|
+
io = upload(file)
|
|
163
|
+
opened << io if file.is_a?(String)
|
|
164
|
+
params[:"file#{idx}"] = io
|
|
165
|
+
attrs = { media: "attach://file#{idx}" }
|
|
166
|
+
if idx.zero? && !caption.nil?
|
|
167
|
+
attrs[:caption] = caption
|
|
168
|
+
attrs[:parse_mode] = parse_mode
|
|
169
|
+
end
|
|
170
|
+
klass(file).new(**attrs)
|
|
126
171
|
end
|
|
127
|
-
@bot.api.
|
|
172
|
+
@bot.api.send_media_group(**params)
|
|
173
|
+
ensure
|
|
174
|
+
opened.each(&:close)
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
def upload(file)
|
|
178
|
+
return file unless file.is_a?(String)
|
|
179
|
+
Faraday::UploadIO.new(file, 'application/octet-stream', File.basename(file))
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
def klass(file)
|
|
183
|
+
photo?(file) ? Telegram::Bot::Types::InputMediaPhoto : Telegram::Bot::Types::InputMediaDocument
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
def photo?(file)
|
|
187
|
+
PHOTO_EXTENSIONS.include?(File.extname(file.is_a?(String) ? file : file.path).downcase)
|
|
128
188
|
end
|
|
129
189
|
end
|
data/telepost.gemspec
CHANGED
|
@@ -9,7 +9,7 @@ Gem::Specification.new do |s|
|
|
|
9
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.10.0'
|
|
13
13
|
s.license = 'MIT'
|
|
14
14
|
s.summary = 'Simple Telegram posting Ruby gem'
|
|
15
15
|
s.description = 'Simple Telegram posting Ruby gem'
|