telegram_bot_middleware 0.3.1 → 0.3.2

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