messagebird-rest 1.3.2 → 2.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.
Files changed (44) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +67 -17
  3. data/lib/messagebird.rb +16 -7
  4. data/lib/messagebird/balance.rb +2 -0
  5. data/lib/messagebird/base.rb +12 -7
  6. data/lib/messagebird/call_flow.rb +22 -0
  7. data/lib/messagebird/call_flow/step.rb +9 -0
  8. data/lib/messagebird/callflow.rb +60 -0
  9. data/lib/messagebird/client.rb +420 -73
  10. data/lib/messagebird/contact.rb +33 -0
  11. data/lib/messagebird/contact_reference.rb +9 -0
  12. data/lib/messagebird/conversation.rb +44 -0
  13. data/lib/messagebird/conversation_channel.rb +18 -0
  14. data/lib/messagebird/conversation_client.rb +22 -0
  15. data/lib/messagebird/conversation_message.rb +10 -0
  16. data/lib/messagebird/conversation_webhook.rb +9 -0
  17. data/lib/messagebird/custom_details.rb +10 -0
  18. data/lib/messagebird/error.rb +2 -0
  19. data/lib/messagebird/group.rb +23 -0
  20. data/lib/messagebird/group_reference.rb +9 -0
  21. data/lib/messagebird/hlr.rb +8 -6
  22. data/lib/messagebird/http_client.rb +95 -0
  23. data/lib/messagebird/list.rb +24 -0
  24. data/lib/messagebird/lookup.rb +7 -5
  25. data/lib/messagebird/message.rb +9 -7
  26. data/lib/messagebird/message_reference.rb +9 -0
  27. data/lib/messagebird/number.rb +18 -0
  28. data/lib/messagebird/number_client.rb +22 -0
  29. data/lib/messagebird/recipient.rb +6 -3
  30. data/lib/messagebird/signed_request.rb +50 -0
  31. data/lib/messagebird/verify.rb +20 -0
  32. data/lib/messagebird/version.rb +7 -0
  33. data/lib/messagebird/voice/base.rb +16 -0
  34. data/lib/messagebird/voice/call.rb +22 -0
  35. data/lib/messagebird/voice/call_leg.rb +11 -0
  36. data/lib/messagebird/voice/call_leg_recording.rb +20 -0
  37. data/lib/messagebird/voice/client.rb +22 -0
  38. data/lib/messagebird/voice/list.rb +24 -0
  39. data/lib/messagebird/voice/transcription.rb +15 -0
  40. data/lib/messagebird/voice/webhook.rb +11 -0
  41. data/lib/messagebird/voice_client.rb +25 -0
  42. data/lib/messagebird/voicemessage.rb +8 -7
  43. metadata +85 -15
  44. data/lib/messagebird/otp.rb +0 -18
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: fef609127e904a092153ab2dc6e80cd6a775b7d0
4
- data.tar.gz: c75c619d065f6e551e9d875098d089915da4bcd2
2
+ SHA256:
3
+ metadata.gz: dd213489a7f5a7e70a7418ab2e3be5c4aa8cedfa61042121edb1c03dddd6d56a
4
+ data.tar.gz: 9eca63a90298b50cc4d07fb0b7ff6abc7d1ae292155e7f456df18256ae7f64e3
5
5
  SHA512:
6
- metadata.gz: d5ed9a42b17dfbdfe55a6b8c2a88218b48001edb8764e748b42e5777406f5fe5d8ce9bd60ebf7801461f8211eecd46e481645c9c068ab59c1dd1ead037a5b07c
7
- data.tar.gz: 8dcca59dca9154927d34ebb5dfcb4b1104427c8dc50fc9b1de7f969583a5a6d536ca3042bc41df4c7c22fd51216f0ab4fc26212b79c6196aa2e8c47344878035
6
+ metadata.gz: 373dae967d6e226cccb6f775666369b1cdc07491593cc1f5ed4fb6e7950c887723475360d4b3d04e50f00b609542190980a99ac3c09bbca5974f636791b86755
7
+ data.tar.gz: 8bc8ca63f00b5b77731ca3082497ea9cf9f8ae4738878e15d49361438adf5aa03baa2a35bc3bebec4e46a5b7c30e42cbc17be109fefee47543e0f3c3ac7410c0
data/README.md CHANGED
@@ -2,9 +2,11 @@ MessageBird's REST API for Ruby
2
2
  ===============================
3
3
  This repository contains the open source Ruby client for MessageBird's REST API. Documentation can be found at: https://developers.messagebird.com/
4
4
 
