messenger-ruby 0.1.0 → 1.0.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ba7478e7dc69de8c24460b8780d2c7c2c0624495
4
- data.tar.gz: 60a772a736040cf834b0cbd08379887d3f3caf01
3
+ metadata.gz: c0002a8167648af1651c41031ec1b600947c5fd7
4
+ data.tar.gz: 399edaa10c599c990ce954a737ee81165548d4fa
5
5
  SHA512:
6
- metadata.gz: 92bc942f56f99fcecea0608cc5e6650df8a0d2b25eac05095163361c1fa08bd78da6dc1a46cb30452b8b79ee811e3d6f4af1f846d210a80bc80607cf468a3436
7
- data.tar.gz: a4f6ffe443cd6dd561dcc99c6e17c1ec9c0c07fa0f3019011ee542965c59300f300a1266d4ff0c9ea05c23f3020abc5a7b4c6a06e51e889939607c96faa9aa4f
6
+ metadata.gz: ff5cc415b65f152f1142bd1ebff07c529e35113b00bcf7b25b5a8f3c8ac29944c0a8f3a924852eccaa91ee383b37a2e2c341b50649d6b22a4738658f540e2821
7
+ data.tar.gz: d23051ac1715597ae5e51d95881fa9337e932f0bdfdc19e5086631c902a473eeb9798976cf9859297bb5e7ad185776a9c6b8fa2aee565477a75937ddabf11bbf
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 CHANGED
@@ -1,2 +1,6 @@
1
1
  /Gemfile.lock
2
2
  /pkg
