bobot 1.0.53 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (66) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +18 -8
  3. data/app/controllers/bobot/webhook_controller.rb +54 -30
  4. data/config/routes.rb +1 -2
  5. data/lib/bobot.rb +15 -1
  6. data/lib/bobot/commander.rb +9 -8
  7. data/lib/bobot/configuration.rb +149 -186
  8. data/lib/bobot/engine.rb +0 -4
  9. data/lib/bobot/events/common.rb +4 -4
  10. data/lib/bobot/events/delivery.rb +0 -1
  11. data/lib/bobot/events/message.rb +4 -0
  12. data/lib/bobot/events/message_echo.rb +3 -2
  13. data/lib/bobot/events/message_request.rb +9 -0
  14. data/lib/bobot/graph_facebook.rb +4 -4
  15. data/lib/bobot/profile.rb +2 -6
  16. data/lib/bobot/version.rb +3 -3
  17. data/lib/generators/bobot/templates/app/bobot/workflow.rb +9 -11
  18. data/lib/generators/bobot/templates/config/bobot.yml +41 -32
  19. data/lib/generators/bobot/templates/config/initializers/bobot.rb +25 -9
  20. data/lib/generators/bobot/templates/config/locales/bobot.en.yml +29 -28
  21. data/lib/generators/bobot/templates/config/locales/bobot.fr.yml +28 -27
  22. data/lib/generators/bobot/utils.rb +0 -9
  23. data/spec/bobot/bobot_spec.rb +18 -12
  24. data/spec/bobot/event/common_spec.rb +3 -1
  25. data/spec/bobot/event/message_spec.rb +7 -0
  26. data/spec/bobot/profile_spec.rb +3 -1
  27. data/spec/bobot/subscription_spec.rb +4 -2
  28. data/spec/bobot/user_spec.rb +4 -2
  29. data/spec/dummy/app/channels/application_cable/channel.rb +4 -0
  30. data/spec/dummy/app/channels/application_cable/connection.rb +4 -0
  31. data/spec/dummy/app/mailers/application_mailer.rb +4 -0
  32. data/spec/dummy/app/views/layouts/mailer.html.erb +13 -0
  33. data/spec/dummy/app/views/layouts/mailer.text.erb +1 -0
  34. data/spec/dummy/bin/setup +0 -8
  35. data/spec/dummy/bin/update +0 -3
  36. data/spec/dummy/config/application.rb +3 -2
  37. data/spec/dummy/config/cable.yml +10 -0
  38. data/spec/dummy/config/environments/development.rb +5 -3
  39. data/spec/dummy/config/environments/production.rb +5 -3
  40. data/spec/dummy/config/environments/test.rb +6 -2
  41. data/spec/dummy/config/initializers/application_controller_renderer.rb +6 -4
  42. data/spec/dummy/config/initializers/wrap_parameters.rb +0 -5
  43. data/spec/dummy/config/routes.rb +1 -1
  44. data/spec/dummy/config/secrets.yml +2 -2
  45. data/spec/dummy/log/development.log +0 -0
  46. data/spec/dummy/log/test.log +2 -0
  47. data/spec/dummy/tmp/generator/app/bobot/workflow.rb +15 -0
  48. data/spec/dummy/tmp/generator/config/bobot.yml +48 -0
  49. data/spec/dummy/tmp/generator/config/initializers/bobot.rb +46 -0
  50. data/spec/dummy/tmp/generator/config/locales/bobot.en.yml +31 -0
  51. data/spec/dummy/tmp/generator/config/locales/bobot.fr.yml +30 -0
  52. data/spec/dummy/tmp/generator/config/routes.rb +0 -0
  53. data/spec/rails_helper.rb +8 -10
  54. metadata +43 -34
  55. data/app/mailers/bobot/application_mailer.rb +0 -6
  56. data/app/models/bobot/application_record.rb +0 -5
  57. data/lib/generators/bobot/templates/app/bobot/message.rb +0 -3
  58. data/lib/generators/bobot/templates/app/bobot/postback.rb +0 -22
  59. data/spec/dummy/app/bobot/workflow.rb +0 -17
  60. data/spec/dummy/app/models/application_record.rb +0 -3
  61. data/spec/dummy/config/bobot.yml +0 -27
  62. data/spec/dummy/config/database.yml +0 -19
  63. data/spec/dummy/config/initializers/bobot.rb +0 -30
  64. data/spec/dummy/config/locales/bobot.en.yml +0 -28
  65. data/spec/dummy/config/locales/bobot.fr.yml +0 -27
  66. data/spec/dummy/db/schema.rb +0 -15
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9abca691c0b2cccaa74e39426221e12d320ff0d4
4
- data.tar.gz: 16f6c8684ae068e0ec36306cf4125061a4fd7fea
3
+ metadata.gz: 238ce4063aa11a3df2f3150c8a7a65e23cc0063f
4
+ data.tar.gz: ce018a45a1d777752c746c4b7f46e2049fdfa071
5
5
  SHA512:
