telegram_bot_middleware 0.1.0 → 0.2.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/README.md +15 -1
- data/examples/cuba/config.ru +46 -0
- data/examples/roda/config.ru +40 -0
- data/examples/sinatra/chuck_norris.rb +1 -1
- data/examples/sinatra/config.ru +2 -2
- data/examples/sinatra/example.rb +27 -4
- data/lib/telegram_bot_middleware/version.rb +1 -1
- data/lib/telegram_bot_middleware.rb +61 -33
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d39fe2bef0e2ca483f3a3c6d31aac1a4c4d8e14b
|
4
|
+
data.tar.gz: 2a3d02a2962ea2910f93ede19af24b18f5ee2201
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 733cbb9bd5f14245bfd6bee885bc7aa86a195db64d7c9657dbcb272267005a6440581ebe33a69063f5d62c923c4f4d40ab8b05aa9217e7d3dd77d94fc86c1b74
|
7
|
+
data.tar.gz: c26f854c127f75e85020acb6c46150632e6664cc2e19ea48ff5093bbe6ead1064ed33743c1ed5227d5eed62d5707ea7f54c5204274d425b41d6307682b33b9fc
|
data/README.md
CHANGED
@@ -18,7 +18,21 @@ Or install it yourself as:
|
|
18
18
|
|
19
19
|
$ gem install telegram_bot_middleware
|
20
20
|
|
21
|
-
|
21
|
+
Add the middleware in config.ru or in other files base on the framework you are using:
|
22
|
+
|
23
|
+
```ruby
|
24
|
+
require 'telegram_bot_middleware'
|
25
|
+
|
26
|
+
use TelegramBotMiddleware do |config|
|
27
|
+
config.token = '<TELEGRAM_TOKEN>'
|
28
|
+
config.host = '<HOST>'
|
29
|
+
config.get_updates = :polling or :webhook
|
30
|
+
end
|
31
|
+
```
|
32
|
+
|
33
|
+
* To obtain a token follow the instructions in [telegram bot api](https://core.telegram.org/bots#botfather).
|
34
|
+
* The host is the address where the script is running, for example during development could be http://127.0.0.1:9292.
|
35
|
+
* The get_updates params specify how to get incoming messages from telegram, can be :polling or :webhook, look at the [telegram bot api](https://core.telegram.org/bots/api#getupdates) for details.
|
22
36
|
|
23
37
|
## Usage
|
24
38
|
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'cuba'
|
2
|
+
require_relative '../../lib/telegram_bot_middleware'
|
3
|
+
|
4
|
+
Cuba.use TelegramBotMiddleware do |config|
|
5
|
+
config.token = '138381425:AAEXjzZx5U5wZmiKvFmHjdNMkXJqnkHnum4'
|
6
|
+
config.host = 'http://127.0.0.1:9292'
|
7
|
+
config.get_updates = :polling
|
8
|
+
end
|
9
|
+
|
10
|
+
Cuba.define do
|
11
|
+
on get do
|
12
|
+
on 'hello' do
|
13
|
+
res.headers["Content-Type"] = "application/json; charset=utf-8"
|
14
|
+
res.write({
|
15
|
+
'text' => 'Ciao',
|
16
|
+
'reply_markup' => {'keyboard' => [%w(A B), ['C', 'D']], 'resize_keyboard' => true, 'one_time_keyboard' => true, 'selective' => false}
|
17
|
+
})
|
18
|
+
end
|
19
|
+
|
20
|
+
on 'test' do
|
21
|
+
res.write({
|
22
|
+
'multiple' => [
|
23
|
+
{
|
24
|
+
'photo' => '../../tmp/test.png',
|
25
|
+
'caption' => 'caption'
|
26
|
+
},
|
27
|
+
{
|
28
|
+
'text' => 'Ciao',
|
29
|
+
'reply_markup' => {'keyboard' => [%w(A B), ['C', 'D']], 'resize_keyboard' => true, 'one_time_keyboard' => true, 'selective' => false}
|
30
|
+
}
|
31
|
+
]
|
32
|
+
})
|
33
|
+
end
|
34
|
+
|
35
|
+
on /.*/ do
|
36
|
+
res.write 'Hello world!'
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
warmup do |app|
|
42
|
+
client = Rack::MockRequest.new(app)
|
43
|
+
client.get('/')
|
44
|
+
end
|
45
|
+
|
46
|
+
run Cuba
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'roda'
|
2
|
+
require_relative '../../lib/telegram_bot_middleware'
|
3
|
+
|
4
|
+
class App < Roda
|
5
|
+
use TelegramBotMiddleware do |config|
|
6
|
+
config.token = '138381425:AAEXjzZx5U5wZmiKvFmHjdNMkXJqnkHnum4'
|
7
|
+
config.host = 'http://127.0.0.1:9292'
|
8
|
+
config.get_updates = :polling
|
9
|
+
end
|
10
|
+
|
11
|
+
#plugin :json
|
12
|
+
|
13
|
+
route do |r|
|
14
|
+
|
15
|
+
r.on 'hello' do
|
16
|
+
{
|
17
|
+
text: 'Ciao',
|
18
|
+
reply_markup: {keyboard: [%w(A B), ['C', 'D']], resize_keyboard: true, one_time_keyboard: true, selective: false}
|
19
|
+
}
|
20
|
+
end
|
21
|
+
|
22
|
+
r.on 'image' do
|
23
|
+
{
|
24
|
+
photo: File.new('../../tmp/test.png'),
|
25
|
+
caption: 'caption'
|
26
|
+
}
|
27
|
+
end
|
28
|
+
|
29
|
+
r.on /.*/ do
|
30
|
+
'Hello world!'
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
warmup do |app|
|
36
|
+
client = Rack::MockRequest.new(app)
|
37
|
+
client.get('/')
|
38
|
+
end
|
39
|
+
|
40
|
+
run App.freeze.app
|
data/examples/sinatra/config.ru
CHANGED
data/examples/sinatra/example.rb
CHANGED
@@ -12,7 +12,11 @@ get %r{/hello/(.*)}i do |name|
|
|
12
12
|
end
|
13
13
|
|
14
14
|
get %r{/image/?$}i do
|
15
|
-
send_file 'tmp/test.png'
|
15
|
+
#send_file 'tmp/test.png'
|
16
|
+
{
|
17
|
+
photo: '../../tmp/test.png',
|
18
|
+
caption: 'caption'
|
19
|
+
}
|
16
20
|
end
|
17
21
|
|
18
22
|
get %r{/audio/?$}i do
|
@@ -23,6 +27,13 @@ get %r{/video/?$}i do
|
|
23
27
|
send_file 'tmp/test.mp4'
|
24
28
|
end
|
25
29
|
|
30
|
+
get '/location' do
|
31
|
+
{
|
32
|
+
latitude: params['location']['latitude'],
|
33
|
+
longitude: params['location']['longitude'],
|
34
|
+
}
|
35
|
+
end
|
36
|
+
|
26
37
|
get %r{/location/?$}i do
|
27
38
|
{
|
28
39
|
latitude: 38.115036,
|
@@ -30,10 +41,22 @@ get %r{/location/?$}i do
|
|
30
41
|
}
|
31
42
|
end
|
32
43
|
|
33
|
-
get %r{/
|
44
|
+
get %r{/test/?$}i do
|
34
45
|
{
|
35
|
-
|
36
|
-
|
46
|
+
multiple:
|
47
|
+
[
|
48
|
+
{
|
49
|
+
photo: '../../tmp/test.png',
|
50
|
+
caption: 'caption'
|
51
|
+
},
|
52
|
+
{
|
53
|
+
text: 'ciao'
|
54
|
+
},
|
55
|
+
{
|
56
|
+
latitude: 38.115036,
|
57
|
+
longitude: 13.366640
|
58
|
+
}
|
59
|
+
]
|
37
60
|
}
|
38
61
|
end
|
39
62
|
|
@@ -17,8 +17,6 @@ class TelegramBotMiddleware
|
|
17
17
|
# save the app var
|
18
18
|
@app = app
|
19
19
|
|
20
|
-
puts 'Initializing...'
|
21
|
-
|
22
20
|
# create the config and populate passing do the block function
|
23
21
|
@config = OpenStruct.new
|
24
22
|
yield(@config) if block_given?
|
@@ -90,15 +88,25 @@ class TelegramBotMiddleware
|
|
90
88
|
req.body.rewind
|
91
89
|
# build an openstruct based on post params
|
92
90
|
params = OpenStruct.from_json(req.body.read)
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
91
|
+
|
92
|
+
path = nil
|
93
|
+
unless params.message['text'].nil?
|
94
|
+
# build path based on message
|
95
|
+
# - get only message part of post params
|
96
|
+
# - remove empty chars from beginning or end (strip)
|
97
|
+
# - replace first sequence of spaces with /
|
98
|
+
# - encode as uri
|
99
|
+
path = URI.escape(params.message.text.strip.sub(/\s+/, '/'))
|
100
|
+
# - add first / if not present
|
101
|
+
path = "/#{path}" unless path.start_with?('/')
|
102
|
+
else
|
103
|
+
%w(audio document photo sticker video voice contact location new_chat_participant left_chat_participant new_chat_title new_chat_photo delete_chat_photo group_chat_created).each do |type|
|
104
|
+
unless params.message[type].nil?
|
105
|
+
path = "/#{type}"
|
106
|
+
break
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
102
110
|
|
103
111
|
# build the querystring using message but nested
|
104
112
|
query_string = Rack::Utils.build_nested_query(params.message.to_h_nested)
|
@@ -117,32 +125,17 @@ class TelegramBotMiddleware
|
|
117
125
|
|
118
126
|
case headers['Content-Type'].split(';').first
|
119
127
|
when 'text/html', 'application/json'
|
120
|
-
|
121
128
|
if body.is_a? Hash
|
122
|
-
|
123
|
-
query = body.clone
|
124
|
-
query[:chat_id] = params.message.chat.id unless query.include?(:chat_id)
|
125
|
-
query[:reply_markup] = query[:reply_markup].to_json if query.include?(:reply_markup)
|
126
|
-
|
129
|
+
process_hash_message(body.clone, params)
|
127
130
|
body = Array.new(1) { '' }
|
128
|
-
|
129
|
-
if query.include?(:text)
|
130
|
-
send_to_bot('sendMessage', query)
|
131
|
-
elsif query.include?(:latitude) and query.include?(:longitude)
|
132
|
-
send_to_bot('sendLocation', query)
|
133
|
-
elsif query.include?(:photo)
|
134
|
-
send_to_bot('sendPhoto', query)
|
135
|
-
elsif query.include?(:audio)
|
136
|
-
send_to_bot('sendAudio', query)
|
137
|
-
elsif query.include?(:video)
|
138
|
-
send_to_bot('sendVideo', query)
|
139
|
-
else
|
140
|
-
# TODO: invalid query
|
141
|
-
end
|
142
|
-
|
143
131
|
else
|
144
132
|
body.each do |data|
|
145
|
-
|
133
|
+
begin
|
134
|
+
#TODO: add better json parsing to support symbols too
|
135
|
+
process_hash_message(JSON.parse(data.gsub('=>', ':')), params)
|
136
|
+
rescue
|
137
|
+
send_to_bot('sendMessage', {chat_id: params.message.chat.id, text: data})
|
138
|
+
end
|
146
139
|
end
|
147
140
|
end
|
148
141
|
|
@@ -165,6 +158,41 @@ class TelegramBotMiddleware
|
|
165
158
|
end
|
166
159
|
end
|
167
160
|
|
161
|
+
def process_hash_message(message, params)
|
162
|
+
if (message.include?(:multiple) && message[:multiple].is_a?(Array))
|
163
|
+
message[:multiple].each { |item| process_json_message(item, params) }
|
164
|
+
elsif (message.include?('multiple') && message['multiple'].is_a?(Array))
|
165
|
+
message['multiple'].each { |item| process_json_message(item, params) }
|
166
|
+
else
|
167
|
+
process_json_message(message, params)
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
def process_json_message(message, params)
|
172
|
+
message[:chat_id] = params.message.chat.id unless message.include?(:chat_id) or message.include?('chat_id')
|
173
|
+
|
174
|
+
message[:reply_markup] = message[:reply_markup].to_json if message.include?(:reply_markup)
|
175
|
+
message['reply_markup'] = message['reply_markup'].to_json if message.include?('reply_markup')
|
176
|
+
|
177
|
+
['photo', :photo, 'audio', :audio, 'video', :video].each do |item|
|
178
|
+
message[item] = File.new(message[item]) if message.include?(item)
|
179
|
+
end
|
180
|
+
|
181
|
+
if message.include?(:text) or message.include?('text')
|
182
|
+
send_to_bot('sendMessage', message)
|
183
|
+
elsif (message.include?(:latitude) and message.include?(:longitude)) or (message.include?('latitude') and message.include?('longitude'))
|
184
|
+
send_to_bot('sendLocation', message)
|
185
|
+
elsif message.include?(:photo) or message.include?('photo')
|
186
|
+
send_to_bot('sendPhoto', message)
|
187
|
+
elsif message.include?(:audio) or message.include?('audio')
|
188
|
+
send_to_bot('sendAudio', message)
|
189
|
+
elsif message.include?(:video) or message.include?('video')
|
190
|
+
send_to_bot('sendVideo', message)
|
191
|
+
else
|
192
|
+
# TODO: invalid query
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
168
196
|
def send_to_bot(path, query)
|
169
197
|
response = self.class.post("/bot#{@config.token}/#{path}", query: query)
|
170
198
|
# TODO check respobse error
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: telegram_bot_middleware
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mirko Mignini
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-11-
|
11
|
+
date: 2015-11-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -112,7 +112,9 @@ files:
|
|
112
112
|
- Rakefile
|
113
113
|
- bin/console
|
114
114
|
- bin/setup
|
115
|
+
- examples/cuba/config.ru
|
115
116
|
- examples/rack/config.ru
|
117
|
+
- examples/roda/config.ru
|
116
118
|
- examples/sinatra/calc.rb
|
117
119
|
- examples/sinatra/chuck_norris.rb
|
118
120
|
- examples/sinatra/config.ru
|