telegram_bot_middleware 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +12 -12
- data/README.md +123 -4
- data/examples/sinatra/example.rb +1 -1
- data/examples/sinatra/example_init.rb +4 -0
- data/lib/telegram_bot_middleware/version.rb +1 -1
- data/lib/telegram_bot_middleware.rb +40 -11
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 19dee6688c9ccd4a5f152303e79a438a3ada2355
|
4
|
+
data.tar.gz: ccd54a63a55513074a270f07fbcd0018a6a2deca
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6ff282369b82fd2ca2f8ee923530f0b7a6d1c1b7ab0ce5dc3a675efef887bf8e1b59d008368aadce034593d69376b89bb3f8b0d6cfcc9779d6c40f025019935e
|
7
|
+
data.tar.gz: 8fcdba4d61f4d1c499aa250f10ce4ef4e3af4ad250f3ea3409353bd0dd0d561a75917d98d39ea87d3ef4afbccef395d59b75ea1f060cce575dcbd93964816460
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
telegram_bot_middleware (0.
|
4
|
+
telegram_bot_middleware (0.2.0)
|
5
5
|
httmultiparty
|
6
6
|
http
|
7
7
|
persistent_httparty
|
@@ -42,19 +42,19 @@ GEM
|
|
42
42
|
httparty (~> 0.9)
|
43
43
|
persistent_http (< 2)
|
44
44
|
rake (10.4.2)
|
45
|
-
rspec (3.
|
46
|
-
rspec-core (~> 3.
|
47
|
-
rspec-expectations (~> 3.
|
48
|
-
rspec-mocks (~> 3.
|
49
|
-
rspec-core (3.
|
50
|
-
rspec-support (~> 3.
|
51
|
-
rspec-expectations (3.
|
45
|
+
rspec (3.4.0)
|
46
|
+
rspec-core (~> 3.4.0)
|
47
|
+
rspec-expectations (~> 3.4.0)
|
48
|
+
rspec-mocks (~> 3.4.0)
|
49
|
+
rspec-core (3.4.0)
|
50
|
+
rspec-support (~> 3.4.0)
|
51
|
+
rspec-expectations (3.4.0)
|
52
52
|
diff-lcs (>= 1.2.0, < 2.0)
|
53
|
-
rspec-support (~> 3.
|
54
|
-
rspec-mocks (3.
|
53
|
+
rspec-support (~> 3.4.0)
|
54
|
+
rspec-mocks (3.4.0)
|
55
55
|
diff-lcs (>= 1.2.0, < 2.0)
|
56
|
-
rspec-support (~> 3.
|
57
|
-
rspec-support (3.
|
56
|
+
rspec-support (~> 3.4.0)
|
57
|
+
rspec-support (3.4.0)
|
58
58
|
thread_safe (0.3.5)
|
59
59
|
unf (0.1.4)
|
60
60
|
unf_ext
|
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
#
|
1
|
+
# Telegram Bot Middleware
|
2
2
|
|
3
3
|
Rack middleware to communicate with a telegram bot.
|
4
4
|
|
@@ -18,7 +18,7 @@ Or install it yourself as:
|
|
18
18
|
|
19
19
|
$ gem install telegram_bot_middleware
|
20
20
|
|
21
|
-
Add the middleware in config.ru or in other files
|
21
|
+
Add the middleware in config.ru or in other files based on the framework you are using:
|
22
22
|
|
23
23
|
```ruby
|
24
24
|
require 'telegram_bot_middleware'
|
@@ -36,7 +36,127 @@ end
|
|
36
36
|
|
37
37
|
## Usage
|
38
38
|
|
39
|
-
|
39
|
+
After the middleware is added to your preferred framework and configured as specified in installation instructions, you are ready to receive and send message to your telegram bot.
|
40
|
+
Every message from the chat where the bot is added is received from your application as a GET request.
|
41
|
+
|
42
|
+
### Text messages
|
43
|
+
|
44
|
+
In case of a text message, the text will be escaped as URI and the first work will be the command, let's see how every message is parsed (message -> result):
|
45
|
+
* '/test' -> '/test'
|
46
|
+
* 'test' -> '/test'
|
47
|
+
* 'test test2' -> '/test/test2'
|
48
|
+
* 'test test2 test3' -> '/test/test2%20test3'
|
49
|
+
|
50
|
+
You can use your preferred framework router to handle the GET requests, for example:
|
51
|
+
```ruby
|
52
|
+
get %r{/greets/(.*)}i do |name|
|
53
|
+
"Hello #{name}!"
|
54
|
+
end
|
55
|
+
```
|
56
|
+
If the chat input is for example 'greets Mike' the bot output will be 'Hello Mike!'
|
57
|
+
|
58
|
+
Every message received from the chat contains parameters as specified in [bot api](https://core.telegram.org/bots/api#message) in the form of query string parameters, let's see an example:
|
59
|
+
```ruby
|
60
|
+
get %r{/hello$}i do
|
61
|
+
"Hello #{params['from']['first_name']} #{params['from']['last_name']}!"
|
62
|
+
end
|
63
|
+
```
|
64
|
+
|
65
|
+
### Other types of messages
|
66
|
+
The middleware supports also every other kind of message from bot, here is the list:
|
67
|
+
* audio
|
68
|
+
* document
|
69
|
+
* photo
|
70
|
+
* sticker
|
71
|
+
* video
|
72
|
+
* voice
|
73
|
+
* contact
|
74
|
+
* location
|
75
|
+
* new_chat_participant
|
76
|
+
* left_chat_participant
|
77
|
+
* new_chat_title
|
78
|
+
* new_chat_photo
|
79
|
+
* delete_chat_photo
|
80
|
+
* group_chat_created
|
81
|
+
|
82
|
+
Every message of this kind is routed as a GET request, the command is the message itself and the message parameters are in querystring, for example:
|
83
|
+
```ruby
|
84
|
+
get '/location' do
|
85
|
+
"Your coordinates are: #{params['location']['latitude']} #{params['location']['longitude']}"
|
86
|
+
end
|
87
|
+
```
|
88
|
+
|
89
|
+
### Return types
|
90
|
+
Depending on the return types of your functions differents telegram methods are used to send bot messages to chat.
|
91
|
+
|
92
|
+
#### Plain text
|
93
|
+
When the function return a string is sent as-is using the [sendMessage Telegram function](https://core.telegram.org/bots/api#sendmessage).
|
94
|
+
|
95
|
+
#### JSON return types
|
96
|
+
When the function return a json a different telegram function is called depending the json content, for example:
|
97
|
+
```ruby
|
98
|
+
{ text: 'Hello', reply_markup: {keyboard: [%w(A B), %w(C D)]} }
|
99
|
+
```
|
100
|
+
In this case the [sendMessage Telegram function](https://core.telegram.org/bots/api#sendmessage) is called but with additional parameter as specified (reply_markup in this case). You can use every telegram functions parameter.
|
101
|
+
|
102
|
+
To return a location the json has to contains latitude and longitude, obviously is possible to use every optional parameters as specified in [sendLocation Telegram function](https://core.telegram.org/bots/api#sendlocation)
|
103
|
+
```ruby
|
104
|
+
{ latitude: 38.115036, longitude: 13.366640 }
|
105
|
+
```
|
106
|
+
|
107
|
+
To return a photo with a caption it's necessary to specify the picture path:
|
108
|
+
```ruby
|
109
|
+
{ photo: 'tmp/test.png', caption: 'Awesome picture!' }
|
110
|
+
```
|
111
|
+
The same to return other types according to [Telegram documentation](https://core.telegram.org/bots/api#available-methods)
|
112
|
+
|
113
|
+
#### Documents, audio, video, images...
|
114
|
+
If the function returns a file, as showing in the following sinatra snippet:
|
115
|
+
```ruby
|
116
|
+
send_file 'tmp/test.png'
|
117
|
+
```
|
118
|
+
According to the file MIME type the appropriate telegram function is called, [sendPhoto](https://core.telegram.org/bots/api#sendphoto) in this example.
|
119
|
+
|
120
|
+
#### Multiple return messages
|
121
|
+
Sometimes can be useful to return more than one message, do this is very simple, it's enough to return an array of single messages json encapsulated with the multiple keyword, example:
|
122
|
+
```ruby
|
123
|
+
{
|
124
|
+
multiple:
|
125
|
+
[
|
126
|
+
{
|
127
|
+
photo: 'tmp/test.png',
|
128
|
+
caption: 'image caption'
|
129
|
+
},
|
130
|
+
{
|
131
|
+
text: 'Hello'
|
132
|
+
},
|
133
|
+
{
|
134
|
+
latitude: 38.115036,
|
135
|
+
longitude: 13.366640
|
136
|
+
}
|
137
|
+
]
|
138
|
+
}
|
139
|
+
```
|
140
|
+
In this case the bot will send an image, a message and a location.
|
141
|
+
|
142
|
+
## Examples
|
143
|
+
|
144
|
+
To run an example call:
|
145
|
+
```shell
|
146
|
+
$ rackup
|
147
|
+
```
|
148
|
+
In the desired example folder
|
149
|
+
|
150
|
+
### Basic examples in various frameworks
|
151
|
+
There are various ready to go basic examples in the following frameworks:
|
152
|
+
* [Sinatra](https://github.com/MirkoMignini/telegram_bot_middleware/tree/master/examples/sinatra)
|
153
|
+
* [Cuba](https://github.com/MirkoMignini/telegram_bot_middleware/tree/master/examples/cuba)
|
154
|
+
* [Roda](https://github.com/MirkoMignini/telegram_bot_middleware/tree/master/examples/roda)
|
155
|
+
* [Rack](https://github.com/MirkoMignini/telegram_bot_middleware/tree/master/examples/rack)
|
156
|
+
|
157
|
+
### Little bot examples:
|
158
|
+
* [Calculator (sinatra)](https://github.com/MirkoMignini/telegram_bot_middleware/blob/master/examples/sinatra/calc.rb)
|
159
|
+
* [Random joke from Chuck Norris database (sinatra)](https://github.com/MirkoMignini/telegram_bot_middleware/blob/master/examples/sinatra/chuck_norris.rb)
|
40
160
|
|
41
161
|
## Development
|
42
162
|
|
@@ -48,7 +168,6 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
|
|
48
168
|
|
49
169
|
Bug reports and pull requests are welcome on GitHub at https://github.com/MirkoMignini/telegram_bot_middleware. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](contributor-covenant.org) code of conduct.
|
50
170
|
|
51
|
-
|
52
171
|
## License
|
53
172
|
|
54
173
|
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
data/examples/sinatra/example.rb
CHANGED
@@ -1,6 +1,10 @@
|
|
1
1
|
require 'sinatra'
|
2
2
|
require_relative '../../lib/telegram_bot_middleware'
|
3
3
|
|
4
|
+
configure :development do
|
5
|
+
set :logging, Logger::DEBUG
|
6
|
+
end
|
7
|
+
|
4
8
|
use TelegramBotMiddleware do |config|
|
5
9
|
config.token = '138381425:AAEXjzZx5U5wZmiKvFmHjdNMkXJqnkHnum4'
|
6
10
|
#config.host = 'https://telegram-bot-middleware.herokuapp.com'
|
@@ -9,17 +9,19 @@ require_relative 'telegram_bot_middleware/version'
|
|
9
9
|
class TelegramBotMiddleware
|
10
10
|
include HTTMultiParty
|
11
11
|
base_uri 'https://api.telegram.org'
|
12
|
-
persistent_connection_adapter pool_size: 1,
|
13
|
-
keep_alive: 30,
|
14
|
-
force_retry: true
|
15
12
|
|
16
|
-
def initialize(app, &block)
|
13
|
+
def initialize(app, &block)
|
17
14
|
# save the app var
|
18
15
|
@app = app
|
16
|
+
@env = nil
|
19
17
|
|
20
18
|
# create the config and populate passing do the block function
|
21
19
|
@config = OpenStruct.new
|
22
20
|
yield(@config) if block_given?
|
21
|
+
|
22
|
+
self.class.persistent_connection_adapter pool_size: (@config.connection_pool_size || 2),
|
23
|
+
keep_alive: (@config.connection_keep_alive || 30),
|
24
|
+
force_retry: (@config.connection_force_retry || true)
|
23
25
|
|
24
26
|
# setup webhook
|
25
27
|
if @config.webhook.nil?
|
@@ -78,8 +80,10 @@ class TelegramBotMiddleware
|
|
78
80
|
end
|
79
81
|
|
80
82
|
def _call(env)
|
83
|
+
@env = env
|
84
|
+
|
81
85
|
# retrieve the request object
|
82
|
-
req = Rack::Request.new(env)
|
86
|
+
req = Rack::Request.new(@env)
|
83
87
|
|
84
88
|
# if the request is a post to bot webhhok
|
85
89
|
if req.post? and req.path == "/#{@config.token}"
|
@@ -88,6 +92,8 @@ class TelegramBotMiddleware
|
|
88
92
|
req.body.rewind
|
89
93
|
# build an openstruct based on post params
|
90
94
|
params = OpenStruct.from_json(req.body.read)
|
95
|
+
|
96
|
+
log_debug("Message from chat: #{params}")
|
91
97
|
|
92
98
|
path = nil
|
93
99
|
unless params.message['text'].nil?
|
@@ -112,14 +118,14 @@ class TelegramBotMiddleware
|
|
112
118
|
query_string = Rack::Utils.build_nested_query(params.message.to_h_nested)
|
113
119
|
|
114
120
|
# transform the POST in GET
|
115
|
-
env['PATH_INFO'] = path
|
116
|
-
env['QUERY_STRING'] = query_string
|
117
|
-
env['REQUEST_METHOD'] = 'GET'
|
118
|
-
env['REQUEST_URI'] = "https://#{req.host}#{path}"
|
121
|
+
@env['PATH_INFO'] = path
|
122
|
+
@env['QUERY_STRING'] = query_string
|
123
|
+
@env['REQUEST_METHOD'] = 'GET'
|
124
|
+
@env['REQUEST_URI'] = "https://#{req.host}#{path}"
|
119
125
|
# TODO use update(hash) { |name, old_value, new_value| }
|
120
126
|
|
121
127
|
# call the rack stack
|
122
|
-
status, headers, body = @app.call(env)
|
128
|
+
status, headers, body = @app.call(@env)
|
123
129
|
|
124
130
|
if status == 200 or status == '200'
|
125
131
|
|
@@ -193,8 +199,31 @@ class TelegramBotMiddleware
|
|
193
199
|
end
|
194
200
|
end
|
195
201
|
|
202
|
+
def log_error(exception)
|
203
|
+
message = "Error: #{exception.message}\n#{exception.backtrace.join("\n")}\n"
|
204
|
+
log(:error, message)
|
205
|
+
end
|
206
|
+
|
207
|
+
def log_info(message)
|
208
|
+
log(:info, message)
|
209
|
+
end
|
210
|
+
|
211
|
+
def log_debug(message)
|
212
|
+
log(:debug, message)
|
213
|
+
end
|
214
|
+
|
215
|
+
def log(level, message)
|
216
|
+
return if @env.nil?
|
217
|
+
if @env['rack.logger']
|
218
|
+
@env['rack.logger'].send(level, message)
|
219
|
+
else
|
220
|
+
@env['rack.errors'].write(message)
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
196
224
|
def send_to_bot(path, query)
|
225
|
+
log_debug("Sending to chat: #{path} - #{query}")
|
197
226
|
response = self.class.post("/bot#{@config.token}/#{path}", query: query)
|
198
|
-
# TODO check
|
227
|
+
# TODO check response error and return response
|
199
228
|
end
|
200
229
|
end
|
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.3.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-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|