6
- metadata.gz: 52e6bb306d99fc08db6436822c9b29396e5ecf4031b59e62f35da3bc5af71fb9a426138faccc338dcbed38b0c695345c7b9b1ad75a813976d62fb70590c54cb6
7
- data.tar.gz: bb9bf2d9500c16da7c4dc5a6233bb467b3564263028d24882a85b8104c3273f4ad315aac1bd6ab85a12a2c717ebcc4072a13bcced26d5d8d6424e003a30f2bc1
6
+ metadata.gz: 76f2106985520b82654e76d11340e24bcf3c4a25074c87a345f3d543f54384419538fbcc05ed82b33015ee539c4f5dc75736e5eb9f518ae38ef179e9978e0802
7
+ data.tar.gz: f793e2ae3e8b5bdb50bcbda3e639c16018e4db52f420bf823dd81b489ce4f208623fe78050f09337a67f53c29d3a465756f676fe3c8a62cfb53192fb26b7b54d
data/README.md CHANGED
@@ -31,16 +31,26 @@ Typing the following command in your Rails application will add the bot to your
31
31
  `config/bobot.yml` contains your bot keys
32
32
  `app/bobot/workflow.rb` contains the workflow of your bot
33
33
 
34
- You can run in a Rails console:
35
- `Bobot.update_facebook_setup!`
34
+ You can access to page settings:
35
+ ```
36
+ Bobot.config.find_page_by_id(facebook_page_id)
37
+ Bobot.config.find_page_by_slug(facebook_page_slug)
38
+ ```
39
+
40
+ After fetching the page with command above, you have access to:
41
+ `update_facebook_setup!`
36
42
 
37
43
  Or one by one in a Rails console:
38
- - `Bobot.subscribe_to_facebook_page!`
39
- - `Bobot.unsubscribe_to_facebook_page!`
40
- - `Bobot.set_greeting_text!`
41
- - `Bobot.set_whitelist_domains!`
42
- - `Bobot.set_get_started_button!`
43
- - `Bobot.set_persistent_menu!`
44
+ - `subscribe_to_facebook_page!`
45
+ - `unsubscribe_to_facebook_page!`
46
+ - `unset_greeting_text!`
47
+ - `set_greeting_text!`
48
+ - `unset_whitelist_domains!`
49
+ - `set_whitelist_domains!`
50
+ - `unset_get_started_button!`
51
+ - `set_get_started_button!`
52
+ - `unset_persistent_menu!`
53
+ - `set_persistent_menu!`
44
54
 
45
55
  Greeting Text and Persistent Menus are translated by I18n.
46
56
  You have to define into your `config/application.rb` your available_locales as I18n defined them.
@@ -1,28 +1,46 @@
1
1
  module Bobot
2
2
  class WebhookController < Bobot::ApplicationController
3
+ class BadRequestError < Error; end
4
+
3
5
  include ActionView::Helpers::TextHelper
4
6
 
