messagebird-rest 1.3.3 → 2.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +58 -8
  3. data/lib/messagebird.rb +15 -6
  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 +400 -64
  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 +8 -6
  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 +79 -9
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 4726ce8ee0e2583a41d1f73a7e6866dda139fb14
4
- data.tar.gz: 484cd5e20ed84a89ea58e969289e58daa2d02bdd
2
+ SHA256:
3
+ metadata.gz: 3fde70fc0a75d2f007d9c317974f657973264297eab5ff2f0b2a0f959e30d2d2
4
+ data.tar.gz: cb9bad90faa280eeea6a127fc8885bb63bf3eeb6dd607eb3483f27be3469ff3c
5
5
  SHA512:
6
- metadata.gz: 79a490c8dd3d3af74ff5ab0bb45209982f35dae182fc6b83cb90177e5b75a60afd36c56bb4285f0affbc1fff15cc7eacf0542e88a1fe742fc88c5a39eee11985
7
- data.tar.gz: 6869c83755659c52549eee08b411076a42ed4c469d7ba1b8016f1b3b1668e681db46d8439ac32c2fcb32054207db9a51cdbf76d57c76ddf3d352af121c6ef26b
6
+ metadata.gz: 1ede3f901990e717e00ce5765d9df78edf7797663f2211da70a4ae37d0c1a7b339a6d0f91b6f462563bf2c4ded69f227987da630e5d4dcb2c87b9017790a0e70
7
+ data.tar.gz: 29866e1b73c36d108604860a13d1434f2cf85b0905ef21d485e5114c8dd6bb8b4aa640bb1ceba0c472691e5225c4904cde9b312ef7427d0a107b59b5c4bbe2ed
data/README.md CHANGED
@@ -2,6 +2,8 @@ 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
9
  - [Sign up](https://dashboard.messagebird.com/app/en/sign-up) for a free MessageBird account
@@ -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,
@@ -124,7 +126,7 @@ client.verify_create(31612345678, {:reference => "YourReference"})
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
 
@@ -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.3'
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/http_client'
14
+ require 'messagebird/message_reference'
15
+ require 'messagebird/signed_request'
13
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/verify'
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,51 +40,148 @@ module MessageBird
19
40
  end
20
41
  end
21
42
 
22
- class InvalidPhoneNumberException < TypeError; end
43
+ class InvalidFeatureException < StandardError
44
+ end
23
45
 
24
46
  class Client
25
- attr_reader :access_key
47
+ attr_reader :access_key, :http_client, :conversation_client, :voice_client
26
48
 
27
- def initialize(access_key = nil)
49
+ def initialize(access_key = nil, http_client = nil, conversation_client = nil, voice_client = nil)
28
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)
29
55
  end
30
56
 
31
- def request(method, path, params={})
32
- 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?
33
60
 
34
- # Set up the HTTP object.
35
- http = Net::HTTP.new(uri.host, uri.port)
36
- http.use_ssl = true
61
+ parse_body(response_body)
62
+ end
37
63
 
38
- # Construct the HTTP GET or POST request.
39
- request = Net::HTTP::Get.new(uri.request_uri) if method == :get
40
- request = Net::HTTP::Post.new(uri.request_uri) if method == :post
41
- request['Accept'] = 'application/json'
42
- request['Authorization'] = "AccessKey #{@access_key}"
43
- 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?
44
67
 
45
- # If present, add the HTTP POST parameters.
46
- request.set_form_data(params) if method == :post && !params.empty?
68
+ parse_body(response_body)
69
+ end
47
70
 
48
- # Execute the request and fetch the response.
49
- 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?
50
74
 
51
- # Parse the HTTP response.
52
- case response.code.to_i
53
- when 200, 201, 204, 401, 404, 405, 422
54
- json = JSON.parse(response.body)
55
- else
56
- raise InvalidPhoneNumberException, 'Unknown response from server'
57
- 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)
58
87
 
59
88
  # If the request returned errors, create Error objects and raise.
60
- if json.has_key?('errors')
61
- raise ErrorException, json['errors'].map { |e| Error.new(e) }
89
+ if json.key?('errors')
90
+ raise(ErrorException, json['errors'].map { |e| Error.new(e) })
62
91
  end
63
92
 
64
93
  json
65
94
  end
66
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
+
67
185
  # Retrieve your balance.
68
186
  def balance
69
187
  Balance.new(request(:get, 'balance'))
@@ -71,90 +189,308 @@ module MessageBird
71
189
 
72
190
  # Retrieve the information of specific HLR.
73
191
  def hlr(id)
74
- HLR.new(request(:get, "hlr/#{id.to_s}"))
192
+ HLR.new(request(:get, "hlr/#{id}"))
75
193
  end
