iter 0.1.0
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/.rspec +3 -0
- data/.rubocop.yml +17 -0
- data/CHANGELOG.md +3 -0
- data/LICENSE.txt +21 -0
- data/README.md +113 -0
- data/Rakefile +6 -0
- data/lib/iter/config.rb +45 -0
- data/lib/iter/configuration.rb +39 -0
- data/lib/iter/connection_error.rb +5 -0
- data/lib/iter/error.rb +5 -0
- data/lib/iter/http_request.rb +88 -0
- data/lib/iter/mock_request.rb +34 -0
- data/lib/iter/relation.rb +89 -0
- data/lib/iter/resource.rb +12 -0
- data/lib/iter/user.rb +26 -0
- data/lib/iter/version.rb +3 -0
- data/lib/iter.rb +10 -0
- metadata +102 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 0e2f0aa5860775ce8a35e8071cea50f55340a251d177e6ea71c52acc6a30165b
|
4
|
+
data.tar.gz: 0fad5fafa01504d396598a07184eaeaadc3675f60317e04d51f74b8ffc1fd3f4
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: e5269a14093d64f8b193cdb72d2f5838a418cc7c6ff910a0d560cdfcc371cfe7edf1baf0cdeb334427b09e1aa5c394a08d8960c63b0133d52b6f35f94b438c3c
|
7
|
+
data.tar.gz: e42058290262b82e5d20215694fb00598e4fa839e7e4e3d0a43abb5382576293ce21a85f09d886316c736af8e82608f319baa3cd4ebc0d48776a984014b271ab
|
data/.rspec
ADDED
data/.rubocop.yml
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
# Omakase Ruby styling for Rails
|
2
|
+
inherit_gem: { rubocop-rails-omakase: rubocop.yml }
|
3
|
+
|
4
|
+
AllCops:
|
5
|
+
TargetRubyVersion: 3.2.2
|
6
|
+
|
7
|
+
Style/StringLiterals:
|
8
|
+
Enabled: false
|
9
|
+
|
10
|
+
Layout/SpaceInsideArrayLiteralBrackets:
|
11
|
+
Enabled: false
|
12
|
+
|
13
|
+
Style/TrailingCommaInHashLiteral:
|
14
|
+
Enabled: false
|
15
|
+
|
16
|
+
Style/TrailingCommaInArrayLiteral:
|
17
|
+
Enabled: false
|
data/CHANGELOG.md
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2025 HouseAccount, Inc.
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,113 @@
|
|
1
|
+
Iter - a Ruby client for the Iterable API
|
2
|
+
======================================================
|
3
|
+
|
4
|
+
Iter helps you write apps that need to interact with Iterable.
|
5
|
+
|
6
|
+
The **source code** is available on [GitHub](https://github.com/claudiob/iter) and the **documentation** on [RubyDoc](http://www.rubydoc.info/gems/iter/frames).
|
7
|
+
|
8
|
+
[](https://codeclimate.com/github/claudiob/iter)
|
9
|
+
[](https://github.com/claudiob/bookmaker/actions)
|
10
|
+
[](https://rubygems.org/gems/iter)
|
11
|
+
|
12
|
+
After [registering your app](#configuring-your-app), you can run commands like:
|
13
|
+
|
14
|
+
|
15
|
+
```ruby
|
16
|
+
Iter::User.new(id:).update email:, fields:
|
17
|
+
Iter::User.new(id:).delete
|
18
|
+
Iter::Event.create(user_id:, name:, fields:)
|
19
|
+
```
|
20
|
+
|
21
|
+
The **full documentation** is available at [rubydoc.info](http://www.rubydoc.info/gems/iter/frames).
|
22
|
+
|
23
|
+
How to install
|
24
|
+
==============
|
25
|
+
|
26
|
+
To install on your system, run
|
27
|
+
|
28
|
+
gem install iter
|
29
|
+
|
30
|
+
To use inside a bundled Ruby project, add this line to the Gemfile:
|
31
|
+
|
32
|
+
gem 'iter', '~> 1.0'
|
33
|
+
|
34
|
+
Since the gem follows [Semantic Versioning](http://semver.org),
|
35
|
+
indicating the full version in your Gemfile (~> *major*.*minor*.*patch*)
|
36
|
+
guarantees that your project won’t occur in any error when you `bundle update`
|
37
|
+
and a new version of Iter is released.
|
38
|
+
|
39
|
+
Configuring your app
|
40
|
+
====================
|
41
|
+
|
42
|
+
In order to use Iter you must have credentials to the [Iterable](https://www.iterable.com/) API.
|
43
|
+
|
44
|
+
Add them to your code with the following snippet of code (replacing with your own credentials):
|
45
|
+
|
46
|
+
```ruby
|
47
|
+
Iter.configure do |config|
|
48
|
+
config.api_key = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ012345'
|
49
|
+
end
|
50
|
+
```
|
51
|
+
|
52
|
+
Mocking the Iterable API
|
53
|
+
======================
|
54
|
+
|
55
|
+
Sometimes you want to mock the API requests to Iterable and obtain results that
|
56
|
+
are equivalent to the original API calls. This can be useful to test your flow
|
57
|
+
without hitting the API.
|
58
|
+
|
59
|
+
|
60
|
+
Configuring with environment variables
|
61
|
+
--------------------------------------
|
62
|
+
|
63
|
+
As an alternative to the approach above, you can configure your app with
|
64
|
+
variables. Setting the following environment variables:
|
65
|
+
|
66
|
+
```bash
|
67
|
+
export ITER_API_KEY="ABCDEFGHIJKLMNOPQRSTUVWXYZ012345"
|
68
|
+
```
|
69
|
+
|
70
|
+
is equivalent to the previous approach so pick the one you prefer.
|
71
|
+
If a variable is set in both places, then `Iter.configure` takes precedence.
|
72
|
+
|
73
|
+
How to test
|
74
|
+
===========
|
75
|
+
|
76
|
+
To run tests:
|
77
|
+
|
78
|
+
```bash
|
79
|
+
rspec
|
80
|
+
```
|
81
|
+
|
82
|
+
By default, tests are run with real HTTP calls to Iterable that must be
|
83
|
+
set with the environment variables specified above.
|
84
|
+
|
85
|
+
If you do not have access to Iterable, you can still run the tests mocked:
|
86
|
+
|
87
|
+
```bash
|
88
|
+
ITER_MOCK=1 rspec
|
89
|
+
```
|
90
|
+
|
91
|
+
How to release new versions
|
92
|
+
===========================
|
93
|
+
|
94
|
+
If you are a manager of this project, remember to upgrade the [Iter gem](http://rubygems.org/gems/iter)
|
95
|
+
whenever a new feature is added or a bug gets fixed.
|
96
|
+
Make sure all the tests are passing and the code is 100% test-covered.
|
97
|
+
Document the changes in CHANGELOG.md and README.md, bump the version, then run:
|
98
|
+
|
99
|
+
rake release
|
100
|
+
|
101
|
+
Remember that the iter gem follows [Semantic Versioning](http://semver.org).
|
102
|
+
Any new release that is fully backward-compatible should bump the *minor* version (1.x).
|
103
|
+
Any new version that breaks compatibility should bump the *major* version (x.0)
|
104
|
+
|
105
|
+
How to contribute
|
106
|
+
=================
|
107
|
+
|
108
|
+
Iter needs your support!
|
109
|
+
The goal of Iter is to provide a Ruby interface for all the methods exposed by the Iterable API.
|
110
|
+
|
111
|
+
If you find that a method is missing, fork the project, add the missing code,
|
112
|
+
write the appropriate tests, then submit a pull request, and it will gladly
|
113
|
+
be merged!
|
data/Rakefile
ADDED
data/lib/iter/config.rb
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'iter/configuration'
|
2
|
+
|
3
|
+
# An object-oriented Ruby client for Iterable.
|
4
|
+
# @see http://www.rubydoc.info/gems/iter/
|
5
|
+
module Iter
|
6
|
+
# Provides methods to read and write global configuration settings.
|
7
|
+
#
|
8
|
+
# A typical usage is to set the API key for the API calls.
|
9
|
+
#
|
10
|
+
# @example Set the API key for the API client:
|
11
|
+
# Iter.configure do |config|
|
12
|
+
# config.api_key = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ012345'
|
13
|
+
# end
|
14
|
+
#
|
15
|
+
module Config
|
16
|
+
# Yields the global configuration to the given block.
|
17
|
+
#
|
18
|
+
# @example
|
19
|
+
# Iter.configure do |config|
|
20
|
+
# config.api_key = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ012345'
|
21
|
+
# end
|
22
|
+
#
|
23
|
+
# @yield [Iter::Models::Configuration] The global configuration.
|
24
|
+
def configure
|
25
|
+
yield configuration if block_given?
|
26
|
+
end
|
27
|
+
|
28
|
+
# Returns the global {Iter::Models::Configuration} object.
|
29
|
+
#
|
30
|
+
# While this method _can_ be used to read and write configuration settings,
|
31
|
+
# it is easier to use {Iter::Config#configure} Iter.configure}.
|
32
|
+
#
|
33
|
+
# @example
|
34
|
+
# Iter.configuration.api_key = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ012345'
|
35
|
+
#
|
36
|
+
# @return [Iter::Models::Configuration] The global configuration.
|
37
|
+
def configuration
|
38
|
+
@configuration ||= Iter::Configuration.new
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
# @note Config is the only module auto-loaded in the Iter module,
|
43
|
+
# in order to have a syntax as easy as Iter.configure
|
44
|
+
extend Config
|
45
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module Iter
|
2
|
+
# Provides an object to store global configuration settings.
|
3
|
+
#
|
4
|
+
# This class is typically not used directly, but by calling
|
5
|
+
# {Iter::Config#configure Iter.configure}, which creates and updates a single
|
6
|
+
# instance of {Iter::Models::Configuration}.
|
7
|
+
#
|
8
|
+
# @example Set the API key for the API client:
|
9
|
+
# Iter.configure do |config|
|
10
|
+
# config.api_key = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ012345'
|
11
|
+
# end
|
12
|
+
#
|
13
|
+
# @see Iter::Config for more examples.
|
14
|
+
#
|
15
|
+
# An alternative way to set global configuration settings is by storing
|
16
|
+
# them in the following environment variables:
|
17
|
+
#
|
18
|
+
# * +ITER_API_KEY+ to store the API key for the Iterable API
|
19
|
+
#
|
20
|
+
# In case both methods are used together,
|
21
|
+
# {Iter::Config#configure Iter.configure} takes precedence.
|
22
|
+
#
|
23
|
+
# @example Set the API credentials
|
24
|
+
# ENV['ITER_API_KEY'] = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ012345'
|
25
|
+
class Configuration
|
26
|
+
# @return [String] the API key for the API calls.
|
27
|
+
attr_accessor :api_key
|
28
|
+
|
29
|
+
# @return [Boolean] whether to mock the HTTP calls to Iterable
|
30
|
+
attr_accessor :mock
|
31
|
+
|
32
|
+
# Initialize the global configuration settings, using the values of
|
33
|
+
# the specified following environment variables by default.
|
34
|
+
def initialize
|
35
|
+
@api_key = ENV['ITER_API_KEY']
|
36
|
+
@mock = ENV['ITER_MOCK'] == '1'
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
data/lib/iter/error.rb
ADDED
@@ -0,0 +1,88 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'net/http'
|
3
|
+
|
4
|
+
require 'iter/connection_error'
|
5
|
+
require 'iter/error'
|
6
|
+
|
7
|
+
module Iter
|
8
|
+
# A wrapper around +Net::HTTP+ to send HTTP requests to the Iterable API and
|
9
|
+
# return their result or raise an error if the result is unexpected.
|
10
|
+
# The basic way to use HTTPRequest is by calling +run+ on an instance.
|
11
|
+
# @example List the species of all breeds.
|
12
|
+
# path = '/api/v1/resources/breeds/'
|
13
|
+
# body = {securityToken: api_key}
|
14
|
+
# response = Iter::HTTPRequest.new(path: path, body: body).run
|
15
|
+
# response['Breeds'].map{|breed| breed['species']}
|
16
|
+
# @api private
|
17
|
+
class Request
|
18
|
+
# Initializes an HTTPRequest object.
|
19
|
+
# @param [Hash] options the options for the request.
|
20
|
+
# @option options [String] :path The path of the request URI.
|
21
|
+
# @option options [Hash] :body The body of the request.
|
22
|
+
def initialize(options = {})
|
23
|
+
@path = options[:path]
|
24
|
+
@body = options[:body]
|
25
|
+
end
|
26
|
+
|
27
|
+
# Sends the request and returns the body parsed from the JSON response.
|
28
|
+
# @return [Hash] the body parsed from the JSON response.
|
29
|
+
# @raise [Iter::ConnectionError] if the request fails.
|
30
|
+
# @raise [Iter::Error] if parsed body includes errors.
|
31
|
+
def run
|
32
|
+
return {} if response.body.empty?
|
33
|
+
JSON(response.body).tap do |data|
|
34
|
+
raise Error, "#{data['errMsg']} #{data['Errors']}" unless data['errNo'].zero?
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
# Run the request and memoize the response or the server error received.
|
41
|
+
def response
|
42
|
+
@response ||= Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|
|
43
|
+
http.request http_request
|
44
|
+
end
|
45
|
+
rescue *server_errors => e
|
46
|
+
raise ConnectionError, e.message
|
47
|
+
end
|
48
|
+
|
49
|
+
# @return [URI::HTTPS] the (memoized) URI of the request.
|
50
|
+
def uri
|
51
|
+
attributes = { host: 'https://api.iterable.com', path: @path }
|
52
|
+
@uri ||= URI::HTTPS.build attributes
|
53
|
+
end
|
54
|
+
|
55
|
+
# @return [Net::HTTPRequest] the full HTTP request object,
|
56
|
+
# inclusive of headers of request body.
|
57
|
+
def http_request
|
58
|
+
http_class = @query.any? ? Net::HTTP::Get : Net::HTTP::Post
|
59
|
+
|
60
|
+
@http_request ||= http_class.new(uri.request_uri).tap do |request|
|
61
|
+
set_request_body! request
|
62
|
+
set_request_headers! request
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
# Adds the request headers to the request in the appropriate format.
|
67
|
+
# The User-Agent header is also set to recognize the request.
|
68
|
+
def set_request_headers!(request)
|
69
|
+
request.initialize_http_header 'Content-Type' => 'application/json'
|
70
|
+
request.add_field 'User-Agent', 'Iter::HTTPRequest'
|
71
|
+
end
|
72
|
+
|
73
|
+
# Adds the request body to the request in the appropriate format.
|
74
|
+
def set_request_body!(request)
|
75
|
+
request.body = @body.to_json if @body
|
76
|
+
end
|
77
|
+
|
78
|
+
# Returns the list of server errors worth retrying the request once.
|
79
|
+
def server_errors
|
80
|
+
[
|
81
|
+
Errno::ECONNRESET, Errno::EHOSTUNREACH, Errno::ENETUNREACH,
|
82
|
+
Errno::ETIMEDOUT, Errno::ECONNREFUSED, Net::HTTPServerError,
|
83
|
+
OpenSSL::SSL::SSLError, OpenSSL::SSL::SSLErrorWaitReadable,
|
84
|
+
Net::OpenTimeout, SocketError,
|
85
|
+
]
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Iter
|
2
|
+
# A mock version of HTTPRequest which returns pre-built responses.
|
3
|
+
# @example Updates the email of a user.
|
4
|
+
# path = '/api/users/update'
|
5
|
+
# body = {userId: '666', email: 'iter@example.com'}
|
6
|
+
# response = Iter::Request.new(path: path, body: body).run
|
7
|
+
# response['msg'] # => User successfully created/updated.
|
8
|
+
# @api private
|
9
|
+
class Request
|
10
|
+
# Initializes an MockRequest object.
|
11
|
+
# @param [Hash] options the options for the request.
|
12
|
+
# @option options [String] :path The path of the request URI.
|
13
|
+
# @option options [Hash] :body The body of the request.
|
14
|
+
def initialize(options = {})
|
15
|
+
@path = options[:path]
|
16
|
+
@body = options[:body]
|
17
|
+
end
|
18
|
+
|
19
|
+
# Sends the request and returns the body parsed from the JSON response.
|
20
|
+
# @return [Hash] the body parsed from the JSON response.
|
21
|
+
# @raise [Iter::ConnectionError] if the request fails.
|
22
|
+
# @raise [Iter::Error] if parsed body includes errors.
|
23
|
+
def run
|
24
|
+
case @path
|
25
|
+
when '/api/users/update'
|
26
|
+
# if @body[:email].include? '@'
|
27
|
+
{ "msg" => "User successfully created/updated.", "code" => "Success" }
|
28
|
+
# else
|
29
|
+
# raise Error.new '{"msg"=>"Invalid email: iterexample.com", "code": "InvalidEmailAddressError"}'
|
30
|
+
# end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
module Iter
|
2
|
+
# Provides methods to iterate through collections of Iterable resources.
|
3
|
+
# @private
|
4
|
+
class Relation
|
5
|
+
include Enumerable
|
6
|
+
|
7
|
+
# @yield [Hash] the options to change which items to iterate through.
|
8
|
+
def initialize(options = {}, &item_block)
|
9
|
+
@options = {parts: ['objectID', 'isActive'], next_page: 1}
|
10
|
+
@options.merge! options
|
11
|
+
@item_block = item_block
|
12
|
+
end
|
13
|
+
|
14
|
+
# Specifies which items to fetch when hitting the data API.
|
15
|
+
# @param [Hash<Symbol, String>] conditions The conditions for the items.
|
16
|
+
# @return [Iter::Relation] itself.
|
17
|
+
def where(conditions = {})
|
18
|
+
if @options[:conditions] != conditions
|
19
|
+
@items = []
|
20
|
+
@options.merge! conditions: conditions
|
21
|
+
end
|
22
|
+
self
|
23
|
+
end
|
24
|
+
|
25
|
+
# Specifies which parts of the resource to fetch when hitting the data API.
|
26
|
+
# @param [Array<Symbol>] parts The parts to fetch.
|
27
|
+
# @return [Iter::Relation] itself.
|
28
|
+
def select(*parts)
|
29
|
+
if @options[:parts] != parts + ['objectID', 'isActive']
|
30
|
+
@items = nil
|
31
|
+
@options.merge! parts: (parts + ['objectID', 'isActive'])
|
32
|
+
end
|
33
|
+
self
|
34
|
+
end
|
35
|
+
|
36
|
+
def each
|
37
|
+
@last_index = 0
|
38
|
+
while next_item = find_next
|
39
|
+
yield next_item
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def request(path:, body: {}, query: {}, include_api_key: true)
|
46
|
+
if query.none? && include_api_key
|
47
|
+
body = body.merge securityToken: Iter.configuration.api_key
|
48
|
+
end
|
49
|
+
|
50
|
+
response_for path:, body:, query:
|
51
|
+
end
|
52
|
+
|
53
|
+
def response_for(path:, body: {}, query: {})
|
54
|
+
instrument do |data|
|
55
|
+
Request.new(path: path, query: query, body: body).run
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def find_next
|
60
|
+
@items ||= []
|
61
|
+
if @items[@last_index].nil? && more_pages?
|
62
|
+
body = @options[:conditions].merge pageSize: 500, pageNo: @options[:next_page], sortMode: 3, sortDirection: 0
|
63
|
+
|
64
|
+
response_body = request path: '/api/v1/data/Contacts/', body: body
|
65
|
+
|
66
|
+
more_items = response_body['Contacts'].map do |contact_data|
|
67
|
+
Iter::Contact.new contact_data.slice(*@options[:parts])
|
68
|
+
end
|
69
|
+
@options.merge! next_page: (more_items.size == 500 ? @options[:next_page] + 1 : 1)
|
70
|
+
@items.concat more_items
|
71
|
+
end
|
72
|
+
@items[(@last_index +=1) -1]
|
73
|
+
end
|
74
|
+
|
75
|
+
def more_pages?
|
76
|
+
@last_index.zero? || @options[:next_page] > 1
|
77
|
+
end
|
78
|
+
|
79
|
+
# Provides instrumentation to ActiveSupport listeners
|
80
|
+
def instrument(&block)
|
81
|
+
data = { class_name: 'Iter::Contact' }
|
82
|
+
if defined?(ActiveSupport::Notifications)
|
83
|
+
ActiveSupport::Notifications.instrument 'Iter.request', data, &block
|
84
|
+
else
|
85
|
+
block.call data
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require ENV['ITER_MOCK'] ? 'iter/mock_request' : 'iter/http_request'
|
2
|
+
|
3
|
+
module Iter
|
4
|
+
# Provides an abstract class for every Iterable resource.
|
5
|
+
class Resource
|
6
|
+
private
|
7
|
+
|
8
|
+
def self.request(path:, body: {})
|
9
|
+
Request.new(path: path, body: body).run
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
data/lib/iter/user.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
module Iter
|
2
|
+
# Provides methods to interact with Iterable users.
|
3
|
+
class User < Resource
|
4
|
+
PATH = '/api/v1/data/Clients/'
|
5
|
+
|
6
|
+
attr_reader :id, :email
|
7
|
+
|
8
|
+
def initialize(id:)
|
9
|
+
@id = id
|
10
|
+
end
|
11
|
+
|
12
|
+
|
13
|
+
def self.update(email:, fields:)
|
14
|
+
body = {
|
15
|
+
userId: id,
|
16
|
+
email: email,
|
17
|
+
dataFields: fields,
|
18
|
+
}
|
19
|
+
|
20
|
+
data = request path: '/api/users/update', body: body
|
21
|
+
|
22
|
+
email = value_for_field data, 238
|
23
|
+
new id: contact_id, email: email
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
data/lib/iter/version.rb
ADDED
data/lib/iter.rb
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
# Used by multiple resources
|
2
|
+
require 'uri'
|
3
|
+
require_relative 'iter/error'
|
4
|
+
require_relative 'iter/config'
|
5
|
+
|
6
|
+
# Individual resources
|
7
|
+
require_relative 'iter/connection_error'
|
8
|
+
require_relative 'iter/event'
|
9
|
+
require_relative 'iter/user'
|
10
|
+
require_relative 'iter/version'
|
metadata
ADDED
@@ -0,0 +1,102 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: iter
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- claudiob
|
8
|
+
bindir: exe
|
9
|
+
cert_chain: []
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
11
|
+
dependencies:
|
12
|
+
- !ruby/object:Gem::Dependency
|
13
|
+
name: simplecov
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
15
|
+
requirements:
|
16
|
+
- - ">="
|
17
|
+
- !ruby/object:Gem::Version
|
18
|
+
version: '0'
|
19
|
+
type: :development
|
20
|
+
prerelease: false
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
22
|
+
requirements:
|
23
|
+
- - ">="
|
24
|
+
- !ruby/object:Gem::Version
|
25
|
+
version: '0'
|
26
|
+
- !ruby/object:Gem::Dependency
|
27
|
+
name: rubocop
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
29
|
+
requirements:
|
30
|
+
- - ">="
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
33
|
+
type: :development
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - ">="
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '0'
|
40
|
+
- !ruby/object:Gem::Dependency
|
41
|
+
name: yard
|
42
|
+
requirement: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - ">="
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '0'
|
47
|
+
type: :development
|
48
|
+
prerelease: false
|
49
|
+
version_requirements: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - ">="
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
description: A Ruby client for the Iterable API.
|
55
|
+
email:
|
56
|
+
- claudiob@users.noreply.github.com
|
57
|
+
executables: []
|
58
|
+
extensions: []
|
59
|
+
extra_rdoc_files: []
|
60
|
+
files:
|
61
|
+
- ".rspec"
|
62
|
+
- ".rubocop.yml"
|
63
|
+
- CHANGELOG.md
|
64
|
+
- LICENSE.txt
|
65
|
+
- README.md
|
66
|
+
- Rakefile
|
67
|
+
- lib/iter.rb
|
68
|
+
- lib/iter/config.rb
|
69
|
+
- lib/iter/configuration.rb
|
70
|
+
- lib/iter/connection_error.rb
|
71
|
+
- lib/iter/error.rb
|
72
|
+
- lib/iter/http_request.rb
|
73
|
+
- lib/iter/mock_request.rb
|
74
|
+
- lib/iter/relation.rb
|
75
|
+
- lib/iter/resource.rb
|
76
|
+
- lib/iter/user.rb
|
77
|
+
- lib/iter/version.rb
|
78
|
+
homepage: https://rubygems.org/gems/iter
|
79
|
+
licenses:
|
80
|
+
- MIT
|
81
|
+
metadata:
|
82
|
+
homepage_uri: https://rubygems.org/gems/iter
|
83
|
+
source_code_uri: https://github.com/claudiob/iter
|
84
|
+
changelog_uri: https://github.com/claudiob/iter/blob/main/CHANGELOG.md
|
85
|
+
rdoc_options: []
|
86
|
+
require_paths:
|
87
|
+
- lib
|
88
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
89
|
+
requirements:
|
90
|
+
- - ">="
|
91
|
+
- !ruby/object:Gem::Version
|
92
|
+
version: 3.0.0
|
93
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
94
|
+
requirements:
|
95
|
+
- - ">="
|
96
|
+
- !ruby/object:Gem::Version
|
97
|
+
version: '0'
|
98
|
+
requirements: []
|
99
|
+
rubygems_version: 3.6.9
|
100
|
+
specification_version: 4
|
101
|
+
summary: A Ruby client for the Iterable API.
|
102
|
+
test_files: []
|