5
7
  skip_before_action :verify_authenticity_token, raise: false
6
8
 
7
9
  layout :bobot_layout rescue nil
8
10
 
9
- def notify
10
- if check_integrity?
11
- respond_with body: ActiveSupport::JSON.encode(trigger(parsed_body)), status: :ok
11
+ X_HUB_SIGNATURE_MISSING_WARNING = <<-HEREDOC.freeze
12
+ The X-Hub-Signature header is not present in the request. This is
13
+ expected for the first webhook requests. If it continues after
14
+ some time, check your app's secret token.
15
+ HEREDOC
16
+
17
+ def webhook
18
+ if request.get?
19
+ verify
20
+ elsif request.post?
21
+ receive
12
22
  else
13
- respond_with status: :forbidden
23
+ head :method_not_allowed
14
24
  end
15
25
  end
16
26
 
17
27
  def verify
18
- if verify_params['hub.mode'] == 'subscribe' &&
19
- verify_params['hub.verify_token'] == Bobot.verify_token
20
- respond_with body: params['hub.challenge'], status: :ok
28
+ if params['hub.mode'.freeze] == 'subscribe' &&
29
+ params['hub.verify_token'.freeze] == Bobot.config.verify_token
30
+ render plain: params['hub.challenge'.freeze], status: :ok
21
31
  else
22
- respond_with status: :forbidden
32
+ render plain: "Error wrong verify token".freeze, status: :forbidden
23
33
  end
24
34
  end
25
35
 
36
+ def receive
37
+ check_integrity
38
+ return_json = trigger(parsed_body)
39
+ render plain: ActiveSupport::JSON.encode(return_json), status: :ok
40
+ rescue BadRequestError => error
41
+ render plain: error.message, status: :bad_request
42
+ end
43
+
26
44
  private
27
45
 
28
46
  def body
@@ -30,27 +48,42 @@ module Bobot
30
48
  end
31
49
 
32
50
  def parsed_body
33
- @parsed_body ||= begin
34
- ActiveSupport::JSON.decode(body)
35
- rescue ::ActiveSupport::JSON.parse_error
36
- 'payload is not string and not a valid to be JSONified.'
37
- end
51
+ @parsed_body ||= ActiveSupport::JSON.decode(body)
52
+ rescue ::ActiveSupport::JSON.parse_error
53
+ raise BadRequestError.new("Error parsing request body format")
54
+ end
55
+
56
+ def valid_signature?
57
+ Rack::Utils.secure_compare(signature, signature_for(body))
58
+ end
59
+
60
+ def generate_hmac(content)
61
+ OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha1'.freeze), Bobot.config.app_secret, content)
38
62
  end
39
63
 
40
- def signature(str, key = nil)
41
- key ||= Bobot.app_secret
42
- OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha1'), key, str)
64
+ def signature_for(string)
65
+ format('sha1=%s'.freeze, generate_hmac(string))
43
66
  end
44
67
 
45
- def check_integrity?
46
- request.headers['HTTP_X_HUB_SIGNATURE'].to_s =~ /\Asha1=([0-9a-z]{40})\z/
68
+ def signature
69
+ request.headers['HTTP_X_HUB_SIGNATURE'.freeze].to_s
70
+ end
71
+
72
+ def check_integrity
73
+ signature =~ /\Asha1=([0-9a-z]{40})\z/
47
74
  hub_signature = Regexp.last_match(1)
48
- hub_signature && Rack::Utils.secure_compare(hub_signature, signature(body))
75
+ unless hub_signature
76
+ Rails.logger.error(X_HUB_SIGNATURE_MISSING_WARNING)
77
+ raise BadRequestError.new("Error getting integrity signature".freeze)
78
+ end
79
+ unless valid_signature?
80
+ raise BadRequestError.new("Error checking message integrity".freeze)
81
+ end
49
82
  end
50
83
 
51
84
  def trigger(events)
