telegram_workflow 1.0.0 → 1.1.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 73a03ae1f9bea58f5cdc6bd1917107795429c95c2a54b98bd9ae3e8d95dd5bfe
4
- data.tar.gz: 762fbb323b0e4529118e7af5c1f5f35b1bad859fcc0b7b036fdc60d57a791f59
3
+ metadata.gz: edd8db5bb9937c5ae2154339550dc286f10e94c4b8290419ba9795d3e92a0f23
4
+ data.tar.gz: 26e421252440cbc137c6b25529e1c6cb8746aa63df41afc212724cd5229b8cc5
5
5
  SHA512:
6
- metadata.gz: 2c1b7bc39edcd1e4c133939aa3c7289b887a9540ba8ff64415b7428f9841e86b0f1f42b46734ba6f1359657e3dc4607e468b5d1a68720c76961a0c66fd80a788
7
- data.tar.gz: 5049a58f13c5717412ecd524a7219b8bdbf8d77d24447c5e0471f60c9256fc363b23c95639aed0d97ca0352edc10d1fa349cbc36690fe373da8919de5830d8fa
6
+ metadata.gz: 827dae61b2e7a63b2f4a36809e72fb79e67e619c8ec3570b11b6a1a1f0fdecb19d445a5ac91005ca3020d2baea9c8eb145311e59f449c411c023b09679be8978
7
+ data.tar.gz: 83d320d61b074092d6bf6a7783d73a88bed3b04f0ba83e2261108bbf5fc80760694d25736ff01693a4c3f81ce3fe7ed816ebb5298400cb19a3a39fa70255a718
data/.gitignore CHANGED
@@ -6,6 +6,7 @@
6
6
  /pkg/
7
7
  /spec/reports/
8
8
  /tmp/
9
+ Gemfile.lock
9
10
 
10
11
  # rspec failure tracking
11
12
  .rspec_status
@@ -2,5 +2,8 @@
2
2
  language: ruby
3
3
  cache: bundler
4
4
  rvm:
5
+ - 2.4.9
6
+ - 2.5.7
7
+ - 2.6.5
5
8
  - 2.7.0
6
- before_install: gem install bundler -v 2.1.4
9
+ before_install: gem install bundler
data/Gemfile CHANGED
@@ -5,3 +5,7 @@ gemspec
5
5
 
6
6
  gem "rake", "~> 12.0"
7
7
  gem "rspec", "~> 3.0"
8
+
9
+ group :test do
10
+ gem "coveralls", require: false
11
+ end
data/README.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # TelegramWorkflow
2
2
 
