iterable-api-client 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,54 @@
1
+ module Iterable
2
+ ##
3
+ #
4
+ # Interact with /templates/push API endpoints
5
+ #
6
+ # @example Creating push templates endpoint object
7
+ # # With default config
8
+ # templates = Iterable::PushTemplates.new
9
+ # templates.get
10
+ #
11
+ # # With custom config
12
+ # conf = Iterable::Config.new(token: 'new-token')
13
+ # templates = Iterable::PushTemplates.new(config)
14
+ class PushTemplates < ApiResource
15
+ ##
16
+ #
17
+ # Get a push template
18
+ #
19
+ # @param template_id [String|Integer] A push template ID
20
+ # @param params [Hash] Additional params to use such as locale
21
+ #
22
+ # @return [Iterable::Response] A response object
23
+ def get(template_id, params = {})
24
+ params['templateId'] = template_id
25
+ Iterable.request(conf, '/templates/push/get', params).get
26
+ end
27
+
28
+ ##
29
+ #
30
+ # Update a push template
31
+ #
32
+ # @param template_id [String|Integer] A push template ID
33
+ # @param attrs [Hash] Update attributes
34
+ #
35
+ # @return [Iterable::Response] A response object
36
+ def update(template_id, attrs = {})
37
+ attrs['templateId'] = template_id
38
+ Iterable.request(conf, '/templates/push/update').post(attrs)
39
+ end
40
+
41
+ ##
42
+ #
43
+ # Upsert a push template by client template ID
44
+ #
45
+ # @param client_template_id [String] A client template id to use or create
46
+ # @param attrs [Hash] Update attributes
47
+ #
48
+ # @return [Iterable::Response] A response object
49
+ def upsert(client_template_id, attrs = {})
50
+ attrs['clientTemplateId'] = client_template_id
51
+ Iterable.request(conf, '/templates/push/upsert').post(attrs)
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,100 @@
1
+ require 'openssl'
2
+ require 'uri'
3
+
4
+ module Iterable
5
+ # @!visibility private
6
+ class Request
7
+ DEFAULT_OPTIONS = {
8
+ use_ssl: true,
9
+ verify_ssl: true,
10
+ verify_mode: OpenSSL::SSL::VERIFY_PEER
11
+ }.freeze
12
+
13
+ DEFAULT_HEADERS = {
14
+ 'accept' => 'application/json',
15
+ 'content-type' => 'application/json'
16
+ }.freeze
17
+
18
+ def initialize(config, path, params = {})
19
+ @config = config
20
+ @uri = build_uri(path, params)
21
+ @net = net_http
22
+ setup_http(@net)
23
+ end
24
+
25
+ def get(headers = {})
26
+ execute :get, {}, headers
27
+ end
28
+
29
+ def post(body = {}, headers = {})
30
+ execute :post, body, headers
31
+ end
32
+
33
+ def put(body = {}, headers = {})
34
+ execute :put, body, headers
35
+ end
36
+
37
+ def delete(headers = {})
38
+ execute :delete, {}, headers
39
+ end
40
+
41
+ private
42
+
43
+ def execute(verb, body = {}, headers = {})
44
+ http = connection(verb, body, headers)
45
+ setup_http(http)
46
+ transmit http
47
+ end
48
+
49
+ def connection(verb, body = {}, headers = {})
50
+ conn_headers = DEFAULT_HEADERS.merge(headers)
51
+ req = Net::HTTP.const_get(verb.to_s.capitalize, false).new(@uri, conn_headers)
52
+ req.body = JSON.dump(body)
53
+ req
54
+ end
55
+
56
+ def setup_http(http)
57
+ DEFAULT_OPTIONS.dup.each do |option, value|
58
+ setter = "#{option.to_sym}="
59
+ http.send(setter, value) if http.respond_to?(setter)
60
+ end
61
+ end
62
+
63
+ def build_uri(path, params = {})
64
+ uri = @config.uri
65
+ uri.path += path
66
+ params['api_key'] = @config.token
67
+ uri.query = URI.encode_www_form(params)
68
+ uri
69
+ end
70
+
71
+ def net_http
72
+ Net::HTTP.new(@uri.hostname, @uri.port, nil, nil, nil, nil)
73
+ end
74
+
75
+ def transmit(req)
76
+ response = nil
77
+ @net.start do |http|
78
+ response = http.request(req, nil, &:read_body)
79
+ end
80
+ handle_response response
81
+ end
82
+
83
+ def handle_response(response)
84
+ redirected = response.is_a?(Net::HTTPRedirection) || response.code == '303'
85
+ if redirected && response['location']
86
+ Response.new Net::HTTP.get_response(uri_for_redirect(response))
87
+ else
88
+ Response.new response
89
+ end
90
+ end
91
+
92
+ def uri_for_redirect(response)
93
+ uri = @config.uri
94
+ redirect_uri = URI(response['location'])
95
+ uri.path = redirect_uri.path
96
+ uri.query = redirect_uri.query
97
+ uri
98
+ end
99
+ end
100
+ end
@@ -0,0 +1,46 @@
1
+ require 'forwardable'
2
+
3
+ module Iterable
4
+ ##
5
+ #
6
+ # Response class is used to get access to raw HTTP request info
7
+ class Response
8
+ extend Forwardable
9
+
10
+ def_delegators :@resp, :code, :message, :uri
11
+
12
+ attr_reader :body
13
+
14
+ # @!visibility private
15
+ def initialize(resp) # @private
16
+ @resp = resp
17
+ @body = parsed_body
18
+ end
19
+
20
+ ##
21
+ #
22
+ # Convenience method to determine if request was successfull or not
23
+ # @return [Boolean]
24
+ def success?
25
+ case @resp.code.to_i
26
+ when (200..299) then true
27
+ else
28
+ false
29
+ end
30
+ end
31
+
32
+ private
33
+
34
+ ##
35
+ # Attempts to parse the response as JSON. Will rescue and return original
36
+ # if unable to parse.
37
+ #
38
+ # @return [Hash,Array,String] A parsed JSON object or the original response body
39
+ def parsed_body
40
+ response_body = @resp.body
41
+ MultiJson.load response_body
42
+ rescue MultiJson::ParseError
43
+ response_body
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,37 @@
1
+ module Iterable
2
+ ##
3
+ #
4
+ # Interact with /templates API endpoints
5
+ #
6
+ # @example Creating templates endpoint object
7
+ # # With default config
8
+ # templates = Iterable::Templates.new
9
+ # templates.all
10
+ #
11
+ # # With custom config
12
+ # conf = Iterable::Config.new(token: 'new-token')
13
+ # templates = Iterable::Templates.new(config)
14
+ class Templates < ApiResource
15
+ # Template types
16
+ TYPES = [
17
+ BASE_TYPE = 'Base'.freeze,
18
+ BLAST_TYPE = 'Blast'.freeze,
19
+ TRIGGERED_TYPE = 'Triggered'.freeze,
20
+ WORKFLOW_TYPE = 'Workflow'.freeze
21
+ ].freeze
22
+
23
+ ##
24
+ #
25
+ # Get all templates
26
+ #
27
+ # @return [Iterable::Response] A response object
28
+ def all(params = {})
29
+ Iterable.request(conf, '/templates', params).get
30
+ end
31
+
32
+ def for_client_template_id(client_template_id)
33
+ params = { clientTemplateId: client_template_id }
34
+ Iterable.request(conf, '/templates/getByClientTemplateId', params).get
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,190 @@
1
+ module Iterable
2
+ ##
3
+ #
4
+ # Interact with /users API endpoints
5
+ #
6
+ # @example Creating users endpoint object
7
+ # # With default config
8
+ # templates = Iterable::Users.new
9
+ # templates.get
10
+ #
11
+ # # With custom config
12
+ # conf = Iterable::Config.new(token: 'new-token')
13
+ # templates = Iterable::Users.new(config)
14
+ class Users < ApiResource
15
+ ##
16
+ #
17
+ # Update user data or adds a user if missing. Data is merged - missing
18
+ # fields are not deleted
19
+ #
20
+ # @param email [String] User email to update or create
21
+ # @param attrs [Hash] Additional data to update or add
22
+ #
23
+ # @return [Iterable::Response] A response object
24
+ def update(email, attrs = {})
25
+ attrs['email'] = email
26
+ Iterable.request(conf, '/users/update').post(attrs)
27
+ end
28
+
29
+ ##
30
+ #
31
+ # Bulk update user data or adds it if does not exist. Data is merged and
32
+ # missing fields are not deleted
33
+ #
34
+ # @param users [Array[Hash]] Array of hashes of user details
35
+ #
36
+ # @return [Iterable::Response] A response object
37
+ #
38
+ # @note User fields can be email [String], dataFields [Hash], or userId [String]
39
+ def bulk_update(users = [])
40
+ Iterable.request(conf, '/users/bulkUpdate').post(users: users)
41
+ end
42
+
43
+ ##
44
+ #
45
+ # Update user subscriptions. Overwrites existing data if the field is
46
+ # provided and not null
47
+ #
48
+ # @param email [String] User email to update
49
+ # @param attrs [Hash] Additional data to update
50
+ #
51
+ # @return [Iterable::Response] A response object
52
+ def update_subscriptions(email, attrs = {})
53
+ attrs['email'] = email
54
+ Iterable.request(conf, '/users/updateSubscriptions').post(attrs)
55
+ end
56
+
57
+ ##
58
+ #
59
+ # Update user subscriptions in bulk. Overwrites existing data if the field is
60
+ # provided and not null
61
+ #
62
+ # @param subscriptions [Array[Hash]] An array of subscription update attributes
63
+ #
64
+ # @return [Iterable::Response] A response object
65
+ #
66
+ # @note Refer to [Iterable::Users#update_subscriptions] for what subscription
67
+ # information is needed such as email
68
+ def bulk_update_subscriptions(subscriptions = [])
69
+ attrs = { updateSubscriptionsRequests: subscriptions }
70
+ Iterable.request(conf, '/users/bulkUpdateSubscriptions').post(attrs)
71
+ end
72
+
73
+ ##
74
+ #
75
+ # Get a user by their email
76
+ #
77
+ # @param email [String] The email of the user to get
78
+ #
79
+ # @return [Iterable::Response] A response object
80
+ def for_email(email)
81
+ Iterable.request(conf, "/users/#{email}").get
82
+ end
83
+
84
+ ##
85
+ #
86
+ # Update a user email
87
+ #
88
+ # @param email [String] The email of the user to get
89
+ #
90
+ # @return [Iterable::Response] A response object
91
+ def update_email(email, new_email)
92
+ attrs = { currentEmail: email, newEmail: new_email }
93
+ Iterable.request(conf, '/users/updateEmail').post(attrs)
94
+ end
95
+
96
+ ##
97
+ #
98
+ # Delete a user by their email
99
+ #
100
+ # @param email [String] The email of the user to delete
101
+ #
102
+ # @return [Iterable::Response] A response object
103
+ def delete(email)
104
+ Iterable.request(conf, "/users/#{email}").delete
105
+ end
106
+
107
+ ##
108
+ #
109
+ # Delete a user by their userId
110
+ #
111
+ # @param user_id [String] The userId of the user to delete
112
+ #
113
+ # @return [Iterable::Response] A response object
114
+ def delete_by_id(user_id)
115
+ Iterable.request(conf, "/users/byUserId/#{user_id}").delete
116
+ end
117
+
118
+ ##
119
+ #
120
+ # Get a user by their userId
121
+ #
122
+ # @param user_id [String] The user ID of the user to get
123
+ #
124
+ # @return [Iterable::Response] A response object
125
+ def for_id(user_id)
126
+ Iterable.request(conf, "/users/byUserId/#{user_id}").get
127
+ end
128
+
129
+ ##
130
+ #
131
+ # Get the user fields with mappings from field to type
132
+ #
133
+ # @return [Iterable::Response] A response object
134
+ def fields
135
+ Iterable.request(conf, '/users/getFields').get
136
+ end
137
+
138
+ ##
139
+ #
140
+ # Register a browser token for a user
141
+ #
142
+ # @param email [String] An email of a user
143
+ # @param token [String] The browser token to register
144
+ # @param attrs [Hash] Additional attrs like userId to pass along
145
+ #
146
+ # @return [Iterable::Response] A response object
147
+ #
148
+ # @note An email or userId is required
149
+ def register_browser_token(email, token, attrs = {})
150
+ attrs[:email] = email
151
+ attrs[:browserToken] = token
152
+ Iterable.request(conf, '/users/registerBrowserToken').post(attrs)
153
+ end
154
+
155
+ ##
156
+ #
157
+ # Disable a device
158
+ #
159
+ # @param token [String] A device token to disable
160
+ # @param email [String] Optional user email device belongs to to disable
161
+ # @param user_id [String] Optional user_id device belongs to to disable
162
+ #
163
+ # @return [Iterable::Response] A response object
164
+ #
165
+ # @note An email or userId is required
166
+ def disable_device(token, email = nil, user_id = nil)
167
+ attrs = { token: token }
168
+ attrs[:email] = email if email
169
+ attrs[:userId] = user_id if user_id
170
+ Iterable.request(conf, '/users/disableDevice').post(attrs)
171
+ end
172
+
173
+ ##
174
+ #
175
+ # Get sent messages for a user
176
+ #
177
+ # @param email [String] An email for a user to retreive messages for
178
+ # @param start_time [Time] An optional start time for range of messages
179
+ # @param end_time [Time] An optional end time for range of messages
180
+ # @param params [Hash] Additional params to use to filter messages further
181
+ #
182
+ # @return [Iterable::Response] A response object
183
+ def sent_messages(email, start_time = nil, end_time = nil, params = {})
184
+ params[:email] = email
185
+ params[:startTime] = start_time.to_s if start_time
186
+ params[:endTime] = end_time.to_s if end_time
187
+ Iterable.request(conf, '/users/getSentMessages', params).get
188
+ end
189
+ end
190
+ end
@@ -0,0 +1,30 @@
1
+ module Iterable
2
+ ##
3
+ #
4
+ # Interact with /workflows API endpoints
5
+ #
6
+ # @example Creating workflows endpoint object
7
+ # # With default config
8
+ # templates = Iterable::Workflows.new
9
+ # templates.get
10
+ #
11
+ # # With custom config
12
+ # conf = Iterable::Config.new(token: 'new-token')
13
+ # templates = Iterable::Workflows.new(config)
14
+ class Workflows < ApiResource
15
+ ##
16
+ #
17
+ # Trigger a workflow for an email or a list.
18
+ #
19
+ # @param workflow_id [Integer] workflow_id to trigger
20
+ # @param attrs [Hash] Additional data fields
21
+ #
22
+ # @return [Iterable::Response] A response object
23
+ #
24
+ # @note An email or listId is required to trigger a workflow
25
+ def trigger(workflow_id, attrs = {})
26
+ attrs['workflowId'] = workflow_id
27
+ Iterable.request(conf, '/workflows/triggerWorkflow').post(attrs)
28
+ end
29
+ end
30
+ end