52
- events['entry'].inject([]) do |payloads_sent, entry|
53
- entry['messaging'].each do |messaging|
85
+ events['entry'.freeze].to_a.inject([]) do |payloads_sent, entry|
86
+ entry['messaging'.freeze].to_a.each do |messaging|
54
87
  begin
55
88
  payloads_sent << Bobot::Commander.receive(messaging)
56
89
  rescue => e
@@ -60,15 +93,6 @@ module Bobot
60
93
  end
61
94
  end
62
95
 
63
- def respond_with(body: '', status:)
64
- self.response_body = body
65
- self.status = status
66
- end
67
-
68
- def verify_params
69
- params.permit('hub.mode', 'hub.challenge', 'hub.verify_token')
70
- end
71
-
72
96
  def bobot_layout
73
97
  'bobot/application'
74
98
  end
@@ -1,6 +1,5 @@
1
1
  Bobot::Engine.routes.draw do
2
2
  controller 'webhook' do
3
- match 'facebook', action: :notify, via: :post, as: :facebook_notify
4
- match 'facebook', action: :verify, via: :get, as: :facebook_verify
3
+ match 'facebook', action: :webhook, via: [:get, :post]
5
4
  end
6
5
  end
@@ -14,5 +14,19 @@ require 'bobot/commander'
14
14
  require 'bobot/event'
15
15
 
16
16
  module Bobot
17
- extend Configuration
17
+ def self.configure
18
+ yield config
19
+ end
20
+
21
+ def self.config
22
+ @config ||= Configuration.new
23
+ end
24
+
25
+ def self.config=(config)
26
+ @config = config
27
+ end
28
+
29
+ configure do |config|
30
+ config.pages = []
31
+ end
18
32
  end
@@ -11,6 +11,7 @@ module Bobot
11
11
  account_linking
12
12
  referral
13
13
  message_echo
14
+ message_request
14
15
  ].freeze
15
16
 
16
17
  include Bobot::GraphFacebook
@@ -32,28 +33,28 @@ module Bobot
32
33
  def receive(payload)
33
34
  event = Bobot::Event.parse(payload)
34
35
  hooks.fetch(Bobot::Event::EVENTS.invert[event.class].to_sym)
35
- puts "[ActiveJob] << Bobot::HookJob with event #{event.class}" if Bobot.debug_log
36
- #event.mark_as_seen
36
+ puts "[ActiveJob] << Bobot::HookJob with event #{event.class}" if Bobot.config.debug_log
37
+ # event.mark_as_seen
37
38
  job = Bobot::CommanderJob
38
- if Bobot.async
39
+ if Bobot.config.async
39
40
  job.perform_later(payload: payload)
40
41
  else
41
42
  job.perform_now(payload: payload)
42
43
  end
43
44
  rescue KeyError
44
- $stderr.puts "Ignoring #{event.class} (no hook registered)"
45
+ warn "Ignoring #{event.class} (no hook registered)"
45
46
  end
46
47
 
47
48
  def trigger(payload)
48
49
  event = Bobot::Event.parse(payload)
49
50
  hook = hooks.fetch(Bobot::Event::EVENTS.invert[event.class].to_sym)
50
- puts "[ActiveJob] >> Bobot::HookJob related to event #{name.class}" if Bobot.debug_log
51
- #event.show_typing(state: true)
51
+ puts "[ActiveJob] >> Bobot::HookJob related to event #{name.class}" if Bobot.config.debug_log
52
+ # event.show_typing(state: true)
52
53
  hook.call(event)
53
- #event.show_typing(state: false)
54
+ # event.show_typing(state: false)
54
55
  [event, event.payloads_sent[1..-2]]
55
56
  rescue KeyError
56
- $stderr.puts "Ignoring #{event.class} (no hook registered)"
57
+ warn "Ignoring #{event.class} (no hook registered)"
57
58
  end
58
59
 
59
60
  def hooks
@@ -1,60 +1,7 @@
1
1
  module Bobot