3
+ /coverage
4
+
5
+ spec/test_app/config/secrets.yml
6
+ spec/test_app/log/*
data/README.md CHANGED
@@ -1,11 +1,17 @@
1
1
  # messenger-ruby
2
+ [![](https://img.shields.io/gem/v/messenger-ruby.svg?style=flat-square)](https://rubygems.org/gems/messenger-ruby)
3
+ [![](https://img.shields.io/circleci/project/netguru/messenger-ruby.svg?style=flat-square)](https://circleci.com/gh/netguru/messenger-ruby)
4
+ [![](http://img.shields.io/codeclimate/github/netguru/messenger-ruby.svg?style=flat-square)](https://codeclimate.com/github/netguru/messenger-ruby)
5
+ [![](http://img.shields.io/codeclimate/coverage/github/netguru/messenger-ruby.svg?style=flat-square)](https://codeclimate.com/github/netguru/messenger-ruby)
6
+
7
+ A simple library for supporting implementation of [Facebook Messenger Bots](https://developers.facebook.com/products/messenger/).
2
8
 
3
9
  ## Installation
4
10
 
5
11
  Add this line to your application's Gemfile:
6
12
 
7
13
  ```ruby
8
- gem 'messenger-ruby'
14
+ gem 'messenger-ruby', git: 'https://github.com/netguru/messenger-ruby.git'
9
15
  ```
10
16
 
11
17
  And then execute:
@@ -18,23 +24,402 @@ Or install it yourself as:
18
24
 
19
25
  ## Configuration
20
26
 
21
- Create `messenger.rb` initializer in you app directory:
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:
22
36
 
23
37
  ```ruby
24
- # app/config/initializers/messenger.rb
38
+ # YOUR_APP/config/initializers/messenger.rb
25
39
  Messenger.configure do |config|
26
- config.verify_token = '...'
27
- config.page_access_token = '...'
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
+ render nothing: true, status: 200
65
+ end
28
66
  end
29
67
  ```
30
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
+ * 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
78
+
31
79
  ## Usage
32
80
 
33
- TODO: Write usage instructions here
81
+ 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).
82
+
83
+ ### Messenger::Request
84
+
85
+ It's used to build parameters for Facebook API. Requires [component](#components) and `recipient_id`.
86
+
87
+ Example usage:
88
+ ```ruby
89
+ Messenger::Request.new(some_component, recipient_id)
90
+ ```
91
+
92
+ ### Messenger::Client
93
+
94
+ Sends requests to Facebook API. Has two methods:
95
+ * `get_user_profile` - requires id of existing facebook user
96
+ * `send` - requires [Messenger::Request](#messengerrequest) object
97
+
98
+ Example usage:
99
+ ```ruby
100
+ Messenger::Client.get_user_profile(user_id) #=> hash with name, surname and profile picture
101
+ Messenger::Client.send(request) #=> hash with message details or exception if request is incorrect
102
+ ```
103
+
104
+ Please note that unsuccessful `send` will be shown in logs as `Facebook API response from invalid request: ...`
105
+
106
+ ### Elements
107
+
108
+ Elements can't be used outside of templates.
109
+
110
+ #### Button
111
+
112
+ Lives inside [Bubble](#bubble) element or [Button template](#button-template).
113
+
114
+ Attribute | Allowed values | Required?
115
+ --------- | -------------- | :--------:
116
+ type | `'web_url'`, `'postback'` | &#10004;
117
+ title | String | &#10004;
118
+ value | String | &#10004;
119
+
120
+ Example usage:
121
+ ```ruby
122
+ Messenger::Elements::Button.new(type: 'web_url', title: 'Button', value: 'http://github.com')
123
+ ```
124
+
125
+ #### Bubble
126
+
127
+ Part of [Generic template](#button-template).
128
+
129
+ Attribute | Allowed values | Required?
130
+ --------- | -------------- | :--------:
131
+ title | String | &#10004;
132
+ subtitle | String | &#10004;*
133
+ image_url | String | &#10004;*
134
+ buttons | [`Messenger::Elements::Button`](#button) objects array | &#10004;*
135
+ item_url | String | &#10008;
136
+
137
+ `*` - at least one of them is required
138
+
139
+ Example usage:
140
+ ```ruby
141
+ Messenger::Elements::Bubble.new(title: 'First', subtitle: 'Bubble')
142
+
143
+ ```
144
+
145
+ #### Address
146
+
147
+ Used by [Receipt template](#receipt-template).
148
+
149
+ Attribute | Allowed values | Required?
150
+ --------- | -------------- | :--------:
151
+ street_1 | String | &#10004;
152
+ street_2 | String | &#10008;
153
+ city | String | &#10004;
154
+ postal_code | String | &#10004;
155
+ state | String | &#10004;
156
+ country | String | &#10004;
157
+
158
+ Example usage:
159
+ ```ruby
160
+ Messenger::Elements::Address.new(
161
+ street_1: 'Vachel Lindsay Dr',
162
+ street_2: '',
163
+ city: 'Springfield',
164
+ postal_code: '62701',
165
+ state: 'IL',
166
+ country:'USA'
167
+ )
168
+ ```
169
+
170
+ #### Adjustment
171
+
172
+ Used by [Receipt template](#receipt-template).
173
+
174
+ Attribute | Allowed values | Required?
175
+ --------- | -------------- | :--------:
176
+ name | String | &#10004;
177
+ amount | Integer, greater than 0 | &#10004;
178
+
179
+ Example usage:
180
+ ```ruby
181
+ Messenger::Elements::Adjustment.new(name: 'Adjustment 1', amount: 20)
182
+ ```
183
+
184
+ #### Item
185
+
186
+ Used by [Receipt template](#receipt-template).
187
+
188
+ Attribute | Allowed values | Required?
189
+ --------- | -------------- | :--------:
190
+ title | String | &#10004;
191
+ subtilte | String | &#10008;
192
+ quantity | Integer | &#10008;
193
+ price | Decimal | &#10008;
194
+ currency | String, from _ISO 4217 Currency Codes_ | &#10008;
195
+ image_url | String | &#10008;
196
+
197
+ Example usage:
198
+ ```ruby
199
+ Messenger::Elements::Item.new(
200
+ title: 'Cool Tshirt',
201
+ subtitle: 'XXL White',
202
+ quantity: 3,
203
+ price: 34,
204
+ currency: 'USD',
205
+ image_url: 'http://assets.servedby-buysellads.com/p/manage/asset/id/25397'
206
+ )
207
+ ```
208
+
209
+ #### Order
210
+
211
+ Used by [Receipt template](#receipt-template).
212
+
213
+ Attribute | Allowed values | Required?
214
+ --------- | -------------- | :--------:
215
+ order_number | String, unique per conversation | &#10004;
216
+ currency | String, from _ISO 4217 Currency Codes_ | &#10004;
217
+ payment_method | String | &#10004;
218
+ timestamp | correct timestamp (String) | &#10008;
219
+ order_url | String | &#10008;
220
+
221
+ Example usage:
222
+ ```ruby
223
+ Messenger::Elements::Order.new(
224
+ order_number: 'R190581345',
225
+ currency: 'USD',
226
+ payment_method: 'Visa',
227
+ timestamp: '1428444852',
228
+ order_url: 'http://petersapparel.parseapp.com/order?order_id=123456'
229
+ )
230
+ ```
231
+
232
+ #### Summary
233
+
234
+
235
+ Used by [Receipt template](#receipt-template).
236
+
237
+ Attribute | Allowed values | Required?
238
+ --------- | -------------- | :--------:
239
+ subtotal | Decimal | &#10008;
240
+ shipping_cost | Decimal | &#10008;
241
+ total_tax | Decimal | &#10008;
242
+ total_cost | Decimal | &#10004;
243
+
244
+ Example usage:
245
+ ```ruby
246
+ Messenger::Elements::Summary.new(subtotal: 70, shipping_cost: 20, total_tax: 10, total_cost: 100)
247
+ ```
248
+
249
+ ### Components
250
+
251
+ You can find more info about what can be send in [Messenger Platform Docs](https://developers.facebook.com/docs/messenger-platform/send-api-reference).
252
+
253
+ #### Text
254
+
255
+ Attribute | Allowed values | Required?
256
+ --------- | -------------- | :--------:
257
+ text | String | &#10004;
258
+
259
+
260
+ Here is complete example on how to send sample text to the user:
261
+ ```ruby
262
+ if fb_params.message?
263
+ Messenger::Client.send(
264
+ Messenger::Request.new(
265
+ Messenger::Elements::Text.new(text: 'some text'),
266
+ fb_params.sender_id
267
+ )
268
+ )
269
+ end
270
+
271
+ #make sure to send 200 at the end
272
+ render nothing: true, status: 200
273
+ ```
274
+
275
+ #### Image
276
+
277
+ Attribute | Allowed values | Required?
278
+ --------- | -------------- | :--------:
279
+ url | String | &#10004;
280
+
281
+
282
+ Sending images is simple as well:
283
+ ```ruby
284
+ ...
285
+ Messenger::Client.send(
286
+ Messenger::Request.new(
287
+ Messenger::Elements::Image.new(url: 'http://lorempixel.com/400/400/cats'),
288
+ fb_params.sender_id
289
+ )
290
+ )
291
+ ...
292
+ ```
293
+
294
+ #### Generic template
295
+
296
+ Attribute | Allowed values | Required?
297
+ --------- | -------------- | :--------:
298
+ elements | Array of [Messenger::Elements::Bubble](#bubble) objects | &#10004;
299
+
300
+ Example usage:
301
+ ```ruby
302
+
303
+ #define bubbles here...
304
+ bubble1 = Messenger::Elements::Bubble.new(
305
+ title: 'Bubble 1',
306
+ subtitle: 'Cool Bubble',
307
+ item_url: 'http://lorempixel.com/400/400/cats',
308
+ image_url: 'http://lorempixel.com/400/400/cats',
309
+ buttons: [
310
+ Messenger::Elements::Button.new(
311
+ type: 'web_url',
312
+ title: 'Show Website',
313
+ value: 'https://petersapparel.parseapp.com'
314
+ )
315
+ ]
316
+ )
317
+
318
+ bubble2 = ...
319
+
320
+ #lets create Generic template
321
+ generic = Messenger::Templates::Generic.new(
322
+ elements: [bubble1, bubble2]
323
+ )
324
+
325
+ #now send Generic template to the user
326
+ Messenger::Client.send(
327
+ Messenger::Request.new(generic, fb_params.sender_id)
328
+ )
329
+ ```
330
+
331
+ #### Button template
332
+
333
+ Attribute | Allowed values | Required?
334
+ --------- | -------------- | :--------:
335
+ text | String | &#10004;
336
+ buttons | Array of [Messenger::Elements::Button](#button) objects | &#10004;
337
+
338
+ Example usage:
339
+ ```ruby
340
+
341
+ #lets create Buttons template
342
+ buttons = Messenger::Templates::Buttons.new(
343
+ text: 'Some Cool Text',
344
+ buttons: [
345
+ Messenger::Elements::Button.new(
346
+ type: 'web_url',
347
+ title: 'Show Website',
348
+ value: 'https://petersapparel.parseapp.com'
349
+ )
350
+ ]
351
+ )
352
+
353
+ #now send Buttons template to the user
354
+ Messenger::Client.send(
355
+ Messenger::Request.new(buttons, fb_params.sender_id)
356
+ )
357
+ ```
358
+
359
+ #### Receipt template
360
+
361
+ Attribute | Allowed values | Required?
362
+ --------- | -------------- | :--------:
363
+ recipient_name | String | &#10004;
364
+ order | [Messenger::Elements::Order](#order) object | &#10004;
365
+ elements | Array of [Messenger::Elements::Item](#item) objects | &#10004;
366
+ address | [Messenger::Elements::Address](#address) object | &#10008;
367
+ summary | [Messenger::Elements::Summary](#summary) object | &#10004;
368
+ adjustments | Array of [Messenger::Elements::Adjustment](#adjustment) objects | &#10008;
369
+
370
+ Example usage:
371
+ ```ruby
372
+ #define order element here...
373
+ order = Messenger::Elements::Order.new(
374
+ order_number: 'R190581345',
375
+ currency: 'USD',
376
+ payment_method: 'Visa',
377
+ timestamp: '1428444852',
378
+ order_url: 'http://petersapparel.parseapp.com/order?order_id=123456'
379
+ )
380
+
381
+ #and define all other template elements
382
+ item1 = ...
383
+ item2 = ...
384
+ address = ...
385
+ summary = ...
386
+ adjustment1 = ...
387
+ adjustment2 = ...
388
+
389
+ #lets create Receipt template
390
+ receipt = Messenger::Templates::Receipt.new(
391
+ recipient_name: 'Random Recipient',
392
+ order: order,
393
+ elements: [item1, item2],
394
+ address: address,
395
+ summary: summary,
396
+ adjustments: [adjustment1, adjustment2]
397
+ )
398
+
399
+ #now send Receipt template to the user
400
+ Messenger::Client.send(
401
+ Messenger::Request.new(receipt, fb_params.sender_id)
402
+ )
403
+
404
+ ```
405
+
406
+ ### fb_params
407
+
408
+ Deserializes params recived from Facebook. Available in MessengerController. Methods:
409
+
410
+ * `message?`
411
+ * `delivery?`
412
+ * `postback?`
413
+ * `attachments`
414
+ * `text_message`
415
+ * `sender_id`
416
+ * `recipient_id`
417
+
418
+ _Will be extended soon._
34
419
 
35
420
  ## Development
36
421
 
37
- After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
422
+ 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.
38
423
 
39
424
  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).
40
425
 
data/Rakefile CHANGED
@@ -4,5 +4,5 @@ require "rspec/core/rake_task"
4
4
  task default: :spec
5
5
 
6
6
  task :console do
7
- exec "irb -r messenger -I ./lib"
7
+ exec "irb -r messenger-ruby -I ./lib"
8
8
  end
@@ -0,0 +1,45 @@
1
+ require 'rest-client'
2
+
3
+ module Messenger
4
+ class MessengerController < ActionController::Base
5
+ def validate
6
+ if verify_token_valid? && access_token_valid?
7
+ render json: params["hub.challenge"]
8
+ elsif !verify_token_valid?
9
+ render json: 'Invalid verify token'
10
+ else
11
+ render json: 'Invalid page access token'
12
+ end
13
+ end
14
+
15
+ def subscribe
16
+ render json: activate_bot
17
+ rescue RestClient::BadRequest
18
+ render json: 'Invalid page access token'
19
+ end
20
+
21
+ private
22
+
23
+ def app_location
24
+ "https://graph.facebook.com/v2.6/me/subscribed_apps?access_token=#{Messenger.config.page_access_token}"
25
+ end
26
+
27
+ def activate_bot
28
+ RestClient.post(app_location, nil)
29
+ end
30
+
31
+ def access_token_valid?
32
+ JSON.parse(RestClient.get(app_location)).key?('data')
33
+ rescue RestClient::BadRequest
34
+ return false
35
+ end
36
+
37
+ def verify_token_valid?
38
+ params["hub.verify_token"] == Messenger.config.verify_token
39
+ end
40
+
41
+ def fb_params
42
+ Params.new(params)
43
+ end
44
+ end
45
+ end
data/bin/console CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  require "bundler/setup"
4
- require "messenger"
4
+ require "messenger-ruby"
5
5
 
6
6
  # You can add fixtures and/or initialization code here to make experimenting
7
7
  # with your gem easier. You can also use a different console, if you like.
data/circle.yml ADDED
@@ -0,0 +1,6 @@
1
+ dependencies:
2
+ pre:
3
+ - gem install bundler --pre
4
+ machine:
5
+ ruby:
6
+ version: 2.2.0
data/config/routes.rb ADDED
@@ -0,0 +1,8 @@
1
+ Messenger::Engine.routes.draw do
2
+ get :subscribe, to: "messenger#subscribe"
3
+ get :webhook, to: "messenger#validate"
4
+ end
5
+
6
+ Rails.application.routes.draw do
7
+ post 'messenger/webhook', to: "messenger#webhook"
8
+ end
@@ -0,0 +1,41 @@
1
+ require "messenger/version"
2
+ require "messenger/configuration"
3
+
4
+ require "messenger/components/elements/text"
5
+ require "messenger/components/elements/image"
6
+ require "messenger/components/elements/button"
7
+ require "messenger/components/elements/bubble"
8
+
9
+ require "messenger/components/elements/receipt/address"
10
+ require "messenger/components/elements/receipt/adjustment"
11
+ require "messenger/components/elements/receipt/item"
12
+ require "messenger/components/elements/receipt/order"
13
+ require "messenger/components/elements/receipt/summary"
14
+
15
+ require "messenger/components/templates/buttons"
16
+ require "messenger/components/templates/generic"
17
+ require "messenger/components/templates/receipt"
18
+
19
+ require "messenger/client"
20
+ require "messenger/request"
21
+
22
+ module Messenger
23
+ class << self
24
+ attr_accessor :config
25
+
26
+ def config
27
+ @config ||= Configuration.new
28
+ end
29
+
30
+ def configure
31
+ yield(config)
32
+ end
33
+
34
+ def reset
35
+ @config = Configuration.new
36
+ end
37
+ end
38
+ end
39
+
40
+ require "messenger/engine"
41
+ require "messenger/params"
@@ -0,0 +1,20 @@
1
+ module Messenger
2
+ class Client
3
+ def self.get_user_profile(user_id)
4
+ RestClient.get(
5
+ "https://graph.facebook.com/v2.6/#{user_id}?fields=first_name,last_name,profile_pic \
6
+ &access_token=#{Messenger.config.page_access_token}"
7
+ )
8
+ end
9
+
10
+ def self.send(data)
11
+ RestClient.post(
12
+ "https://graph.facebook.com/v2.6/me/messages?access_token=#{Messenger.config.page_access_token}",
13
+ data.build.to_json,
14
+ content_type: :json
15
+ )
16
+ rescue RestClient::ExceptionWithResponse => err
17
+ puts "\nFacebook API response from invalid request:\n#{err.response}\n\n"
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,35 @@
1
+ module Messenger
2
+ module Components
3
+ class Attachment
4
+ def initialize
5
+ raise 'This class is abstract!'
6
+ end
7
+
8
+ def build
9
+ {
10
+ attachment: {
11
+ type: @type,
12
+ payload: payload
13
+ }
14
+ }
15
+ end
16
+
17
+ def all_attributes
18
+ return instance_values unless defined?(flattened_attributes)
19
+ instance_values.merge! flattened_attributes
20
+ end
21
+
22
+ def payload
23
+ all_attributes.select { |attribute, value| allowed_attribute?(attribute) && value.present? }
24
+ end
25
+
26
+ def allowed_attribute?(attribute)
27
+ self.class::ATTRIBUTES.include?(attribute)
28
+ end
29
+
30
+ def build_elements(elements)
31
+ elements.map { |element| element.build } if elements.present?
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,13 @@
1
+ module Messenger
2
+ module Components
3
+ class Element
4
+ def initialize
5
+ raise 'This class is abstract!'
6
+ end
7
+
8
+ def build
9
+ instance_values.delete_if { |_attribute, value| value.nil? }
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,19 @@
1
+ require 'messenger/components/element'
2
+
3
+ module Messenger
4
+ module Elements
5
+ class Bubble < Components::Element
6
+ def initialize(title:, subtitle: nil, item_url: nil, image_url: nil, buttons: nil)
7
+ @title = title
8
+ @subtitle = subtitle
9
+ @image_url = image_url
10
+ @item_url = item_url
11
+ @buttons = build_buttons(buttons)
12
+ end
13
+
14
+ def build_buttons(buttons)
15
+ buttons.map { |button| button.build } if buttons.present?
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,23 @@
1
+ module Messenger
2
+ module Elements
3
+ class Button
4
+ def initialize(type:, title:, value:)
5
+ @type = type
6
+ @title = title
7
+ @value = value
8
+ end
9
+
10
+ def build
11
+ { type: @type, title: @title }.merge! eval(@type.to_s)
12
+ end
13
+
14
+ def web_url
15
+ { url: @value }
16
+ end
17
+
18
+ def postback
19
+ { payload: @value }
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,14 @@
1
+ require 'messenger/components/attachment'
2
+
3
+ module Messenger
4
+ module Elements
5
+ class Image < Components::Attachment
6
+ ATTRIBUTES = %w(url).freeze
7
+
8
+ def initialize(url:)
9
+ @url = url
10
+ @type = 'image'
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,16 @@
1
+ require 'messenger/components/element'
2
+
3
+ module Messenger
4
+ module Elements
5
+ class Address < Components::Element
6
+ def initialize(street_1:, street_2: nil, city:, postal_code:, state:, country:)
7
+ @street_1 = street_1
8
+ @street_2 = street_2
9
+ @city = city
10
+ @postal_code = postal_code
11
+ @state = state
12
+ @country = country
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,12 @@
1
+ require 'messenger/components/element'
2
+
3
+ module Messenger
4
+ module Elements
5
+ class Adjustment < Components::Element
6
+ def initialize(name: nil, amount: nil)
7
+ @name = name
8
+ @amount = amount
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,16 @@
1
+ require 'messenger/components/element'
2
+
3
+ module Messenger
4
+ module Elements
5
+ class Item < Components::Element
6
+ def initialize(title:, subtitle: nil, quantity: nil, price: nil, currency: nil, image_url: nil)
7
+ @title = title
8
+ @subtitle = subtitle
9
+ @quantity = quantity
10
+ @price = price
11
+ @currency = currency
12
+ @image_url = image_url
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,15 @@
1
+ require 'messenger/components/element'
2
+
3
+ module Messenger
4
+ module Elements
5
+ class Order < Components::Element
6
+ def initialize(order_number:, currency:, payment_method:, timestamp: nil, order_url: nil)
7
+ @order_number = order_number
8
+ @currency = currency
9
+ @payment_method = payment_method
10
+ @timestamp = timestamp
11
+ @order_url = order_url
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,14 @@
1
+ require 'messenger/components/element'
2
+
3
+ module Messenger
4
+ module Elements
5
+ class Summary < Components::Element
6
+ def initialize(subtotal: nil, shipping_cost: nil, total_tax: nil, total_cost:)
7
+ @subtotal = subtotal
8
+ @shipping_cost = shipping_cost
9
+ @total_tax = total_tax
10
+ @total_cost = total_cost
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,13 @@
1
+ module Messenger
2
+ module Elements
3
+ class Text
4
+ def initialize(text:)
5
+ @text = text
6
+ end
7
+
8
+ def build
9
+ instance_values
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,16 @@
1
+ require 'messenger/components/attachment'
2
+
3
+ module Messenger
4
+ module Templates
5
+ class Buttons < Components::Attachment
6
+ ATTRIBUTES = %w(template_type text buttons).freeze
7
+
8
+ def initialize(text:, buttons:)
9
+ @type = 'template'
10
+ @template_type = 'button'
11
+ @text = text
12
+ @buttons = build_elements(buttons)
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,15 @@
1
+ require 'messenger/components/attachment'
2
+
3
+ module Messenger
4
+ module Templates
5
+ class Generic < Components::Attachment
6
+ ATTRIBUTES = %w(template_type elements).freeze
7
+
8
+ def initialize(elements:)
9
+ @type = 'template'
10
+ @template_type = 'generic'
11
+ @elements = build_elements(elements)
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,36 @@
1
+ require 'messenger/components/attachment'
2
+
3
+ module Messenger
4
+ module Templates
5
+ class Receipt < Components::Attachment
6
+ ATTRIBUTES = %w(
7
+ template_type
8
+ recipient_name
9
+ order_number
10
+ currency
11
+ payment_method
12
+ timestamp
13
+ order_url
14
+ elements
15
+ address
16
+ summary
17
+ adjustments
18
+ ).freeze
19
+
20
+ def initialize(recipient_name:, order:, elements:, address: nil, summary:, adjustments: nil)
21
+ @type = 'template'
22
+ @template_type = 'receipt'
23
+ @recipient_name = recipient_name
24
+ @order = order
25
+ @elements = build_elements(elements)
26
+ @address = address.build
27
+ @summary = summary.build
28
+ @adjustments = build_elements(adjustments)
29
+ end
30
+
31
+ def flattened_attributes
32
+ @order.build
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,7 @@
1
+ require 'rails'
2
+
3
+ module Messenger
4
+ class Engine < ::Rails::Engine
5
+ isolate_namespace Messenger
6
+ end
7
+ end
@@ -0,0 +1,43 @@
1
+ module Messenger
2
+ class Params
3
+ attr_accessor :params
4
+
5
+ def initialize(params)
6
+ @params = params
7
+ end
8
+
9
+ def message?
10
+ messaging_entry.key?('message')
11
+ end
12
+
13
+ def delivery?
14
+ messaging_entry.key?('delivery')
15
+ end
16
+
17
+ def postback?
18
+ messaging_entry.key?('postback')
19
+ end
20
+
21
+ def attachments
22
+ messaging_entry['message']['attachments'].map { |a| a['payload']['url'] }
23
+ end
24
+
25
+ def text_message
26
+ messaging_entry['message']['text']
27
+ end
28
+
29
+ def sender_id
30
+ messaging_entry['sender']['id']
31
+ end
32
+
33
+ def recipient_id
34
+ messaging_entry['recipient']['id']
35
+ end
36
+
37
+ private
38
+
39
+ def messaging_entry
40
+ params['entry'][0]['messaging'][0]
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,24 @@
1
+ module Messenger
2
+ class Request
3
+ def initialize(component, recipient_id)
4
+ @recipient_id = recipient_id
5
+ @body = body
6
+ add_element(component)
7
+ end
8
+
9
+ def build
10
+ return @body
11
+ end
12
+
13
+ def add_element(element)
14
+ @body[:message].merge! element.build
15
+ end
16
+
17
+ def body
18
+ {
19
+ recipient: { id: @recipient_id },
20
+ message: {}
21
+ }
22
+ end
23
+ end
24
+ end
@@ -1,3 +1,3 @@
1
1
  module Messenger
2
- VERSION = "0.1.0"
2
+ VERSION = "1.0.0"
3
3
  end
@@ -18,7 +18,14 @@ Gem::Specification.new do |spec|
18
18
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
19
19
  spec.require_paths = ["lib"]
20
20
 
21
- spec.add_development_dependency "bundler", "~> 1.11"
21
+ spec.add_dependency 'rest-client'
22
+
23
+ spec.add_development_dependency "bundler"
22
24
  spec.add_development_dependency "rake", "~> 10.0"
23
25
  spec.add_development_dependency "rspec"
26
+ spec.add_development_dependency 'rspec-rails'
27
+ spec.add_development_dependency 'webmock'
28
+ spec.add_development_dependency "pry"
29
+ spec.add_development_dependency "rails"
30
+ spec.add_development_dependency "codeclimate-test-reporter"
24
31
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: messenger-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - justynjozwiak
@@ -9,22 +9,36 @@ authors:
9
9
  autorequire:
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2016-04-18 00:00:00.000000000 Z
12
+ date: 2016-04-22 00:00:00.000000000 Z
13
13
  dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rest-client
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - ">="
19
+ - !ruby/object:Gem::Version
20
+ version: '0'
21
+ type: :runtime
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ version: '0'
14
28
  - !ruby/object:Gem::Dependency
15
29
  name: bundler
16
30
  requirement: !ruby/object:Gem::Requirement
17
31
  requirements:
18
- - - "~>"
32
+ - - ">="
19
33
  - !ruby/object:Gem::Version
20
- version: '1.11'
34
+ version: '0'
21
35
  type: :development
22
36
  prerelease: false
23
37
  version_requirements: !ruby/object:Gem::Requirement
24
38
  requirements:
25
- - - "~>"
39
+ - - ">="
26
40
  - !ruby/object:Gem::Version
27
- version: '1.11'
41
+ version: '0'
28
42
  - !ruby/object:Gem::Dependency
29
43
  name: rake
30
44
  requirement: !ruby/object:Gem::Requirement
@@ -53,6 +67,76 @@ dependencies:
53
67
  - - ">="
54
68
  - !ruby/object:Gem::Version
55
69
  version: '0'
70
+ - !ruby/object:Gem::Dependency
71
+ name: rspec-rails
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ version: '0'
84
+ - !ruby/object:Gem::Dependency
85
+ name: webmock
86
+ requirement: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - ">="
89
+ - !ruby/object:Gem::Version
90
+ version: '0'
91
+ type: :development
92
+ prerelease: false
93
+ version_requirements: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - ">="
96
+ - !ruby/object:Gem::Version
97
+ version: '0'
98
+ - !ruby/object:Gem::Dependency
99
+ name: pry
100
+ requirement: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - ">="
103
+ - !ruby/object:Gem::Version
104
+ version: '0'
105
+ type: :development
106
+ prerelease: false
107
+ version_requirements: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - ">="
110
+ - !ruby/object:Gem::Version
111
+ version: '0'
112
+ - !ruby/object:Gem::Dependency
113
+ name: rails
114
+ requirement: !ruby/object:Gem::Requirement
115
+ requirements:
116
+ - - ">="
117
+ - !ruby/object:Gem::Version
118
+ version: '0'
119
+ type: :development
120
+ prerelease: false
121
+ version_requirements: !ruby/object:Gem::Requirement
122
+ requirements:
123
+ - - ">="
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
126
+ - !ruby/object:Gem::Dependency
127
+ name: codeclimate-test-reporter
128
+ requirement: !ruby/object:Gem::Requirement
129
+ requirements:
130
+ - - ">="
131
+ - !ruby/object:Gem::Version
132
+ version: '0'
133
+ type: :development
134
+ prerelease: false
135
+ version_requirements: !ruby/object:Gem::Requirement
136
+ requirements:
137
+ - - ">="
138
+ - !ruby/object:Gem::Version
139
+ version: '0'
56
140
  description:
57
141
  email:
58
142
  - justyn.jozwiak@netguru.pl
@@ -61,15 +145,37 @@ executables: []
61
145
  extensions: []
62
146
  extra_rdoc_files: []
63
147
  files:
148
+ - ".codeclimate.yml"
64
149
  - ".gitignore"
65
150
  - ".rspec"
66
151
  - Gemfile
67
152
  - README.md
68
153
  - Rakefile
154
+ - app/controllers/messenger/messenger_controller.rb
69
155
  - bin/console
70
156
  - bin/setup
71
- - lib/messenger.rb
157
+ - circle.yml
158
+ - config/routes.rb
159
+ - lib/messenger-ruby.rb
160
+ - lib/messenger/client.rb
161
+ - lib/messenger/components/attachment.rb
162
+ - lib/messenger/components/element.rb
163
+ - lib/messenger/components/elements/bubble.rb
164
+ - lib/messenger/components/elements/button.rb
165
+ - lib/messenger/components/elements/image.rb
166
+ - lib/messenger/components/elements/receipt/address.rb
167
+ - lib/messenger/components/elements/receipt/adjustment.rb
168
+ - lib/messenger/components/elements/receipt/item.rb
169
+ - lib/messenger/components/elements/receipt/order.rb
170
+ - lib/messenger/components/elements/receipt/summary.rb
171
+ - lib/messenger/components/elements/text.rb
172
+ - lib/messenger/components/templates/buttons.rb
173
+ - lib/messenger/components/templates/generic.rb
174
+ - lib/messenger/components/templates/receipt.rb
72
175
  - lib/messenger/configuration.rb
176
+ - lib/messenger/engine.rb
177
+ - lib/messenger/params.rb
178
+ - lib/messenger/request.rb
73
179
  - lib/messenger/version.rb
74
180
  - messenger-ruby.gemspec
75
181
  homepage: https://github.com/netguru/messenger-ruby
data/lib/messenger.rb DELETED
@@ -1,20 +0,0 @@
1
- require "messenger/version"
2
- require "messenger/configuration"
3
-
4
- module Messenger
5
- class << self
6
- attr_accessor :config
7
-
8
- def config
9
- @config ||= Configuration.new
10
- end
11
-
12
- def configure
13
- yield(config)
14
- end
15
-
16
- def reset
17
- @config = Configuration.new
18
- end
19
- end
20
- end