messenger-bot-client 1.2.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.
Files changed (51) hide show
  1. checksums.yaml +7 -0
  2. data/.codeclimate.yml +9 -0
  3. data/.gitignore +6 -0
  4. data/.rspec +2 -0
  5. data/Gemfile +4 -0
  6. data/README.md +593 -0
  7. data/Rakefile +8 -0
  8. data/app/controllers/messenger/messenger_controller.rb +89 -0
  9. data/bin/console +14 -0
  10. data/bin/setup +8 -0
  11. data/circle.yml +6 -0
  12. data/config/routes.rb +8 -0
  13. data/lib/messenger-ruby.rb +57 -0
  14. data/lib/messenger/client.rb +19 -0
  15. data/lib/messenger/components/attachment.rb +33 -0
  16. data/lib/messenger/components/element.rb +13 -0
  17. data/lib/messenger/components/elements/bubble.rb +23 -0
  18. data/lib/messenger/components/elements/button.rb +25 -0
  19. data/lib/messenger/components/elements/image.rb +18 -0
  20. data/lib/messenger/components/elements/quick_reply.rb +24 -0
  21. data/lib/messenger/components/elements/receipt/address.rb +20 -0
  22. data/lib/messenger/components/elements/receipt/adjustment.rb +16 -0
  23. data/lib/messenger/components/elements/receipt/item.rb +20 -0
  24. data/lib/messenger/components/elements/receipt/order.rb +19 -0
  25. data/lib/messenger/components/elements/receipt/summary.rb +18 -0
  26. data/lib/messenger/components/elements/sender_action.rb +15 -0
  27. data/lib/messenger/components/elements/text.rb +15 -0
  28. data/lib/messenger/components/elements/video.rb +18 -0
  29. data/lib/messenger/components/templates/buttons.rb +20 -0
  30. data/lib/messenger/components/templates/generic.rb +19 -0
  31. data/lib/messenger/components/templates/quick_replies.rb +18 -0
  32. data/lib/messenger/components/templates/receipt.rb +40 -0
  33. data/lib/messenger/configuration.rb +10 -0
  34. data/lib/messenger/engine.rb +7 -0
  35. data/lib/messenger/parameters/account_linking.rb +14 -0
  36. data/lib/messenger/parameters/attachment.rb +23 -0
  37. data/lib/messenger/parameters/callback.rb +15 -0
  38. data/lib/messenger/parameters/delivery.rb +15 -0
  39. data/lib/messenger/parameters/entry.rb +17 -0
  40. data/lib/messenger/parameters/message.rb +29 -0
  41. data/lib/messenger/parameters/messaging.rb +24 -0
  42. data/lib/messenger/parameters/optin.rb +13 -0
  43. data/lib/messenger/parameters/postback.rb +13 -0
  44. data/lib/messenger/parameters/quick_reply.rb +11 -0
  45. data/lib/messenger/parameters/read.rb +14 -0
  46. data/lib/messenger/parameters/referral.rb +15 -0
  47. data/lib/messenger/params.rb +25 -0
  48. data/lib/messenger/request.rb +35 -0
  49. data/lib/messenger/version.rb +3 -0
  50. data/messenger-ruby.gemspec +31 -0
  51. metadata +219 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: d02b206fcbc81c1593fbf311fce9eac3d4379ed5