2
- # Defines constants and methods related to configuration
3
- module Configuration
4
- # An array of valid keys in the options hash when configuring
5
- VALID_CONFIGURATION_KEYS = %i[
6
- page_id
7
- app_id
8
- app_secret
9
- page_access_token
10
- verify_token
11
- domains
12
- debug_log
13
- async
14
- ].freeze
15
-
16
- # By default, don't set a facebook page id
17
- DEFAULT_PAGE_ID = nil
18
-
19
- # By default, don't set a facebook developper app id
20
- DEFAULT_APP_ID = nil
21
-
22
- # By default, don't set a facebook developper app secret
23
- DEFAULT_APP_SECRET = nil
24
-
25
- # By default, don't set a facebook developper page access token
26
- DEFAULT_PAGE_ACCESS_TOKEN = nil
27
-
28
- # By default, don't set a facebook webhook_verify_token
29
- DEFAULT_VERIFY_TOKEN = nil
30
-
31
- # By default, don't set a facebook whitelisting domains
32
- DEFAULT_DOMAINS = nil
33
-
34
- # By default, debug log is to false
35
- DEFAULT_DEBUG_LOG = false
36
-
37
- # By default, async is to false
38
- DEFAULT_ASYNC = false
39
-
40
- # @private
41
- attr_accessor(*VALID_CONFIGURATION_KEYS)
42
-
43
- # Our host application root path
44
- # We set this when the engine is initialized
45
- mattr_accessor :app_root
46
-
47
- # When this module is extended, set all configuration options to their default values
48
- def self.extended(base)
49
- base.reset!
50
- end
51
-
52
- # Convenience method to allow configuration options to be set in a block
53
- def configure
54
- yield self
55
- end
2
+ class Configuration
3
+ attr_accessor :app_id, :app_secret, :verify_token, :debug_log, :async, :pages
56
4
 
57
- # Custom self assignments
58
5
  def domains=(rhs)
59
6
  return unless rhs.present?
60
7
  if rhs.respond_to?(:to_str)
@@ -66,166 +13,182 @@ module Bobot
66
13
  end
67
14
  end
68
15
 
69
- # Create a hash of options and their values
70
- def configurations
71
- VALID_CONFIGURATION_KEYS.inject({}) do |option, key|
72
- option.merge!(key => send(key))
73
- end
16
+ def find_page_by_id(page_id)
17
+ pages.find { |page| page.page_id == page_id }
74
18
  end
75
19
 
76
- # Reset all configuration options to defaults
77
- def reset!
78
- self.page_id = DEFAULT_PAGE_ID
79
- self.app_id = DEFAULT_APP_ID
80
- self.app_secret = DEFAULT_APP_SECRET
81
- self.page_access_token = DEFAULT_PAGE_ACCESS_TOKEN
82
- self.verify_token = DEFAULT_VERIFY_TOKEN
83
- self.domains = DEFAULT_DOMAINS
84
- self.debug_log = DEFAULT_DEBUG_LOG
85
- self.async = DEFAULT_ASYNC
20
+ def find_page_by_slug(slug)
21
+ pages.find { |page| page.slug == slug }
86
22
  end
87
23
 
88
- def update_facebook_setup!
89
- subscribe_to_facebook_page!
90
- set_greeting_text!
91
- set_whitelist_domains!
92
- set_get_started_button!
93
- set_persistent_menu!
94
- end
24
+ class Page
25
+ attr_accessor :slug, :language, :page_id, :page_access_token
95
26
 
96
- ## == Subcribe your bot to your page ==
97
- def subscribe_to_facebook_page!
98
- raise Bobot::InvalidParameter.new(:page_id) unless Bobot.page_id.present?
99
- raise Bobot::InvalidParameter.new(:access_token) unless Bobot.page_access_token.present?
100
- Bobot::Subscription.set(
101
- query: {
102
- page_id: Bobot.page_id,
103
- access_token: Bobot.page_access_token,
104
- },
105
- )
106
- end
27
+ def initialize(options = {})
28
+ self.slug = options[:slug]
29
+ self.language = options[:language]
30
+ self.page_id = options[:page_id]
31
+ self.page_access_token = options[:page_access_token]
32
+ end
107
33
 
