telegram_bot_middleware 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|