bobot 2.6.2 → 3.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +139 -63
- data/app/controllers/bobot/application_controller.rb +0 -1
- data/app/controllers/bobot/webhook_controller.rb +2 -16
- data/app/jobs/bobot/deliver_job.rb +2 -2
- data/lib/bobot.rb +1 -0
- data/lib/bobot/commander.rb +5 -5
- data/lib/bobot/configuration.rb +5 -192
- data/lib/bobot/events/common.rb +16 -105
- data/lib/bobot/events/message_echo.rb +1 -1
- data/lib/bobot/graph_facebook.rb +6 -12
- data/lib/bobot/page.rb +331 -0
- data/lib/bobot/version.rb +3 -3
- data/lib/generators/bobot/install_generator.rb +1 -3
- data/lib/generators/bobot/templates/config/initializers/bobot.rb +4 -5
- data/lib/generators/bobot/templates/config/locales/bobot.en.yml +8 -8
- data/lib/generators/bobot/templates/config/locales/bobot.fr.yml +8 -8
- data/lib/generators/bobot/uninstall_generator.rb +0 -1
- data/spec/bobot/bobot_spec.rb +3 -3
- data/spec/bobot/event/common_spec.rb +28 -16
- data/spec/bobot/page_spec.rb +61 -0
- data/spec/bobot/profile_spec.rb +1 -1
- data/spec/bobot/subscription_spec.rb +1 -1
- data/spec/bobot/user_spec.rb +1 -1
- data/spec/dummy/log/development.log +45 -0
- data/spec/dummy/log/test.log +24 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/dummy/tmp/generator/config/initializers/bobot.rb +8 -8
- metadata +7 -7
- data/lib/generators/bobot/templates/config/bobot.yml +0 -52
- data/spec/dummy/tmp/generator/config/bobot.yml +0 -52
- data/spec/travis/database.travis.mysql.yml +0 -19
data/lib/bobot/events/common.rb
CHANGED
@@ -2,18 +2,10 @@ module Bobot
|
|
2
2
|
module Event
|
3
3
|
# Common attributes for all incoming data from Facebook.
|
4
4
|
module Common
|
5
|
-
attr_reader :messaging
|
6
|
-
attr_accessor :delay_options
|
7
|
-
attr_accessor :payloads_sent
|
5
|
+
attr_reader :messaging, :page
|
8
6
|
|
9
7
|
def initialize(messaging)
|
10
8
|
@messaging = messaging
|
11
|
-
@delay_options = { wait: 0, wait_until: nil }
|
12
|
-
@payloads_sent = []
|
13
|
-
end
|
14
|
-
|
15
|
-
def add_delivery(payload:)
|
16
|
-
@payloads_sent << payload
|
17
9
|
end
|
18
10
|
|
19
11
|
def sender
|
@@ -24,146 +16,65 @@ module Bobot
|
|
24
16
|
@messaging['recipient']
|
25
17
|
end
|
26
18
|
|
27
|
-
def delay(wait: 0, wait_until: nil)
|
28
|
-
raise Bobot::FieldFormat.new('wait has to be positive integer.') unless wait.present?
|
29
|
-
if Bobot.config.async
|
30
|
-
@delay_options[:wait] = wait if wait >= 0
|
31
|
-
@delay_options[:wait_until] = wait_until if wait_until.present?
|
32
|
-
else
|
33
|
-
warn "delay is ignored since you configured Bobot.config.async to 'false'"
|
34
|
-
end
|
35
|
-
self
|
36
|
-
end
|
37
|
-
|
38
19
|
def sent_at
|
39
20
|
Time.zone.at(@messaging['timestamp'] / 1000)
|
40
21
|
end
|
41
22
|
|
42
|
-
def deliver(payload_template:)
|
43
|
-
raise Bobot::FieldFormat.new('payload_template is required.') unless payload_template.present?
|
44
|
-
@payloads_sent << payload_template
|
45
|
-
job = Bobot::DeliverJob
|
46
|
-
if Bobot.config.async
|
47
|
-
job = job.set(wait: @delay_options[:wait]) if @delay_options[:wait] > 0
|
48
|
-
job = job.set(wait: @delay_options[:wait_until]) if @delay_options[:wait_until].present?
|
49
|
-
job.perform_later(sender: sender, access_token: access_token, payload_template: payload_template)
|
50
|
-
else
|
51
|
-
job.perform_now(sender: sender, access_token: access_token, payload_template: payload_template)
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
23
|
def sender_action(sender_action:)
|
56
|
-
|
24
|
+
page.sender_action(sender_action: sender_action, to: sender["id"])
|
57
25
|
end
|
58
26
|
|
59
27
|
def show_typing(state:)
|
60
|
-
|
28
|
+
page.show_typing(state: state, to: sender["id"])
|
61
29
|
end
|
62
30
|
|
63
31
|
def mark_as_seen
|
64
|
-
|
32
|
+
page.mark_as_seen(to: sender["id"])
|
65
33
|
end
|
66
34
|
|
67
35
|
def reply(payload_message:)
|
68
|
-
|
36
|
+
page.send(payload_message: payload_message, to: sender["id"])
|
69
37
|
end
|
70
38
|
|
71
39
|
def reply_with_text(text:)
|
72
|
-
|
73
|
-
raise Bobot::FieldFormat.new('text length is limited to 640.') if text.size > 640
|
74
|
-
reply(
|
75
|
-
payload_message: {
|
76
|
-
text: text,
|
77
|
-
},
|
78
|
-
)
|
40
|
+
page.send_text(text: text, to: sender["id"])
|
79
41
|
end
|
80
42
|
|
81
43
|
def reply_with_attachment(url:, type:)
|
82
|
-
|
83
|
-
raise Bobot::FieldFormat.new('type is required.') unless type.present?
|
84
|
-
raise Bobot::FieldFormat.new('type is invalid, only "image, audio, video, file" are permitted.') unless %w[image audio video file].include?(type)
|
85
|
-
reply(
|
86
|
-
payload_message: {
|
87
|
-
attachment: {
|
88
|
-
type: type,
|
89
|
-
payload: {
|
90
|
-
url: url,
|
91
|
-
}.tap { |properties| properties.merge!(is_reusable: true) if type == 'image' },
|
92
|
-
},
|
93
|
-
},
|
94
|
-
)
|
44
|
+
page.send_attachment(url: url, type: type, to: sender["id"])
|
95
45
|
end
|
96
46
|
|
97
47
|
def reply_with_image(url:)
|
98
|
-
|
48
|
+
page.send_image(url: url, to: sender["id"])
|
99
49
|
end
|
100
50
|
|
101
51
|
def reply_with_audio(url:)
|
102
|
-
|
52
|
+
page.send_audio(url: url, to: sender["id"])
|
103
53
|
end
|
104
54
|
|
105
55
|
def reply_with_video(url:)
|
106
|
-
|
56
|
+
page.send_video(url: url, to: sender["id"])
|
107
57
|
end
|
108
58
|
|
109
59
|
def reply_with_file(url:)
|
110
|
-
|
60
|
+
page.send_file(url: url, to: sender["id"])
|
111
61
|
end
|
112
62
|
|
113
63
|
def reply_with_quick_replies(text:, quick_replies:)
|
114
|
-
|
115
|
-
raise Bobot::FieldFormat.new('text length is limited to 640.') if text.size > 640
|
116
|
-
raise Bobot::FieldFormat.new('quick_replies are required.') unless quick_replies.present?
|
117
|
-
raise Bobot::FieldFormat.new('quick_replies are limited to 11.') if quick_replies.size > 11
|
118
|
-
reply(
|
119
|
-
payload_message: {
|
120
|
-
text: text,
|
121
|
-
quick_replies: quick_replies,
|
122
|
-
},
|
123
|
-
)
|
64
|
+
page.send_quick_replies(text: text, quick_replies: quick_replies, to: sender["id"])
|
124
65
|
end
|
125
66
|
|
126
67
|
def reply_with_buttons(text:, buttons:)
|
127
|
-
|
128
|
-
raise Bobot::FieldFormat.new('text length is limited to 640.') if text.size > 640
|
129
|
-
raise Bobot::FieldFormat.new('buttons are required.') unless buttons.present?
|
130
|
-
raise Bobot::FieldFormat.new('buttons are limited to 3.') if buttons.size > 3
|
131
|
-
reply(
|
132
|
-
payload_message: {
|
133
|
-
attachment: {
|
134
|
-
type: 'template',
|
135
|
-
payload: {
|
136
|
-
template_type: 'button',
|
137
|
-
text: text,
|
138
|
-
buttons: buttons,
|
139
|
-
},
|
140
|
-
},
|
141
|
-
},
|
142
|
-
)
|
68
|
+
page.send_buttons(text: text, buttons: buttons, to: sender["id"])
|
143
69
|
end
|
144
70
|
|
145
71
|
def reply_with_generic(elements:, image_aspect_ratio: 'square')
|
146
|
-
|
147
|
-
raise Bobot::FieldFormat.new('elements are limited to 10.') if elements.size > 10
|
148
|
-
raise Bobot::FieldFormat.new('image_aspect_ratio is required.') if image_aspect_ratio.nil?
|
149
|
-
raise Bobot::FieldFormat.new('image_aspect_ratio is invalid, only "square, horizontal" are permitted.') unless %w[square horizontal].include?(image_aspect_ratio)
|
150
|
-
reply(
|
151
|
-
payload_message: {
|
152
|
-
attachment: {
|
153
|
-
type: 'template',
|
154
|
-
payload: {
|
155
|
-
template_type: 'generic',
|
156
|
-
image_aspect_ratio: image_aspect_ratio,
|
157
|
-
elements: elements,
|
158
|
-
},
|
159
|
-
},
|
160
|
-
},
|
161
|
-
)
|
72
|
+
page.send_generic(elements: elements, image_aspect_ratio: image_aspect_ratio, to: sender["id"])
|
162
73
|
end
|
163
74
|
alias_method :reply_with_carousel, :reply_with_generic
|
164
75
|
|
165
|
-
def
|
166
|
-
Bobot.
|
76
|
+
def page
|
77
|
+
Bobot::Page.find(recipient["id"])
|
167
78
|
end
|
168
79
|
end
|
169
80
|
end
|
data/lib/bobot/graph_facebook.rb
CHANGED
@@ -19,10 +19,8 @@ module Bobot
|
|
19
19
|
end
|
20
20
|
res = https.request(req)
|
21
21
|
json = ActiveSupport::JSON.decode(res.send(:body) || '{}')
|
22
|
-
|
23
|
-
|
24
|
-
puts "[GET] << #{json}"
|
25
|
-
end
|
22
|
+
Rails.logger.debug "[GET] >> #{uri.request_uri}"
|
23
|
+
Rails.logger.debug "[GET] << #{json}"
|
26
24
|
Bobot::ErrorParser.raise_errors_from(json)
|
27
25
|
json
|
28
26
|
end
|
@@ -44,10 +42,8 @@ module Bobot
|
|
44
42
|
end
|
45
43
|
res = https.request(req)
|
46
44
|
json = ActiveSupport::JSON.decode(res.send(:body) || '{}')
|
47
|
-
|
48
|
-
|
49
|
-
puts "[POST] << #{json}"
|
50
|
-
end
|
45
|
+
Rails.logger.debug "[POST] >> #{uri.request_uri}"
|
46
|
+
Rails.logger.debug "[POST] << #{json}"
|
51
47
|
Bobot::ErrorParser.raise_errors_from(json)
|
52
48
|
json
|
53
49
|
end
|
@@ -69,10 +65,8 @@ module Bobot
|
|
69
65
|
end
|
70
66
|
res = https.request(req)
|
71
67
|
json = ActiveSupport::JSON.decode(res.send(:body) || '{}')
|
72
|
-
|
73
|
-
|
74
|
-
puts "[DELETE] << #{json}"
|
75
|
-
end
|
68
|
+
Rails.logger.debug "[DELETE] >> #{uri.request_uri}"
|
69
|
+
Rails.logger.debug "[DELETE] << #{json}"
|
76
70
|
Bobot::ErrorParser.raise_errors_from(json)
|
77
71
|
json
|
78
72
|
end
|
data/lib/bobot/page.rb
ADDED
@@ -0,0 +1,331 @@
|
|
1
|
+
module Bobot
|
2
|
+
class Page
|
3
|
+
attr_accessor :slug, :language, :page_id, :page_access_token, :get_started_payload
|
4
|
+
|
5
|
+
def initialize(options = {})
|
6
|
+
self.slug = options[:slug]
|
7
|
+
self.language = options[:language]
|
8
|
+
self.page_id = options[:page_id]
|
9
|
+
self.page_access_token = options[:page_access_token]
|
10
|
+
self.get_started_payload = options[:get_started_payload]
|
11
|
+
end
|
12
|
+
|
13
|
+
#####################################
|
14
|
+
#
|
15
|
+
# FINDERS
|
16
|
+
#
|
17
|
+
#####################################
|
18
|
+
|
19
|
+
def self.find(page_id)
|
20
|
+
Bobot.config.pages.find { |page| page.page_id.to_s == page_id.to_s }
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.find_by_slug(slug)
|
24
|
+
Bobot.config.pages.find { |page| page.slug.to_s == slug.to_s }
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.[](value)
|
28
|
+
find(value) || find_by_slug(value)
|
29
|
+
end
|
30
|
+
|
31
|
+
#####################################
|
32
|
+
#
|
33
|
+
# REQUESTS
|
34
|
+
#
|
35
|
+
#####################################
|
36
|
+
|
37
|
+
def deliver(payload_template:, to:)
|
38
|
+
raise Bobot::FieldFormat.new('payload_template is required.') unless payload_template.present?
|
39
|
+
job = Bobot::DeliverJob
|
40
|
+
if Bobot.config.async
|
41
|
+
job.perform_later(target_facebook_uid: to, access_token: page_access_token, payload_template: payload_template)
|
42
|
+
else
|
43
|
+
job.perform_now(target_facebook_uid: to, access_token: page_access_token, payload_template: payload_template)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def sender_action(sender_action:, to: nil)
|
48
|
+
deliver(payload_template: { sender_action: sender_action }, to: to)
|
49
|
+
end
|
50
|
+
|
51
|
+
def show_typing(state:, to: nil)
|
52
|
+
sender_action(sender_action: (state ? 'typing_on' : 'typing_off'), to: to)
|
53
|
+
end
|
54
|
+
|
55
|
+
def mark_as_seen(to: nil)
|
56
|
+
sender_action(sender_action: 'mark_seen', to: to)
|
57
|
+
end
|
58
|
+
|
59
|
+
def send(payload_message:, to: nil)
|
60
|
+
deliver(payload_template: { message: payload_message }, to: to)
|
61
|
+
end
|
62
|
+
|
63
|
+
def send_text(text:, to: nil)
|
64
|
+
raise Bobot::FieldFormat.new('text is required.') unless text.present?
|
65
|
+
raise Bobot::FieldFormat.new('text length is limited to 640.') if text.size > 640
|
66
|
+
send(
|
67
|
+
payload_message: {
|
68
|
+
text: text,
|
69
|
+
},
|
70
|
+
to: to,
|
71
|
+
)
|
72
|
+
end
|
73
|
+
|
74
|
+
def send_attachment(url:, type:, to: nil)
|
75
|
+
raise Bobot::FieldFormat.new('url is required.') unless url.present?
|
76
|
+
raise Bobot::FieldFormat.new('type is required.') unless type.present?
|
77
|
+
raise Bobot::FieldFormat.new('type is invalid, only "image, audio, video, file" are permitted.') unless %w[image audio video file].include?(type)
|
78
|
+
send(
|
79
|
+
payload_message: {
|
80
|
+
attachment: {
|
81
|
+
type: type,
|
82
|
+
payload: {
|
83
|
+
url: url,
|
84
|
+
}.tap { |properties| properties.merge!(is_reusable: true) if type == 'image' },
|
85
|
+
},
|
86
|
+
},
|
87
|
+
to: to,
|
88
|
+
)
|
89
|
+
end
|
90
|
+
|
91
|
+
def send_image(url:, to: nil)
|
92
|
+
send_attachment(url: url, type: 'image', to: to)
|
93
|
+
end
|
94
|
+
|
95
|
+
def send_audio(url:, to: nil)
|
96
|
+
send_attachment(url: url, type: 'audio', to: to)
|
97
|
+
end
|
98
|
+
|
99
|
+
def send_video(url:, to: nil)
|
100
|
+
send_attachment(url: url, type: 'video', to: to)
|
101
|
+
end
|
102
|
+
|
103
|
+
def send_file(url:, to: nil)
|
104
|
+
send_attachment(url: url, type: 'file', to: to)
|
105
|
+
end
|
106
|
+
|
107
|
+
def send_quick_replies(text:, quick_replies:, to: nil)
|
108
|
+
raise Bobot::FieldFormat.new('text is required.') unless text.present?
|
109
|
+
raise Bobot::FieldFormat.new('text length is limited to 640.') if text.size > 640
|
110
|
+
raise Bobot::FieldFormat.new('quick_replies are required.') unless quick_replies.present?
|
111
|
+
raise Bobot::FieldFormat.new('quick_replies are limited to 11.') if quick_replies.size > 11
|
112
|
+
send(
|
113
|
+
payload_message: {
|
114
|
+
text: text,
|
115
|
+
quick_replies: quick_replies,
|
116
|
+
},
|
117
|
+
to: to,
|
118
|
+
)
|
119
|
+
end
|
120
|
+
|
121
|
+
def send_buttons(text:, buttons:, to: nil)
|
122
|
+
raise Bobot::FieldFormat.new('text is required.') unless text.present?
|
123
|
+
raise Bobot::FieldFormat.new('text length is limited to 640.') if text.size > 640
|
124
|
+
raise Bobot::FieldFormat.new('buttons are required.') unless buttons.present?
|
125
|
+
raise Bobot::FieldFormat.new('buttons are limited to 3.') if buttons.size > 3
|
126
|
+
send(
|
127
|
+
payload_message: {
|
128
|
+
attachment: {
|
129
|
+
type: 'template',
|
130
|
+
payload: {
|
131
|
+
template_type: 'button',
|
132
|
+
text: text,
|
133
|
+
buttons: buttons,
|
134
|
+
},
|
135
|
+
},
|
136
|
+
},
|
137
|
+
to: to,
|
138
|
+
)
|
139
|
+
end
|
140
|
+
|
141
|
+
def send_generic(elements:, image_aspect_ratio: 'square', to: nil)
|
142
|
+
raise Bobot::FieldFormat.new('elements are required.') if elements.nil?
|
143
|
+
raise Bobot::FieldFormat.new('elements are limited to 10.') if elements.size > 10
|
144
|
+
raise Bobot::FieldFormat.new('image_aspect_ratio is required.') if image_aspect_ratio.nil?
|
145
|
+
raise Bobot::FieldFormat.new('image_aspect_ratio is invalid, only "square, horizontal" are permitted.') unless %w[square horizontal].include?(image_aspect_ratio)
|
146
|
+
send(
|
147
|
+
payload_message: {
|
148
|
+
attachment: {
|
149
|
+
type: 'template',
|
150
|
+
payload: {
|
151
|
+
template_type: 'generic',
|
152
|
+
image_aspect_ratio: image_aspect_ratio,
|
153
|
+
elements: elements,
|
154
|
+
},
|
155
|
+
},
|
156
|
+
},
|
157
|
+
to: to,
|
158
|
+
)
|
159
|
+
end
|
160
|
+
alias_method :send_carousel, :send_generic
|
161
|
+
|
162
|
+
#####################################
|
163
|
+
#
|
164
|
+
# SETUP
|
165
|
+
#
|
166
|
+
#####################################
|
167
|
+
def update_facebook_setup!
|
168
|
+
subscribe_to_facebook_page!
|
169
|
+
set_greeting_text!
|
170
|
+
set_whitelist_domains!
|
171
|
+
set_get_started_button!
|
172
|
+
set_persistent_menu!
|
173
|
+
end
|
174
|
+
|
175
|
+
## == Subcribe your bot to your page ==
|
176
|
+
def subscribe_to_facebook_page!
|
177
|
+
raise Bobot::InvalidParameter.new(:page_id) unless page_id.present?
|
178
|
+
raise Bobot::InvalidParameter.new(:access_token) unless page_access_token.present?
|
179
|
+
Bobot::Subscription.set(
|
180
|
+
query: {
|
181
|
+
page_id: page_id,
|
182
|
+
access_token: page_access_token,
|
183
|
+
},
|
184
|
+
)
|
185
|
+
end
|
186
|
+
|
187
|
+
## == Unsubcribe your bot from your page ==
|
188
|
+
def unsubscribe_to_facebook_page!
|
189
|
+
raise Bobot::InvalidParameter.new(:page_id) unless page_id.present?
|
190
|
+
raise Bobot::InvalidParameter.new(:access_token) unless page_access_token.present?
|
191
|
+
Bobot::Subscription.unset(
|
192
|
+
query: {
|
193
|
+
page_id: page_id,
|
194
|
+
access_token: page_access_token,
|
195
|
+
},
|
196
|
+
)
|
197
|
+
end
|
198
|
+
|
199
|
+
## == Set bot description (only displayed on first time). ==
|
200
|
+
def set_greeting_text!
|
201
|
+
raise Bobot::InvalidParameter.new(:access_token) unless page_access_token.present?
|
202
|
+
greeting_texts = []
|
203
|
+
if language.nil?
|
204
|
+
# Default text
|
205
|
+
greeting_text = I18n.t("bobot.#{slug}.config.greeting_text", locale: I18n.default_locale, default: nil)
|
206
|
+
greeting_texts << { locale: 'default', text: greeting_text } if greeting_text.present?
|
207
|
+
# Each languages
|
208
|
+
I18n.available_locales.each do |locale|
|
209
|
+
greeting_text = I18n.t("bobot.#{slug}.config.greeting_text", locale: locale, default: nil)
|
210
|
+
next unless greeting_text.present?
|
211
|
+
facebook_locales = I18n.t("bobot.#{slug}.config.facebook_locales", locale: locale, default: nil)
|
212
|
+
facebook_locales.to_a.each do |locale_long|
|
213
|
+
greeting_texts << { locale: locale_long, text: greeting_text }
|
214
|
+
end
|
215
|
+
end
|
216
|
+
else
|
217
|
+
greeting_text = I18n.t("bobot.#{slug}.config.greeting_text", locale: language, default: nil)
|
218
|
+
greeting_texts << { locale: 'default', text: greeting_text } if greeting_text.present?
|
219
|
+
end
|
220
|
+
if greeting_texts.present?
|
221
|
+
Bobot::Profile.set(
|
222
|
+
body: { greeting: greeting_texts },
|
223
|
+
query: { access_token: page_access_token },
|
224
|
+
)
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
228
|
+
def unset_greeting_text!
|
229
|
+
raise Bobot::InvalidParameter.new(:access_token) unless page_access_token.present?
|
230
|
+
Bobot::Profile.unset(
|
231
|
+
body: { fields: %w[greeting] },
|
232
|
+
query: { access_token: page_access_token },
|
233
|
+
)
|
234
|
+
end
|
235
|
+
|
236
|
+
## == Set bot whitelist domains (only displayed on first time) ==
|
237
|
+
## == Some features like Messenger Extensions and Checkbox Plugin require ==
|
238
|
+
## == a page to specify a domain whitelist. ==
|
239
|
+
def set_whitelist_domains!
|
240
|
+
raise Bobot::InvalidParameter.new(:access_token) unless page_access_token.present?
|
241
|
+
raise Bobot::InvalidParameter.new(:domains) unless Bobot.config.domains.present?
|
242
|
+
Bobot::Profile.set(
|
243
|
+
body: { whitelisted_domains: Bobot.config.domains },
|
244
|
+
query: { access_token: page_access_token },
|
245
|
+
)
|
246
|
+
end
|
247
|
+
|
248
|
+
def unset_whitelist_domains!
|
249
|
+
raise Bobot::InvalidParameter.new(:access_token) unless page_access_token.present?
|
250
|
+
Bobot::Profile.unset(
|
251
|
+
body: { fields: ["whitelisted_domains"] },
|
252
|
+
query: { access_token: page_access_token },
|
253
|
+
)
|
254
|
+
end
|
255
|
+
|
256
|
+
## == You can define the action to trigger when new humans click on ==
|
257
|
+
## == the Get Started button. Before doing it you should check to select the ==
|
258
|
+
## == messaging_postbacks field when setting up your webhook. ==
|
259
|
+
def set_get_started_button!
|
260
|
+
raise Bobot::InvalidParameter.new(:access_token) unless page_access_token.present?
|
261
|
+
raise Bobot::InvalidParameter.new(:get_started_payload) unless get_started_payload.present?
|
262
|
+
Bobot::Profile.set(
|
263
|
+
body: { get_started: { payload: get_started_payload } },
|
264
|
+
query: { access_token: page_access_token },
|
265
|
+
)
|
266
|
+
end
|
267
|
+
|
268
|
+
def unset_get_started_button!
|
269
|
+
raise Bobot::InvalidParameter.new(:access_token) unless page_access_token.present?
|
270
|
+
Bobot::Profile.unset(
|
271
|
+
body: { fields: %w[persistent_menu get_started] },
|
272
|
+
query: { access_token: page_access_token },
|
273
|
+
)
|
274
|
+
end
|
275
|
+
|
276
|
+
## == You can show a persistent menu to humans. ==
|
277
|
+
## == If you want to have a persistent menu, you have to set get_started ==
|
278
|
+
## == button before. ==
|
279
|
+
def set_persistent_menu!
|
280
|
+
raise Bobot::InvalidParameter.new(:access_token) unless page_access_token.present?
|
281
|
+
persistent_menus = []
|
282
|
+
# Default text
|
283
|
+
if language.nil?
|
284
|
+
persistent_menu = I18n.t("bobot.#{slug}.config.persistent_menu", locale: I18n.default_locale, default: nil)
|
285
|
+
if persistent_menu.present?
|
286
|
+
persistent_menus << {
|
287
|
+
locale: 'default',
|
288
|
+
composer_input_disabled: persistent_menu[:composer_input_disabled],
|
289
|
+
call_to_actions: persistent_menu[:call_to_actions],
|
290
|
+
}
|
291
|
+
end
|
292
|
+
# Each languages
|
293
|
+
I18n.available_locales.each do |locale|
|
294
|
+
persistent_menu = I18n.t("bobot.#{slug}.config.persistent_menu", locale: locale, default: nil)
|
295
|
+
facebook_locales = I18n.t("bobot.#{slug}.config.facebook_locales", locale: locale, default: nil)
|
296
|
+
next unless persistent_menu.present?
|
297
|
+
facebook_locales.to_a.each do |locale_long|
|
298
|
+
persistent_menus << {
|
299
|
+
locale: locale_long,
|
300
|
+
composer_input_disabled: persistent_menu[:composer_input_disabled],
|
301
|
+
call_to_actions: persistent_menu[:call_to_actions],
|
302
|
+
}
|
303
|
+
end
|
304
|
+
end
|
305
|
+
else
|
306
|
+
persistent_menu = I18n.t("bobot.#{slug}.config.persistent_menu", locale: language, default: nil)
|
307
|
+
if persistent_menu.present?
|
308
|
+
persistent_menus << {
|
309
|
+
locale: 'default',
|
310
|
+
composer_input_disabled: persistent_menu[:composer_input_disabled],
|
311
|
+
call_to_actions: persistent_menu[:call_to_actions],
|
312
|
+
}
|
313
|
+
end
|
314
|
+
end
|
315
|
+
if persistent_menus.present?
|
316
|
+
Bobot::Profile.set(
|
317
|
+
body: { persistent_menu: persistent_menus },
|
318
|
+
query: { access_token: page_access_token },
|
319
|
+
)
|
320
|
+
end
|
321
|
+
end
|
322
|
+
|
323
|
+
def unset_persistent_menu!
|
324
|
+
raise Bobot::InvalidParameter.new(:access_token) unless page_access_token.present?
|
325
|
+
Bobot::Profile.unset(
|
326
|
+
body: { fields: ["persistent_menu"] },
|
327
|
+
query: { access_token: page_access_token },
|
328
|
+
)
|
329
|
+
end
|
330
|
+
end
|
331
|
+
end
|