108
- ## == Unsubcribe your bot from your page ==
109
- def unsubscribe_to_facebook_page!
110
- raise Bobot::InvalidParameter.new(:page_id) unless Bobot.page_id.present?
111
- raise Bobot::InvalidParameter.new(:access_token) unless Bobot.page_access_token.present?
112
- Bobot::Subscription.unset(
113
- query: {
114
- page_id: Bobot.page_id,
115
- access_token: Bobot.page_access_token,
116
- },
117
- )
118
- end
34
+ def update_facebook_setup!
35
+ subscribe_to_facebook_page!
36
+ set_greeting_text!
37
+ set_whitelist_domains!
38
+ set_get_started_button!
39
+ set_persistent_menu!
40
+ end
41
+
42
+ ## == Subcribe your bot to your page ==
43
+ def subscribe_to_facebook_page!
44
+ raise Bobot::InvalidParameter.new(:page_id) unless page_id.present?
45
+ raise Bobot::InvalidParameter.new(:access_token) unless page_access_token.present?
46
+ Bobot::Subscription.set(
47
+ query: {
48
+ page_id: page_id,
49
+ access_token: page_access_token,
50
+ },
51
+ )
52
+ end
119
53
 
120
- ## == Set bot description (only displayed on first time). ==
121
- def set_greeting_text!
122
- raise Bobot::InvalidParameter.new(:access_token) unless Bobot.page_access_token.present?
123
- greeting_texts = []
124
- # Default text
125
- greeting_text = I18n.t('bobot.config.greeting_text', locale: I18n.default_locale, default: nil)
126
- if greeting_text.present?
127
- greeting_texts << {
128
- locale: 'default',
129
- text: greeting_text,
130
- }
54
+ ## == Unsubcribe your bot from your page ==
55
+ def unsubscribe_to_facebook_page!
56
+ raise Bobot::InvalidParameter.new(:page_id) unless page_id.present?
57
+ raise Bobot::InvalidParameter.new(:access_token) unless page_access_token.present?
58
+ Bobot::Subscription.unset(
59
+ query: {
60
+ page_id: page_id,
61
+ access_token: page_access_token,
62
+ },
63
+ )
131
64
  end
132
- # Each languages
133
- I18n.available_locales.each do |locale|
134
- greeting_text = I18n.t('bobot.config.greeting_text', locale: locale, default: nil)
135
- next unless greeting_text.present?
136
- facebook_locales = I18n.t('bobot.config.facebook_locales', locale: locale, default: nil)
137
- facebook_locales.to_a.each do |locale_long|
138
- greeting_texts << { locale: locale_long, text: greeting_text }
65
+
66
+ ## == Set bot description (only displayed on first time). ==
67
+ def set_greeting_text!
68
+ raise Bobot::InvalidParameter.new(:access_token) unless page_access_token.present?
69
+ greeting_texts = []
70
+ # Default text
71
+ greeting_text = I18n.t("bobot.#{slug}.config.greeting_text", locale: I18n.default_locale, default: nil)
72
+ greeting_texts << { locale: 'default', text: greeting_text } if greeting_text.present?
73
+ # Each languages
74
+ I18n.available_locales.each do |locale|
75
+ greeting_text = I18n.t("bobot.#{slug}.config.greeting_text", locale: locale, default: nil)
76
+ next unless greeting_text.present?
77
+ facebook_locales = I18n.t("bobot.#{slug}.config.facebook_locales", locale: locale, default: nil)
78
+ facebook_locales.to_a.each do |locale_long|
79
+ greeting_texts << { locale: locale_long, text: greeting_text }
80
+ end
81
+ end
82
+ if greeting_texts.present?
83
+ Bobot::Profile.set(
84
+ body: { greeting: greeting_texts },
85
+ query: { access_token: page_access_token },
86
+ )
87
+ else
88
+ unset_greeting_text!
139
89
  end
