telegram_workflow 1.3.0 → 1.4.0

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
  SHA256:
3
- metadata.gz: 9f33398c3b33397236392a5b645e39b58827df8e453727fd06496ce0b4479e11
4
- data.tar.gz: 9155e202748c8242adc4f4789623b8c42156658616e545d1aafd2aa4f2f776f7
3
+ metadata.gz: b9e4c2c5c0d7ee686ea3961a0af8c50ae6511c26cbf5ee704f1c3e27dad82e65
4
+ data.tar.gz: 80ce424f3627fb918810020c7811dbbe98713bd87e59280815ca6f7e37d6550f
5
5
  SHA512:
6
- metadata.gz: 4f85e7ab9b297deab054185d03863c8183bf7fbd6a7f1325ec612fa0042ee0999a700e80d91cb5cbed3b945605595904ec1716192b341d39f2402df805ea69f1
7
- data.tar.gz: 67bf8b6d8abc59f26c2e302f989aaa17777303bc3efdfb29844686d35f62994a2257557e7838188292e2fbbecc7eb7d1ad872c3f123eb9eb1b61b686b046a5ba
6
+ metadata.gz: 9ff7be3ead93112c1cb5debbe5f8a62399948057b445b896c4d3a585b660dfa9707569a5e214faa5fa75230b180db76b27167ae4c097ff687f7cec297dda5fa8
7
+ data.tar.gz: 04b307ae0e32fc0a5a76019372d8fed3fc5e70229818a90dbc134da3a5a9da1ce7d01e5ee50f3c41f905931f2fe5157b8bcff5d4c93a59009d9c6ce29dc4ea13
@@ -39,6 +39,6 @@ require "telegram_workflow/stores/file"
39
39
 
40
40
  TelegramWorkflow.__after_configuration do |config|
41
41
  if config.webhook_url
42
- TelegramWorkflow::Client.new.__setup_webhook
42
+ TelegramWorkflow::Client.new.__setup_webhook(config.webhook_url, config.webhook_params)
43
43
  end
44
44
  end
@@ -1,6 +1,6 @@
1
1
  class TelegramWorkflow::Client
2
2
  API_VERSION = "4.9"
3
- WebhookFilePath = Pathname.new("tmp/telegram_workflow/webhook_url.txt")
3
+ WebhookConfigPath = Pathname.new("tmp/telegram_workflow/webhook_config.txt")
4
4
 
