messenger-bot-client 1.2.1

Sign up to get free protection for your applications and to get access to all the features.
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).