bobot 1.0.53 → 2.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 +4 -4
- data/README.md +18 -8
- data/app/controllers/bobot/webhook_controller.rb +54 -30
- data/config/routes.rb +1 -2
- data/lib/bobot.rb +15 -1
- data/lib/bobot/commander.rb +9 -8
- data/lib/bobot/configuration.rb +149 -186
- data/lib/bobot/engine.rb +0 -4
- data/lib/bobot/events/common.rb +4 -4
- data/lib/bobot/events/delivery.rb +0 -1
- data/lib/bobot/events/message.rb +4 -0
- data/lib/bobot/events/message_echo.rb +3 -2
- data/lib/bobot/events/message_request.rb +9 -0
- data/lib/bobot/graph_facebook.rb +4 -4
- data/lib/bobot/profile.rb +2 -6
- data/lib/bobot/version.rb +3 -3
- data/lib/generators/bobot/templates/app/bobot/workflow.rb +9 -11
- data/lib/generators/bobot/templates/config/bobot.yml +41 -32
- data/lib/generators/bobot/templates/config/initializers/bobot.rb +25 -9
- data/lib/generators/bobot/templates/config/locales/bobot.en.yml +29 -28
- data/lib/generators/bobot/templates/config/locales/bobot.fr.yml +28 -27
- data/lib/generators/bobot/utils.rb +0 -9
- data/spec/bobot/bobot_spec.rb +18 -12
- data/spec/bobot/event/common_spec.rb +3 -1
- data/spec/bobot/event/message_spec.rb +7 -0
- data/spec/bobot/profile_spec.rb +3 -1
- data/spec/bobot/subscription_spec.rb +4 -2
- data/spec/bobot/user_spec.rb +4 -2
- data/spec/dummy/app/channels/application_cable/channel.rb +4 -0
- data/spec/dummy/app/channels/application_cable/connection.rb +4 -0
- data/spec/dummy/app/mailers/application_mailer.rb +4 -0
- data/spec/dummy/app/views/layouts/mailer.html.erb +13 -0
- data/spec/dummy/app/views/layouts/mailer.text.erb +1 -0
- data/spec/dummy/bin/setup +0 -8
- data/spec/dummy/bin/update +0 -3
- data/spec/dummy/config/application.rb +3 -2
- data/spec/dummy/config/cable.yml +10 -0
- data/spec/dummy/config/environments/development.rb +5 -3
- data/spec/dummy/config/environments/production.rb +5 -3
- data/spec/dummy/config/environments/test.rb +6 -2
- data/spec/dummy/config/initializers/application_controller_renderer.rb +6 -4
- data/spec/dummy/config/initializers/wrap_parameters.rb +0 -5
- data/spec/dummy/config/routes.rb +1 -1
- data/spec/dummy/config/secrets.yml +2 -2
- data/spec/dummy/log/development.log +0 -0
- data/spec/dummy/log/test.log +2 -0
- data/spec/dummy/tmp/generator/app/bobot/workflow.rb +15 -0
- data/spec/dummy/tmp/generator/config/bobot.yml +48 -0
- data/spec/dummy/tmp/generator/config/initializers/bobot.rb +46 -0
- data/spec/dummy/tmp/generator/config/locales/bobot.en.yml +31 -0
- data/spec/dummy/tmp/generator/config/locales/bobot.fr.yml +30 -0
- data/spec/dummy/tmp/generator/config/routes.rb +0 -0
- data/spec/rails_helper.rb +8 -10
- metadata +43 -34
- data/app/mailers/bobot/application_mailer.rb +0 -6
- data/app/models/bobot/application_record.rb +0 -5
- data/lib/generators/bobot/templates/app/bobot/message.rb +0 -3
- data/lib/generators/bobot/templates/app/bobot/postback.rb +0 -22
- data/spec/dummy/app/bobot/workflow.rb +0 -17
- data/spec/dummy/app/models/application_record.rb +0 -3
- data/spec/dummy/config/bobot.yml +0 -27
- data/spec/dummy/config/database.yml +0 -19
- data/spec/dummy/config/initializers/bobot.rb +0 -30
- data/spec/dummy/config/locales/bobot.en.yml +0 -28
- data/spec/dummy/config/locales/bobot.fr.yml +0 -27
- data/spec/dummy/db/schema.rb +0 -15
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 238ce4063aa11a3df2f3150c8a7a65e23cc0063f
|
4
|
+
data.tar.gz: ce018a45a1d777752c746c4b7f46e2049fdfa071
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
35
|
-
|
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
|
-
- `
|
39
|
-
- `
|
40
|
-
- `
|
41
|
-
- `
|
42
|
-
- `
|
43
|
-
- `
|
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
|
-
|
10
|
-
|
11
|
-
|
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
|
-
|
23
|
+
head :method_not_allowed
|
14
24
|
end
|
15
25
|
end
|
16
26
|
|
17
27
|
def verify
|
18
|
-
if
|
19
|
-
|
20
|
-
|
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
|
-
|
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 ||=
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
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
|
41
|
-
|
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
|
46
|
-
request.headers['HTTP_X_HUB_SIGNATURE'].to_s
|
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
|
-
|
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
|
data/config/routes.rb
CHANGED
data/lib/bobot.rb
CHANGED
@@ -14,5 +14,19 @@ require 'bobot/commander'
|
|
14
14
|
require 'bobot/event'
|
15
15
|
|
16
16
|
module Bobot
|
17
|
-
|
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
|
data/lib/bobot/commander.rb
CHANGED
@@ -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
|
-
|
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
|
-
|
57
|
+
warn "Ignoring #{event.class} (no hook registered)"
|
57
58
|
end
|
58
59
|
|
59
60
|
def hooks
|
data/lib/bobot/configuration.rb
CHANGED
@@ -1,60 +1,7 @@
|
|
1
1
|
module Bobot
|
2
|
-
|
3
|
-
|
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
|
-
|
70
|
-
|
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
|
-
|
77
|
-
|
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
|
-
|
89
|
-
|
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
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
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
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
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
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
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
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
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
|
-
|
142
|
-
|
143
|
-
|
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: [
|
149
|
-
query: { access_token:
|
150
|
-
)
|
95
|
+
body: { fields: %w[greeting] },
|
96
|
+
query: { access_token: page_access_token },
|
97
|
+
)
|
151
98
|
end
|
152
|
-
end
|
153
99
|
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
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:
|
169
|
-
)
|
121
|
+
query: { access_token: page_access_token },
|
122
|
+
)
|
170
123
|
end
|
171
|
-
end
|
172
124
|
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
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: [
|
186
|
-
query: { 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
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
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:
|
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
|
-
|
220
|
-
|
221
|
-
|
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:
|
228
|
-
)
|
190
|
+
query: { access_token: page_access_token },
|
191
|
+
)
|
229
192
|
end
|
230
193
|
end
|
231
194
|
end
|