5
5
  AVAILABLE_ACTIONS = %i(
6
6
  getUpdates
@@ -90,45 +90,46 @@ class TelegramWorkflow::Client
90
90
 
91
91
  def initialize(chat_id = nil)
92
92
  @chat_id = chat_id
93
- @webhook_url = TelegramWorkflow.config.webhook_url
94
93
  @api_url = "https://api.telegram.org/bot#{TelegramWorkflow.config.api_token}"
95
94
  end
96
95
 
97
96
  def set_webhook(params = {})
98
97
  make_request("setWebhook", params)
99
- cached_webhook_url(new_url: @webhook_url)
98
+ cached_webhook_config(params)
100
99
  end
101
100
 
102
101
  def delete_webhook
103
- make_request("deleteWebhook", {})
104
- cached_webhook_url(new_url: "")
102
+ make_request("deleteWebhook")
103
+ cached_webhook_config({})
105
104
  end
106
105
 
107
- def __setup_webhook
106
+ def __setup_webhook(webhook_url = TelegramWorkflow.config.webhook_url, params = {})
108
107
  TelegramWorkflow.config.logger.info "[TelegramWorkflow] Checking webhook setup..."
109
108
 
110
- if cached_webhook_url != @webhook_url
109
+ webhook_params = { url: webhook_url, allowed_updates: [], **params }
110
+
111
+ if cached_webhook_config != webhook_params
111
112
  TelegramWorkflow.config.logger.info "[TelegramWorkflow] Setting up a new webhook..."
112
- set_webhook(url: @webhook_url)
113
+ set_webhook(webhook_params)
113
114
  end
114
115
  end
115
116
 
116
117
  private
117
118
 
118
- def cached_webhook_url(new_url: nil)
119
- unless WebhookFilePath.exist?
120
- WebhookFilePath.dirname.mkpath
121
- WebhookFilePath.write("")
119
+ def cached_webhook_config(new_config = nil)
120
+ unless WebhookConfigPath.exist?
121
+ WebhookConfigPath.dirname.mkpath
122
+ WebhookConfigPath.write(Marshal.dump({}))
122
123
  end
123
124
 
124
- if new_url.nil?
125
- WebhookFilePath.read
125
+ if new_config.nil?
126
+ Marshal.load(WebhookConfigPath.read)
126
127
  else
127
- WebhookFilePath.write(new_url)
128
+ WebhookConfigPath.write(Marshal.dump(new_config))
128
129
  end
129
130
  end
130
131
 
131
- def make_request(action, params)
132
+ def make_request(action, params = {})
132
133
  has_file_params = params.any? { |_, param| param.is_a?(TelegramWorkflow::InputFile) }
133
134
  request_type = has_file_params ? :form : :json
134
135
 
@@ -21,12 +21,14 @@ module TelegramWorkflow
21
21
  end
22
22
 
23
23
  class Configuration
24
- attr_accessor :session_store, :logger, :client, :start_action, :webhook_url, :api_token
24
+ attr_accessor :session_store, :logger, :client, :start_action, :webhook_url, :api_token,
25
+ :webhook_params
25
26
 
26
27
  REQUIRED_PARAMS = %i(session_store start_action api_token)
27
28
 
28
29
  def initialize
29
30
  @client = TelegramWorkflow::Client
31
+ @webhook_params = {}
30
32
 
31
33
  if defined?(Rails)
32
34
  @session_store = Rails.cache
@@ -1,3 +1,3 @@
1
1
  module TelegramWorkflow
2
- VERSION = "1.3.0"
2
+ VERSION = "1.4.0"
3
3
  end
@@ -21,7 +21,7 @@ Gem::Specification.new do |spec|
21
21
  # Specify which files should be added to the gem when it is released.
22
22
  # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
23
23
  spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
24
- `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
24
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features|example)/}) }
25
25
  end
26
26
  spec.bindir = "exe"
27
27
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
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.3.0
4
+ version: 1.4.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-06-29 00:00:00.000000000 Z
11
+ date: 2020-07-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: http
@@ -82,17 +82,6 @@ files:
82
82
  - Rakefile
83
83
  - bin/console
84
84
  - bin/setup
85
- - example/Gemfile
86
- - example/README.md
87
- - example/actions/create_appointment.rb
88
- - example/actions/list_actions.rb
89
- - example/actions/list_appointments.rb
90
- - example/actions/select_doctor.rb
91
- - example/actions/start.rb
92
- - example/client.rb
93
- - example/environment.rb
94
- - example/flow.jpg
95
- - example/main.rb
96
85
  - lib/telegram_workflow.rb
97
86
  - lib/telegram_workflow/action.rb
98
87
  - lib/telegram_workflow/client.rb
@@ -1,2 +0,0 @@
1
- source "https://rubygems.org"
2
- gem "telegram_workflow"
@@ -1,79 +0,0 @@
1
- ## Description
2
-
3
- This is a fully working example of a bot which allows you to book an appointment with a doctor.
4
-
5
- The following diagram will help you understand the bot's flow:
6
- <p>
7
- <img src="https://github.com/rsamoilov/telegram_workflow/blob/master/example/flow.jpg" width="400">
8
- </p>
9
-
10
- ## Running the bot
11
-
12
- First, open [main.rb](main.rb) and configure the bot with your API token:
13
-
14
- ```diff
15
- TelegramWorkflow.configure do |config|
16
- - config.api_token = <YOUR_TOKEN>
17
- + config.api_token = "123456780:ABCDE_my-token"
18
- end
19
- ```
20
-
21
- Next, run the bot:
22
-
23
- ```
24
- bundle
25
- ruby main.rb
26
- ```
27
-
28
- ## Configuration
29
-
30
- Every Bot workflow begins with **`on_message`** callback in a `start_action`.
31
- There's no need to store current user data in session in this example, so we simply redirect to the `ListActions` action, which will be our "main" action.
32
-
33
- ```ruby
34
- class Actions::Start < TelegramWorkflow::Action
35
- def initial
36
- on_message do
37
- redirect_to Actions::ListActions
38
- end
39
- end
40
- end
41
- ```
42
-
43
- Next, the Telegram client can be customized. We want to use Telegram's [InlineKeyboard](https://core.telegram.org/bots#inline-keyboards-and-on-the-fly-updating) to provide a user with a list of available actions.
44
-
45
- Let's encapsulate this inside our custom client class:
46
-
47
- ```ruby
48
- class Client < TelegramWorkflow::Client
49
- def send_actions(message, actions)
50
- send_message text: message, reply_markup: { inline_keyboard: actions }
51
- end
52
- end
53
- ```
54
-
55
- Now, let's configure the gem:
56
-
57
- ```ruby
58
- TelegramWorkflow.configure do |config|
59
- config.start_action = Actions::Start
60
- config.client = Client
61
- config.session_store = TelegramWorkflow::Stores::File.new
62
- end
63
- ```
64
-
65
- The last configuration parameter here is `session_store`. We are using `TelegramWorkflow::Stores::File` - a built-in implementation of persistent file store.
66
-
67
- [getUpdates](https://core.telegram.org/bots/api#getupdates) method is used in this example to receive the updates:
68
-
69
- ```ruby
70
- TelegramWorkflow.updates.each do |params|
71
- TelegramWorkflow.process(params)
72
- end
73
- ```
74
-
75
- After a user has sent a message, `TelegramWorkflow.process` will initialize the last processed action and step and then call `on_message` callback on it.
76
-
77
- ## Actions
78
-
79
- Check out the bot's code under [actions](actions) folder.
@@ -1,56 +0,0 @@
1
- #
2
- # this is an action to create an appointment;
3
- # each method represents one of the steps for appointment creation;
4
- # for the sake of simplicity, all created appointments are stored in the session
5
- #
6
- class Actions::CreateAppointment < TelegramWorkflow::Action
7
- def initial
8
- on_redirect do
9
- client.send_message text: "Enter patient's name:"
10
- end
11
-
12
- on_message do
13
- flash[:name] = params.message_text
14
- redirect_to :reason
15
- end
16
- end
17
-
18
- def reason
19
- on_redirect do
20
- client.send_message text: "What is the reason for visit?"
21
- end
22
-
23
- on_message do
24
- flash[:reason] = params.message_text
25
- redirect_to :date
26
- end
27
- end
28
-
29
- def date
30
- on_redirect do
31
- client.send_message text: "What date works best for you?"
32
- end
33
-
34
- on_message do
35
- date = Date.parse(params.message_text) rescue nil
36
-
37
- # there's no redirect in case the date is invalid;
38
- # this means that next time a user sends a message, the current action will be executed again
39
- if date
40
- flash[:date] = date
41
- redirect_to :done
42
- else
43
- client.send_message text: "Invalid date format. Please try again."
44
- end
45
- end
46
- end
47
-
48
- # `specialty` parameter is added to flash in previous `Actions::SelectDoctor` action
49
- def done
50
- on_redirect do
51
- (session[:appointments] ||= []) << flash.slice(:name, :reason, :date, :specialty)
52
- client.send_message text: "Your appointment has been created!"
53
- redirect_to Actions::ListActions
54
- end
55
- end
56
- end
@@ -1,28 +0,0 @@
1
- class Actions::ListActions < TelegramWorkflow::Action
2
- def initial
3
- on_redirect do
4
- available_actions = [
5
- [{ text: "Make an appointment", callback_data: "create" }]
6
- ]
7
-
8
- if session[:appointments]&.any?
9
- available_actions.unshift [{ text: "List my appointments", callback_data: "list" }]
10
- end
11
-
12
- # this is the customized client object
13
- client.send_actions "Select an action:", available_actions
14
- end
15
-
16
- # `params.callback_data` here will be one of the identifiers defined as `callback_data` in `available_actions` array
17
- # refer to https://core.telegram.org/bots/api#inlinekeyboardbutton
18
- on_message do
19
- next_action = if params.callback_data == "create"
20
- Actions::SelectDoctor
21
- elsif params.callback_data == "list"
22
- Actions::ListAppointments
23
- end
24
-
25
- redirect_to next_action
26
- end
27
- end
28
- end
@@ -1,13 +0,0 @@
1
- class Actions::ListAppointments < TelegramWorkflow::Action
2
- def initial
3
- on_redirect do
4
- appointments = session[:appointments].map do |app|
5
- "<b>#{app[:name]}</b> on #{app[:date].to_s}"
6
- end
7
-
8
- # refer to https://core.telegram.org/bots/api#sendmessage for the list of available parameters
9
- client.send_message text: appointments.join("\n"), parse_mode: "HTML"
10
- redirect_to Actions::ListActions
11
- end
12
- end
13
- end
@@ -1,19 +0,0 @@
1
- class Actions::SelectDoctor < TelegramWorkflow::Action
2
- def initial
3
- on_redirect do
4
- available_doctors = [
5
- [{ text: "Family Medicine", callback_data: "family" }],
6
- [{ text: "Emergency Medicine", callback_data: "emergency" }],
7
- [{ text: "Pediatrics", callback_data: "pediatrics" }]
8
- ]
9
-
10
- client.send_actions "Select a doctor:", available_doctors
11
- end
12
-
13
- on_message do
14
- # pass `specialty` parameter to the next action
15
- # https://github.com/rsamoilov/telegram_workflow#redirect_toaction_or_class-flash_params--
16
- redirect_to Actions::CreateAppointment, specialty: params.callback_data
17
- end
18
- end
19
- end
@@ -1,9 +0,0 @@
1
- class Actions::Start < TelegramWorkflow::Action
2
- def initial
3
- # we don't need to store current user id in session or make any other setup,
4
- # so just redirect to the `ListActions` action
5
- on_message do
6
- redirect_to Actions::ListActions
7
- end
8
- end
9
- end
@@ -1,5 +0,0 @@
1
- class Client < TelegramWorkflow::Client
2
- def send_actions(message, actions)
3
- send_message text: message, reply_markup: { inline_keyboard: actions }
4
- end
5
- end
@@ -1,13 +0,0 @@
1
- require "telegram_workflow"
2
- require "date"
3
-
4
- module Actions
5
- end
6
-
7
- dependencies = %w(
8
- ./actions/*.rb
9
- ./client.rb
10
- )
11
- dependencies.each do |path|
12
- Dir[path].each { |path| require_relative path }
13
- end
Binary file
@@ -1,17 +0,0 @@
1
- require_relative "environment"
2
-
3
- TelegramWorkflow.configure do |config|
4
- config.start_action = Actions::Start
5
- config.client = Client
6
- config.session_store = TelegramWorkflow::Stores::File.new
7
- config.api_token = <YOUR_TOKEN>
8
- end
9
-
10
- trap "SIGINT" do
11
- puts "Exiting..."
12
- TelegramWorkflow.stop_updates
13
- end
14
-
15
- TelegramWorkflow.updates(timeout: 5).each do |params|
16
- TelegramWorkflow.process(params)
17
- end