telegram_bot_middleware 0.3.1 → 0.3.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 870191d85926103616be33ea31cb39dc8bb1d272
4
- data.tar.gz: bc550f86c1c106ae526d18d4e5afaa31b91fdcf0
3
+ metadata.gz: e64e5b8be07193b800fce0ed89221089356e346e
4
+ data.tar.gz: 64ce2fa555fcd5126a447b8aba38cabed1f796fd
5
5
  SHA512:
6
- metadata.gz: 42cf0b10bfb844b86c821140e64f35271e0f7ee37fe4f4a818cf14e5040db05fb4f418f70a371d2cae5f9e4f1c529ce4524f85e085a8be701b8a81bd748ce4f3
7
- data.tar.gz: 2de4247868fb47150d373d91254ad41fa964e519303e5287243b278744f03cf07fcd77794eba22a8f2d41665ca2189e957ec4590cb0f7afc431275dc61bd1c86
6
+ metadata.gz: ebe6680804b864eec96966a784c75107d99537dfae53cb0b11b55f67795d80a7dcb8b059d7d5fc64559325cca4f80811f53b311399dcff8c82e186be918be7d9
7
+ data.tar.gz: d71a1d3d656e25befab1663a17e0a23527dd6ae5bd62c5e5ca41eb2f60cc57031378eca4e9a472cb11b475393619df36cc5d2c8a7b85b31e2f14698247fc299a
data/.travis.yml CHANGED
@@ -1,4 +1,5 @@
1
1
  language: ruby
2
+ cache: bundler
2
3
  rvm:
3
4
  - 2.1.2
4
- before_install: gem install bundler -v 1.10.6
5
+ before_install: gem install bundler
data/Gemfile.lock CHANGED
@@ -1,17 +1,26 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- telegram_bot_middleware (0.2.0)
4
+ telegram_bot_middleware (0.3.1)
5
5
  httmultiparty
6
6
  http
7
7
  persistent_httparty
8
+ rack
8
9
  rake (~> 10.0)
9
10
 
10
11
  GEM
11
12
  remote: https://rubygems.org/
12
13
  specs:
13
14
  addressable (2.3.8)
15
+ coveralls (0.8.9)
16
+ json (~> 1.8)
17
+ rest-client (>= 1.6.8, < 2)
18
+ simplecov (~> 0.10.0)
19
+ term-ansicolor (~> 1.3)
20
+ thor (~> 0.19.1)
21
+ tins (~> 1.6.0)
14
22
  diff-lcs (1.2.5)
23
+ docile (1.1.5)
15
24
  domain_name (0.5.25)
16
25
  unf (>= 0.0.5, < 1.0.0)
17
26
  gene_pool (1.4.1)
@@ -33,20 +42,27 @@ GEM
33
42
  json (~> 1.8)
34
43
  multi_xml (>= 0.5.2)
35
44
  json (1.8.3)
45
+ mime-types (2.99)
36
46
  mimemagic (0.3.0)
37
47
  multi_xml (0.5.5)
38
48
  multipart-post (2.0.0)
49
+ netrc (0.11.0)
39
50
  persistent_http (1.0.6)
40
51
  gene_pool (>= 1.3)
41
52
  persistent_httparty (0.1.2)
42
53
  httparty (~> 0.9)
43
54
  persistent_http (< 2)
55
+ rack (1.6.4)
44
56
  rake (10.4.2)
57
+ rest-client (1.8.0)
58
+ http-cookie (>= 1.0.2, < 2.0)
59
+ mime-types (>= 1.16, < 3.0)
60
+ netrc (~> 0.7)
45
61
  rspec (3.4.0)
46
62
  rspec-core (~> 3.4.0)
47
63
  rspec-expectations (~> 3.4.0)
48
64
  rspec-mocks (~> 3.4.0)
49
- rspec-core (3.4.0)
65
+ rspec-core (3.4.1)
50
66
  rspec-support (~> 3.4.0)
51
67
  rspec-expectations (3.4.0)
52
68
  diff-lcs (>= 1.2.0, < 2.0)
@@ -54,8 +70,17 @@ GEM
54
70
  rspec-mocks (3.4.0)
55
71
  diff-lcs (>= 1.2.0, < 2.0)
56
72
  rspec-support (~> 3.4.0)