140
90
  end
141
- if greeting_texts.present?
142
- Bobot::Profile.set(
143
- body: { greeting: greeting_texts },
144
- query: { access_token: Bobot.page_access_token },
145
- )
146
- else
91
+
92
+ def unset_greeting_text!
93
+ raise Bobot::InvalidParameter.new(:access_token) unless page_access_token.present?
147
94
  Bobot::Profile.unset(
148
- body: { fields: ["greeting"] },
149
- query: { access_token: Bobot.page_access_token },
150
- )
95
+ body: { fields: %w[greeting] },
96
+ query: { access_token: page_access_token },
97
+ )
151
98
  end
152
- end
153
99
 
154
- ## == Set bot whitelist domains (only displayed on first time) ==
155
- ## == Some features like Messenger Extensions and Checkbox Plugin require ==
156
- ## == a page to specify a domain whitelist. ==
157
- def set_whitelist_domains!
158
- raise Bobot::InvalidParameter.new(:access_token) unless Bobot.page_access_token.present?
159
- raise Bobot::InvalidParameter.new(:domains) unless Bobot.domains.present?
160
- if Bobot.domains.present?
161
- Bobot::Profile.set(
162
- body: { whitelisted_domains: Bobot.domains },
163
- query: { access_token: Bobot.page_access_token },
164
- )
165
- else
100
+ ## == Set bot whitelist domains (only displayed on first time) ==
101
+ ## == Some features like Messenger Extensions and Checkbox Plugin require ==
102
+ ## == a page to specify a domain whitelist. ==
103
+ def set_whitelist_domains!
104
+ raise Bobot::InvalidParameter.new(:access_token) unless page_access_token.present?
105
+ raise Bobot::InvalidParameter.new(:domains) unless domains.present?
106
+ if domains.present?
107
+ Bobot::Profile.set(
108
+ body: { whitelisted_domains: domains },
109
+ query: { access_token: page_access_token },
110
+ )
111
+ else
112
+ unset_whitelist_domains!
113
+ end
114
+ end
115
+
116
+ def unset_whitelist_domains!
117
+ raise Bobot::InvalidParameter.new(:access_token) unless page_access_token.present?
118
+ raise Bobot::InvalidParameter.new(:domains) unless domains.present?
166
119
  Bobot::Profile.unset(
167
120
  body: { fields: ["whitelisted_domains"] },
168
- query: { access_token: Bobot.page_access_token },
169
- )
121
+ query: { access_token: page_access_token },
122
+ )
170
123
  end
171
- end
172
124
 
173
- ## == You can define the action to trigger when new humans click on ==
174
- ## == the Get Started button. Before doing it you should check to select the ==
175
- ## == messaging_postbacks field when setting up your webhook. ==
176
- def set_get_started_button!
177
- raise Bobot::InvalidParameter.new(:access_token) unless Bobot.page_access_token.present?
178
- if I18n.exists?('bobot.config.get_started.payload')
179
- Bobot::Profile.set(
180
- body: { get_started: { payload: I18n.t('bobot.config.get_started.payload') } },
181
- query: { access_token: Bobot.page_access_token },
182
- )
183
- else
125
+ ## == You can define the action to trigger when new humans click on ==
126
+ ## == the Get Started button. Before doing it you should check to select the ==
127
+ ## == messaging_postbacks field when setting up your webhook. ==
128
+ def set_get_started_button!
129
+ raise Bobot::InvalidParameter.new(:access_token) unless page_access_token.present?
130
+ if I18n.exists?("bobot.#{slug}.config.get_started.payload")
131
+ Bobot::Profile.set(
132
+ body: { get_started: { payload: I18n.t("bobot.#{slug}.config.get_started.payload") } },
133
+ query: { access_token: page_access_token },
134
+ )
135
+ else
136
+ unset_get_started_button!
137
+ end
138
+ end
139
+
140
+ def unset_get_started_button!
141
+ raise Bobot::InvalidParameter.new(:access_token) unless page_access_token.present?
184
142
  Bobot::Profile.unset(
185
- body: { fields: ["persistent_menu", "get_started"] },
186
- query: { access_token: Bobot.page_access_token },
143
+ body: { fields: %w[persistent_menu get_started] },
144
+ query: { access_token: page_access_token },
187
145
  )
