telerivet 1.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,156 @@
1
+ module Telerivet
2
+
3
+ #
4
+ # An easy-to-use interface for interacting with API methods that return collections of objects
5
+ # that may be split into multiple pages of results.
6
+ #
7
+ # Using the APICursor, you can easily iterate over query results without
8
+ # having to manually fetch each page of results.
9
+ #
10
+ class APICursor
11
+
12
+ include Enumerable
13
+
14
+ def initialize(api, item_cls, path, params = nil)
15
+ params ||= {}
16
+
17
+ if params.has_key?('count')
18
+ raise Exception, "Cannot construct APICursor with 'count' parameter. Call the count() method instead."
19
+ end
20
+
21
+ @api = api
22
+ @item_cls = item_cls
23
+ @path = path
24
+ @params = params
25
+
26
+ @count = -1
27
+ @pos = nil
28
+ @data = nil
29
+ @truncated = nil
30
+ @next_marker = nil
31
+ @limit = nil
32
+ @offset = 0
33
+ end
34
+
35
+ def each()
36
+ loop do
37
+ item = self.next()
38
+ return if item == nil
39
+ yield item
40
+ end
41
+ end
42
+
43
+ #
44
+ # Limits the maximum number of entities fetched by this query.
45
+ #
46
+ # By default, iterating over the cursor will automatically fetch
47
+ # additional result pages as necessary. To prevent fetching more objects than you need, call
48
+ # this method to set the maximum number of objects retrieved from the API.
49
+ #
50
+ # Arguments:
51
+ # - limit (int)
52
+ # * The maximum number of entities to fetch from the server (may require multiple API
53
+ # calls if greater than 200)
54
+ # * Required
55
+ #
56
+ # Returns:
57
+ # the current APICursor object
58
+ #
59
+ def limit(_limit)
60
+ @limit = _limit
61
+ self
62
+ end
63
+
64
+ #
65
+ # Returns the total count of entities matching the current query, without actually fetching
66
+ # the entities themselves.
67
+ #
68
+ # This is much more efficient than all() if you only need the count,
69
+ # as it only results in one API call, regardless of the number of entities matched by the
70
+ # query.
71
+ #
72
+ # Returns:
73
+ # int
74
+ #
75
+ def count()
76
+ if @count == -1
77
+ params = @params.clone
78
+ params['count'] = 1
79
+
80
+ res = @api.do_request("GET", @path, params)
81
+ @count = res['count'].to_i
82
+ end
83
+ @count
84
+ end
85
+
86
+ def all()
87
+ to_a
88
+ end
89
+
90
+ #
91
+ # Returns true if there are any more entities in the result set, false otherwise
92
+ #
93
+ # Returns:
94
+ # bool
95
+ #
96
+ def has_next?()
97
+ return false if @limit != nil && @offset >= @limit
98
+
99
+ load_next_page() if @data == nil
100
+
101
+ return true if @pos < @data.length
102
+
103
+ return false if !@truncated
104
+
105
+ load_next_page()
106
+
107
+ @pos < @data.length
108
+ end
109
+
110
+ #
111
+ # Returns the next entity in the result set.
112
+ #
113
+ # Returns:
114
+ # Telerivet::Entity
115
+ #
116
+ def next()
117
+ if @limit != nil && @offset >= @limit
118
+ return nil
119
+ end
120
+
121
+ if @data == nil || (@pos >= @data.length && @truncated)
122
+ load_next_page()
123
+ end
124
+
125
+ if @pos < @data.length
126
+ item_data = @data[@pos]
127
+ @pos += 1
128
+ @offset += 1
129
+ cls = @item_cls
130
+ return cls.new(@api, item_data, true)
131
+ else
132
+ return nil
133
+ end
134
+ end
135
+
136
+ def load_next_page()
137
+ request_params = @params.clone
138
+
139
+ if @next_marker != nil
140
+ request_params['marker'] = @next_marker
141
+ end
142
+
143
+ if @limit != nil && !request_params.has_key?("page_size")
144
+ request_params['page_size'] = [@limit, 200].min
145
+ end
146
+
147
+ response = @api.do_request("GET", @path, request_params)
148
+
149
+ @data = response['data']
150
+ @truncated = response['truncated']
151
+ @next_marker = response['next_marker']
152
+ @pos = 0
153
+ end
154
+ end
155
+
156
+ end
@@ -0,0 +1,403 @@
1
+ module Telerivet
2
+
3
+ #
4
+ # Fields:
5
+ #
6
+ # - id (string, max 34 characters)
7
+ # * ID of the contact
8
+ # * Read-only
9
+ #
10
+ # - name
11
+ # * Name of the contact
12
+ # * Updatable via API
13
+ #
14
+ # - phone_number (string)
15
+ # * Phone number of the contact
16
+ # * Updatable via API
17
+ #
18
+ # - time_created (UNIX timestamp)
19
+ # * Time the contact was added in Telerivet
20
+ # * Read-only
21
+ #
22
+ # - last_message_time (UNIX timestamp)
23
+ # * Last time the contact sent or received a message (null if no messages have been sent
24
+ # or received)
25
+ # * Read-only
26
+ #
27
+ # - last_message_id
28
+ # * ID of the last message sent or received by this contact (null if no messages have
29
+ # been sent or received)
30
+ # * Read-only
31
+ #
32
+ # - default_route_id
33
+ # * ID of the phone or route that Telerivet will use by default to send messages to this
34
+ # contact (null if using project default route)
35
+ # * Updatable via API
36
+ #
37
+ # - group_ids (array of strings)
38
+ # * List of IDs of groups that this contact belongs to
39
+ # * Read-only
40
+ #
41
+ # - vars (Hash)
42
+ # * Custom variables stored for this contact
43
+ # * Updatable via API
44
+ #
45
+ # - project_id
46
+ # * ID of the project this contact belongs to
47
+ # * Read-only
48
+ #
49
+ class Contact < Entity
50
+
51
+ #
52
+ # Returns true if this contact is in a particular group, false otherwise.
53
+ #
54
+ # Arguments:
55
+ # - group (Telerivet::Group)
56
+ # * Required
57
+ #
58
+ # Returns:
59
+ # bool
60
+ #
61
+ def is_in_group?(group)
62
+ load_data()
63
+ return @group_ids_set.has_key?(group.id)
64
+ end
65
+
66
+ #
67
+ # Adds this contact to a group.
68
+ #
69
+ # Arguments:
70
+ # - group (Telerivet::Group)
71
+ # * Required
72
+ #
73
+ def add_to_group(group)
74
+ @api.do_request("PUT", group.get_base_api_path() + "/contacts/" + get('id'));
75
+ @group_ids_set[group.id] = true
76
+ end
77
+
78
+ #
79
+ # Removes this contact from a group.
80
+ #
81
+ # Arguments:
82
+ # - group (Telerivet::Group)
83
+ # * Required
84
+ #
85
+ def remove_from_group(group)
86
+ @api.do_request("DELETE", group.get_base_api_path() + "/contacts/" + get('id'))
87
+ if @group_ids_set.has_key?(group.id)
88
+ @group_ids_set.delete(group.id)
89
+ end
90
+ end
91
+
92
+ #
93
+ # Queries messages sent or received by this contact.
94
+ #
95
+ # Arguments:
96
+ # - options (Hash)
97
+ #
98
+ # - direction
99
+ # * Filter messages by direction
100
+ # * Allowed values: incoming, outgoing
101
+ #
102
+ # - message_type
103
+ # * Filter messages by message_type
104
+ # * Allowed values: sms, mms, ussd, call
105
+ #
106
+ # - source
107
+ # * Filter messages by source
108
+ # * Allowed values: phone, provider, web, api, service, webhook, scheduled
109
+ #
110
+ # - starred (bool)
111
+ # * Filter messages by starred/unstarred
112
+ #
113
+ # - status
114
+ # * Filter messages by status
115
+ # * Allowed values: ignored, processing, received, sent, queued, failed,
116
+ # failed_queued, cancelled, delivered, not_delivered
117
+ #
118
+ # - time_created[min] (UNIX timestamp)
119
+ # * Filter messages created on or after a particular time
120
+ #
121
+ # - time_created[max] (UNIX timestamp)
122
+ # * Filter messages created before a particular time
123
+ #
124
+ # - contact_id
125
+ # * ID of the contact who sent/received the message
126
+ #
127
+ # - phone_id
128
+ # * ID of the phone that sent/received the message
129
+ #
130
+ # - sort
131
+ # * Sort the results based on a field
132
+ # * Allowed values: default
133
+ # * Default: default
134
+ #
135
+ # - sort_dir
136
+ # * Sort the results in ascending or descending order
137
+ # * Allowed values: asc, desc
138
+ # * Default: asc
139
+ #
140
+ # - page_size (int)
141
+ # * Number of results returned per page (max 200)
142
+ # * Default: 50
143
+ #
144
+ # - offset (int)
145
+ # * Number of items to skip from beginning of result set
146
+ # * Default: 0
147
+ #
148
+ # Returns:
149
+ # Telerivet::APICursor (of Telerivet::Message)
150
+ #
151
+ def query_messages(options = nil)
152
+ require_relative 'message'
153
+ @api.cursor(Message, get_base_api_path() + "/messages", options)
154
+ end
155
+
156
+ #
157
+ # Queries groups for which this contact is a member.
158
+ #
159
+ # Arguments:
160
+ # - options (Hash)
161
+ #
162
+ # - name
163
+ # * Filter groups by name
164
+ # * Allowed modifiers: name[ne], name[prefix], name[not_prefix], name[gte], name[gt],
165
+ # name[lt], name[lte]
166
+ #
167
+ # - sort
168
+ # * Sort the results based on a field
169
+ # * Allowed values: default, name
170
+ # * Default: default
171
+ #
172
+ # - sort_dir
173
+ # * Sort the results in ascending or descending order
174
+ # * Allowed values: asc, desc
175
+ # * Default: asc
176
+ #
177
+ # - page_size (int)
178
+ # * Number of results returned per page (max 200)
179
+ # * Default: 50
180
+ #
181
+ # - offset (int)
182
+ # * Number of items to skip from beginning of result set
183
+ # * Default: 0
184
+ #
185
+ # Returns:
186
+ # Telerivet::APICursor (of Telerivet::Group)
187
+ #
188
+ def query_groups(options = nil)
189
+ require_relative 'group'
190
+ @api.cursor(Group, get_base_api_path() + "/groups", options)
191
+ end
192
+
193
+ #
194
+ # Queries messages scheduled to this contact (not including messages scheduled to groups that
195
+ # this contact is a member of)
196
+ #
197
+ # Arguments:
198
+ # - options (Hash)
199
+ #
200
+ # - message_type
201
+ # * Filter scheduled messages by message_type
202
+ # * Allowed values: sms, mms, ussd, call
203
+ #
204
+ # - time_created (UNIX timestamp)
205
+ # * Filter scheduled messages by time_created
206
+ # * Allowed modifiers: time_created[ne], time_created[min], time_created[max]
207
+ #
208
+ # - next_time (UNIX timestamp)
209
+ # * Filter scheduled messages by next_time
210
+ # * Allowed modifiers: next_time[exists], next_time[ne], next_time[min],
211
+ # next_time[max]
212
+ #
213
+ # - sort
214
+ # * Sort the results based on a field
215
+ # * Allowed values: default, name
216
+ # * Default: default
217
+ #
218
+ # - sort_dir
219
+ # * Sort the results in ascending or descending order
220
+ # * Allowed values: asc, desc
221
+ # * Default: asc
222
+ #
223
+ # - page_size (int)
224
+ # * Number of results returned per page (max 200)
225
+ # * Default: 50
226
+ #
227
+ # - offset (int)
228
+ # * Number of items to skip from beginning of result set
229
+ # * Default: 0
230
+ #
231
+ # Returns:
232
+ # Telerivet::APICursor (of Telerivet::ScheduledMessage)
233
+ #
234
+ def query_scheduled_messages(options = nil)
235
+ require_relative 'scheduledmessage'
236
+ @api.cursor(ScheduledMessage, get_base_api_path() + "/scheduled", options)
237
+ end
238
+
239
+ #
240
+ # Queries data rows associated with this contact (in any data table).
241
+ #
242
+ # Arguments:
243
+ # - options (Hash)
244
+ #
245
+ # - time_created (UNIX timestamp)
246
+ # * Filter data rows by the time they were created
247
+ # * Allowed modifiers: time_created[ne], time_created[min], time_created[max]
248
+ #
249
+ # - vars (Hash)
250
+ # * Filter data rows by value of a custom variable (e.g. vars[q1], vars[foo], etc.)
251
+ # * Allowed modifiers: vars[foo][exists], vars[foo][ne], vars[foo][prefix],
252
+ # vars[foo][not_prefix], vars[foo][gte], vars[foo][gt], vars[foo][lt], vars[foo][lte],
253
+ # vars[foo][min], vars[foo][max]
254
+ #
255
+ # - sort
256
+ # * Sort the results based on a field
257
+ # * Allowed values: default
258
+ # * Default: default
259
+ #
260
+ # - sort_dir
261
+ # * Sort the results in ascending or descending order
262
+ # * Allowed values: asc, desc
263
+ # * Default: asc
264
+ #
265
+ # - page_size (int)
266
+ # * Number of results returned per page (max 200)
267
+ # * Default: 50
268
+ #
269
+ # - offset (int)
270
+ # * Number of items to skip from beginning of result set
271
+ # * Default: 0
272
+ #
273
+ # Returns:
274
+ # Telerivet::APICursor (of Telerivet::DataRow)
275
+ #
276
+ def query_data_rows(options = nil)
277
+ require_relative 'datarow'
278
+ @api.cursor(DataRow, get_base_api_path() + "/rows", options)
279
+ end
280
+
281
+ #
282
+ # Queries this contact's current states for any service
283
+ #
284
+ # Arguments:
285
+ # - options (Hash)
286
+ #
287
+ # - id
288
+ # * Filter states by id
289
+ # * Allowed modifiers: id[ne], id[prefix], id[not_prefix], id[gte], id[gt], id[lt],
290
+ # id[lte]
291
+ #
292
+ # - vars (Hash)
293
+ # * Filter states by value of a custom variable (e.g. vars[email], vars[foo], etc.)
294
+ # * Allowed modifiers: vars[foo][exists], vars[foo][ne], vars[foo][prefix],
295
+ # vars[foo][not_prefix], vars[foo][gte], vars[foo][gt], vars[foo][lt], vars[foo][lte],
296
+ # vars[foo][min], vars[foo][max]
297
+ #
298
+ # - sort
299
+ # * Sort the results based on a field
300
+ # * Allowed values: default
301
+ # * Default: default
302
+ #
303
+ # - sort_dir
304
+ # * Sort the results in ascending or descending order
305
+ # * Allowed values: asc, desc
306
+ # * Default: asc
307
+ #
308
+ # - page_size (int)
309
+ # * Number of results returned per page (max 200)
310
+ # * Default: 50
311
+ #
312
+ # - offset (int)
313
+ # * Number of items to skip from beginning of result set
314
+ # * Default: 0
315
+ #
316
+ # Returns:
317
+ # Telerivet::APICursor (of Telerivet::ContactServiceState)
318
+ #
319
+ def query_service_states(options = nil)
320
+ require_relative 'contactservicestate'
321
+ @api.cursor(ContactServiceState, get_base_api_path() + "/states", options)
322
+ end
323
+
324
+ #
325
+ # Saves any fields or custom variables that have changed for this contact.
326
+ #
327
+ def save()
328
+ super
329
+ end
330
+
331
+ #
332
+ # Deletes this contact.
333
+ #
334
+ def delete()
335
+ @api.do_request("DELETE", get_base_api_path())
336
+ end
337
+
338
+ def id
339
+ get('id')
340
+ end
341
+
342
+ def name
343
+ get('name')
344
+ end
345
+
346
+ def name=(value)
347
+ set('name', value)
348
+ end
349
+
350
+ def phone_number
351
+ get('phone_number')
352
+ end
353
+
354
+ def phone_number=(value)
355
+ set('phone_number', value)
356
+ end
357
+
358
+ def time_created
359
+ get('time_created')
360
+ end
361
+
362
+ def last_message_time
363
+ get('last_message_time')
364
+ end
365
+
366
+ def last_message_id
367
+ get('last_message_id')
368
+ end
369
+
370
+ def default_route_id
371
+ get('default_route_id')
372
+ end
373
+
374
+ def default_route_id=(value)
375
+ set('default_route_id', value)
376
+ end
377
+
378
+ def group_ids
379
+ get('group_ids')
380
+ end
381
+
382
+ def project_id
383
+ get('project_id')
384
+ end
385
+
386
+ def get_base_api_path()
387
+ "/projects/#{get('project_id')}/contacts/#{get('id')}"
388
+ end
389
+
390
+
391
+ def set_data(data)
392
+ super
393
+
394
+ @group_ids_set = {}
395
+
396
+ if data.has_key?('group_ids')
397
+ data['group_ids'].each { |id| @group_ids_set[id] = true }
398
+ end
399
+ end
400
+
401
+ end
402
+
403
+ end
@@ -0,0 +1,108 @@
1
+
2
+ module Telerivet
3
+
4
+ #
5
+ # Represents the current state of a particular contact for a particular Telerivet service.
6
+ #
7
+ # Some automated services (including polls) are 'stateful'. For polls,
8
+ # Telerivet needs to keep track of which question the contact is currently answering, and
9
+ # stores store the ID of each contact's current question (e.g. 'q1' or 'q2') as the ID of the
10
+ # contact's state for the poll service. Any type of conversation-like service will also need
11
+ # to store state for each contact.
12
+ #
13
+ # For this type of entity, the 'id' field is NOT a read-only unique ID (unlike
14
+ # all other types of entities). Instead it is an arbitrary string that identifies the
15
+ # contact's current state within your poll/conversation; many contacts may have the same state
16
+ # ID, and it may change over time. Additional custom fields may be stored in the 'vars'.
17
+ #
18
+ # Initially, the state 'id' for any contact is null. When saving the state,
19
+ # setting the 'id' to null is equivalent to resetting the state (so all 'vars' will be
20
+ # deleted); if you want to save custom variables, the state 'id' must be non-null.
21
+ #
22
+ # Many Telerivet services are stateless, such as auto-replies or keyword-based
23
+ # services where the behavior only depends on the current message, and not any previous
24
+ # messages sent by the same contact. Telerivet doesn't store any state for contacts that
25
+ # interact with stateless services.
26
+ #
27
+ # Fields:
28
+ #
29
+ # - id (string, max 63 characters)
30
+ # * Arbitrary string representing the contact's current state for this service, e.g.
31
+ # 'q1', 'q2', etc.
32
+ # * Updatable via API
33
+ #
34
+ # - contact_id
35
+ # * ID of the contact
36
+ # * Read-only
37
+ #
38
+ # - service_id
39
+ # * ID of the service
40
+ # * Read-only
41
+ #
42
+ # - vars (Hash)
43
+ # * Custom variables stored for this contact/service state
44
+ # * Updatable via API
45
+ #
46
+ # - time_created (UNIX timestamp)
47
+ # * Time the state was first created in Telerivet
48
+ # * Read-only
49
+ #
50
+ # - time_updated (UNIX timestamp)
51
+ # * Time the state was last updated in Telerivet
52
+ # * Read-only
53
+ #
54
+ # - project_id
55
+ # * ID of the project this contact/service state belongs to
56
+ # * Read-only
57
+ #
58
+ class ContactServiceState < Entity
59
+ #
60
+ # Saves the state id and any custom variables for this contact. If the state id is null, this
61
+ # is equivalent to calling reset().
62
+ #
63
+ def save()
64
+ super
65
+ end
66
+
67
+ #
68
+ # Resets the state for this contact for this service.
69
+ #
70
+ def reset()
71
+ @api.do_request("DELETE", get_base_api_path())
72
+ end
73
+
74
+ def id
75
+ get('id')
76
+ end
77
+
78
+ def id=(value)
79
+ set('id', value)
80
+ end
81
+
82
+ def contact_id
83
+ get('contact_id')
84
+ end
85
+
86
+ def service_id
87
+ get('service_id')
88
+ end
89
+
90
+ def time_created
91
+ get('time_created')
92
+ end
93
+
94
+ def time_updated
95
+ get('time_updated')
96
+ end
97
+
98
+ def project_id
99
+ get('project_id')
100
+ end
101
+
102
+ def get_base_api_path()
103
+ "/projects/#{get('project_id')}/services/#{get('service_id')}/states/#{get('contact_id')}"
104
+ end
105
+
106
+ end
107
+
108
+ end