3
+ [![Build Status](https://travis-ci.org/rsamoilov/telegram_workflow.svg?branch=master)](https://travis-ci.org/rsamoilov/telegram_workflow)
4
+ [![Coverage Status](https://coveralls.io/repos/github/rsamoilov/telegram_workflow/badge.svg?branch=master)](https://coveralls.io/github/rsamoilov/telegram_workflow?branch=master)
5
+ [![Maintainability](https://api.codeclimate.com/v1/badges/fd13239262e3550c2193/maintainability)](https://codeclimate.com/github/rsamoilov/telegram_workflow/maintainability)
6
+
3
7
  TelegramWorkflow is a simple utility to help you organize the code to create Telegram bots.
4
8
 
5
9
  It includes the HTTP client, which implements the complete Telegram API and a set of helpers to improve
@@ -237,6 +241,14 @@ end
237
241
 
238
242
  Be aware that `TelegramWorkflow.updates.each` call is blocking.
239
243
 
244
+ `TelegramWorkflow` accepts all the parameters [getUpdates](https://core.telegram.org/bots/api#getupdates) does.
245
+
246
+ ```ruby
247
+ TelegramWorkflow.updates(timeout: 60, allowed_updates: %w(channel_post edited_channel_post)).each do |params|
248
+ ...
249
+ end
250
+ ```
251
+
240
252
  Since most of the time will be spent on waiting for the Telegram API to respond, you might also want to process the updates in parallel:
241
253
 
242
254
  ```ruby
@@ -249,6 +261,20 @@ TelegramWorkflow.updates.each do |params|
249
261
  end
250
262
  ```
251
263
 
264
+ Use `stop_updates` call to exit the updates loop:
265
+
266
+ ```ruby
267
+ trap "SIGINT" do
268
+ TelegramWorkflow.stop_updates
269
+ end
270
+
271
+ # decrease the timeout to wait no more than 10 seconds when exiting
272
+ TelegramWorkflow.updates(timeout: 10).each do |params|
273
+ TelegramWorkflow.process(params)
274
+ end
275
+
276
+ ```
277
+
252
278
  ## Customization
253
279
 
254
280
  Object | Customization
@@ -300,7 +326,21 @@ end
300
326
 
301
327
  ## Testing
302
328
 
303
- Testing utility provides `send_message` helper to emulate messages sent into the chat. Currently it accepts either `message_text` or `callback_data` as arguments.
329
+ Testing utility provides `send_message` helper to emulate messages sent into the chat.
330
+
331
+ ```ruby
332
+ # send a message
333
+ send_message message_text: "text"
334
+
335
+ # send CallbackQuery data
336
+ send_message callback_data: "data"
337
+
338
+ # send InlineQuery data
339
+ send_message inline_data: "data"
340
+
341
+ # customize the params
342
+ send_message { |params| params[:edited_channel_post] = { text: "message" } }
343
+ ```
304
344
 
305
345
  Also, `subject.client` and `subject.flow` spies are available to track redirects and calls to the API client inside your actions.
306
346
  Store your tests under `spec/telegram_actions` or tag them with `type: :telegram_action`.
@@ -15,7 +15,11 @@ module TelegramWorkflow
15
15
  params[:timeout] = timeout if timeout
16
16
  params[:allowed_updates] = allowed_updates if allowed_updates
17
17
 
18
- Updates.new(params).enum
18
+ (@updates = Updates.new(params)).enum
19
+ end
20
+
21
+ def self.stop_updates
22
+ @updates && @updates.stop = true
19
23
  end
20
24
  end
21
25
 
@@ -11,6 +11,12 @@ module TelegramWorkflow::Errors
11
11
  end
12
12
  end
13
13
 
14
+ class NoSession < StandardError
15
+ def initialize(msg = "Session could not be fetched for this update.")
16
+ super
17
+ end
18
+ end
19
+
14
20
  class ApiError < StandardError
15
21
  end
16
22
 
@@ -10,24 +10,25 @@ class TelegramWorkflow::Params
10
10
  end
11
11
 
12
12
  def user
13
- @user ||= @params.dig("message", "from") ||
13
+ @user ||= message&.dig("from") ||
14
14
  @params.dig("callback_query", "from") ||
15
15
  @params.dig("pre_checkout_query", "from") ||
16
16
  @params.dig("shipping_query", "from") ||
17
17
  @params.dig("inline_query", "from") ||
18
- @params.dig("chosen_inline_result", "from")
18
+ @params.dig("chosen_inline_result", "from") ||
19
+ @params.dig("poll_answer", "user")
19
20
  end
20
21
 
21
22
  def language_code
22
- user["language_code"]
23
+ user&.dig("language_code") || "en"
23
24
  end
24
25
 
25
26
  def user_id
26
- user["id"]
27
+ user&.dig("id")
27
28
  end
28
29
 
29
30
  def username
30
- user["username"]
31
+ user&.dig("username")
31
32
  end
32
33
 
33
34
  def chat_id
@@ -38,14 +39,25 @@ class TelegramWorkflow::Params
38
39
  @params.dig("edited_channel_post", "chat", "id")
39
40
  end
40
41
 
42
+ def message
43
+ @params["message"] ||
44
+ @params["edited_message"] ||
45
+ @params["channel_post"] ||
46
+ @params["edited_channel_post"]
47
+ end
48
+
41
49
  def message_text
42
- @params.dig("message", "text")
50
+ message&.dig("text")
43
51
  end
44
52
 
45
53
  def callback_data
46
54
  @params.dig("callback_query", "data")
47
55
  end
48
56
 
57
+ def inline_data
58
+ @params.dig("inline_query", "query")
59
+ end
60
+
49
61
  def start?
50
62
  !!message_text&.start_with?("/start")
51
63
  end
@@ -18,6 +18,9 @@ module TelegramActionExampleGroup
18
18
  },
19
19
  "callback_query" => {
20
20
  "data" => ""
21
+ },
22
+ "inline_query" => {
23
+ "query" => ""
21
24
  }
22
25
  }
23
26
  end
@@ -33,9 +36,11 @@ module TelegramActionExampleGroup
33
36
  end
34
37
 
35
38
  module InstanceMethods
36
- def send_message(message_text: "", callback_data: "")
39
+ def send_message(message_text: "", callback_data: "", inline_data: "")
37
40
  action_params["message"]["text"] = message_text
38
41
  action_params["callback_query"]["data"] = callback_data
42
+ action_params["inline_query"]["query"] = inline_data
43
+ yield action_params if block_given?
39
44
 
40
45
  workflow = TestFlow.new(action_params)
41
46
  workflow.example_group = self
@@ -27,20 +27,34 @@ class TelegramWorkflow::Session
27
27
  end
28
28
 
29
29
  def dump
30
- @store.write(@session_id, Marshal.dump(@session))
30
+ @session_id && @store.write(@session_id, Marshal.dump(@session))
31
31
  end
32
32
 
33
33
  # this is a user space to store some session data separately from the gem session
34
34
  def user_session
35
- @session[:user_session] ||= {}
35
+ @session_id ?
36
+ @session[:user_session] ||= {} :
37
+ NullSession.new
36
38
  end
37
39
 
38
40
  # this is a temporary per-action store
39
41
  def flash
40
- @session[:flash] ||= {}
42
+ @session_id ?
43
+ @session[:flash] ||= {} :
44
+ NullSession.new
41
45
  end
42
46
 
43
47
  def reset_flash
44
48
  flash.clear
45
49
  end
50
+
51
+ class NullSession < Hash
52
+ def [](key)
53
+ raise TelegramWorkflow::Errors::NoSession
54
+ end
55
+
56
+ def []=(key, value)
57
+ raise TelegramWorkflow::Errors::NoSession
58
+ end
59
+ end
46
60
  end
@@ -1,4 +1,6 @@
1
1
  class TelegramWorkflow::Updates
2
+ attr_writer :stop
3
+
2
4
  def initialize(params)
3
5
  @params = params
4
6
  end
@@ -6,12 +8,16 @@ class TelegramWorkflow::Updates
6
8
  def enum
7
9
  Enumerator.new do |y|
8
10
  loop do
11
+ break if @stop
12
+
9
13
  updates = TelegramWorkflow::Client.new.get_updates(@params)["result"]
10
14
  updates.each do |update|
11
15
  y << update
12
16
  end
13
17
 
14
- @params.merge! offset: updates.last["update_id"] + 1
18
+ if updates.any?
19
+ @params.merge! offset: updates.last["update_id"] + 1
20
+ end
15
21
  end
16
22
  end
17
23
  end
@@ -1,3 +1,3 @@
1
1
  module TelegramWorkflow
2
- VERSION = "1.0.0"
2
+ VERSION = "1.1.0"
3
3
  end
@@ -8,14 +8,14 @@ Gem::Specification.new do |spec|
8
8
  spec.summary = %q{A simple library to create Telegram Bots in Ruby.}
9
9
  spec.homepage = "https://github.com/rsamoilov/telegram_workflow"
10
10
  spec.license = "MIT"
11
- spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
11
+ spec.required_ruby_version = Gem::Requirement.new(">= 2.4.0")
12
12
 
13
13
  spec.metadata["homepage_uri"] = spec.homepage
14
14
  spec.metadata["source_code_uri"] = spec.homepage
15
15
 
16
16
  spec.add_dependency "http"
17
17
  spec.add_development_dependency "rspec", "~> 3.9"
18
- spec.add_development_dependency "activesupport", "~> 6.0.0"
18
+ spec.add_development_dependency "activesupport", "~> 5.2.0"
19
19
 
20
20
  # Specify which files should be added to the gem when it is released.
21
21
  # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: telegram_workflow
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Roman Samoilov
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-05-21 00:00:00.000000000 Z
11
+ date: 2020-06-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: http
@@ -44,14 +44,14 @@ dependencies:
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: 6.0.0
47
+ version: 5.2.0
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: 6.0.0
54
+ version: 5.2.0
55
55
  description:
56
56
  email:
57
57
  executables: []
@@ -63,7 +63,6 @@ files:
63
63
  - ".travis.yml"
64
64
  - CODE_OF_CONDUCT.md
65
65
  - Gemfile
66
- - Gemfile.lock
67
66
  - LICENSE.txt
68
67
  - README.md
69
68
  - Rakefile
@@ -97,7 +96,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
97
96
  requirements:
98
97
  - - ">="
99
98
  - !ruby/object:Gem::Version
100
- version: 2.3.0
99
+ version: 2.4.0
101
100
  required_rubygems_version: !ruby/object:Gem::Requirement
102
101
  requirements:
103
102
  - - ">="
@@ -1,72 +0,0 @@
1
- PATH
2
- remote: .
3
- specs:
4
- telegram_workflow (0.1.0)
5
- http
6
-
7
- GEM
8
- remote: https://rubygems.org/
9
- specs:
10
- activesupport (6.0.2.2)
11
- concurrent-ruby (~> 1.0, >= 1.0.2)
12
- i18n (>= 0.7, < 2)
13
- minitest (~> 5.1)
14
- tzinfo (~> 1.1)
15
- zeitwerk (~> 2.2)
16
- addressable (2.7.0)
17
- public_suffix (>= 2.0.2, < 5.0)
18
- concurrent-ruby (1.1.6)
19
- diff-lcs (1.3)
20
- domain_name (0.5.20190701)
21
- unf (>= 0.0.5, < 1.0.0)
22
- ffi (1.12.2)
23
- ffi-compiler (1.0.1)
24
- ffi (>= 1.0.0)
25
- rake
26
- http (4.4.1)
27
- addressable (~> 2.3)
28
- http-cookie (~> 1.0)
29
- http-form_data (~> 2.2)
30
- http-parser (~> 1.2.0)
31
- http-cookie (1.0.3)
32
- domain_name (~> 0.5)
33
- http-form_data (2.3.0)
34
- http-parser (1.2.1)
35
- ffi-compiler (>= 1.0, < 2.0)
36
- i18n (1.8.2)
37
- concurrent-ruby (~> 1.0)
38
- minitest (5.14.0)
39
- public_suffix (4.0.4)
40
- rake (12.3.3)
41
- rspec (3.9.0)
42
- rspec-core (~> 3.9.0)
43
- rspec-expectations (~> 3.9.0)
44
- rspec-mocks (~> 3.9.0)
45
- rspec-core (3.9.1)
46
- rspec-support (~> 3.9.1)
47
- rspec-expectations (3.9.1)
48
- diff-lcs (>= 1.2.0, < 2.0)
49
- rspec-support (~> 3.9.0)
50
- rspec-mocks (3.9.1)
51
- diff-lcs (>= 1.2.0, < 2.0)
52
- rspec-support (~> 3.9.0)
53
- rspec-support (3.9.2)
54
- thread_safe (0.3.6)
55
- tzinfo (1.2.7)
56
- thread_safe (~> 0.1)
57
- unf (0.1.4)
58
- unf_ext
59
- unf_ext (0.0.7.7)
60
- zeitwerk (2.3.0)
61
-
62
- PLATFORMS
63
- ruby
64
-
65
- DEPENDENCIES
66
- activesupport (~> 6.0.0)
67
- rake (~> 12.0)
68
- rspec (~> 3.0)
69
- telegram_workflow!
70
-
71
- BUNDLED WITH
72
- 2.1.4