188
146
  end
189
- end
190
147
 
191
- ## == You can show a persistent menu to humans. ==
192
- ## == If you want to have a persistent menu, you have to set get_started ==
193
- ## == button before. ==
194
- def set_persistent_menu!
195
- raise Bobot::InvalidParameter.new(:access_token) unless Bobot.page_access_token.present?
196
- persistent_menus = []
197
- # Default text
198
- persistent_menu = I18n.t('bobot.config.persistent_menu', locale: I18n.default_locale, default: nil)
199
- if persistent_menu.present?
200
- persistent_menus << {
201
- locale: 'default',
202
- composer_input_disabled: persistent_menu[:composer_input_disabled],
203
- call_to_actions: persistent_menu[:call_to_actions],
204
- }
205
- end
206
- # Each languages
207
- I18n.available_locales.each do |locale|
208
- persistent_menu = I18n.t('bobot.config.persistent_menu', locale: locale, default: nil)
209
- facebook_locales = I18n.t('bobot.config.facebook_locales', locale: locale, default: nil)
210
- next unless persistent_menu.present?
211
- facebook_locales.to_a.each do |locale_long|
148
+ ## == You can show a persistent menu to humans. ==
149
+ ## == If you want to have a persistent menu, you have to set get_started ==
150
+ ## == button before. ==
151
+ def set_persistent_menu!
152
+ raise Bobot::InvalidParameter.new(:access_token) unless page_access_token.present?
153
+ persistent_menus = []
154
+ # Default text
155
+ persistent_menu = I18n.t("bobot.#{slug}.config.persistent_menu", locale: I18n.default_locale, default: nil)
156
+ if persistent_menu.present?
212
157
  persistent_menus << {
213
- locale: locale_long,
158
+ locale: 'default',
214
159
  composer_input_disabled: persistent_menu[:composer_input_disabled],
215
160
  call_to_actions: persistent_menu[:call_to_actions],
216
161
  }
217
162
  end
163
+ # Each languages
164
+ I18n.available_locales.each do |locale|
165
+ persistent_menu = I18n.t("bobot.#{slug}.config.persistent_menu", locale: locale, default: nil)
166
+ facebook_locales = I18n.t("bobot.#{slug}.config.facebook_locales", locale: locale, default: nil)
167
+ next unless persistent_menu.present?
168
+ facebook_locales.to_a.each do |locale_long|
169
+ persistent_menus << {
170
+ locale: locale_long,
171
+ composer_input_disabled: persistent_menu[:composer_input_disabled],
172
+ call_to_actions: persistent_menu[:call_to_actions],
173
+ }
174
+ end
175
+ end
176
+ if persistent_menus.present?
177
+ Bobot::Profile.set(
178
+ body: { persistent_menu: persistent_menus },
179
+ query: { access_token: page_access_token },
180
+ )
181
+ else
182
+ unset_persistent_menu!
183
+ end
218
184
  end
219
- if persistent_menus.present?
220
- Bobot::Profile.set(
221
- body: { persistent_menu: persistent_menus },
222
- query: { access_token: Bobot.page_access_token },
223
- )
224
- else
185
+
186
+ def unset_persistent_menu!
187
+ raise Bobot::InvalidParameter.new(:access_token) unless page_access_token.present?
225
188
  Bobot::Profile.unset(
226
189
  body: { fields: ["persistent_menu"] },
227
- query: { access_token: Bobot.page_access_token },
228
- )
190
+ query: { access_token: page_access_token },
191
+ )
229
192
  end
230
193
  end
231
194
  end