57
- rspec-support (3.4.0)
73
+ rspec-support (3.4.1)
74
+ simplecov (0.10.0)
75
+ docile (~> 1.1.0)
76
+ json (~> 1.8)
77
+ simplecov-html (~> 0.10.0)
78
+ simplecov-html (0.10.0)
79
+ term-ansicolor (1.3.2)
80
+ tins (~> 1.0)
81
+ thor (0.19.1)
58
82
  thread_safe (0.3.5)
83
+ tins (1.6.0)
59
84
  unf (0.1.4)
60
85
  unf_ext
61
86
  unf_ext (0.0.7.1)
@@ -65,6 +90,7 @@ PLATFORMS
65
90
 
66
91
  DEPENDENCIES
67
92
  bundler (~> 1.10)
93
+ coveralls
68
94
  rspec
69
95
  telegram_bot_middleware!
70
96
 
data/README.md CHANGED
@@ -1,3 +1,9 @@
1
+ [![Build Status](https://travis-ci.org/MirkoMignini/telegram_bot_middleware.svg)](https://travis-ci.org/MirkoMignini/telegram_bot_middleware)
2
+ [![Coverage Status](https://coveralls.io/repos/MirkoMignini/telegram_bot_middleware/badge.svg?branch=master&service=github)](https://coveralls.io/github/MirkoMignini/telegram_bot_middleware?branch=master)
3
+ [![Code Climate](https://codeclimate.com/github/MirkoMignini/telegram_bot_middleware/badges/gpa.svg)](https://codeclimate.com/github/MirkoMignini/telegram_bot_middleware)
4
+ [![Dependency Status](https://gemnasium.com/MirkoMignini/telegram_bot_middleware.svg)](https://gemnasium.com/MirkoMignini/telegram_bot_middleware)
5
+ [![Gem Version](https://badge.fury.io/rb/telegram_bot_middleware.svg)](https://badge.fury.io/rb/telegram_bot_middleware)
6
+
1
7
  # Telegram Bot Middleware
2
8
 
3
9
  Rack middleware to communicate with a telegram bot.
@@ -10,23 +10,27 @@ class TelegramBotMiddleware
10
10
  include HTTMultiParty
11
11
  base_uri 'https://api.telegram.org'
12
12
 
13
- def initialize(app, &block)
13
+ def initialize(app, &_block)
14
14
  # save the app var
15
15
  @app = app
16
16
 
17
17
  # local cookies hash
18
18
  @cookies = Hash.new
19
19
 
20
- @env = nil
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?
25
23
 
24
+ # validate required input params
25
+ raise ArgumentError.new("Config error: host can't be null || empty.") if @config.host.nil? || @config.host.empty?
26
+ raise ArgumentError.new("Config error: token can't be null || empty.") if @config.token.nil? || @config.token.empty?
27
+
28
+ # initialize persistent connection to telegram
26
29
  self.class.persistent_connection_adapter pool_size: (@config.connection_pool_size || 2),
27
30
  keep_alive: (@config.connection_keep_alive || 30),
28
31
  force_retry: (@config.connection_force_retry || true)
29
32
 
33
+ # if get_updates is empty set to :polling by default
30
34
  @config.get_updates ||= :polling
31
35
 
32
36
  # setup webhook
@@ -41,18 +45,18 @@ class TelegramBotMiddleware
41
45
  # setup polling
42
46
  when :polling
43
47
  # clear the webhook in case was set in the past
44
- send_to_bot('setWebhook', {url: ''})
48
+ send_to_telegram('setWebhook', {url: ''})
45
49
 
46
50
  # setup a thread with get_updates function
47
51
  start_get_updates_thread
48
52
 
49
53
  # setup webhook
50
54
  when :webhook
51
- send_to_bot('setWebhook', {url: @config.webhook})
55
+ send_to_telegram('setWebhook', {url: @config.webhook})
52
56
 
53
57
  # in this case get_updates is a non valid value
54
58
  else
55
- raise ArgumentError.new('Config error: get_updates must be :webhook or :polling.')
59
+ raise ArgumentError.new('Config error: get_updates must be :webhook || :polling.')
56
60
  end
57
61
  end
58
62
 
@@ -66,7 +70,7 @@ class TelegramBotMiddleware
66
70
  # loop forever
67
71
  loop do
68
72
  # call the getUpdates telegram function
69
- response = send_to_bot('getUpdates', {offset: @offset})
73
+ response = send_to_telegram('getUpdates', {offset: @offset})
70
74
  # enumerate the results
71
75
  response.to_hash['result'].each do |data|
72
76
  # create an update message from the post data
@@ -85,58 +89,37 @@ class TelegramBotMiddleware
85
89
  dup._call(env)
86
90
  end
87
91
 
88
- def _call(env)
89
- @env = env
90
-
92
+ def _call(env)
91
93
  # retrieve the request object
92
- req = Rack::Request.new(@env)
94
+ request = Rack::Request.new(env)
93
95
 
94
96
  # if the request is a post to bot webhhok
95
- if req.post? and req.path == "/#{@config.token}"
97
+ if request.post? and request.path == "/#{@config.token}"
96
98
 
97
99
  # in case someone already read it
98
- req.body.rewind
100
+ request.body.rewind
99
101
  # build an openstruct based on post params
100
- params = OpenStruct.from_json(req.body.read)
102
+ params = OpenStruct.from_json(request.body.read)
101
103
 
102
104
  log_debug("Message from chat: #{params}")
103
-
104
- path = nil
105
- unless params.message['text'].nil?
106
- # build path based on message
107
- # - get only message part of post params
108
- # - remove empty chars from beginning or end (strip)
109
- # - replace first sequence of spaces with /
110
- # - encode as uri
111
- path = URI.escape(params.message.text.strip.sub(/\s+/, '/'))
112
- # - add first / if not present
113
- path = "/#{path}" unless path.start_with?('/')
114
- else
115
- %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|
116
- unless params.message[type].nil?
117
- path = "/#{type}"
118
- break
119
- end
120
- end
121
- end
122
105
 
123
- # build the querystring using message but nested
124
- query_string = Rack::Utils.build_nested_query(params.message.to_h_nested)
106
+ # build command based on message
107
+ command = get_command(params)
125
108
 
126
109
  # transform the POST in GET
127
- @env['PATH_INFO'] = path
128
- @env['QUERY_STRING'] = query_string
129
- @env['REQUEST_METHOD'] = 'GET'
130
- @env['REQUEST_URI'] = "https://#{req.host}#{path}"
110
+ env['PATH_INFO'] = command
111
+ env['QUERY_STRING'] = Rack::Utils.build_nested_query(params.message.to_h_nested)
112
+ env['REQUEST_METHOD'] = 'GET'
113
+ env['REQUEST_URI'] = "https://#{request.host}#{command}"
131
114
 
132
115
  # if in cache a cookie for this chat was present add to the header
133
- @env['HTTP_COOKIE'] = @cookies[params.message.chat.id] if @cookies.include?(params.message.chat.id)
116
+ env['HTTP_COOKIE'] = @cookies[params.message.chat.id] if @cookies.include?(params.message.chat.id)
134
117
 
135
118
  # call the rack stack
136
- status, headers, body = @app.call(@env)
119
+ status, headers, body = @app.call(env)
137
120
 
138
121
  # try to send to telegram only if no errors
139
- if status == 200 or status == '200'
122
+ if status == 200 || status == '200'
140
123
 
141
124
  # if the call setted a cookie save to local cache
142
125
  @cookies[params.message.chat.id] = headers['Set-Cookie'] if headers.include?('Set-Cookie')
@@ -152,19 +135,19 @@ class TelegramBotMiddleware
152
135
  #TODO: add better json parsing to support symbols too
153
136
  process_hash_message(JSON.parse(data.gsub('=>', ':')), params)
154
137
  rescue
155
- send_to_bot('sendMessage', {chat_id: params.message.chat.id, text: data})
138
+ send_to_telegram('sendMessage', {chat_id: params.message.chat.id, text: data})
156
139
  end
157
140
  end
158
141
  end
159
142
 
160
143
  when /(^image\/)/
161
- send_to_bot('sendPhoto', {chat_id: params.message.chat.id, photo: File.new(body)})
144
+ send_to_telegram('sendPhoto', {chat_id: params.message.chat.id, photo: File.new(body)})
162
145
 
163
146
  when /(^audio\/)/
164
- send_to_bot('sendAudio', {chat_id: params.message.chat.id, audio: File.new(body)})
147
+ send_to_telegram('sendAudio', {chat_id: params.message.chat.id, audio: File.new(body)})
165
148
 
166
149
  when /(^video\/)/
167
- send_to_bot('sendVideo', {chat_id: params.message.chat.id, video: File.new(body)})
150
+ send_to_telegram('sendVideo', {chat_id: params.message.chat.id, video: File.new(body)})
168
151
  end
169
152
  end
170
153
 
@@ -176,7 +159,28 @@ class TelegramBotMiddleware
176
159
  end
177
160
  end
178
161
 
179
- def process_hash_message(message, params)
162
+ # build command based on message
163
+ def get_command(params)
164
+ unless params.message['text'].nil?
165
+ # build path based on message
166
+ # - get only message part of post params
167
+ # - remove empty chars from beginning || end (strip)
168
+ # - replace first sequence of spaces with /
169
+ # - encode as uri
170
+ command = URI.escape(params.message.text.strip.sub(/\s+/, '/'))
171
+ # - add first / if not present
172
+ command = "/#{command}" unless command.start_with?('/')
173
+ return command
174
+ else
175
+ %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|
176
+ unless params.message[type].nil?
177
+ return "/#{type}"
178
+ end
179
+ end
180
+ end
181
+ end
182
+
183
+ def process_hash_message(message, params)
180
184
  if (message.include?(:multiple) && message[:multiple].is_a?(Array))
181
185
  message[:multiple].each { |item| process_json_message(item, params) }
182
186
  elsif (message.include?('multiple') && message['multiple'].is_a?(Array))
@@ -187,28 +191,35 @@ class TelegramBotMiddleware
187
191
  end
188
192
 
189
193
  def process_json_message(message, params)
190
- message[:chat_id] = params.message.chat.id unless message.include?(:chat_id) or message.include?('chat_id')
194
+ message[:chat_id] = params.message.chat.id unless message.include?(:chat_id) || message.include?('chat_id')
191
195
 
192
- message[:reply_markup] = message[:reply_markup].to_json if message.include?(:reply_markup)
193
- message['reply_markup'] = message['reply_markup'].to_json if message.include?('reply_markup')
196
+ ['reply_markup', :reply_markup].each do |item|
197
+ message[item] = message[item].to_json if message.include?(item)
198
+ end
194
199
 
195
200
  ['photo', :photo, 'audio', :audio, 'video', :video].each do |item|
196
201
  message[item] = File.new(message[item]) if message.include?(item)
197
202
  end
198
203
 
199
- if message.include?(:text) or message.include?('text')
200
- send_to_bot('sendMessage', message)
201
- elsif (message.include?(:latitude) and message.include?(:longitude)) or (message.include?('latitude') and message.include?('longitude'))
202
- send_to_bot('sendLocation', message)
203
- elsif message.include?(:photo) or message.include?('photo')
204
- send_to_bot('sendPhoto', message)
205
- elsif message.include?(:audio) or message.include?('audio')
206
- send_to_bot('sendAudio', message)
207
- elsif message.include?(:video) or message.include?('video')
208
- send_to_bot('sendVideo', message)
204
+ if message.include?(:text) || message.include?('text')
205
+ send_to_telegram('sendMessage', message)
206
+ elsif (message.include?(:latitude) and message.include?(:longitude)) || (message.include?('latitude') and message.include?('longitude'))
207
+ send_to_telegram('sendLocation', message)
208
+ elsif message.include?(:photo) || message.include?('photo')
209
+ send_to_telegram('sendPhoto', message)
210
+ elsif message.include?(:audio) || message.include?('audio')
211
+ send_to_telegram('sendAudio', message)
212
+ elsif message.include?(:video) || message.include?('video')
213
+ send_to_telegram('sendVideo', message)
209
214
  else
210
215
  # TODO: invalid query
211
- end
216
+ end
217
+ end
218
+
219
+ def send_to_telegram(path, query)
220
+ log_debug("Sending to chat: #{path} - #{query}")
221
+ self.class.post("/bot#{@config.token}/#{path}", query: query)
222
+ # TODO check response error and return response
212
223
  end
213
224
 
214
225
  def log_error(exception)
@@ -224,18 +235,13 @@ class TelegramBotMiddleware
224
235
  log(:debug, message)
225
236
  end
226
237
 
238
+ # TODO: to fix env
227
239
  def log(level, message)
228
- return if @env.nil?
229
- if @env['rack.logger']
230
- @env['rack.logger'].send(level, message)
231
- else
232
- @env['rack.errors'].write(message)
233
- end
234
- end
235
-
236
- def send_to_bot(path, query)
237
- log_debug("Sending to chat: #{path} - #{query}")
238
- response = self.class.post("/bot#{@config.token}/#{path}", query: query)
239
- # TODO check response error and return response
240
+ #return if @env.nil?
241
+ #if @env['rack.logger']
242
+ # @env['rack.logger'].send(level, message)
243
+ #else
244
+ # @env['rack.errors'].write(message)
245
+ #end
240
246
  end
241
247
  end
@@ -1,3 +1,3 @@
1
1
  class TelegramBotMiddleware
2
- VERSION = "0.3.1"
2
+ VERSION = "0.3.2"
3
3
  end
@@ -0,0 +1,5 @@
1
+ require 'coveralls'
2
+ Coveralls.wear!
3
+
4
+ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
5
+ require 'telegram_bot_middleware'
@@ -0,0 +1,39 @@
1
+ require 'spec_helper'
2
+
3
+ describe TelegramBotMiddleware do
4
+
5
+ let(:app) { ->(env) { [200, env, 'app'] } }
6
+ let(:token) { '138381425:AAEXjzZx5U5wZmiKvFmHjdNMkXJqnkHnum4' }
7
+ let(:host) { 'http://127.0.0.1:9292' }
8
+ let(:middleware) {
9
+ TelegramBotMiddleware.new(app) { |config|
10
+ config.token = token
11
+ config.host = host
12
+ }
13
+ }
14
+
15
+ def init_middleware(&block)
16
+ TelegramBotMiddleware.new(app, &block)
17
+ end
18
+
19
+ context 'Preliminary checks' do
20
+ it 'has a version number' do
21
+ expect(TelegramBotMiddleware::VERSION).not_to be nil
22
+ end
23
+ end
24
+
25
+ context 'Configuration not valid' do
26
+ it 'raise ArgumentError if token is null' do expect { init_middleware { |config| config.token = nil } }.to raise_error(ArgumentError) end
27
+ it 'raise ArgumentError if token is empty' do expect { init_middleware { |config| config.token = '' } }.to raise_error(ArgumentError) end
28
+ it 'raise ArgumentError if host is null' do expect { init_middleware { |config| config.token = token; config.host = nil } }.to raise_error(ArgumentError) end
29
+ it 'raise ArgumentError if host is empty' do expect { init_middleware { |config| config.token = token; config.host = '' } }.to raise_error(ArgumentError) end
30
+ it 'raise ArgumentError if get_updates is not valid' do expect { init_middleware { |config| config.token = token; config.host = host; config.get_updates = :not_valid } }.to raise_error(ArgumentError) end
31
+ end
32
+
33
+ context 'Configuration valid' do
34
+ it 'initialize with correct parameters' do
35
+ expect(middleware).to_not be nil
36
+ end
37
+ end
38
+
39
+ end
@@ -13,15 +13,18 @@ Gem::Specification.new do |spec|
13
13
  spec.homepage = 'https://github.com/MirkoMignini/telegram_bot_middleware'
14
14
  spec.license = 'MIT'
15
15
  spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
16
+ spec.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
16
17
  spec.bindir = "exe"
17
18
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
18
19
  spec.require_paths = ["lib"]
19
20
 
20
21
  spec.add_dependency 'rake', '~> 10.0'
22
+ spec.add_dependency 'rack'
21
23
  spec.add_dependency 'http'
22
24
  spec.add_dependency 'httmultiparty'
23
25
  spec.add_dependency 'persistent_httparty'
24
26
 
25
27
  spec.add_development_dependency 'bundler', '~> 1.10'
26
28
  spec.add_development_dependency 'rspec'
27
- end
29
+ spec.add_development_dependency 'coveralls'
30
+ 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.3.1
4
+ version: 0.3.2
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-17 00:00:00.000000000 Z
11
+ date: 2015-11-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '10.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rack
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: http
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -94,6 +108,20 @@ dependencies:
94
108
  - - ">="
95
109
  - !ruby/object:Gem::Version
96
110
  version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: coveralls
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
97
125
  description:
98
126
  email:
99
127
  - mirko.mignini@gmail.com
@@ -123,6 +151,8 @@ files:
123
151
  - lib/ostruct_nested.rb
124
152
  - lib/telegram_bot_middleware.rb
125
153
  - lib/telegram_bot_middleware/version.rb
154
+ - spec/spec_helper.rb
155
+ - spec/telegram_bot_middleware_spec.rb
126
156
  - telegram_bot_middleware.gemspec
127
157
  homepage: https://github.com/MirkoMignini/telegram_bot_middleware
128
158
  licenses:
@@ -148,4 +178,6 @@ rubygems_version: 2.2.2
148
178
  signing_key:
149
179
  specification_version: 4
150
180
  summary: Rack middleware to communicate with a telegram bot.
151
- test_files: []
181
+ test_files:
182
+ - spec/spec_helper.rb
183
+ - spec/telegram_bot_middleware_spec.rb