76
194
 
77
195
  # Create a new HLR.
78
196
  def hlr_create(msisdn, reference)
79
197
  HLR.new(request(
80
- :post,
81
- 'hlr',
82
- :msisdn => msisdn,
83
- :reference => reference))
198
+ :post,
199
+ 'hlr',
200
+ msisdn: msisdn,
201
+ reference: reference
202
+ ))
84
203
  end
85
204
 
86
205
  # Retrieve the information of specific Verify.
87
206
  def verify(id)
88
- Verify.new(request(:get, "verify/#{id.to_s}"))
207
+ Verify.new(request(:get, "verify/#{id}"))
89
208
  end
90
209
 
91
210
  # Generate a new One-Time-Password message.
92
- def verify_create(recipient, params={})
211
+ def verify_create(recipient, params = {})
93
212
  Verify.new(request(
94
- :post,
95
- 'verify',
96
- params.merge({
97
- :recipient => recipient
98
- })
213
+ :post,
214
+ 'verify',
215
+ params.merge(recipient: recipient)
99
216
  ))
100
217
  end
101
218
 
102
219
  # Verify the One-Time-Password.
103
220
  def verify_token(id, token)
104
- Verify.new(request(:get, "verify/#{id.to_s}?token=#{token}"))
221
+ Verify.new(request(:get, "verify/#{id}?token=#{token}"))
105
222
  end
106
223
 
107
224
  # Delete a Verify
108
225
  def verify_delete(id)
109
- Verify.new(request(:delete, "verify/#{id.to_s}"))
226
+ Verify.new(request(:delete, "verify/#{id}"))
110
227
  end
111
228
 
112
229
  # Retrieve the information of specific message.
113
230
  def message(id)
114
- 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(filters = {})
236
+ params = { limit: 10, offset: 0 }.merge(filters).compact
237
+ query = "messages?#{URI.encode_www_form(params)}"
238
+
239
+ List.new(Message, request(:get, query))
115
240
  end
116
241
 
117
242
  # Create a new message.
118
- def message_create(originator, recipients, body, params={})
243
+ def message_create(originator, recipients, body, params = {})
119
244
  # Convert an array of recipients to a comma-separated string.
120
- recipients = recipients.join(',') if recipients.kind_of?(Array)
245
+ recipients = recipients.join(',') if recipients.is_a?(Array)
121
246
 
122
247
  Message.new(request(
123
- :post,
124
- 'messages',
125
- params.merge({
126
- :originator => originator.to_s,
127
- :body => body.to_s,
128
- :recipients => recipients })))
248
+ :post,
249
+ 'messages',
250
+ params.merge(originator: originator.to_s,
251
+ body: body.to_s,
252
+ recipients: recipients)
253
+ ))
129
254
  end
130
255
 
131
256
  # Retrieve the information of a specific voice message.
132
257
  def voice_message(id)
133
- VoiceMessage.new(request(:get, "voicemessages/#{id.to_s}"))
258
+ VoiceMessage.new(request(:get, "voicemessages/#{id}"))
134
259
  end
135
260
 
136
261
  # Create a new voice message.
137
- def voice_message_create(recipients, body, params={})
262
+ def voice_message_create(recipients, body, params = {})
138
263
  # Convert an array of recipients to a comma-separated string.
139
- recipients = recipients.join(',') if recipients.kind_of?(Array)
264
+ recipients = recipients.join(',') if recipients.is_a?(Array)
140
265
 
141
266
  VoiceMessage.new(request(
142
- :post,
143
- 'voicemessages',
144
- params.merge({ :recipients => recipients, :body => body.to_s })))
267
+ :post,
268
+ 'voicemessages',
269
+ params.merge(recipients: recipients, body: body.to_s)
270
+ ))
271
+ end
272
+
273
+ def voice_webhook_create(url, params = {})
274
+ Voice::Webhook.new(voice_request(:post, 'webhooks', params.merge(url: url)))
275
+ end
276
+
277
+ def voice_webhooks_list(per_page = VoiceList::PER_PAGE, page = VoiceList::CURRENT_PAGE)
278
+ Voice::List.new(Voice::Webhook, voice_request(:get, "webhooks?perPage=#{per_page}&page=#{page}"))
279
+ end
280
+
281
+ def voice_webhook_update(id, params = {})
282
+ Voice::Webhook.new(voice_request(:put, "webhooks/#{id}", params))
283
+ end
284
+
285
+ def voice_webhook(id)
286
+ Voice::Webhook.new(voice_request(:get, "webhooks/#{id}"))
287
+ end
288
+
289
+ def voice_webhook_delete(id)
290
+ voice_request(:delete, "webhooks/#{id}")
291
+ end
292
+
293
+ def call_create(source, destination, call_flow = {}, webhook = {}, params = {})
294
+ params = params.merge(callFlow: call_flow.to_json) unless call_flow.empty?
295
+ params = params.merge(webhook: webhook.to_json) unless webhook.empty?
296
+
297
+ Voice::Call.new(voice_request(:post, 'calls', params.merge(source: source, destination: destination)))
298
+ end
299
+
300
+ def call_list(per_page = Voice::List::PER_PAGE, page = Voice::List::CURRENT_PAGE)
301
+ Voice::List.new(Voice::Call, voice_request(:get, "calls?perPage=#{per_page}&currentPage=#{page}"))
302
+ end
303
+
304
+ def call_view(id)
305
+ Voice::Call.new(voice_request(:get, "calls/#{id}"))
145
306
  end
