bobot 2.6.2 → 3.0.1
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 +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
|