messagebird-rest 1.3.2 → 2.0.0

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