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,185 @@
1
+
2
+ module Telerivet
3
+
4
+ #
5
+ # Represents a scheduled message within Telerivet.
6
+ #
7
+ # Fields:
8
+ #
9
+ # - id (string, max 34 characters)
10
+ # * ID of the scheduled message
11
+ # * Read-only
12
+ #
13
+ # - content
14
+ # * Text content of the scheduled message
15
+ # * Read-only
16
+ #
17
+ # - rrule
18
+ # * Recurrence rule for recurring scheduled messages, e.g. 'FREQ=MONTHLY' or
19
+ # 'FREQ=WEEKLY;INTERVAL=2'; see <https://tools.ietf.org/html/rfc2445#section-4.3.10>
20
+ # * Read-only
21
+ #
22
+ # - timezone_id
23
+ # * Timezone ID used to compute times for recurring messages; see
24
+ # <http://en.wikipedia.org/wiki/List_of_tz_database_time_zones>
25
+ # * Read-only
26
+ #
27
+ # - group_id
28
+ # * ID of the group to send the message to (null if scheduled to an individual contact)
29
+ # * Read-only
30
+ #
31
+ # - contact_id
32
+ # * ID of the contact to send the message to (null if scheduled to a group)
33
+ # * Read-only
34
+ #
35
+ # - to_number
36
+ # * Phone number to send the message to (null if scheduled to a group)
37
+ # * Read-only
38
+ #
39
+ # - route_id
40
+ # * ID of the phone or route to the message will be sent from
41
+ # * Read-only
42
+ #
43
+ # - message_type
44
+ # * Type of scheduled message
45
+ # * Allowed values: sms, ussd
46
+ # * Read-only
47
+ #
48
+ # - time_created (UNIX timestamp)
49
+ # * Time the scheduled message was created in Telerivet
50
+ # * Read-only
51
+ #
52
+ # - start_time (UNIX timestamp)
53
+ # * The time that the message will be sent (or first sent for recurring messages)
54
+ # * Read-only
55
+ #
56
+ # - end_time (UNIX timestamp)
57
+ # * Time after which a recurring message will stop (not applicable to non-recurring
58
+ # scheduled messages)
59
+ # * Read-only
60
+ #
61
+ # - prev_time (UNIX timestamp)
62
+ # * The most recent time that Telerivet has sent this scheduled message (null if it has
63
+ # never been sent)
64
+ # * Read-only
65
+ #
66
+ # - next_time (UNIX timestamp)
67
+ # * The next upcoming time that Telerivet will sent this scheduled message (null if it
68
+ # will not be sent again)
69
+ # * Read-only
70
+ #
71
+ # - occurrences (int)
72
+ # * Number of times this scheduled message has already been sent
73
+ # * Read-only
74
+ #
75
+ # - is_template
76
+ # * Set to true if Telerivet will render variables like [[contact.name]] in the message
77
+ # content, false otherwise
78
+ # * Read-only
79
+ #
80
+ # - vars (Hash)
81
+ # * Custom variables stored for this scheduled message (copied to Message when sent)
82
+ # * Updatable via API
83
+ #
84
+ # - label_ids (array)
85
+ # * IDs of labels to add to the Message
86
+ # * Read-only
87
+ #
88
+ # - project_id
89
+ # * ID of the project this scheduled message belongs to
90
+ # * Read-only
91
+ #
92
+ class ScheduledMessage < Entity
93
+ #
94
+ # Saves any fields or custom variables that have changed for this scheduled message.
95
+ #
96
+ def save()
97
+ super
98
+ end
99
+
100
+ #
101
+ # Cancels this scheduled message.
102
+ #
103
+ def delete()
104
+ @api.do_request("DELETE", get_base_api_path())
105
+ end
106
+
107
+ def id
108
+ get('id')
109
+ end
110
+
111
+ def content
112
+ get('content')
113
+ end
114
+
115
+ def rrule
116
+ get('rrule')
117
+ end
118
+
119
+ def timezone_id
120
+ get('timezone_id')
121
+ end
122
+
123
+ def group_id
124
+ get('group_id')
125
+ end
126
+
127
+ def contact_id
128
+ get('contact_id')
129
+ end
130
+
131
+ def to_number
132
+ get('to_number')
133
+ end
134
+
135
+ def route_id
136
+ get('route_id')
137
+ end
138
+
139
+ def message_type
140
+ get('message_type')
141
+ end
142
+
143
+ def time_created
144
+ get('time_created')
145
+ end
146
+
147
+ def start_time
148
+ get('start_time')
149
+ end
150
+
151
+ def end_time
152
+ get('end_time')
153
+ end
154
+
155
+ def prev_time
156
+ get('prev_time')
157
+ end
158
+
159
+ def next_time
160
+ get('next_time')
161
+ end
162
+
163
+ def occurrences
164
+ get('occurrences')
165
+ end
166
+
167
+ def is_template
168
+ get('is_template')
169
+ end
170
+
171
+ def label_ids
172
+ get('label_ids')
173
+ end
174
+
175
+ def project_id
176
+ get('project_id')
177
+ end
178
+
179
+ def get_base_api_path()
180
+ "/projects/#{get('project_id')}/scheduled/#{get('id')}"
181
+ end
182
+
183
+ end
184
+
185
+ end
@@ -0,0 +1,296 @@
1
+ module Telerivet
2
+
3
+ #
4
+ # Represents an automated service on Telerivet, for example a poll, auto-reply, webhook
5
+ # service, etc.
6
+ #
7
+ # A service, generally, defines some automated behavior that can be
8
+ # invoked/triggered in a particular context, and may be invoked either manually or when a
9
+ # particular event occurs.
10
+ #
11
+ # Most commonly, services work in the context of a particular message, when
12
+ # the message is originally received by Telerivet.
13
+ #
14
+ # Fields:
15
+ #
16
+ # - id (string, max 34 characters)
17
+ # * ID of the service
18
+ # * Read-only
19
+ #
20
+ # - name
21
+ # * Name of the service
22
+ # * Updatable via API
23
+ #
24
+ # - active (bool)
25
+ # * Whether the service is active or inactive. Inactive services are not automatically
26
+ # triggered and cannot be invoked via the API.
27
+ # * Updatable via API
28
+ #
29
+ # - priority (int)
30
+ # * A number that determines the order that services are triggered when a particular
31
+ # event occurs (smaller numbers are triggered first). Any service can determine whether
32
+ # or not execution "falls-through" to subsequent services (with larger priority values)
33
+ # by setting the return_value variable within Telerivet's Rules Engine.
34
+ # * Updatable via API
35
+ #
36
+ # - contexts (Hash)
37
+ # * A key/value map where the keys are the names of contexts supported by this service
38
+ # (e.g. message, contact), and the values are themselves key/value maps where the keys
39
+ # are event names and the values are all true. (This structure makes it easy to test
40
+ # whether a service can be invoked for a particular context and event.)
41
+ # * Read-only
42
+ #
43
+ # - vars (Hash)
44
+ # * Custom variables stored for this service
45
+ # * Updatable via API
46
+ #
47
+ # - project_id
48
+ # * ID of the project this service belongs to
49
+ # * Read-only
50
+ #
51
+ # - label_id
52
+ # * ID of the label containing messages sent or received by this service (currently only
53
+ # used for polls)
54
+ # * Read-only
55
+ #
56
+ # - response_table_id
57
+ # * ID of the data table where responses to this service will be stored (currently only
58
+ # used for polls)
59
+ # * Read-only
60
+ #
61
+ # - sample_group_id
62
+ # * ID of the group containing contacts that have been invited to interact with this
63
+ # service (currently only used for polls)
64
+ # * Read-only
65
+ #
66
+ # - respondent_group_id
67
+ # * ID of the group containing contacts that have completed an interaction with this
68
+ # service (currently only used for polls)
69
+ # * Read-only
70
+ #
71
+ class Service < Entity
72
+
73
+ #
74
+ # Manually invoke this service in a particular context.
75
+ #
76
+ # For example, to send a poll to a particular contact (or resend the
77
+ # current question), you can invoke the poll service with context=contact, and contact_id as
78
+ # the ID of the contact to send the poll to.
79
+ #
80
+ # Or, to manually apply a service for an incoming message, you can
81
+ # invoke the service with context=message, event=incoming\_message, and message_id as the ID
82
+ # of the incoming message. (This is normally not necessary, but could be used if you want to
83
+ # override Telerivet's standard priority-ordering of services.)
84
+ #
85
+ # Arguments:
86
+ # - options (Hash)
87
+ # * Required
88
+ #
89
+ # - context
90
+ # * The name of the context in which this service is invoked
91
+ # * Allowed values: message, contact, project, receipt
92
+ # * Required
93
+ #
94
+ # - event
95
+ # * The name of the event that is triggered (must be supported by this service)
96
+ # * Default: default
97
+ #
98
+ # - message_id
99
+ # * The ID of the message this service is triggered for
100
+ # * Required if context is 'message'
101
+ #
102
+ # - contact_id
103
+ # * The ID of the contact this service is triggered for
104
+ # * Required if context is 'contact'
105
+ #
106
+ def invoke(options)
107
+ invoke_result = @api.do_request('POST', get_base_api_path() + '/invoke', options)
108
+
109
+ if invoke_result.has_key?('sent_messages')
110
+ require_relative 'message'
111
+
112
+ sent_messages = []
113
+
114
+ invoke_result['sent_messages'].each { |sent_message_data|
115
+ sent_messages.push(Message.new(@api, sent_message_data))
116
+ }
117
+
118
+ invoke_result['sent_messages'] = sent_messages
119
+ end
120
+
121
+ return invoke_result
122
+ end
123
+
124
+ #
125
+ # Gets the current state for a particular contact for this service.
126
+ #
127
+ # If the contact doesn't already have a state, this method will return
128
+ # a valid state object with id=null. However this object would not be returned by
129
+ # queryContactStates() unless it is saved with a non-null state id.
130
+ #
131
+ # Arguments:
132
+ # - contact (Telerivet::Contact)
133
+ # * The contact whose state you want to retrieve.
134
+ # * Required
135
+ #
136
+ # Returns:
137
+ # Telerivet::ContactServiceState
138
+ #
139
+ def get_contact_state(contact)
140
+ require_relative 'contactservicestate'
141
+ ContactServiceState.new(@api, @api.do_request('GET', get_base_api_path() + '/states/' + contact.id))
142
+ end
143
+
144
+ #
145
+ # Initializes or updates the current state for a particular contact for the given service. If
146
+ # the state id is null, the contact's state will be reset.
147
+ #
148
+ # Arguments:
149
+ # - contact (Telerivet::Contact)
150
+ # * The contact whose state you want to update.
151
+ # * Required
152
+ #
153
+ # - options (Hash)
154
+ # * Required
155
+ #
156
+ # - id (string, max 63 characters)
157
+ # * Arbitrary string representing the contact's current state for this service, e.g.
158
+ # 'q1', 'q2', etc.
159
+ # * Required
160
+ #
161
+ # - vars (Hash)
162
+ # * Custom variables stored for this contact's state
163
+ #
164
+ # Returns:
165
+ # Telerivet::ContactServiceState
166
+ #
167
+ def set_contact_state(contact, options)
168
+ require_relative 'contactservicestate'
169
+ ContactServiceState.new(@api, @api.do_request('POST', get_base_api_path() + '/states/' + contact.id, options))
170
+ end
171
+
172
+ #
173
+ # Resets the current state for a particular contact for the given service.
174
+ #
175
+ # Arguments:
176
+ # - contact (Telerivet::Contact)
177
+ # * The contact whose state you want to reset.
178
+ # * Required
179
+ #
180
+ # Returns:
181
+ # Telerivet::ContactServiceState
182
+ #
183
+ def reset_contact_state(contact)
184
+ require_relative 'contactservicestate'
185
+ ContactServiceState.new(@api, @api.do_request('DELETE', get_base_api_path() + '/states/' + contact.id))
186
+ end
187
+
188
+ #
189
+ # Query the current states of contacts for this service.
190
+ #
191
+ # Arguments:
192
+ # - options (Hash)
193
+ #
194
+ # - id
195
+ # * Filter states by id
196
+ # * Allowed modifiers: id[ne], id[prefix], id[not_prefix], id[gte], id[gt], id[lt],
197
+ # id[lte]
198
+ #
199
+ # - vars (Hash)
200
+ # * Filter states by value of a custom variable (e.g. vars[email], vars[foo], etc.)
201
+ # * Allowed modifiers: vars[foo][exists], vars[foo][ne], vars[foo][prefix],
202
+ # vars[foo][not_prefix], vars[foo][gte], vars[foo][gt], vars[foo][lt], vars[foo][lte],
203
+ # vars[foo][min], vars[foo][max]
204
+ #
205
+ # - sort
206
+ # * Sort the results based on a field
207
+ # * Allowed values: default
208
+ # * Default: default
209
+ #
210
+ # - sort_dir
211
+ # * Sort the results in ascending or descending order
212
+ # * Allowed values: asc, desc
213
+ # * Default: asc
214
+ #
215
+ # - page_size (int)
216
+ # * Number of results returned per page (max 200)
217
+ # * Default: 50
218
+ #
219
+ # - offset (int)
220
+ # * Number of items to skip from beginning of result set
221
+ # * Default: 0
222
+ #
223
+ # Returns:
224
+ # Telerivet::APICursor (of Telerivet::ContactServiceState)
225
+ #
226
+ def query_contact_states(options = nil)
227
+ require_relative 'contactservicestate'
228
+ @api.cursor(ContactServiceState, get_base_api_path() + "/states", options)
229
+ end
230
+
231
+ #
232
+ # Saves any fields or custom variables that have changed for this service.
233
+ #
234
+ def save()
235
+ super
236
+ end
237
+
238
+ def id
239
+ get('id')
240
+ end
241
+
242
+ def name
243
+ get('name')
244
+ end
245
+
246
+ def name=(value)
247
+ set('name', value)
248
+ end
249
+
250
+ def active
251
+ get('active')
252
+ end
253
+
254
+ def active=(value)
255
+ set('active', value)
256
+ end
257
+
258
+ def priority
259
+ get('priority')
260
+ end
261
+
262
+ def priority=(value)
263
+ set('priority', value)
264
+ end
265
+
266
+ def contexts
267
+ get('contexts')
268
+ end
269
+
270
+ def project_id
271
+ get('project_id')
272
+ end
273
+
274
+ def label_id
275
+ get('label_id')
276
+ end
277
+
278
+ def response_table_id
279
+ get('response_table_id')
280
+ end
281
+
282
+ def sample_group_id
283
+ get('sample_group_id')
284
+ end
285
+
286
+ def respondent_group_id
287
+ get('respondent_group_id')
288
+ end
289
+
290
+ def get_base_api_path()
291
+ "/projects/#{get('project_id')}/services/#{get('id')}"
292
+ end
293
+
294
+ end
295
+
296
+ end
data/lib/telerivet.rb ADDED
@@ -0,0 +1,193 @@
1
+ require 'net/http'
2
+ require 'json'
3
+ require_relative 'telerivet/entity'
4
+ require_relative 'telerivet/apicursor'
5
+
6
+ module Telerivet
7
+
8
+ #
9
+ #
10
+ #
11
+ class API
12
+ attr_reader :num_requests
13
+
14
+ @@client_version = '1.0.2'
15
+
16
+ #
17
+ # Initializes a client handle to the Telerivet REST API.
18
+ #
19
+ # Each API key is associated with a Telerivet user account, and all
20
+ # API actions are performed with that user's permissions. If you want to restrict the
21
+ # permissions of an API client, simply add another user account at
22
+ # <https://telerivet.com/dashboard/users> with the desired permissions.
23
+ #
24
+ # Arguments:
25
+ # - api_key (Your Telerivet API key; see <https://telerivet.com/dashboard/api>)
26
+ # * Required
27
+ #
28
+ def initialize(api_key, api_url = 'https://api.telerivet.com/v1')
29
+ @api_key = api_key
30
+ @api_url = api_url
31
+ @num_requests = 0
32
+ @session = nil
33
+ end
34
+
35
+ public
36
+
37
+ def do_request(method, path, params = nil)
38
+
39
+ has_post_data = (method == 'POST' || method == 'PUT')
40
+
41
+ url = @api_url + path
42
+
43
+ if !has_post_data and params != nil && params.length > 0
44
+ url += '?' + URI.encode_www_form(get_url_params(params))
45
+ end
46
+
47
+ uri = URI(url)
48
+
49
+ if @session == nil
50
+ @session = Net::HTTP.start(uri.host, uri.port,
51
+ :use_ssl => @api_url.start_with?("https://"),
52
+ :ca_file => File.dirname(__FILE__) + '/cacert.pem',
53
+ :read_timeout => 35,
54
+ :open_timeout => 20,
55
+ )
56
+ end
57
+
58
+ cls = get_request_class(method)
59
+ request = cls.new(uri)
60
+
61
+ request['User-Agent'] = "Telerivet Ruby Client/#{@@client_version} Ruby/#{RUBY_VERSION} OS/#{RUBY_PLATFORM}"
62
+ request.basic_auth(@api_key, "")
63
+
64
+ if has_post_data
65
+ request.set_content_type("application/json")
66
+ request.body = JSON.dump(params)
67
+ end
68
+
69
+ @num_requests += 1
70
+
71
+ response = @session.request(request)
72
+
73
+ res = JSON.parse(response.body)
74
+
75
+ if res.has_key?("error")
76
+ error = res['error']
77
+ error_code = error['code']
78
+
79
+ if error_code == 'invalid_param'
80
+ raise InvalidParameterException, error['message'] #, error['code'], error['param'])
81
+ elsif error_code == 'not_found'
82
+ raise NotFoundException, error['message'] #, error['code']);
83
+ else
84
+ raise APIException, error['message'] #, error['code'])
85
+ end
86
+ else
87
+ return res
88
+ end
89
+ end
90
+
91
+ #
92
+ # Retrieves the Telerivet project with the given ID.
93
+ #
94
+ # Arguments:
95
+ # - id
96
+ # * ID of the project -- see <https://telerivet.com/dashboard/api>
97
+ # * Required
98
+ #
99
+ # Returns:
100
+ # Telerivet::Project
101
+ #
102
+ def get_project_by_id(id)
103
+ require_relative 'telerivet/project'
104
+ Project.new(self, {'id' => id}, false)
105
+ end
106
+
107
+ #
108
+ # Queries projects accessible to the current user account.
109
+ #
110
+ # Arguments:
111
+ # - options (Hash)
112
+ #
113
+ # - name
114
+ # * Filter projects by name
115
+ # * Allowed modifiers: name[ne], name[prefix], name[not_prefix], name[gte], name[gt],
116
+ # name[lt], name[lte]
117
+ #
118
+ # - sort
119
+ # * Sort the results based on a field
120
+ # * Allowed values: default, name
121
+ # * Default: default
122
+ #
123
+ # - sort_dir
124
+ # * Sort the results in ascending or descending order
125
+ # * Allowed values: asc, desc
126
+ # * Default: asc
127
+ #
128
+ # - page_size (int)
129
+ # * Number of results returned per page (max 200)
130
+ # * Default: 50
131
+ #
132
+ # - offset (int)
133
+ # * Number of items to skip from beginning of result set
134
+ # * Default: 0
135
+ #
136
+ # Returns:
137
+ # Telerivet::APICursor (of Telerivet::Project)
138
+ #
139
+ def query_projects(options = nil)
140
+ require_relative 'telerivet/project'
141
+ cursor(Project, '/projects', options)
142
+ end
143
+
144
+ def cursor(item_cls, path, options)
145
+ APICursor.new(self, item_cls, path, options)
146
+ end
147
+
148
+ private
149
+
150
+ def encode_params_rec(param_name, value, res)
151
+ return if value == nil
152
+
153
+ if value.kind_of?(Array)
154
+ value.each_index { |i| encode_params_rec("#{param_name}[#{i}]", value[i], res) }
155
+ elsif value.kind_of?(Hash)
156
+ value.each { |k,v| encode_params_rec("#{param_name}[#{k}]", v, res) }
157
+ elsif !!value == value
158
+ res[param_name] = value ? 1 : 0
159
+ else
160
+ res[param_name] = value
161
+ end
162
+ end
163
+
164
+ def get_url_params(params)
165
+ res = {}
166
+ if params != nil
167
+ params.each { |key,value| encode_params_rec(key, value, res) }
168
+ end
169
+ return res
170
+ end
171
+
172
+ def get_request_class(method)
173
+ case method
174
+ when 'GET' then return Net::HTTP::Get
175
+ when 'POST' then return Net::HTTP::Post
176
+ when 'DELETE' then return Net::HTTP::Delete
177
+ when 'PUT' then return Net::HTTP::Put
178
+ else return nil
179
+ end
180
+ end
181
+
182
+ end
183
+
184
+ class APIException < Exception
185
+ end
186
+
187
+ class NotFoundException < APIException
188
+ end
189
+
190
+ class InvalidParameterException < APIException
191
+ end
192
+
193
+ end