5
+ [![Build Status](https://travis-ci.org/messagebird/ruby-rest-api.svg?branch=master)](https://travis-ci.org/messagebird/ruby-rest-api)
6
+
5
7
  Requirements
6
8
  ------------
7
- - [Sign up](https://www.messagebird.com/en/signup) for a free MessageBird account
9
+ - [Sign up](https://dashboard.messagebird.com/app/en/sign-up) for a free MessageBird account
8
10
  - Create a new `access_key` in the developers sections
9
11
  - MessageBird's API client for Ruby requires Ruby >= 1.9
10
12
 
@@ -56,7 +58,7 @@ pp client.message_create('FromMe', '31612345678', 'Hello World', :reference => '
56
58
 
57
59
  #<MessageBird::Message:0x007f8d5b883520
58
60
  @body="Hello World",
59
- @createdDatetime=2014-07-07 12:20:30 +0200,
61
+ @created_datetime=2014-07-07 12:20:30 +0200,
60
62
  @datacoding="plain",
61
63
  @direction="mt",
62
64
  @gateway=239,
@@ -66,7 +68,7 @@ pp client.message_create('FromMe', '31612345678', 'Hello World', :reference => '
66
68
  @mclass=1,
67
69
  @originator="FromMe",
68
70
  @recipient=
69
- {"totalCount"=>1,
71
+ {"total_count"=>1,
70
72
  "totalSentCount"=>1,
71
73
  "totalDeliveredCount"=>0,
72
74
  "totalDeliveryFailedCount"=>0,
@@ -76,9 +78,9 @@ pp client.message_create('FromMe', '31612345678', 'Hello World', :reference => '
76
78
  @status="sent",
77
79
  @statusDatetime=2014-07-07 12:20:30 +0200>]},
78
80
  @reference="MyReference",
79
- @scheduledDatetime=nil,
81
+ @scheduled_datetime=nil,
80
82
  @type="sms",
81
- @typeDetails={},
83
+ @type_details={},
82
84
  @validity=nil>
83
85
  ```
84
86
 
@@ -95,7 +97,7 @@ To perform HLR lookups we have created the **hlr_create** method, which takes a
95
97
  pp client.hlr_create('31612345678', 'MyReference')
96
98
 
97
99
  #<MessageBird::HLR:0x007f8d5b8dafc8
98
- @createdDatetime=2014-07-07 12:20:05 +0200,
100
+ @created_datetime=2014-07-07 12:20:05 +0200,
99
101
  @href="https://rest.messagebird.com/hlr/4933bed0453ba7455031712h16830892",
100
102
  @id="4933bed0453ba7455031712h16830892",
101
103
  @msisdn=31612345678,
@@ -111,28 +113,28 @@ Similar to the **message_create** and **message** methods, the **hlr_create** me
111
113
  client.hlr('4933bed0453ba7455031712h16830892')
112
114
  ```
113
115
 
114
- ##### OTP (One-Time Password)
115
- You can send and verify One-Time Passwords through the MessageBird API using the **otp_generate** and **otp_verify** methods.
116
+ ##### Verify (One-Time Password)
117
+ You can send and verify One-Time Passwords through the MessageBird API using the **verify_create** and **verify_token** methods.
116
118
 
117
119
  ```ruby
118
- # otp_generate requires a recipient as a required parameter, and other optional paramaters
119
- client.otp_generate(31612345678, {:reference => "YourReference"})
120
+ # verify_create requires a recipient as a required parameter, and other optional paramaters
121
+ client.verify_create(31612345678, {:reference => "YourReference"})
120
122
 
121
- #<MessageBird::OTP:0x007fb3c18c8148
123
+ #<MessageBird::Verify:0x007fb3c18c8148
122
124
  @id="080b7f804555213678f14f6o24607735",
123
125
  @recipient="31612345678",
124
126
  @reference="YourReference",
125
127
  @status="sent",
126
128
  @href={"message"=>"https://rest.messagebird.com/messages/67d42f004555213679416f0b13254392"},
127
- @createdDatetime=2015-05-12 16:51:19 +0200,
129
+ @created_datetime=2015-05-12 16:51:19 +0200,
128
130
  @validUntilDatetime=2015-05-12 16:51:49 +0200>
129
131
  ```
130
132
 
131
- This sends a token to the recipient, which can be verified with the **otp_verify** method.
133
+ This sends a token to the recipient, which can be verified with the **verify_token** method.
132
134
 
133
135
  ```ruby
134
- # otp_verify requires a recipient, a token as required parameters, and other optional paramaters
135
- client.otp_verify(31612345678, 123456, {:reference => "YourReference"})
136
+ # verify_token requires the id of the verify request and a token as required parameters.
137
+ client.verify_token('080b7f804555213678f14f6o24607735', 123456)
136
138
  ```
137
139
 
138
140
  ##### Voice Message
@@ -145,14 +147,14 @@ pp client.voice_message_create('31612345678', 'Hello World', :reference => 'MyRe
145
147
 
146
148
  #<MessageBird::VoiceMessage:0x000001030101b8
147
149
  @body="Hello World",
148
- @createdDatetime=2014-07-09 12:17:50 +0200,
150
+ @created_datetime=2014-07-09 12:17:50 +0200,
149
151
  @href=
150
152
  "https://rest.messagebird.com/voicemessages/a08e51a0353bd16cea7f298a37405850",
151
153
  @id="a08e51a0353bd16cea7f298a37405850",
152
154
  @ifMachine="continue",
153
155
  @language="en-gb",
154
156
  @recipients=
155
- {"totalCount"=>1,
157
+ {"total_count"=>1,
156
158
  "totalSentCount"=>1,
157
159
  "totalDeliveredCount"=>0,
158
160
  "totalDeliveryFailedCount"=>0,
@@ -173,6 +175,54 @@ Similar to regular messaging and HLR lookups, there is a method available to fet
173
175
  client.voice_message('a08e51a0353bd16cea7f298a37405850')
174
176
  ```
175
177
 
178
+ ##### Numbers
179
+ There is also a Numbers API that allow you to search for and purchase number subscriptions to use as originator in other services.
180
+
181
+ ```ruby
182
+ pp client.number_search("NL", {:limit=>5})
183
+
184
+ #<List:0x00007fa405130618
185
+ @count=5,
186
+ @items=
187
+ [#<MessageBird::Number:0x00007fa405130528
188
+ @country="NL",
189
+ @features=["voice"],
190
+ @locality="Rotterdam",
191
+ @number="31102005108",
192
+ @region="",
193
+ @type="unknown">,
194
+ #<MessageBird::Number:0x00007fa4051303c0
195
+ @country="NL",
196
+ @features=["voice"],
197
+ @locality="Rotterdam",
198
+ @number="31102005143",
199
+ @region="",
200
+ @type="unknown">,
201
+ #<MessageBird::Number:0x00007fa405130208
202
+ @country="NL",
203
+ @features=["voice"],
204
+ @locality="Rotterdam",
205
+ @number="31102005145",
206
+ @region="",
207
+ @type="unknown">,
208
+ #<MessageBird::Number:0x00007fa4051300c8
209
+ @country="NL",
210
+ @features=["voice"],
211
+ @locality="Rotterdam",
212
+ @number="31102005147",
213
+ @region="",
214
+ @type="unknown">,
215
+ #<MessageBird::Number:0x00007fa405131c48
216
+ @country="NL",
217
+ @features=["voice"],
218
+ @locality="Rotterdam",
219
+ @number="31102005148",
220
+ @region="",
221
+ @type="unknown">],
222
+ @limit=5,
223
+ @type=MessageBird::Number>
224
+ ````
225
+
176
226
  Documentation
177
227
  -------------
178
228
  Complete documentation, instructions, and examples are available at:
data/lib/messagebird.rb CHANGED
@@ -1,15 +1,24 @@
1
- libdir = File.dirname(__FILE__)
2
- $:.unshift(libdir) unless $:.include?(libdir)
1
+ # frozen_string_literal: true
3
2
 
4
- module MessageBird
5
- CLIENT_VERSION = '1.3.2'
6
- ENDPOINT = 'https://rest.messagebird.com'
7
- end
3
+ libdir = File.dirname(__FILE__)
4
+ $LOAD_PATH.unshift(libdir) unless $LOAD_PATH.include?(libdir)
8
5
 
6
+ require 'messagebird/version'
9
7
  require 'messagebird/balance'
10
8
  require 'messagebird/client'
9
+ require 'messagebird/contact'
11
10
  require 'messagebird/error'
11
+ require 'messagebird/group_reference'
12
12
  require 'messagebird/hlr'
13
- require 'messagebird/otp'
13
+ require 'messagebird/http_client'
14
+ require 'messagebird/message_reference'
15
+ require 'messagebird/signed_request'
16
+ require 'messagebird/verify'
14
17
  require 'messagebird/message'
15
18
  require 'messagebird/voicemessage'
19
+ require 'messagebird/callflow'
20
+ require 'messagebird/voice/call'
21
+ require 'messagebird/voice/call_leg'
22
+ require 'messagebird/voice/call_leg_recording'
23
+ require 'messagebird/voice/transcription'
24
+ require 'messagebird/voice/webhook'
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'messagebird/base'
2
4
 
3
5
  module MessageBird
@@ -1,18 +1,23 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'json'
2
4
  require 'time'
3
5
 
4
6
  module MessageBird
5
7
  class Base
6
- def initialize(json)
7
- json.each do |k,v|
8
- begin
9
- send("#{k}=", v)
10
- rescue NoMethodError
11
- # Silently ignore parameters that are not supported.
12
- end
8
+ # takes each element from the given hash and apply it to ourselves through an assignment method
9
+ def map_hash_elements_to_self(hash)
10
+ hash.each do |key, value|
11
+ method_name = key.gsub(/([a-z\d])([A-Z])/, '\1_\2').downcase # convert came case to snake case
12
+ method_name += '='
13
+ send(method_name, value) if respond_to?(method_name)
13
14
  end
14
15
  end
15
16
 
17
+ def initialize(json)
18
+ map_hash_elements_to_self(json)
19
+ end
20
+
16
21
  def value_to_time(value)
17
22
  value ? Time.parse(value) : nil
18
23
  end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'messagebird/base'
4
+
5
+ module MessageBird
6
+ class CallFlow < MessageBird::Base
7
+ attr_accessor :id, :title, :record, :default
8
+ attr_reader :steps, :created_at, :updated_at
9
+
10
+ def steps=(json)
11
+ @steps = json.map { |s| MessageBird::CallFlowStep.new(s) }
12
+ end
13
+
14
+ def created_at=(value)
15
+ @created_at = value_to_time(value)
16
+ end
17
+
18
+ def updated_at=(value)
19
+ @updated_at = value_to_time(value)
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'messagebird/base'
4
+
5
+ module MessageBird
6
+ class CallFlowStep < MessageBird::Base
7
+ attr_accessor :id, :action, :options
8
+ end
9
+ end
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'messagebird/base'
4
+
5
+ module MessageBird
6
+ class CallFlow < MessageBird::Base
7
+ attr_accessor :id, :title, :record, :default
8
+ attr_reader :steps, :created_at, :updated_at
9
+
10
+ def initialize(json)
11
+ params = json.include?('data') ? json['data'].first : json
12
+ super(params)
13
+ end
14
+
15
+ def steps=(json)
16
+ @steps = json.map { |c| MessageBird::CallFlowStep.new(c) }
17
+ end
18
+
19
+ def created_at=(value)
20
+ @created_at = value_to_time(value)
21
+ end
22
+
23
+ def updated_at=(value)
24
+ @updated_at = value_to_time(value)
25
+ end
26
+ end
27
+
28
+ class CallFlowList < List
29
+ attr_accessor :perPage, :currentPage, :pageCount, :totalCount
30
+ PER_PAGE = 20
31
+ CURRENT_PAGE = 1
32
+
33
+ def data=(value)
34
+ self.items = value
35
+ end
36
+
37
+ def pagination=(value)
38
+ value.each do |k, v|
39
+ send("#{k}=", v)
40
+ rescue NoMethodError
41
+ puts 'An error occurred while listing callflows'
42
+ end
43
+ end
44
+ end
45
+
46
+ class CallFlowStep < MessageBird::Base
47
+ attr_accessor :id, :action
48
+
49
+ def options=(json)
50
+ @options = CallFlowStepOption.new(json)
51
+ end
52
+ end
53
+
54
+ class CallFlowStepOption < MessageBird::Base
55
+ attr_accessor :destination, :payload, :language, :voice, :repeat,
56
+ :media, :length, :maxLength, :timeout, :finishOnKey, :transcribe,
57
+ :transcribeLanguage, :record, :url, :ifMachine, :machineTimeout,
58
+ :onFinish, :mask
59
+ end
60
+ end
@@ -1,14 +1,35 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'json'
2
4
  require 'net/https'
3
5
  require 'uri'
4
6
 
5
7
  require 'messagebird/balance'
8
+ require 'messagebird/contact'
9
+ require 'messagebird/conversation'
10
+ require 'messagebird/conversation_client'
11
+ require 'messagebird/conversation_message'
12
+ require 'messagebird/conversation_webhook'
6
13
  require 'messagebird/error'
14
+ require 'messagebird/group'
7
15
  require 'messagebird/hlr'
8
- require 'messagebird/otp'
16
+ require 'messagebird/http_client'
17
+ require 'messagebird/list'
18
+ require 'messagebird/lookup'
9
19
  require 'messagebird/message'
20
+ require 'messagebird/number'
21
+ require 'messagebird/number_client'
22
+ require 'messagebird/verify'
23
+ require 'messagebird/voice/client'
24
+ require 'messagebird/voice/list'
25
+ require 'messagebird/voice/webhook'
10
26
  require 'messagebird/voicemessage'
11
- require 'messagebird/lookup'
27
+ require 'messagebird/voice_client'
28
+ require 'messagebird/voice/call'
29
+ require 'messagebird/voice/call_leg'
30
+ require 'messagebird/voice/call_leg_recording'
31
+ require 'messagebird/voice/transcription'
32
+ require 'messagebird/voice/list'
12
33
 
13
34
  module MessageBird
14
35
  class ErrorException < StandardError
@@ -19,49 +40,148 @@ module MessageBird
19
40
  end
20
41
  end
21
42
 
43
+ class InvalidFeatureException < StandardError
44
+ end
45
+
22
46
  class Client
23
- attr_reader :access_key
47
+ attr_reader :access_key, :http_client, :conversation_client, :voice_client
24
48
 
25
- def initialize(access_key = nil)
49
+ def initialize(access_key = nil, http_client = nil, conversation_client = nil, voice_client = nil)
26
50
  @access_key = access_key || ENV['MESSAGEBIRD_ACCESS_KEY']
51
+ @http_client = http_client || HttpClient.new(@access_key)
52
+ @conversation_client = conversation_client || ConversationClient.new(@access_key)
53
+ @number_client = http_client || NumberClient.new(@access_key)
54
+ @voice_client = voice_client || VoiceClient.new(@access_key)
27
55
  end
28
56
 
29
- def request(method, path, params={})
30
- uri = URI.join(ENDPOINT, '/', path)
57
+ def conversation_request(method, path, params = {})
58
+ response_body = @conversation_client.request(method, path, params)
59
+ return if response_body.nil? || response_body.empty?
31
60
 
32
- # Set up the HTTP object.
33
- http = Net::HTTP.new(uri.host, uri.port)
34
- http.use_ssl = true
61
+ parse_body(response_body)
62
+ end
35
63
 
36
- # Construct the HTTP GET or POST request.
37
- request = Net::HTTP::Get.new(uri.request_uri) if method == :get
38
- request = Net::HTTP::Post.new(uri.request_uri) if method == :post
39
- request['Accept'] = 'application/json'
40
- request['Authorization'] = "AccessKey #{@access_key}"
41
- request['User-Agent'] = "MessageBird/ApiClient/#{CLIENT_VERSION} Ruby/#{RUBY_VERSION}"
64
+ def number_request(method, path, params = {})
65
+ response_body = @number_client.request(method, path, params)
66
+ return if response_body.nil? || response_body.empty?
42
67
 
43
- # If present, add the HTTP POST parameters.
44
- request.set_form_data(params) if method == :post && !params.empty?
68
+ parse_body(response_body)
69
+ end
45
70
 
46
- # Execute the request and fetch the response.
47
- response = http.request(request)
71
+ def voice_request(method, path, params = {})
72
+ response_body = @voice_client.request(method, path, params)
73
+ return if response_body.nil? || response_body.empty?
48
74
 
49
- # Parse the HTTP response.
50
- case response.code.to_i
51
- when 200, 201, 204, 401, 404, 405, 422
52
- json = JSON.parse(response.body)
53
- else
54
- raise Net::HTTPServerError.new response.http_version, 'Unknown response from server', response
55
- end
75
+ parse_body(response_body)
76
+ end
77
+
78
+ def request(method, path, params = {})
79
+ response_body = @http_client.request(method, path, params)
80
+ return if response_body.empty?
81
+
82
+ parse_body(response_body)
83
+ end
84
+
85
+ def parse_body(body)
86
+ json = JSON.parse(body)
56
87
 
57
88
  # If the request returned errors, create Error objects and raise.
58
- if json.has_key?('errors')
59
- raise ErrorException, json['errors'].map { |e| Error.new(e) }
89
+ if json.key?('errors')
90
+ raise(ErrorException, json['errors'].map { |e| Error.new(e) })
60
91
  end
61
92
 
62
93
  json
63
94
  end
64
95
 
96
+ ## Conversations
97
+ # Send a conversation message
98
+ def send_conversation_message(from, to, params = {})
99
+ ConversationMessage.new(conversation_request(
100
+ :post,
101
+ 'send',
102
+ params.merge(from: from,
103
+ to: to)
104
+ ))
105
+ end
106
+
107
+ # Start a conversation
108
+ def start_conversation(to, channel_id, params = {})
109
+ Conversation.new(conversation_request(
110
+ :post,
111
+ 'conversations/start',
112
+ params.merge(to: to,
113
+ channel_id: channel_id)
114
+ ))
115
+ end
116
+
117
+ def conversation_list(limit = -1, offset = -1)
118
+ query = '?'
119
+ if limit != -1
120
+ query += "limit=#{limit}&"
121
+ end
122
+
123
+ if offset != -1
124
+ query += "offset=#{offset}"
125
+ end
126
+
127
+ List.new(Conversation, conversation_request(:get, "conversations#{query}"))
128
+ end
129
+
130
+ def conversation(id)
131
+ Conversation.new(conversation_request(:get, "conversations/#{id}"))
132
+ end
133
+
134
+ def conversation_update(id, status)
135
+ Conversation.new(conversation_request(:patch, "conversations/#{id}", status: status))
136
+ end
137
+
138
+ def conversation_reply(id, params = {})
139
+ ConversationMessage.new(conversation_request(:post, "conversations/#{id}/messages", params))
140
+ end
141
+
142
+ def conversation_messages_list(id, limit = -1, offset = -1)
143
+ query = '?'
144
+ if limit != -1
145
+ query += "limit=#{limit}&"
146
+ end
147
+
148
+ if offset != -1
149
+ query += "offset=#{offset}"
150
+ end
151
+
152
+ List.new(ConversationMessage, conversation_request(:get, "conversations/#{id}/messages#{query}"))
153
+ end
154
+
155
+ def conversation_message(id)
156
+ ConversationMessage.new(conversation_request(:get, "messages/#{id}"))
157
+ end
158
+
159
+ def conversation_webhook_create(channel_id, url, events = [])
160
+ ConversationWebhook.new(conversation_request(
161
+ :post,
162
+ 'webhooks',
163
+ channel_id: channel_id,
164
+ url: url,
165
+ events: events
166
+ ))
167
+ end
168
+
169
+ def conversation_webhooks_list(limit = 0, offset = 0)
170
+ List.new(ConversationWebhook, conversation_request(:get, "webhooks?limit=#{limit}&offset=#{offset}"))
171
+ end
172
+
173
+ def conversation_webhook_update(id, params = {})
174
+ ConversationWebhook.new(conversation_request(:patch, "webhooks/#{id}", params))
175
+ end
176
+
177
+ def conversation_webhook(id)
178
+ ConversationWebhook.new(conversation_request(:get, "webhooks/#{id}"))
179
+ end
180
+
181
+ def conversation_webhook_delete(id)
182
+ conversation_request(:delete, "webhooks/#{id}")
183
+ end
184
+
65
185
  # Retrieve your balance.
66
186
  def balance
67
187
  Balance.new(request(:get, 'balance'))
@@ -69,87 +189,314 @@ module MessageBird
69
189
 
70
190
  # Retrieve the information of specific HLR.
71
191
  def hlr(id)
72
- HLR.new(request(:get, "hlr/#{id.to_s}"))
192
+ HLR.new(request(:get, "hlr/#{id}"))
73
193
  end
74
194
 
75
195
  # Create a new HLR.
76
196
  def hlr_create(msisdn, reference)
77
197
  HLR.new(request(
78
- :post,
79
- 'hlr',
80
- :msisdn => msisdn,
81
- :reference => reference))
198
+ :post,
199
+ 'hlr',
200
+ msisdn: msisdn,
201
+ reference: reference
202
+ ))
82
203
  end
83
204
 
84
- # Generate a new One-Time-Password message
85
- def otp_generate(recipient, params={})
86
- OTP.new(request(
87
- :post,
88
- 'otp/generate',
89
- params.merge({
90
- :recipient => recipient
91
- })
92
- ))
205
+ # Retrieve the information of specific Verify.
206
+ def verify(id)
207
+ Verify.new(request(:get, "verify/#{id}"))
93
208
  end
94
209
 
95
- # Verify the One-Time-Password
96
- def otp_verify(recipient, token, params={})
97
- # Set the path to include all the parameters
98
- # Blame Sam Wierema for not adhering to REST principles...
99
- path = 'otp/verify?' + URI.encode_www_form(params.merge({
100
- :recipient => recipient,
101
- :token => token
102
- }))
210
+ # Generate a new One-Time-Password message.
211
+ def verify_create(recipient, params = {})
212
+ Verify.new(request(
213
+ :post,
214
+ 'verify',
215
+ params.merge(recipient: recipient)
216
+ ))
217
+ end
218
+
219
+ # Verify the One-Time-Password.
220
+ def verify_token(id, token)
221
+ Verify.new(request(:get, "verify/#{id}?token=#{token}"))
222
+ end
103
223
 
104
- OTP.new(request(:get, path))
224
+ # Delete a Verify
225
+ def verify_delete(id)
226
+ Verify.new(request(:delete, "verify/#{id}"))
105
227
  end
106
228
 
107
229
  # Retrieve the information of specific message.
108
230
  def message(id)
109
- Message.new(request(:get, "messages/#{id.to_s}"))
231
+ Message.new(request(:get, "messages/#{id}"))
232
+ end
233
+
234
+ # Retrieve messages with optional paging and status filter.
235
+ def message_list(filter = {})
236
+ limit = filter[:limit] || 10
237
+ offset = filter[:offset] || 0
238
+ status = filter[:status] || ''
239
+
240
+ params = { limit: limit, offset: offset }
241
+ if status != ''
242
+ params['status'] = status
243
+ end
244
+ query = 'messages?' + URI.encode_www_form(params)
245
+ List.new(Message, request(:get, query))
110
246
  end
111
247
 
112
248
  # Create a new message.
113
- def message_create(originator, recipients, body, params={})
249
+ def message_create(originator, recipients, body, params = {})
114
250
  # Convert an array of recipients to a comma-separated string.
115
- recipients = recipients.join(',') if recipients.kind_of?(Array)
251
+ recipients = recipients.join(',') if recipients.is_a?(Array)
116
252
 
117
253
  Message.new(request(
118
- :post,
119
- 'messages',
120
- params.merge({
121
- :originator => originator.to_s,
122
- :body => body.to_s,
123
- :recipients => recipients })))
254
+ :post,
255
+ 'messages',
256
+ params.merge(originator: originator.to_s,
257
+ body: body.to_s,
258
+ recipients: recipients)
259
+ ))
124
260
  end
125
261
 
126
262
  # Retrieve the information of a specific voice message.
127
263
  def voice_message(id)
128
- VoiceMessage.new(request(:get, "voicemessages/#{id.to_s}"))
264
+ VoiceMessage.new(request(:get, "voicemessages/#{id}"))
129
265
  end
130
266
 
131
267
  # Create a new voice message.
132
- def voice_message_create(recipients, body, params={})
268
+ def voice_message_create(recipients, body, params = {})
133
269
  # Convert an array of recipients to a comma-separated string.
134
- recipients = recipients.join(',') if recipients.kind_of?(Array)
270
+ recipients = recipients.join(',') if recipients.is_a?(Array)
135
271
 
136
272
  VoiceMessage.new(request(
137
- :post,
138
- 'voicemessages',
139
- params.merge({ :recipients => recipients, :body => body.to_s })))
273
+ :post,
274
+ 'voicemessages',
275
+ params.merge(recipients: recipients, body: body.to_s)
276
+ ))
277
+ end
278
+
279
+ def voice_webhook_create(url, params = {})
280
+ Voice::Webhook.new(voice_request(:post, 'webhooks', params.merge(url: url)))
281
+ end
282
+
283
+ def voice_webhooks_list(per_page = VoiceList::PER_PAGE, page = VoiceList::CURRENT_PAGE)
284
+ Voice::List.new(Voice::Webhook, voice_request(:get, "webhooks?perPage=#{per_page}&page=#{page}"))
285
+ end
286
+
287
+ def voice_webhook_update(id, params = {})
288
+ Voice::Webhook.new(voice_request(:put, "webhooks/#{id}", params))
289
+ end
290
+
291
+ def voice_webhook(id)
292
+ Voice::Webhook.new(voice_request(:get, "webhooks/#{id}"))
293
+ end
294
+
295
+ def voice_webhook_delete(id)
296
+ voice_request(:delete, "webhooks/#{id}")
297
+ end
298
+
299
+ def call_create(source, destination, call_flow = {}, webhook = {}, params = {})
300
+ params = params.merge(callFlow: call_flow.to_json) unless call_flow.empty?
301
+ params = params.merge(webhook: webhook.to_json) unless webhook.empty?
302
+
303
+ Voice::Call.new(voice_request(:post, 'calls', params.merge(source: source, destination: destination)))
304
+ end
305
+
306
+ def call_list(per_page = Voice::List::PER_PAGE, page = Voice::List::CURRENT_PAGE)
307
+ Voice::List.new(Voice::Call, voice_request(:get, "calls?perPage=#{per_page}&currentPage=#{page}"))
308
+ end
309
+
310
+ def call_view(id)
311
+ Voice::Call.new(voice_request(:get, "calls/#{id}"))
312
+ end
313
+
314
+ def call_delete(id)
315
+ voice_request(:delete, "calls/#{id}")
316
+ end
317
+
318
+ def call_leg_list(call_id, per_page = Voice::List::PER_PAGE, current_page = Voice::List::CURRENT_PAGE)
319
+ Voice::List.new(Voice::CallLeg, voice_request(:get, "calls/#{call_id}/legs?perPage=#{per_page}&currentPage=#{current_page}"))
320
+ end
321
+
322
+ def call_leg_recording_view(call_id, leg_id, recording_id)
323
+ Voice::CallLegRecording.new(voice_request(:get, "calls/#{call_id}/legs/#{leg_id}/recordings/#{recording_id}"))
324
+ end
325
+
326
+ def call_leg_recording_list(call_id, leg_id)
327
+ Voice::List.new(Voice::CallLegRecording, voice_request(:get, "calls/#{call_id}/legs/#{leg_id}/recordings"))
328
+ end
329
+
330
+ def call_leg_recording_delete(call_id, leg_id, recording_id)
331
+ voice_request(:delete, "calls/#{call_id}/legs/#{leg_id}/recordings/#{recording_id}")
332
+ end
333
+
334
+ def call_leg_recording_download(recording_uri, &block)
335
+ @voice_client.request_block(:get, recording_uri, {}, &block)
336
+ end
337
+
338
+ def voice_transcription_create(call_id, leg_id, recording_id, params = {})
339
+ Voice::Transcription.new(voice_request(:post, "calls/#{call_id}/legs/#{leg_id}/recordings/#{recording_id}/transcriptions", params))
340
+ end
341
+
342
+ def voice_transcriptions_list(call_id, leg_id, recording_id)
343
+ Voice::List.new(Voice::Transcription, voice_request(:get, "calls/#{call_id}/legs/#{leg_id}/recordings/#{recording_id}/transcriptions"))
344
+ end
345
+
346
+ def voice_transcription_download(call_id, leg_id, recording_id, transcription_id, &block)
347
+ @voice_client.request_block(:get, "calls/#{call_id}/legs/#{leg_id}/recordings/#{recording_id}/transcriptions/#{transcription_id}.txt", {}, &block)
348
+ end
349
+
350
+ def voice_transcription_view(call_id, leg_id, recording_id, transcription_id)
351
+ Voice::Transcription.new(voice_request(:get, "calls/#{call_id}/legs/#{leg_id}/recordings/#{recording_id}/transcriptions/#{transcription_id}"))
352
+ end
353
+
354
+ def lookup(phone_number, params = {})
355
+ Lookup.new(request(:get, "lookup/#{phone_number}", params))
356
+ end
357
+
358
+ def lookup_hlr_create(phone_number, params = {})
359
+ HLR.new(request(:post, "lookup/#{phone_number}/hlr", params))
360
+ end
361
+
362
+ def lookup_hlr(phone_number, params = {})
363
+ HLR.new(request(:get, "lookup/#{phone_number}/hlr", params))
364
+ end
365
+
366
+ def contact_create(phone_number, params = {})
367
+ Contact.new(request(
368
+ :post,
369
+ 'contacts',
370
+ params.merge(msisdn: phone_number.to_s)
371
+ ))
372
+ end
373
+
374
+ def contact(id)
375
+ Contact.new(request(:get, "contacts/#{id}"))
376
+ end
377
+
378
+ def contact_delete(id)
379
+ request(:delete, "contacts/#{id}")
380
+ end
381
+
382
+ def contact_update(id, params = {})
383
+ request(:patch, "contacts/#{id}", params)
384
+ end
385
+
386
+ def contact_list(limit = 0, offset = 0)
387
+ List.new(Contact, request(:get, "contacts?limit=#{limit}&offset=#{offset}"))
388
+ end
389
+
390
+ def group(id)
391
+ Group.new(request(:get, "groups/#{id}"))
392
+ end
393
+
394
+ def group_create(name)
395
+ Group.new(request(:post, 'groups', name: name))
396
+ end
397
+
398
+ def group_delete(id)
399
+ request(:delete, "groups/#{id}")
400
+ end
401
+
402
+ def group_list(limit = 0, offset = 0)
403
+ List.new(Group, request(:get, "groups?limit=#{limit}&offset=#{offset}"))
404
+ end
405
+
406
+ def group_update(id, name)
407
+ request(:patch, "groups/#{id}", name: name)
408
+ end
409
+
410
+ def group_add_contacts(group_id, contact_ids)
411
+ # We expect an array, but we can handle a string ID as well...
412
+ contact_ids = [contact_ids] if contact_ids.is_a? String
413
+
414
+ query = add_contacts_query(contact_ids)
415
+
416
+ request(:get, "groups/#{group_id}?#{query}")
417
+ end
418
+
419
+ def group_delete_contact(group_id, contact_id)
420
+ request(:delete, "groups/#{group_id}/contacts/#{contact_id}")
421
+ end
422
+
423
+ ## Numbers API
424
+ # Search for available numbers
425
+ def number_search(country_code, params = {})
426
+ List.new(Number, number_request(:get, add_querystring("available-phone-numbers/#{country_code}", params), params))
427
+ end
428
+
429
+ # Purchase an avaiable number
430
+ def number_purchase(number, country_code, billing_interval_months)
431
+ params = {
432
+ number: number,
433
+ countryCode: country_code,
434
+ billingIntervalMonths: billing_interval_months
435
+ }
436
+ Number.new(number_request(:post, 'phone-numbers', params))
437
+ end
438
+
439
+ # Fetch all purchaed numbers' details
440
+ def number_fetch_all(params = {})
441
+ List.new(Number, number_request(:get, add_querystring('phone-numbers', params), params))
442
+ end
443
+
444
+ # Fetch specific purchased number's details
445
+ def number_fetch(number)
446
+ Number.new(number_request(:get, "phone-numbers/#{number}"))
447
+ end
448
+
449
+ # Update a number
450
+ def number_update(number, tags)
451
+ tags = [tags] if tags.is_a? String
452
+ Number.new(number_request(:patch, "phone-numbers/#{number}", tags: tags))
453
+ end
454
+
455
+ # Cancel a number
456
+ def number_cancel(number)
457
+ number_request(:delete, "phone-numbers/#{number}")
140
458
  end
141
459
 
142
- def lookup(phoneNumber, params={})
143
- Lookup.new(request(:get, "lookup/#{phoneNumber}", params))
144
- end
460
+ def call_flow_create(title, steps, default, record, params = {})
461
+ params = params.merge(
462
+ title: title,
463
+ steps: steps,
464
+ default: default,
465
+ record: record
466
+ )
467
+ CallFlow.new(voice_request(:post, 'call-flows', params))
468
+ end
469
+
470
+ def call_flow_view(id)
471
+ CallFlow.new(voice_request(:get, "call-flows/#{id}"))
472
+ end
145
473
 
146
- def lookup_hlr_create(phoneNumber, params={})
147
- HLR.new(request(:post, "lookup/#{phoneNumber}/hlr", params))
474
+ def call_flow_list(per_page = CallFlowList::PER_PAGE, page = CallFlowList::CURRENT_PAGE)
475
+ CallFlowList.new(CallFlow, voice_request(:get, "call-flows?perPage=#{per_page}&page=#{page}"))
148
476
  end
149
477
 
150
- def lookup_hlr(phoneNumber, params={})
151
- HLR.new(request(:get, "lookup/#{phoneNumber}/hlr", params))
478
+ def call_flow_delete(id)
479
+ voice_request(:delete, "call-flows/#{id}")
152
480
  end
153
481
 
482
+ private # Applies to every method below this line
483
+
484
+ # Applies to every method below this line
485
+ def add_contacts_query(contact_ids)
486
+ # add_contacts_query gets a query string to add contacts to a group.
487
+ # We're using the alternative "/foo?_method=PUT&key=value" format to send
488
+ # the contact IDs as GET params. Sending these in the request body would
489
+ # require a painful workaround, as the client sends request bodies as
490
+ # JSON by default. See also:
491
+ # https://developers.messagebird.com/docs/alternatives.
492
+
493
+ '_method=PUT&' + contact_ids.map { |id| "ids[]=#{id}" }.join('&')
494
+ end
495
+
496
+ def add_querystring(path, params)
497
+ return path if params.empty?
498
+
499
+ "#{path}?" + params.collect { |k, v| v.is_a?(Array) ? v.collect { |sv| "#{k}=#{sv}" }.join('&') : "#{k}=#{v}" }.join('&')
500
+ end
154
501
  end
155
502
  end