vivialconnect 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/lib/vivialconnect.rb +14 -0
- data/lib/vivialconnect/account.rb +278 -0
- data/lib/vivialconnect/attachment.rb +74 -0
- data/lib/vivialconnect/client.rb +326 -0
- data/lib/vivialconnect/configuration.rb +172 -0
- data/lib/vivialconnect/contact.rb +4 -0
- data/lib/vivialconnect/log.rb +71 -0
- data/lib/vivialconnect/message.rb +222 -0
- data/lib/vivialconnect/number.rb +296 -0
- data/lib/vivialconnect/resource.rb +261 -0
- data/lib/vivialconnect/user.rb +158 -0
- data/lib/vivialconnect/version.rb +3 -0
- data/lib/vivialconnect/vivial_connect_error.rb +2 -0
- metadata +170 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 828c9a5c3422698044222a0d637bf1993c27014e
|
4
|
+
data.tar.gz: ac62e677b700bb6a7a653ea44d0fcf76933001c8
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: f2a45113770f5c43391cef5484983713f24ecd6f69717c1f2b88c2844ad72bc49fc85ca030c9c651446c6ad36669808eecef8c200dc3c952314bcc31fccdb816
|
7
|
+
data.tar.gz: 3363eb281a9da8c0bfe760843b80ace6d0705138fa136ef64502dd27a7e53a1bc2489f539cb494f72af7180b5aae7fb2343f7237aaf0b92110934b9967003bba
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'vivialconnect/version'
|
3
|
+
require 'vivialconnect/client'
|
4
|
+
require 'vivialconnect/resource'
|
5
|
+
require 'vivialconnect/message'
|
6
|
+
require 'vivialconnect/account'
|
7
|
+
require 'vivialconnect/user'
|
8
|
+
require 'vivialconnect/attachment'
|
9
|
+
require 'vivialconnect/configuration'
|
10
|
+
require 'vivialconnect/number'
|
11
|
+
require 'vivialconnect/log'
|
12
|
+
require 'vivialconnect/contact'
|
13
|
+
require 'vivialconnect/vivial_connect_error'
|
14
|
+
|
@@ -0,0 +1,278 @@
|
|
1
|
+
module VivialConnect
|
2
|
+
##
|
3
|
+
#=== .add_main_contact_to_subaccount(options={})
|
4
|
+
#
|
5
|
+
#Creates a new contact and adds it as the main contact to a subaccount.
|
6
|
+
#
|
7
|
+
# Required parameters:
|
8
|
+
#
|
9
|
+
# account_id | Fixnum | 123456 (subaccount id)
|
10
|
+
# company_name | String | "App Developer Inc."
|
11
|
+
# first_name | String | "Bob"
|
12
|
+
# last_name | String | "Tester"
|
13
|
+
# email | String | "btester@vivialconnect"
|
14
|
+
#
|
15
|
+
#
|
16
|
+
# Optional parameters:
|
17
|
+
#
|
18
|
+
# address1 | String | "500 Office Building Ln"
|
19
|
+
# address2 | String | "Suite 300"
|
20
|
+
# address3 | String | "c/o Front Desk"
|
21
|
+
# city | String | "Columbia Heights"
|
22
|
+
# country | String | "United States"
|
23
|
+
# state | String | "Minnesota"
|
24
|
+
# postal_code | String | "55421"
|
25
|
+
# title | String | "CMO"
|
26
|
+
# work_phone | String | "+1XXXXXXXXXX"
|
27
|
+
# mobile_phone | String | "+1XXXXXXXXXX"
|
28
|
+
# fax | String | "+1XXXXXXXXXX"
|
29
|
+
#
|
30
|
+
# Example Usage
|
31
|
+
#
|
32
|
+
#
|
33
|
+
# VivialConnect::Account.add_main_contact_to_subaccount(email: "btester@vivialconnect", contact_type:"main", company_name: "Acme")
|
34
|
+
# => #<VivialConnect::Contact account_id=1XXXX, active=true, address1=nil, address2=nil, address3=nil, city=nil, company_name="Acme", contact_type="main", country="United States", date_created="2017-04-21T10:51:50-04:00", date_modified="2017-04-21T10:51:50-04:00", email="btester@vivialconnect", fax=nil, first_name="Bob", id=89, last_name="Tester", mobile_phone=nil, postal_code="55421", state=nil, title=nil, work_phone="+1XXXXXXXXXX">
|
35
|
+
#
|
36
|
+
#
|
37
|
+
##
|
38
|
+
#=== .add_user_to_subaccount(options={})
|
39
|
+
#
|
40
|
+
#Creates a new User and adds it to a subaccount.
|
41
|
+
#
|
42
|
+
#
|
43
|
+
# Required parameters:
|
44
|
+
#
|
45
|
+
#
|
46
|
+
# first_name | String | "Bob"
|
47
|
+
# last_name | String | "Tester"
|
48
|
+
# email | String | "btester@vivialconnect"
|
49
|
+
# username | String | "btester"
|
50
|
+
# password | String | "dlrowolleh"
|
51
|
+
#
|
52
|
+
#
|
53
|
+
# Example Usage
|
54
|
+
#
|
55
|
+
#
|
56
|
+
# VivialConnect::Account.add_user_to_subaccount(account_id: 1XXXX, email: "btester@vivialconnect.net", username: "btester", first_name: "Bob", last_name: "Tester", password: "XXXXXXX")
|
57
|
+
# => #<VivialConnect::User account_id=1XXXX, active=true, api_key="XYZYXZYXYZXYXZYXZYXYZYXYZYXYZYXYZYX", date_created="2017-04-21T11:27:16-04:00", date_modified="2017-04-21T11:27:16-04:00", email="btester@vivialconnect.net", first_name="Bob", id=10093, last_name="Tester", roles=[{"active"=>true, "date_created"=>"2016-09-30T19:42:59-04:00", "date_modified"=>"2016-09-30T19:42:59-04:00", "description"=>"User role", "id"=>4, "name"=>"User", "role_type"=>"client"}], timezone="US/Eastern", username="btester", verified=false>
|
58
|
+
#
|
59
|
+
# Note: This method triggers an email to the created user's account. They need to answer this confirmation email before they will be able to log in.
|
60
|
+
##
|
61
|
+
#=== .all
|
62
|
+
#
|
63
|
+
#Returns an array containing ruby objects corresponding to all Account resources associated with your account i.e. main account and associated subaccounts
|
64
|
+
#
|
65
|
+
#
|
66
|
+
# Example usage:
|
67
|
+
#
|
68
|
+
#
|
69
|
+
# VivialConnect::Account.all
|
70
|
+
# => [#<VivialConnect::Account>, #<VivialConnect::Account>, #<VivialConnect::Account>]
|
71
|
+
#
|
72
|
+
#
|
73
|
+
#=== .count
|
74
|
+
#
|
75
|
+
#Returns the amount of Accounts associated with your account
|
76
|
+
#
|
77
|
+
# Example usage:
|
78
|
+
#
|
79
|
+
#
|
80
|
+
# VivialConnect::Account.count
|
81
|
+
# => 5
|
82
|
+
#
|
83
|
+
#
|
84
|
+
##
|
85
|
+
#=== .create(options={})
|
86
|
+
#
|
87
|
+
#Creates a subaccount tied to your main account
|
88
|
+
#
|
89
|
+
#
|
90
|
+
# Required parameters:
|
91
|
+
#
|
92
|
+
#
|
93
|
+
# company_name | String | "App Developer Inc."
|
94
|
+
#
|
95
|
+
#
|
96
|
+
# Example Usage
|
97
|
+
#
|
98
|
+
#
|
99
|
+
# VivialConnect::Account.create(company_name: "App Developer Inc.")
|
100
|
+
# => #<VivialConnect::Account account_id=1XXXX, accounts=[], active=true, company_name="App Developer Inc.", contacts=[], date_created="2017-04-20T17:07:08-04:00", date_modified="2017-04-20T17:07:08-04:00", id=10086, services=[{"active"=>true, "date_created"=>"2016-09-30T19:42:58-04:00", "date_modified"=>"2016-09-30T19:42:58-04:00", "description"=>"SMS service", "id"=>1, "name"=>"sms", "service_type"=>"client"}, {"active"=>true, "date_created"=>"2016-09-30T19:42:58-04:00", "date_modified"=>"2016-09-30T19:42:58-04:00", "description"=>"Account service", "id"=>2, "name"=>"accounts", "service_type"=>"client"}, {"active"=>true, "date_created"=>"2016-09-30T19:42:58-04:00", "date_modified"=>"2016-09-30T19:42:58-04:00", "description"=>"Public service", "id"=>3, "name"=>"public", "service_type"=>"client"}]>
|
101
|
+
#
|
102
|
+
#
|
103
|
+
# Note: When creating subaccounts, the `id` refers to the subaccount id, whereas the `account_id` refers to the main account.
|
104
|
+
#
|
105
|
+
#
|
106
|
+
##
|
107
|
+
#=== .find(id)
|
108
|
+
#
|
109
|
+
#Returns the a Account object referenced by the `id` value.
|
110
|
+
#
|
111
|
+
# Required parameter:
|
112
|
+
#
|
113
|
+
# id | Fixnum | the id of the account you would like to retrieve
|
114
|
+
#
|
115
|
+
#
|
116
|
+
# Example usage:
|
117
|
+
#
|
118
|
+
#
|
119
|
+
# VivialConnect::Account.find(10086)
|
120
|
+
# => #<VivialConnect::Account account_id=1XXXX, accounts=[], active=true, company_name="App Developer Inc.", contacts=[], date_created="2017-04-20T17:07:08-04:00", date_modified="2017-04-20T17:07:08-04:00", id=10086, services=[{"active"=>true, "date_created"=>"2016-09-30T19:42:58-04:00", "date_modified"=>"2016-09-30T19:42:58-04:00", "description"=>"SMS service", "id"=>1, "name"=>"sms", "service_type"=>"client"}, {"active"=>true, "date_created"=>"2016-09-30T19:42:58-04:00", "date_modified"=>"2016-09-30T19:42:58-04:00", "description"=>"Account service", "id"=>2, "name"=>"accounts", "service_type"=>"client"}, {"active"=>true, "date_created"=>"2016-09-30T19:42:58-04:00", "date_modified"=>"2016-09-30T19:42:58-04:00", "description"=>"Public service", "id"=>3, "name"=>"public", "service_type"=>"client"}]>
|
121
|
+
#
|
122
|
+
#
|
123
|
+
##
|
124
|
+
#=== .find_each(start: 1, finish: nil, batch_size: 150)
|
125
|
+
#
|
126
|
+
#Iterates through all Account objects on your account in N sized batches beginning at the `start: value` and ending at the `finish: value`.
|
127
|
+
#
|
128
|
+
#
|
129
|
+
# When a block is given this method yields an individual Account object.
|
130
|
+
# Without a block, this method returns an Enumerator.
|
131
|
+
#
|
132
|
+
#
|
133
|
+
# By default, it will begin at the first Account and end at the last Account
|
134
|
+
#
|
135
|
+
#
|
136
|
+
# With default batch_size: 150, if you wanted to get your records from
|
137
|
+
# 150 to 300 you would start at 2 and finish at 2.
|
138
|
+
#
|
139
|
+
# Returns an Array of objects corresponding to the `start` and `finish` values. Default is all objects.
|
140
|
+
#
|
141
|
+
# Optional parameters:
|
142
|
+
#
|
143
|
+
# start | Fixnum | batch to start with
|
144
|
+
# finish | Fixnum | batch to end with
|
145
|
+
# batch_size | Fixnum | between 1..150
|
146
|
+
#
|
147
|
+
#
|
148
|
+
# Example usage:
|
149
|
+
#
|
150
|
+
#
|
151
|
+
# VivialConnect::Account.find_each {|account| puts account.company_name }
|
152
|
+
# App Developer Inc.
|
153
|
+
# => [#<VivialConnect::Account>]
|
154
|
+
#
|
155
|
+
#
|
156
|
+
#
|
157
|
+
#
|
158
|
+
##
|
159
|
+
#=== .find_in_batches(start: 1, finish: nil, batch_size: 150)
|
160
|
+
#
|
161
|
+
#Iterates through all of the Account objects on your account in N sized batches beginning at the `start: value` and ending at the `finish: value`.
|
162
|
+
#
|
163
|
+
#
|
164
|
+
# When a block is given this method yields an array of batch_size Account objects.
|
165
|
+
# Without a block, it returns an Enumerator.
|
166
|
+
#
|
167
|
+
#
|
168
|
+
# By default, it will begin at the first Account and end at the last Account
|
169
|
+
#
|
170
|
+
#
|
171
|
+
# With default batch_size: 150, if you wanted to get your records from
|
172
|
+
# 150 to 300 you would start at 2 and finish at 2.
|
173
|
+
#
|
174
|
+
#
|
175
|
+
#
|
176
|
+
# Returns an Array of objects corresponding to the `start` and `finish` values. Default is all objects.
|
177
|
+
#
|
178
|
+
#
|
179
|
+
# Optional parameters:
|
180
|
+
#
|
181
|
+
# start | Fixnum | batch to start with
|
182
|
+
# finish | Fixnum | batch to end with
|
183
|
+
# batch_size | Fixnum | between 1..150
|
184
|
+
#
|
185
|
+
#
|
186
|
+
# Example usage:
|
187
|
+
#
|
188
|
+
#
|
189
|
+
# VivialConnect::Account.find_in_batches {|batch| do_something_with_an_array(batch)}
|
190
|
+
# => [#<VivialConnect::Account>]
|
191
|
+
#
|
192
|
+
#
|
193
|
+
##
|
194
|
+
#=== .subaccounts
|
195
|
+
#
|
196
|
+
#Returns an array containing ruby objects containing all associated subaccounts
|
197
|
+
#
|
198
|
+
#
|
199
|
+
# Example usage:
|
200
|
+
#
|
201
|
+
#
|
202
|
+
# VivialConnect::Account.subaccounts
|
203
|
+
# => [#<VivialConnect::Account>, #<VivialConnect::Account>, #<VivialConnect::Account>]
|
204
|
+
#
|
205
|
+
#
|
206
|
+
##
|
207
|
+
#=== .update(id, options={})
|
208
|
+
#
|
209
|
+
# Required parameters:
|
210
|
+
#
|
211
|
+
# id | Fixnum | 10000
|
212
|
+
# company_name | String | "New Name"
|
213
|
+
#
|
214
|
+
# Example usage:
|
215
|
+
#
|
216
|
+
#
|
217
|
+
# VivialConnect::Account.update(1000, company_name: "New Name")
|
218
|
+
# => #<VivialConnect::Account account_id=1XXXX, accounts=[], active=true, company_name="New Name", contacts=[], date_created="2017-04-20T17:07:08-04:00", date_modified="2017-04-20T17:07:08-04:00", id=10086, services=[{"active"=>true, "date_created"=>"2016-09-30T19:42:58-04:00", "date_modified"=>"2016-09-30T19:42:58-04:00", "description"=>"SMS service", "id"=>1, "name"=>"sms", "service_type"=>"client"}, {"active"=>true, "date_created"=>"2016-09-30T19:42:58-04:00", "date_modified"=>"2016-09-30T19:42:58-04:00", "description"=>"Account service", "id"=>2, "name"=>"accounts", "service_type"=>"client"}, {"active"=>true, "date_created"=>"2016-09-30T19:42:58-04:00", "date_modified"=>"2016-09-30T19:42:58-04:00", "description"=>"Public service", "id"=>3, "name"=>"public", "service_type"=>"client"}]>
|
219
|
+
#
|
220
|
+
#
|
221
|
+
##
|
222
|
+
#=== \#save
|
223
|
+
#
|
224
|
+
# Creates a subaccount associated with your main account or updates an existing one
|
225
|
+
#
|
226
|
+
#
|
227
|
+
# Example usage:
|
228
|
+
#
|
229
|
+
# account = VivialConnect::Account.new
|
230
|
+
# account.company_name = "B Tester QA Inc."
|
231
|
+
# account.save
|
232
|
+
# => #<VivialConnect::Account account_id=1XXXX, accounts=[], active=true, company_name="B Tester QA Inc.", contacts=[], date_created="2017-04-20T17:07:08-04:00", date_modified="2017-04-20T17:07:08-04:00", id=10086, services=[{"active"=>true, "date_created"=>"2016-09-30T19:42:58-04:00", "date_modified"=>"2016-09-30T19:42:58-04:00", "description"=>"SMS service", "id"=>1, "name"=>"sms", "service_type"=>"client"}, {"active"=>true, "date_created"=>"2016-09-30T19:42:58-04:00", "date_modified"=>"2016-09-30T19:42:58-04:00", "description"=>"Account service", "id"=>2, "name"=>"accounts", "service_type"=>"client"}, {"active"=>true, "date_created"=>"2016-09-30T19:42:58-04:00", "date_modified"=>"2016-09-30T19:42:58-04:00", "description"=>"Public service", "id"=>3, "name"=>"public", "service_type"=>"client"}]>
|
233
|
+
#
|
234
|
+
#
|
235
|
+
class Account < Resource
|
236
|
+
|
237
|
+
def self.subaccounts # :nodoc:
|
238
|
+
uri = '/subaccounts.json'
|
239
|
+
VivialConnect::Client.instance.make_request('GET', uri)
|
240
|
+
end
|
241
|
+
|
242
|
+
def self.add_main_contact_to_subaccount(options={}) # :nodoc:
|
243
|
+
raise VivialConnectClientError, "you must include an account_id parameter" if !options.keys.include?(:account_id)
|
244
|
+
|
245
|
+
# This call must be made from the subaccount, so the client's account_id has to be updated
|
246
|
+
main_account_id = VivialConnect::Client.instance.account_id
|
247
|
+
|
248
|
+
VivialConnect::Client.instance.account_id = options[:account_id]
|
249
|
+
uri = '/contacts.json'
|
250
|
+
options[:contact_type] = 'main'
|
251
|
+
data = {}
|
252
|
+
data[:contact] = options
|
253
|
+
data = data.to_json
|
254
|
+
|
255
|
+
begin
|
256
|
+
response = VivialConnect::Client.instance.make_request('POST', uri, data)
|
257
|
+
ensure
|
258
|
+
# client's account_id must be set back for future calls to work
|
259
|
+
VivialConnect::Client.instance.account_id = main_account_id
|
260
|
+
end
|
261
|
+
|
262
|
+
response
|
263
|
+
end
|
264
|
+
|
265
|
+
def self.add_user_to_subaccount(options={}) # :nodoc:
|
266
|
+
raise VivialConnectClientError, "you must include an account_id parameter" if !options.keys.include?(:account_id)
|
267
|
+
uri = '/users/register.json'
|
268
|
+
options[:role] = 'User'
|
269
|
+
data = {}
|
270
|
+
data[:user] = options
|
271
|
+
data = data.to_json
|
272
|
+
response = VivialConnect::Client.instance.make_request('POST', uri, data)
|
273
|
+
end
|
274
|
+
|
275
|
+
end
|
276
|
+
end
|
277
|
+
|
278
|
+
|
@@ -0,0 +1,74 @@
|
|
1
|
+
module VivialConnect
|
2
|
+
##
|
3
|
+
#=== .count_by_message_id(message_id)
|
4
|
+
#
|
5
|
+
#Returns the number of attachments related to the message_id passed.
|
6
|
+
#
|
7
|
+
#
|
8
|
+
# Example usage:
|
9
|
+
#
|
10
|
+
#
|
11
|
+
# VivialConnect::Attachment.count_by_message_id(844)
|
12
|
+
# => 1
|
13
|
+
#
|
14
|
+
#
|
15
|
+
##
|
16
|
+
#=== .delete(message_id, attachment_id)
|
17
|
+
#
|
18
|
+
#Deletes Attachment related to the `message_id` passed
|
19
|
+
#
|
20
|
+
#
|
21
|
+
# Example usage:
|
22
|
+
#
|
23
|
+
#
|
24
|
+
# VivialConnect::Attachment.delete(844, 190)
|
25
|
+
# => true
|
26
|
+
#
|
27
|
+
#
|
28
|
+
##
|
29
|
+
#=== .find(message_id, attachment_id)
|
30
|
+
#
|
31
|
+
#Returns an Attachment corresponding to the `message_id` and `attachment_id` passed
|
32
|
+
#
|
33
|
+
#
|
34
|
+
# Example usage:
|
35
|
+
#
|
36
|
+
#
|
37
|
+
# VivialConnect::Attachment.find(844, 190)
|
38
|
+
# => [#<VivialConnect::Attachment account_id=1XXXX, content_type="image/jpeg", date_created="2017-04-19T11:18:16-04:00", date_modified="2017-04-19T11:18:16-04:00", file_name="great-dane.jpg", id=190, key_name="mms/50/e9aa5a6970498352a399ebdf798b86bb801b5b/great-dane.jpg", message_id=844, size=110805>]
|
39
|
+
#
|
40
|
+
#
|
41
|
+
##
|
42
|
+
#=== .find_all_by_message_id(message_id)
|
43
|
+
#
|
44
|
+
#Returns an array containing ruby objects corresponding to all attachment resources related to the `message_id` passed
|
45
|
+
#
|
46
|
+
#
|
47
|
+
# Example usage:
|
48
|
+
#
|
49
|
+
#
|
50
|
+
# VivialConnect::Attachment.find_all_by_message_id(844)
|
51
|
+
# => [#<VivialConnect::Attachment account_id=1XXXX, content_type="image/jpeg", date_created="2017-04-19T11:18:16-04:00", date_modified="2017-04-19T11:18:16-04:00", file_name="great-dane.jpg", id=190, key_name="mms/50/e9aa5a6970498352a399ebdf798b86bb801b5b/great-dane.jpg", message_id=844, size=110805>]
|
52
|
+
#
|
53
|
+
#
|
54
|
+
|
55
|
+
class Attachment < Resource
|
56
|
+
|
57
|
+
def self.find_all_by_message_id(message_id) #:nodoc:
|
58
|
+
VivialConnect::Client.instance.make_request('GET', "/messages/#{message_id}/attachments.json")
|
59
|
+
end
|
60
|
+
|
61
|
+
def self.find(message_id, attachment_id) #:nodoc:
|
62
|
+
VivialConnect::Client.instance.make_request('GET', "/messages/#{message_id}/attachments/#{attachment_id}.json")
|
63
|
+
end
|
64
|
+
|
65
|
+
def self.count_by_message_id(message_id) #:nodoc:
|
66
|
+
VivialConnect::Client.instance.make_request('GET', "/messages/#{message_id}/attachments/count.json")
|
67
|
+
end
|
68
|
+
|
69
|
+
def self.delete(message_id, attachment_id) #:nodoc:
|
70
|
+
VivialConnect::Client.instance.make_request('DELETE', "/messages/#{message_id}/attachments/#{attachment_id}.json")
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,326 @@
|
|
1
|
+
require 'faraday'
|
2
|
+
require 'addressable'
|
3
|
+
require 'digest'
|
4
|
+
require 'openssl'
|
5
|
+
require 'singleton'
|
6
|
+
|
7
|
+
module VivialConnect
|
8
|
+
|
9
|
+
##
|
10
|
+
#=== .configure(api_key, api_secret, account_id, host="https://api.vivialconnect.net/api/", api_version="v1.0" )
|
11
|
+
#
|
12
|
+
#Configures the client with your `api_key`, `api_secret`, `account_id`, `host`, and `api_version`
|
13
|
+
#
|
14
|
+
#
|
15
|
+
# Required parameters:
|
16
|
+
#
|
17
|
+
# api_key | String | "YOURAPIKEY"
|
18
|
+
# api_secret | String | "YOURAPISECRET"
|
19
|
+
# account_id | Fixnum | 100000
|
20
|
+
#
|
21
|
+
#
|
22
|
+
# Optional parameters:
|
23
|
+
#
|
24
|
+
# host | String | "baseapiurl"
|
25
|
+
# api_version | String | "v1.9"
|
26
|
+
#
|
27
|
+
# NOTE: default host is "https://api.vivialconnect.net/api/" and default version is "v1.0"
|
28
|
+
#
|
29
|
+
#
|
30
|
+
# Example usage:
|
31
|
+
#
|
32
|
+
#
|
33
|
+
# VivialConnect::Client.configure(API_KEY, API_SECRET, ACCOUNT_ID)
|
34
|
+
# => true
|
35
|
+
#
|
36
|
+
# NOTE: .configure does not check if your credentials are good, it merely checks that you have entered values for them
|
37
|
+
#=== .reset
|
38
|
+
#
|
39
|
+
#Resets all of the configuration values to nil. This gives you a blank slate client to call .configure on.
|
40
|
+
#
|
41
|
+
#
|
42
|
+
# Example usage
|
43
|
+
#
|
44
|
+
#
|
45
|
+
# VivialConnect::Client.reset
|
46
|
+
# => true
|
47
|
+
#
|
48
|
+
#
|
49
|
+
#=== \#reset_api_base_path(new_host, new_api_version)
|
50
|
+
#
|
51
|
+
#Resets the api base path (host + api_version) on an instantiated client instance
|
52
|
+
#
|
53
|
+
# Required paramters:
|
54
|
+
#
|
55
|
+
# new_host | String | "https://api.vivialconnect.net/api/"
|
56
|
+
# new_api_version | String | "v1.1"
|
57
|
+
#
|
58
|
+
#
|
59
|
+
# Example usage
|
60
|
+
#
|
61
|
+
# VivialConnect::Client.instance.reset_api_base_path("https://api.vivialconnect.net/api/", "v1.1" )
|
62
|
+
# => true
|
63
|
+
|
64
|
+
class Client
|
65
|
+
|
66
|
+
#:nodoc:
|
67
|
+
|
68
|
+
include Singleton
|
69
|
+
|
70
|
+
@@configured = false
|
71
|
+
|
72
|
+
def initialize
|
73
|
+
begin
|
74
|
+
@base_api_path = host + "#{api_version}/"
|
75
|
+
connection
|
76
|
+
rescue NameError => e
|
77
|
+
raise VivialConnectClientError, "Please configure client before making requests. You can do this like so: .configure(api_key, api_secret, account_id) to "
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def self.configure(api_key, api_secret, account_id, host="https://api.vivialconnect.net/api/", api_version="v1.0" )
|
82
|
+
@@api_key= api_key
|
83
|
+
@@api_secret = api_secret
|
84
|
+
@@account_id = account_id
|
85
|
+
@@host = host
|
86
|
+
@@api_version = api_version
|
87
|
+
@@configured = true
|
88
|
+
true
|
89
|
+
end
|
90
|
+
|
91
|
+
def self.reset
|
92
|
+
@@api_key= nil
|
93
|
+
@@api_secret = nil
|
94
|
+
@@account_id = nil
|
95
|
+
@@host = nil
|
96
|
+
@@api_version = nil
|
97
|
+
@@configured = false
|
98
|
+
@base_api_path = nil
|
99
|
+
true
|
100
|
+
end
|
101
|
+
|
102
|
+
def host
|
103
|
+
@@host
|
104
|
+
end
|
105
|
+
|
106
|
+
def account_id
|
107
|
+
@@account_id
|
108
|
+
end
|
109
|
+
|
110
|
+
def account_id=(id)
|
111
|
+
@@account_id = id
|
112
|
+
end
|
113
|
+
|
114
|
+
def reset_api_base_path(new_host, new_api_version)
|
115
|
+
@base_api_path = new_host + "#{new_api_version}/"
|
116
|
+
connection
|
117
|
+
true
|
118
|
+
end
|
119
|
+
|
120
|
+
|
121
|
+
def api_version
|
122
|
+
@@api_version
|
123
|
+
end
|
124
|
+
|
125
|
+
def base_api_path
|
126
|
+
@base_api_path
|
127
|
+
end
|
128
|
+
|
129
|
+
|
130
|
+
def self.configured?
|
131
|
+
@@configured == true
|
132
|
+
end
|
133
|
+
|
134
|
+
|
135
|
+
def set_request_timestamp
|
136
|
+
@request_timestamp = Time.now.utc.strftime('%Y%m%dT%H%M%SZ')
|
137
|
+
end
|
138
|
+
|
139
|
+
|
140
|
+
def request_timestamp
|
141
|
+
@request_timestamp
|
142
|
+
end
|
143
|
+
|
144
|
+
|
145
|
+
def set_date_for_date_header
|
146
|
+
@date_for_date_header = Time.now.utc.strftime('%a, %d %b %Y %H:%M:%S GMT')
|
147
|
+
end
|
148
|
+
|
149
|
+
|
150
|
+
def date_for_date_header
|
151
|
+
@date_for_date_header
|
152
|
+
end
|
153
|
+
|
154
|
+
|
155
|
+
def api_key
|
156
|
+
@@api_key
|
157
|
+
end
|
158
|
+
|
159
|
+
|
160
|
+
def api_secret
|
161
|
+
@@api_secret
|
162
|
+
end
|
163
|
+
|
164
|
+
|
165
|
+
def set_hmac_sha256(canonical_request)
|
166
|
+
@hmac_sha256 = OpenSSL::HMAC.hexdigest('SHA256', api_secret, canonical_request)
|
167
|
+
end
|
168
|
+
|
169
|
+
|
170
|
+
def hmac_sha256
|
171
|
+
@hmac_sha256
|
172
|
+
end
|
173
|
+
|
174
|
+
def build_canonical_request(http_verb, url, request_timestamp, canonicalized_headers, canonicalized_header_names, data={})
|
175
|
+
canonical_request = http_verb + "\n" + request_timestamp + "\n" + Addressable::URI.encode(url.path) +
|
176
|
+
"\n" + get_canonicalized_query_string(url) + "\n" + canonicalized_headers + "\n" +
|
177
|
+
canonicalized_header_names + "\n" + Digest::SHA256.hexdigest(data.to_s)
|
178
|
+
end
|
179
|
+
|
180
|
+
|
181
|
+
def sign_request(http_verb, url, data={})
|
182
|
+
set_request_timestamp
|
183
|
+
set_date_for_date_header
|
184
|
+
canonicalized_headers = "accept:application/json" + "\n" + "date:#{date_for_date_header}" + "\n" +"host:api.vivialconnect.net"
|
185
|
+
canonicalized_header_names = "accept;date;host"
|
186
|
+
canonical_request = build_canonical_request(http_verb, url, request_timestamp, canonicalized_headers, canonicalized_header_names, data)
|
187
|
+
set_hmac_sha256(canonical_request)
|
188
|
+
end
|
189
|
+
|
190
|
+
|
191
|
+
def get_canonicalized_query_string(url)
|
192
|
+
return "" unless url.query_values
|
193
|
+
sorted_params = url.query_values.sort
|
194
|
+
# gsub because Addressable encodes an empty space as + in parameters
|
195
|
+
# and vivial connect api requires spaces to be %20 encoded
|
196
|
+
# http://stackoverflow.com/questions/2824126/whats-the-difference-between-uri-escape-and-cgi-escape
|
197
|
+
encoded_sorted_params = Addressable::URI.form_encode(sorted_params).gsub('+', '%20')
|
198
|
+
end
|
199
|
+
|
200
|
+
|
201
|
+
def connection
|
202
|
+
@conn = Faraday.new(:url => base_api_path)
|
203
|
+
end
|
204
|
+
|
205
|
+
def make_request(request_method, url, data={})
|
206
|
+
raise VivialConnectClientError, "invalid request method" unless ['GET', 'POST', 'PUT', 'DELETE'].include?(request_method)
|
207
|
+
raise VivialConnectClientError, "Please configure client before making requests. You can do this like so: .configure(api_key, api_secret, account_id) to " if !VivialConnect::Client.configured?
|
208
|
+
|
209
|
+
url = get_request_path(url)
|
210
|
+
sign_request(request_method, url, data)
|
211
|
+
headers = create_request_headers
|
212
|
+
request_method = request_method.downcase.to_sym
|
213
|
+
response = connection.run_request(request_method, url, data.to_s, headers)
|
214
|
+
process_api_response(response, url)
|
215
|
+
end
|
216
|
+
|
217
|
+
|
218
|
+
def create_request_headers
|
219
|
+
headers = {}
|
220
|
+
headers['Content-Type'] = 'application/json'
|
221
|
+
headers['Host'] = 'api.vivialconnect.net'
|
222
|
+
headers['X-Auth-Date'] = request_timestamp
|
223
|
+
headers['X-Auth-SignedHeaders'] = 'accept;date;host'
|
224
|
+
headers['Authorization'] = "HMAC" + " " + api_key + ":" + hmac_sha256
|
225
|
+
headers['Date'] = date_for_date_header
|
226
|
+
headers['Accept'] = 'application/json'
|
227
|
+
headers
|
228
|
+
end
|
229
|
+
|
230
|
+
|
231
|
+
def no_account_number_endpoints
|
232
|
+
['accounts.json', '/accounts/count.json', 'registration/register.json']
|
233
|
+
end
|
234
|
+
|
235
|
+
|
236
|
+
def account_regex_match?(url)
|
237
|
+
m = /accounts\/[0-9]+.json/.match(url)
|
238
|
+
return !m.nil?
|
239
|
+
end
|
240
|
+
|
241
|
+
|
242
|
+
def account_query_match?(url)
|
243
|
+
url.include?("accounts.json?")
|
244
|
+
end
|
245
|
+
|
246
|
+
|
247
|
+
def get_request_path(url)
|
248
|
+
if no_account_number_endpoints.include?(url) || account_regex_match?(url) || account_query_match?(url)
|
249
|
+
base_path = base_api_path
|
250
|
+
Addressable::URI.parse(base_path + url)
|
251
|
+
else
|
252
|
+
base_path = base_api_path + "accounts/#{account_id}"
|
253
|
+
Addressable::URI.parse(base_path + url)
|
254
|
+
end
|
255
|
+
end
|
256
|
+
|
257
|
+
def process_api_response(response, url)
|
258
|
+
# make API response into appropriate object and return it
|
259
|
+
api_response = {}
|
260
|
+
raise VivialConnectClientError, JSON.parse(response.body)['message'] ? JSON.parse(response.body)['message'] : response.body if response.status >= 400
|
261
|
+
response_class = choose_response_class(url.path)
|
262
|
+
if response.body == "" || response.body.include?("{}")
|
263
|
+
return true if response.status.between?(200, 299)
|
264
|
+
false
|
265
|
+
else
|
266
|
+
api_response = JSON.parse(response.body)
|
267
|
+
if api_response[api_response.keys.first].is_a?(Array)
|
268
|
+
#return an array of resource objects
|
269
|
+
response_array = api_response[api_response.keys.first]
|
270
|
+
api_response = process_array(response_array, response_class)
|
271
|
+
elsif url.path.split("/")[-1] == "subaccounts.json"
|
272
|
+
#handle subaccounts array
|
273
|
+
response_array = api_response[api_response.keys.first]['accounts']
|
274
|
+
api_response = process_array(response_array, response_class)
|
275
|
+
elsif api_response[api_response.keys[1]].is_a?(Array)
|
276
|
+
#handle Log resource, return last key and an array full of log objects
|
277
|
+
last_key = api_response['last_key']
|
278
|
+
response_array = api_response['log_items']
|
279
|
+
processed_array = process_array(response_array, response_class)
|
280
|
+
[last_key, processed_array]
|
281
|
+
elsif api_response[api_response.keys.first].is_a?(Fixnum)
|
282
|
+
# json is only one level deep for .count response, so no need to delete the json root
|
283
|
+
# return the number
|
284
|
+
api_response['count']
|
285
|
+
else
|
286
|
+
if response_class == VivialConnect::Log
|
287
|
+
# json is only one level deep for Log response, so no need to delete the json root
|
288
|
+
response_class.new(api_response)
|
289
|
+
else
|
290
|
+
# remove json root, these resources return nested info
|
291
|
+
api_response = api_response[api_response.keys.first]
|
292
|
+
response_class.new(api_response)
|
293
|
+
end
|
294
|
+
end
|
295
|
+
|
296
|
+
end
|
297
|
+
end
|
298
|
+
|
299
|
+
def process_array(array, response_class)
|
300
|
+
final_array = []
|
301
|
+
array.each {|index| final_array << response_class.new(index)}
|
302
|
+
final_array
|
303
|
+
end
|
304
|
+
|
305
|
+
def choose_response_class(url)
|
306
|
+
url = url.gsub('.json', '').split('/')
|
307
|
+
if (url.count <= 5 )|| (url.count == 6 && url[5] == 'count')
|
308
|
+
return Account
|
309
|
+
elsif url.include?('attachments')
|
310
|
+
return Attachment
|
311
|
+
elsif url.include?('subaccounts')
|
312
|
+
return Account
|
313
|
+
else
|
314
|
+
api_resource = url[5]
|
315
|
+
#exceptions needed for resources requiring camelcase
|
316
|
+
klass = api_resource.capitalize
|
317
|
+
#takes off pluralization -- may have to be updated to match self.pluralize(string) in Resource, or use library if necessary
|
318
|
+
klass = klass[0..-2]
|
319
|
+
return VivialConnect.const_get(klass)
|
320
|
+
end
|
321
|
+
end
|
322
|
+
|
323
|
+
|
324
|
+
end
|
325
|
+
end
|
326
|
+
|