4
+ data.tar.gz: cc5c0d13261859cc9a24f314d52b434c84b0b3d0
5
+ SHA512:
6
+ metadata.gz: 0fcbe2cef98bbbd333a949358e08ed2aa16f66c8e5058b3c95fb184fbf391219d0f160fdf399fcd9bf6140e92c8da72a24cfe02997fd019a108b4bf769f7a1b9
7
+ data.tar.gz: 1d5b860ac9dc0d1c0a28b038b694518cfe5f45488fc2fa96b1831e80a86111b2194379449f4c9be875d6aa29d2b29204fb6d54a6f256d6f8b2246e4ff2eb1377
data/.codeclimate.yml ADDED
@@ -0,0 +1,9 @@
1
+ engines:
2
+ rubocop:
3
+ enabled: false
4
+ ratings:
5
+ paths:
6
+ - lib/**
7
+ - "**.rb"
8
+ exclude_paths:
9
+ - spec/**/*
data/.gitignore ADDED
@@ -0,0 +1,6 @@
1
+ /Gemfile.lock
2
+ /pkg
3
+ /coverage
4
+
5
+ spec/test_app/config/secrets.yml
6
+ spec/test_app/log/*
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --require spec_helper
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in messenger-ruby.gemspec
4
+ gemspec
data/README.md ADDED
@@ -0,0 +1,593 @@
1
+ # messenger-ruby
2
+
3
+ A simple library for supporting implementation of [Facebook Messenger Bot](https://developers.facebook.com/products/messenger/) in Ruby on Rails.
4
+
5
+ ## Requirments
6
+
7
+ ruby 2.1+
8
+
9
+ ## Installation
10
+
11
+ Add this line to your application's Gemfile:
12
+
13
+ ```ruby
14
+ gem 'messenger-ruby'
15
+ ```
16
+
17
+ And then execute:
18
+
19
+ $ bundle
20
+
21
+ Or install it yourself as:
22
+
23
+ $ gem install messenger-ruby
24
+
25
+ ## Configuration
26
+
27
+ #### Facebook steps
28
+
29
+ * [create Facebook page](https://www.facebook.com/pages/create/) (skip if you want to use existing page)
30
+ * [create Facebook app](https://developers.facebook.com/quickstarts/?platform=web) (skip if you want to use existing app)
31
+ * go to [Facebook for Developers](https://developers.facebook.com/apps/) and get `Page Access Token` (step __3. Get Page Access Token__ from [this tutorial](https://developers.facebook.com/docs/messenger-platform/quickstart#steps]))
32
+
33
+ #### Initializer
34
+
35
+ Create `messenger.rb` initializer in you app directory and paste `Page Access Token` from previous step:
36
+
37
+ ```ruby
38
+ # YOUR_APP/config/initializers/messenger.rb
39
+ Messenger.configure do |config|
40
+ config.verify_token = '<VERIFY_TOKEN>' #will be used in webhook verifiction
41
+ config.page_access_token = '<PAGE_ACCESS_TOKEN>'
42
+ end
43
+ ```
44
+
45
+ #### Routes
46
+
47
+ Add to your `routes.rb`:
48
+
49
+ ```ruby
50
+ # YOUR_APP/config/routes.rb
51
+ mount Messenger::Engine, at: "/messenger"
52
+
53
+ ```
54
+
55
+ #### Controller
56
+
57
+ Create `messenger_controller.rb` in your controllers directory - controller has to inherit from `Messenger::MessengerController`:
58
+
59
+ ```ruby
60
+ # YOUR_APP/app/controllers/messenger_controller.rb
61
+ class MessengerController < Messenger::MessengerController
62
+ def webhook
63
+ #logic here
64
+ head :ok
65
+ end
66
+ end
67
+ ```
68
+
69
+ `2XX` status is necessary to not clog your bot.
70
+
71
+ If you want your controller to be named differently, please update your `routes.rb` with appropriate route for `post /messenger/webhook` request.
72
+
73
+ #### Bot subscription
74
+
75
+ Run your application and:
76
+ * complete step __2. Setup Webhook__ from [this tutorial](https://developers.facebook.com/docs/messenger-platform/quickstart#steps) - _if you mounted `Messenger::Engine` at `/messenger` and your application can be found at `https://example.com`, your `Callback URL` will be `https://example.com/messenger/webhook`_
77
+ * select `message_deliveries`, `messages`, `messaging_optins` and `messaging_postbacks` under Subscription Fields
78
+ * visit `/messenger/subscribe` in your app (it's replacement for __[4. Subscribe the App to the Page](https://developers.facebook.com/docs/messenger-platform/quickstart#steps)__ step) - call `subscribe` action anytime you want to refresh subscription of your app
79
+
80
+ ## Usage
81
+
82
+ To send message you need to create [Messenger::Request](#messengerrequest) with one of the available [components](#components) and pass it to [Messenger::Client](#messengerclient)::send method. You can send message only to users who subscribed to your page (e.g. sent some message before).
83
+
84
+ ### Messenger::Request
85
+
86
+ It's used to build parameters for Facebook API. Requires [component](#components) and `recipient_id`.
87
+
88
+ Example usage:
89
+ ```ruby
90
+ Messenger::Request.new(some_component, recipient_id)
91
+ ```
92
+
93
+ ### Messenger::Client
94
+
95
+ Sends requests to Facebook API. Has two methods:
96
+ * `get_user_profile` - requires id of existing facebook user
97
+ * `send` - requires [Messenger::Request](#messengerrequest) object
98
+
99
+ Example usage:
100
+ ```ruby
101
+ Messenger::Client.get_user_profile(user_id) #=> hash with name, surname and profile picture
102
+ Messenger::Client.send(request) #=> hash with message details or exception if request is incorrect
103
+ ```
104
+
105
+ Please note that unsuccessful `send` will be shown in logs as `Facebook API response from invalid request: ...`
106
+
107
+ ### Elements
108
+
109
+ Elements can't be used outside of templates.
110
+
111
+ #### Button
112
+
113
+ Lives inside [Bubble](#bubble) element or [Button template](#button-template).
114
+
115
+ Attribute | Allowed values | Required?
116
+ --------- | -------------- | :--------:
117
+ type | `'web_url'`, `'postback'` | &#10004;
118
+ title | String | &#10004;
119
+ value | String | &#10004;
120
+
121
+ Example usage:
122
+ ```ruby
123
+ Messenger::Elements::Button.new(type: 'web_url', title: 'Button', value: 'http://github.com')
124
+ ```
125
+
126
+ #### Bubble
127
+
128
+ Part of [Generic template](#button-template).
129
+
130
+ Attribute | Allowed values | Required?
131
+ --------- | -------------- | :--------:
132
+ title | String | &#10004;
133
+ subtitle | String | &#10004;*
134
+ image_url | String | &#10004;*
135
+ buttons | [`Messenger::Elements::Button`](#button) objects array | &#10004;*
136
+ item_url | String | &#10008;
137
+
138
+ `*` - at least one of them is required
139
+
140
+ Example usage:
141
+ ```ruby
142
+ Messenger::Elements::Bubble.new(title: 'First', subtitle: 'Bubble')
143
+
144
+ ```
145
+
146
+ #### Quick Reply
147
+
148
+ Used by [Quick Replies](#quick-replies).
149
+
150
+ Attribute | Allowed values | Required?
151
+ --------- | -------------- | :--------:
152
+ content_type | 'text' or 'location' | &#10004;
153
+ title | String | only if content_type is 'text'
154
+ payload | String | only if content_type is 'text'
155
+ image_url | String | &#10008;
156
+
157
+ Example usage:
158
+ ```ruby
159
+ Messenger::Elements::QuickReply.new(
160
+ content_type: 'text',
161
+ title: 'SomeTitle',
162
+ payload: "PAYLOAD"
163
+ )
164
+ ```
165
+
166
+ #### Address
167
+
168
+ Used by [Receipt template](#receipt-template).
169
+
170
+ Attribute | Allowed values | Required?
171
+ --------- | -------------- | :--------:
172
+ street_1 | String | &#10004;
173
+ street_2 | String | &#10008;
174
+ city | String | &#10004;
175
+ postal_code | String | &#10004;
176
+ state | String | &#10004;
177
+ country | String | &#10004;
178
+
179
+ Example usage:
180
+ ```ruby
181
+ Messenger::Elements::Address.new(
182
+ street_1: 'Vachel Lindsay Dr',
183
+ street_2: '',
184
+ city: 'Springfield',
185
+ postal_code: '62701',
186
+ state: 'IL',
187
+ country:'USA'
188
+ )
189
+ ```
190
+
191
+ #### Adjustment
192
+
193
+ Used by [Receipt template](#receipt-template).
194
+
195
+ Attribute | Allowed values | Required?
196
+ --------- | -------------- | :--------:
197
+ name | String | &#10004;
198
+ amount | Integer, greater than 0 | &#10004;
199
+
200
+ Example usage:
201
+ ```ruby
202
+ Messenger::Elements::Adjustment.new(name: 'Adjustment 1', amount: 20)
203
+ ```
204
+
205
+ #### Item
206
+
207
+ Used by [Receipt template](#receipt-template).
208
+
209
+ Attribute | Allowed values | Required?
210
+ --------- | -------------- | :--------:
211
+ title | String | &#10004;
212
+ subtilte | String | &#10008;
213
+ quantity | Integer | &#10008;
214
+ price | Decimal | &#10008;
215
+ currency | String, from _ISO 4217 Currency Codes_ | &#10008;
216
+ image_url | String | &#10008;
217
+
218
+ Example usage:
219
+ ```ruby
220
+ Messenger::Elements::Item.new(
221
+ title: 'Cool Tshirt',
222
+ subtitle: 'XXL White',
223
+ quantity: 3,
224
+ price: 34,
225
+ currency: 'USD',
226
+ image_url: 'http://assets.servedby-buysellads.com/p/manage/asset/id/25397'
227
+ )
228
+ ```
229
+
230
+ #### Order
231
+
232
+ Used by [Receipt template](#receipt-template).
233
+
234
+ Attribute | Allowed values | Required?
235
+ --------- | -------------- | :--------:
236
+ order_number | String, unique per conversation | &#10004;
237
+ currency | String, from _ISO 4217 Currency Codes_ | &#10004;
238
+ payment_method | String | &#10004;
239
+ timestamp | correct timestamp (String) | &#10008;
240
+ order_url | String | &#10008;
241
+
242
+ Example usage:
243
+ ```ruby
244
+ Messenger::Elements::Order.new(
245
+ order_number: 'R190581345',
246
+ currency: 'USD',
247
+ payment_method: 'Visa',
248
+ timestamp: '1428444852',
249
+ order_url: 'http://petersapparel.parseapp.com/order?order_id=123456'
250
+ )
251
+ ```
252
+
253
+ #### Summary
254
+
255
+
256
+ Used by [Receipt template](#receipt-template).
257
+
258
+ Attribute | Allowed values | Required?
259
+ --------- | -------------- | :--------:
260
+ subtotal | Decimal | &#10008;
261
+ shipping_cost | Decimal | &#10008;
262
+ total_tax | Decimal | &#10008;
263
+ total_cost | Decimal | &#10004;
264
+
265
+ Example usage:
266
+ ```ruby
267
+ Messenger::Elements::Summary.new(subtotal: 70, shipping_cost: 20, total_tax: 10, total_cost: 100)
268
+ ```
269
+
270
+ ### Components
271
+
272
+ You can find more info about what can be send in [Messenger Platform Docs](https://developers.facebook.com/docs/messenger-platform/send-api-reference).
273
+
274
+ #### Text
275
+
276
+ Attribute | Allowed values | Required?
277
+ --------- | -------------- | :--------:
278
+ text | String | &#10004;
279
+
280
+
281
+ Here is complete example on how to send sample text to the user:
282
+ ```ruby
283
+ if fb_params.first_entry.callback.message?
284
+ Messenger::Client.send(
285
+ Messenger::Request.new(
286
+ Messenger::Elements::Text.new(text: 'some text'),
287
+ fb_params.first_entry.sender_id
288
+ )
289
+ )
290
+ end
291
+
292
+ #make sure to send 200 at the end
293
+ head :ok
294
+ ```
295
+
296
+ #### Image
297
+
298
+ Attribute | Allowed values | Required?
299
+ --------- | -------------- | :--------:
300
+ url | String | &#10004;
301
+
302
+
303
+ Sending images is simple as well:
304
+ ```ruby
305
+ ...
306
+ Messenger::Client.send(
307
+ Messenger::Request.new(
308
+ Messenger::Elements::Image.new(url: 'http://lorempixel.com/400/400/cats'),
309
+ fb_params.first_entry.sender_id
310
+ )
311
+ )
312
+ ...
313
+ ```
314
+
315
+ #### Sender Actions
316
+
317
+ Attribute | Allowed values | Required?
318
+ --------- | -------------- | :--------:
319
+ sender_action | 'typing_on', 'typing_off' or 'mark_seen' | &#10004;
320
+
321
+ Sending send action:
322
+ ```ruby
323
+ ...
324
+ Messenger::Client.send(
325
+ Messenger::Request.new(
326
+ Messenger::Elements::SenderAction.new(sender_action: 'mark_seen'),
327
+ fb_params.first_entry.sender_id
328
+ )
329
+ )
330
+ ...
331
+ ```
332
+
333
+ #### Quick Replies
334
+
335
+ Attribute | Allowed values | Required?
336
+ --------- | -------------- | :--------:
337
+ text | String | attachment or text must be set
338
+ attachment | Attachment object | attachment or text must be set
339
+ quick_reply | Array of [Messenger::Elements::QuickReply](#quick_reply) objects| &#10008;
340
+
341
+ Example usage
342
+ ```ruby
343
+
344
+ #define quick_replies here...
345
+ quick_replies = Messenger::Templates::QuickReplies.new(
346
+ text: "Green or Red?",
347
+ quick_replies: [
348
+ Messenger::Elements::QuickReply.new(
349
+ content_type: 'text',
350
+ title: 'Green',
351
+ payload: 'GREEN'
352
+ ),
353
+ Messenger::Elements::QuickReply.new(
354
+ content_type: 'text',
355
+ title: 'Red',
356
+ payload: "RED"
357
+ )
358
+ ]
359
+ )
360
+
361
+ #now send quick_replies to the user
362
+ Messenger::Client.send(
363
+ Messenger::Request.new(quick_replies, fb_params.first_entry.sender_id)
364
+ )
365
+ ```
366
+ #### Generic template
367
+
368
+ Attribute | Allowed values | Required?
369
+ --------- | -------------- | :--------:
370
+ elements | Array of [Messenger::Elements::Bubble](#bubble) objects | &#10004;
371
+
372
+ Example usage:
373
+ ```ruby
374
+
375
+ #define bubbles here...
376
+ bubble1 = Messenger::Elements::Bubble.new(
377
+ title: 'Bubble 1',
378
+ subtitle: 'Cool Bubble',
379
+ item_url: 'http://lorempixel.com/400/400/cats',
380
+ image_url: 'http://lorempixel.com/400/400/cats',
381
+ buttons: [
382
+ Messenger::Elements::Button.new(
383
+ type: 'web_url',
384
+ title: 'Show Website',
385
+ value: 'https://petersapparel.parseapp.com'
386
+ )
387
+ ]
388
+ )
389
+
390
+ bubble2 = ...
391
+
392
+ #lets create Generic template
393
+ generic = Messenger::Templates::Generic.new(
394
+ elements: [bubble1, bubble2]
395
+ )
396
+
397
+ #now send Generic template to the user
398
+ Messenger::Client.send(
399
+ Messenger::Request.new(generic, fb_params.first_entry.sender_id)
400
+ )
401
+ ```
402
+
403
+ #### Button template
404
+
405
+ Attribute | Allowed values | Required?
406
+ --------- | -------------- | :--------:
407
+ text | String | &#10004;
408
+ buttons | Array of [Messenger::Elements::Button](#button) objects | &#10004;
409
+
410
+ Example usage:
411
+ ```ruby
412
+
413
+ #lets create Buttons template
414
+ buttons = Messenger::Templates::Buttons.new(
415
+ text: 'Some Cool Text',
416
+ buttons: [
417
+ Messenger::Elements::Button.new(
418
+ type: 'web_url',
419
+ title: 'Show Website',
420
+ value: 'https://petersapparel.parseapp.com'
421
+ )
422
+ ]
423
+ )
424
+
425
+ #now send Buttons template to the user
426
+ Messenger::Client.send(
427
+ Messenger::Request.new(buttons, fb_params.first_entry.sender_id)
428
+ )
429
+ ```
430
+
431
+ #### Receipt template
432
+
433
+ Attribute | Allowed values | Required?
434
+ --------- | -------------- | :--------:
435
+ recipient_name | String | &#10004;
436
+ order | [Messenger::Elements::Order](#order) object | &#10004;
437
+ elements | Array of [Messenger::Elements::Item](#item) objects | &#10004;
438
+ address | [Messenger::Elements::Address](#address) object | &#10008;
439
+ summary | [Messenger::Elements::Summary](#summary) object | &#10004;
440
+ adjustments | Array of [Messenger::Elements::Adjustment](#adjustment) objects | &#10008;
441
+
442
+ Example usage:
443
+ ```ruby
444
+ #define order element here...
445
+ order = Messenger::Elements::Order.new(
446
+ order_number: 'R190581345',
447
+ currency: 'USD',
448
+ payment_method: 'Visa',
449
+ timestamp: '1428444852',
450
+ order_url: 'http://petersapparel.parseapp.com/order?order_id=123456'
451
+ )
452
+
453
+ #and define all other template elements
454
+ item1 = ...
455
+ item2 = ...
456
+ address = ...
457
+ summary = ...
458
+ adjustment1 = ...
459
+ adjustment2 = ...
460
+
461
+ #lets create Receipt template
462
+ receipt = Messenger::Templates::Receipt.new(
463
+ recipient_name: 'Random Recipient',
464
+ order: order,
465
+ elements: [item1, item2],
466
+ address: address,
467
+ summary: summary,
468
+ adjustments: [adjustment1, adjustment2]
469
+ )
470
+
471
+ #now send Receipt template to the user
472
+ Messenger::Client.send(
473
+ Messenger::Request.new(receipt, fb_params.first_entry.sender_id)
474
+ )
475
+
476
+ ```
477
+
478
+ ### Entries
479
+
480
+ According to Facebook documentation, there is possibility that you can receive multiple `entries` and multiple `messagings`.
481
+ That's why we made it easy for you to iterate over `entries` and `messagings`, but we've also created `first_entry` method
482
+ that returns first entry in `entry` array, because that is the most common case.
483
+
484
+ Example usage:
485
+
486
+ ```ruby
487
+ fb_params.entries.each do |entry|
488
+ entry.messagings.each do |messaging|
489
+ if messaging.callback.message?
490
+ Messenger::Client.send(
491
+ Messenger::Request.new(
492
+ Messenger::Elements::Text.new(text: "Echo: #{messaging.callback.text}"),
493
+ messaging.sender_id
494
+ )
495
+ )
496
+ end
497
+ end
498
+ end
499
+ ```
500
+
501
+ Or with `first_entry` method:
502
+
503
+ ```ruby
504
+ if fb_params.first_entry.callback.message?
505
+ Messenger::Client.send(
506
+ Messenger::Request.new(
507
+ Messenger::Elements::Text.new(text: "Echo: #{fb_params.first_entry.callback.text}"),
508
+ fb_params.first_entry.sender_id
509
+ )
510
+ )
511
+ end
512
+ ```
513
+
514
+ ### fb_params
515
+
516
+ Has control over entries received from Facebook API. For more informations please visit Messenger Platform Docs. `fb_params` includes array of Entry objects.
517
+
518
+ #### Entry
519
+
520
+ Attribute | Additional info
521
+ ----------| ---------------
522
+ id | String, unique for conversation
523
+ time | String, timestamp format
524
+ messagings | Array of [Messenger::Parameters::Messaging](#messaging) objects
525
+
526
+
527
+ #### Messaging
528
+
529
+ Attribute | Additional info
530
+ --------- | ---------------
531
+ sender_id | String
532
+ recipient_id | String
533
+ callback | [Messenger::Parameters::Message](#message), [Messenger::Parameters::Delivery](#delivery), [Messenger::Parameters::Optin](#optin), [Messenger::Parameters::Delivery](#postback), [Messenger::Parameters::Read](#read) or [Messenger::Parameters::AccountLinking](#account_linking) object
534
+
535
+ Callback responds to following methods to help detect types:
536
+
537
+ Method | Type returned
538
+ ------ | -------------
539
+ message? | Boolean
540
+ delivery? | Boolean
541
+ optin? | Boolean
542
+ postback? | Boolean
543
+ read? | Boolean
544
+ account_linking? | Boolean
545
+
546
+ #### Message
547
+
548
+ Attribute | Additional info
549
+ ----------| ---------------
550
+ mid |
551
+ seq |
552
+ sticker_id |
553
+ text |
554
+
555
+ s | Array of [Messenger::Parameters::Attachment](#attachment) objects
556
+ is_echo |
557
+ app_id |
558
+ metadata |
559
+
560
+ #### Attachment
561
+
562
+ #### Delivery
563
+
564
+ #### Optin
565
+
566
+ #### Postback
567
+
568
+ #### Read
569
+
570
+ #### Account Linking
571
+
572
+
573
+ Example usage:
574
+
575
+ ```ruby
576
+ fb_params.first_entry.callback.message?
577
+ fb_params.first_entry.callback.postback?
578
+ fb_params.first_entry.callback.delivery?
579
+ fb_params.first_entry.callback.optin?
580
+ fb_params.first_entry.callback.attachments
581
+ fb_params.first_entry.callback.text
582
+ ```
583
+
584
+ ## Development
585
+
586
+ After checking out the repo, run `bin/setup` to install dependencies. You can also run `rake console` for an interactive prompt that will allow you to experiment.
587
+
588
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
589
+
590
+
591
+ ## License
592
+
593
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).