146
307
 
147
- def lookup(phoneNumber, params={})
148
- Lookup.new(request(:get, "lookup/#{phoneNumber}", params))
308
+ def call_delete(id)
309
+ voice_request(:delete, "calls/#{id}")
149
310
  end
150
311
 
151
- def lookup_hlr_create(phoneNumber, params={})
152
- HLR.new(request(:post, "lookup/#{phoneNumber}/hlr", params))
312
+ def call_leg_list(call_id, per_page = Voice::List::PER_PAGE, current_page = Voice::List::CURRENT_PAGE)
313
+ Voice::List.new(Voice::CallLeg, voice_request(:get, "calls/#{call_id}/legs?perPage=#{per_page}&currentPage=#{current_page}"))
153
314
  end
154
315
 
155
- def lookup_hlr(phoneNumber, params={})
156
- HLR.new(request(:get, "lookup/#{phoneNumber}/hlr", params))
316
+ def call_leg_recording_view(call_id, leg_id, recording_id)
317
+ Voice::CallLegRecording.new(voice_request(:get, "calls/#{call_id}/legs/#{leg_id}/recordings/#{recording_id}"))
157
318
  end
158
319
 
320
+ def call_leg_recording_list(call_id, leg_id)
321
+ Voice::List.new(Voice::CallLegRecording, voice_request(:get, "calls/#{call_id}/legs/#{leg_id}/recordings"))
322
+ end
323
+
324
+ def call_leg_recording_delete(call_id, leg_id, recording_id)
325
+ voice_request(:delete, "calls/#{call_id}/legs/#{leg_id}/recordings/#{recording_id}")
326
+ end
327
+
328
+ def call_leg_recording_download(recording_uri, &block)
329
+ @voice_client.request_block(:get, recording_uri, {}, &block)
330
+ end
331
+
332
+ def voice_transcription_create(call_id, leg_id, recording_id, params = {})
333
+ Voice::Transcription.new(voice_request(:post, "calls/#{call_id}/legs/#{leg_id}/recordings/#{recording_id}/transcriptions", params))
334
+ end
335
+
336
+ def voice_transcriptions_list(call_id, leg_id, recording_id)
337
+ Voice::List.new(Voice::Transcription, voice_request(:get, "calls/#{call_id}/legs/#{leg_id}/recordings/#{recording_id}/transcriptions"))
338
+ end
339
+
340
+ def voice_transcription_download(call_id, leg_id, recording_id, transcription_id, &block)
341
+ @voice_client.request_block(:get, "calls/#{call_id}/legs/#{leg_id}/recordings/#{recording_id}/transcriptions/#{transcription_id}.txt", {}, &block)
342
+ end
343
+
344
+ def voice_transcription_view(call_id, leg_id, recording_id, transcription_id)
345
+ Voice::Transcription.new(voice_request(:get, "calls/#{call_id}/legs/#{leg_id}/recordings/#{recording_id}/transcriptions/#{transcription_id}"))
346
+ end
347
+
348
+ def lookup(phone_number, params = {})
349
+ Lookup.new(request(:get, "lookup/#{phone_number}", params))
350
+ end
351
+
352
+ def lookup_hlr_create(phone_number, params = {})
353
+ HLR.new(request(:post, "lookup/#{phone_number}/hlr", params))
354
+ end
355
+
356
+ def lookup_hlr(phone_number, params = {})
357
+ HLR.new(request(:get, "lookup/#{phone_number}/hlr", params))
358
+ end
359
+
360
+ def contact_create(phone_number, params = {})
361
+ Contact.new(request(
362
+ :post,
363
+ 'contacts',
364
+ params.merge(msisdn: phone_number.to_s)
365
+ ))
366
+ end
367
+
368
+ def contact(id)
369
+ Contact.new(request(:get, "contacts/#{id}"))
370
+ end
371
+
372
+ def contact_delete(id)
373
+ request(:delete, "contacts/#{id}")
374
+ end
375
+
376
+ def contact_update(id, params = {})
377
+ request(:patch, "contacts/#{id}", params)
378
+ end
379
+
380
+ def contact_list(limit = 0, offset = 0)
381
+ List.new(Contact, request(:get, "contacts?limit=#{limit}&offset=#{offset}"))
382
+ end
383
+
384
+ def group(id)
385
+ Group.new(request(:get, "groups/#{id}"))
386
+ end
387
+
388
+ def group_create(name)
389
+ Group.new(request(:post, 'groups', name: name))
390
+ end
391
+
392
+ def group_delete(id)
393
+ request(:delete, "groups/#{id}")
394
+ end
395
+
396
+ def group_list(limit = 0, offset = 0)
397
+ List.new(Group, request(:get, "groups?limit=#{limit}&offset=#{offset}"))
398
+ end
399
+
400
+ def group_update(id, name)
401
+ request(:patch, "groups/#{id}", name: name)
402
+ end
403
+
404
+ def group_add_contacts(group_id, contact_ids)
405
+ # We expect an array, but we can handle a string ID as well...
406
+ contact_ids = [contact_ids] if contact_ids.is_a? String
407
+
408
+ query = add_contacts_query(contact_ids)
409
+
410
+ request(:get, "groups/#{group_id}?#{query}")
411
+ end
412
+
413
+ def group_delete_contact(group_id, contact_id)
414
+ request(:delete, "groups/#{group_id}/contacts/#{contact_id}")
415
+ end
416
+
417
+ ## Numbers API
418
+ # Search for available numbers
419
+ def number_search(country_code, params = {})
420
+ List.new(Number, number_request(:get, add_querystring("available-phone-numbers/#{country_code}", params), params))
421
+ end
422
+
423
+ # Purchase an avaiable number
424
+ def number_purchase(number, country_code, billing_interval_months)
425
+ params = {
426
+ number: number,
427
+ countryCode: country_code,
428
+ billingIntervalMonths: billing_interval_months
429
+ }
430
+ Number.new(number_request(:post, 'phone-numbers', params))
431
+ end
432
+
433
+ # Fetch all purchaed numbers' details
434
+ def number_fetch_all(params = {})
435
+ List.new(Number, number_request(:get, add_querystring('phone-numbers', params), params))
436
+ end
437
+
438
+ # Fetch specific purchased number's details
439
+ def number_fetch(number)
440
+ Number.new(number_request(:get, "phone-numbers/#{number}"))
441
+ end
442
+
443
+ # Update a number
444
+ def number_update(number, tags)
445
+ tags = [tags] if tags.is_a? String
446
+ Number.new(number_request(:patch, "phone-numbers/#{number}", tags: tags))
447
+ end
448
+
449
+ # Cancel a number
450
+ def number_cancel(number)
451
+ number_request(:delete, "phone-numbers/#{number}")
452
+ end
453
+
454
+ def call_flow_create(title, steps, default, record, params = {})
455
+ params = params.merge(
456
+ title: title,
457
+ steps: steps,
458
+ default: default,
459
+ record: record
460
+ )
461
+ CallFlow.new(voice_request(:post, 'call-flows', params))
462
+ end
463
+
464
+ def call_flow_view(id)
465
+ CallFlow.new(voice_request(:get, "call-flows/#{id}"))
466
+ end
467
+
468
+ def call_flow_list(per_page = CallFlowList::PER_PAGE, page = CallFlowList::CURRENT_PAGE)
469
+ CallFlowList.new(CallFlow, voice_request(:get, "call-flows?perPage=#{per_page}&page=#{page}"))
470
+ end
471
+
472
+ def call_flow_delete(id)
473
+ voice_request(:delete, "call-flows/#{id}")
474
+ end
475
+
476
+ private # Applies to every method below this line
477
+
478
+ # Applies to every method below this line
479
+ def add_contacts_query(contact_ids)
480
+ # add_contacts_query gets a query string to add contacts to a group.
481
+ # We're using the alternative "/foo?_method=PUT&key=value" format to send
482
+ # the contact IDs as GET params. Sending these in the request body would
483
+ # require a painful workaround, as the client sends request bodies as
484
+ # JSON by default. See also:
485
+ # https://developers.messagebird.com/docs/alternatives.
486
+
487
+ '_method=PUT&' + contact_ids.map { |id| "ids[]=#{id}" }.join('&')
488
+ end
489
+
490
+ def add_querystring(path, params)
491
+ return path if params.empty?
492
+
493
+ "#{path}?" + params.collect { |k, v| v.is_a?(Array) ? v.collect { |sv| "#{k}=#{sv}" }.join('&') : "#{k}=#{v}" }.join('&')
494
+ end
159
495
  end
160
496
  end