telerivet 1.0.2

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.
@@ -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