iterable-api-client 0.1.0 → 0.2.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.
@@ -1,4 +1,34 @@
1
- files = %w[]
1
+ require 'json'
2
+ require 'net/http'
3
+ require 'uri'
4
+
5
+ require 'multi_json'
6
+
7
+ files = %w[
8
+ api_resource
9
+ config
10
+ response
11
+ request
12
+ lists
13
+ campaigns
14
+ channels
15
+ events
16
+ message_types
17
+ templates
18
+ email_templates
19
+ push_templates
20
+ users
21
+ workflows
22
+ metadata
23
+ metadata_table
24
+ experiments
25
+ email
26
+ device
27
+ commerce
28
+ export
29
+ json_exporter
30
+ csv_exporter
31
+ ]
2
32
 
3
33
  files.each { |path| require_relative "./iterable/#{path}" }
4
34
 
@@ -6,4 +36,34 @@ files.each { |path| require_relative "./iterable/#{path}" }
6
36
  #
7
37
  # Iterable module for API interactions
8
38
  module Iterable
39
+ DATE_FORMAT = '%Y-%m-%d'.freeze
40
+
41
+ module_function
42
+
43
+ ##
44
+ #
45
+ # Configure a default [Iterable::Config] object to be used when interacting
46
+ # with API endpoints
47
+ #
48
+ # @example Configuring with token
49
+ # Iterable.configure do |conf|
50
+ # conf.token = 'secret-token'
51
+ # end
52
+ def configure
53
+ config.tap do |conf|
54
+ yield conf
55
+ end
56
+ end
57
+
58
+ ##
59
+ #
60
+ # @return [Iterable::Config] The default config for API endpoints
61
+ def config
62
+ @config ||= Config.new
63
+ end
64
+
65
+ # @!visibility private
66
+ def request(conf, path, params = {})
67
+ Request.new conf, path, params
68
+ end
9
69
  end
@@ -0,0 +1,39 @@
1
+ module Iterable
2
+ ##
3
+ #
4
+ # ApiResource is a parent class for rest resources for the
5
+ # Iterable API. It allows for request conifugration to be
6
+ # set per request if needed, otherwise the default global
7
+ # Iterable.config is used
8
+ class ApiResource
9
+ attr_reader :conf
10
+
11
+ ##
12
+ #
13
+ # Initialize a new ApiResource with an optional config. Will default to
14
+ # the global [Iterable::Config] via `Iterable.config`
15
+ #
16
+ # @return [Iterable::ApiResource]
17
+ def initialize(conf = nil)
18
+ @conf = conf ? conf : default_config
19
+ end
20
+
21
+ ##
22
+ #
23
+ # Global Iterable config accessor for class
24
+ #
25
+ # @return [Iterable::Config]
26
+ def self.default_config
27
+ Iterable.config
28
+ end
29
+
30
+ ##
31
+ #
32
+ # Global Iterable config accessor for instance
33
+ #
34
+ # @return [Iterable::Config]
35
+ def default_config
36
+ self.class.default_config
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,68 @@
1
+ module Iterable
2
+ ##
3
+ #
4
+ # Interact with /campaigns API endpoints
5
+ #
6
+ # @example Creating campaigns endpoint object
7
+ # # With default config
8
+ # campaigns = Iterable::Campaigns.new
9
+ # campaigns.all
10
+ #
11
+ # # With custom config
12
+ # conf = Iterable::Config.new(token: 'new-token')
13
+ # campaigns = Iterable::Campaigns.new(config)
14
+ class Campaigns < ApiResource
15
+ ##
16
+ #
17
+ # Get all campaigns
18
+ #
19
+ # @return [Iterable::Response] A response object
20
+ def all
21
+ Iterable.request(conf, '/campaigns').get
22
+ end
23
+
24
+ ##
25
+ #
26
+ # Create a new campaign. Requires a name, templateId and at least one listId
27
+ #
28
+ # @param name [String] The name of the campaign
29
+ # @param template_id [Integer] The templateId to use for the campaign
30
+ # @param list_ids [Array] Array of listIds to use for the campaign
31
+ # @param attrs [Hash] Any other campaign attributes to set
32
+ #
33
+ # @return [Iterable::Response] A response object
34
+ def create(name, template_id, list_ids = [], attrs = {})
35
+ body = attrs.merge(name: name, templateId: template_id, listIds: list_ids)
36
+ Iterable.request(conf, '/campaigns/create').post(body)
37
+ end
38
+
39
+ ##
40
+ #
41
+ # Get recurring child campaigns for a campaign
42
+ #
43
+ # @param campaign_id [Integer] Root campaign ID to get child recurring campaigns for
44
+ #
45
+ # @return [Iterable::Response] A response object
46
+ def recurring(campaign_id)
47
+ Iterable.request(conf, "/campaigns/recurring/#{campaign_id}/childCampaigns").get
48
+ end
49
+
50
+ ##
51
+ #
52
+ # Export metrics in CSV format for one or more campaigns
53
+ #
54
+ # @param name [Array] An array of campaign ids, must have at least one
55
+ # @param start_time [Date|Time] Start of metrics to query for
56
+ # @param end_time [Date|Time] End of metrics to query for
57
+ #
58
+ # @return [Iterable::Response] A response object
59
+ def metrics(campaign_ids = [], start_time = nil, end_time = nil)
60
+ params = { campaignId: campaign_ids }
61
+ if start_time
62
+ params[:startTime] = start_time.to_date.strftime(Iterable::DATE_FORMAT)
63
+ params[:endTime] = end_time.to_date.strftime(Iterable::DATE_FORMAT)
64
+ end
65
+ Iterable.request(conf, '/campaigns/metrics', params).get
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,24 @@
1
+ module Iterable
2
+ ##
3
+ #
4
+ # Interact with /channels API endpoints
5
+ #
6
+ # @example Creating channels endpoint object
7
+ # # With default config
8
+ # campaigns = Iterable::Channels.new
9
+ # campaigns.all
10
+ #
11
+ # # With custom config
12
+ # conf = Iterable::Config.new(token: 'new-token')
13
+ # campaigns = Iterable::Channels.new(config)
14
+ class Channels < ApiResource
15
+ ##
16
+ #
17
+ # Get all channels
18
+ #
19
+ # @return [Iterable::Response] A response object
20
+ def all
21
+ Iterable.request(conf, '/channels').get
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,53 @@
1
+ module Iterable
2
+ ##
3
+ #
4
+ # Interact with /commerce API endpoints
5
+ #
6
+ # @example Creating commerce endpoint object
7
+ # # With default config
8
+ # commerce = Iterable::Commerce.new
9
+ # commerce.all
10
+ #
11
+ # # With custom config
12
+ # conf = Iterable::Config.new(token: 'new-token')
13
+ # commerce = Iterable::Commerce.new(config)
14
+ class Commerce < ApiResource
15
+ ##
16
+ #
17
+ # Track a purchase. 'shoppingCartItems' field on the user profile is cleared.
18
+ # User profile is also updated (created otherwise) using the user request field
19
+ #
20
+ # @param total [Float] Total order amount
21
+ # @param items [Array[Hash]] Array of hashes of commerce items
22
+ # @param user [Hash] User update request details to update or create user
23
+ # @param attrs [Hash] Track purchase request additional fields
24
+ #
25
+ # @return [Iterable::Response] A response object
26
+ def track_purchase(total, items = [], user = {}, attrs = {})
27
+ data = {
28
+ total: total,
29
+ items: items,
30
+ user: user
31
+ }
32
+ data.merge!(attrs)
33
+ Iterable.request(conf, '/commerce/trackPurchase').post(data)
34
+ end
35
+
36
+ ##
37
+ #
38
+ # Updates the 'shoppingCartItems' field on the user profile with shopping
39
+ # cart items. User profile is updated (created otherwise) via the user field.
40
+ #
41
+ # @param user [Hash] User update request details to update or create user
42
+ # @param items [Array[Hash]] Array of hashes of commerce items
43
+ #
44
+ # @return [Iterable::Response] A response object
45
+ def update_cart(user = {}, items = [])
46
+ data = {
47
+ items: items,
48
+ user: user
49
+ }
50
+ Iterable.request(conf, '/commerce/updateCart').post(data)
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,39 @@
1
+ module Iterable
2
+ ##
3
+ # Config provides a class to configre the API calls when interacting with
4
+ # REST endpoints
5
+ #
6
+ # @example Creating a config object
7
+ # Iterable::Config.new token: 'secret-token'
8
+ class Config
9
+ DEFAULT_VERSION = '1.8'.freeze
10
+ DEFAULT_HOST = 'https://api.iterable.com'.freeze
11
+ DEFAULT_URI = "#{DEFAULT_HOST}/api".freeze
12
+ DEFAULT_PORT = 443
13
+
14
+ attr_accessor :token
15
+ attr_reader :host, :port, :version
16
+
17
+ ##
18
+ #
19
+ # initialize a new [Iterable::Config] object for requests
20
+ #
21
+ # @param token [String] Iterable API token
22
+ # @return [Iterable::Config]
23
+ def initialize(token: nil)
24
+ @host = DEFAULT_HOST
25
+ @port = DEFAULT_PORT
26
+ @version = DEFAULT_VERSION
27
+ @token = token
28
+ end
29
+
30
+ ##
31
+ #
32
+ # Creates a [URI] for the API host
33
+ #
34
+ # @return [URI] API URI object
35
+ def uri
36
+ URI.parse("#{@host || DEFAULT_HOST}:#{@port || DEFAULT_PORT}/api")
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,19 @@
1
+ module Iterable
2
+ ##
3
+ #
4
+ # Subclass of [Iterable::Export] for CSV exporting of data
5
+ #
6
+ # @example Creating a CSV Exporter
7
+ # # With default config
8
+ # exporter = Iterable::CsvExporter.new Iterable::Export::EMAIL_SEND_TYPE
9
+ # exporter.export
10
+ #
11
+ # # With custom config
12
+ # conf = Iterable::Config.new(token: 'new-token')
13
+ # exporter = Iterable::CsvExporter.new(Iterable::Export::EMAIL_SEND_TYPE, nil, nil, nil, config)
14
+ class CsvExporter < Export
15
+ def format
16
+ 'csv'
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,74 @@
1
+ module Iterable
2
+ ##
3
+ #
4
+ # Interact with user device API endpoints
5
+ #
6
+ # @example Creating device endpoint object
7
+ # # With default config
8
+ # campaigns = Iterable::Device.new 'token', 'app-name', Iterable::Device::APNS
9
+ # campaigns.all
10
+ #
11
+ # # With custom config
12
+ # conf = Iterable::Device.new(token: 'new-token')
13
+ # campaigns = Iterable::Device.new('token', 'app-name', Iterable::Device::APNS, config)
14
+ class Device < ApiResource
15
+ PLATFORMS = [
16
+ APNS = 'APNS'.freeze,
17
+ APNS_SANDBOX = 'APNS_SANDBOX'.freeze,
18
+ GCM = 'GCM'.freeze
19
+ ].freeze
20
+
21
+ attr_reader :app, :data_fields, :platform, :token
22
+
23
+ ##
24
+ #
25
+ # Initialize an [Iterable::Device] to register for a user
26
+ #
27
+ # @param token [String] The device token
28
+ # @param app [String] The application name for mobile push
29
+ # @param platform [String] The device device platform; one of [Iterable::Device::PLATFORMS]
30
+ # @param data_fields [Hash] Additional device data fields
31
+ # @param conf [Iterable::Config] A config to optionally pass for requests
32
+ #
33
+ # @return [Iterable::Device]
34
+ def initialize(token, app, platform, data_fields = {}, conf = nil)
35
+ @token = token
36
+ @app = app
37
+ @platform = platform
38
+ @data_fields = data_fields
39
+ super conf
40
+ end
41
+
42
+ ##
43
+ #
44
+ # Register a device for a user email or id
45
+ #
46
+ # @param email [String] Email of user to associate device with
47
+ # @param user_id [String] User ID to associate device with instead of email
48
+ #
49
+ # @return [Iterable::Response] A response object
50
+ def register(email, user_id = nil)
51
+ attrs = {
52
+ device: device_data
53
+ }
54
+ attrs[:email] = email if email
55
+ attrs[:userId] = user_id if user_id
56
+ Iterable.request(conf, base_path).post(attrs)
57
+ end
58
+
59
+ private
60
+
61
+ def base_path
62
+ '/users/registerDeviceToken'
63
+ end
64
+
65
+ def device_data
66
+ {
67
+ token: @token,
68
+ applicationName: @app,
69
+ platform: @platform,
70
+ dataFields: @data_fields
71
+ }
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,28 @@
1
+ module Iterable
2
+ ##
3
+ #
4
+ # Interact with /email API endpoints
5
+ #
6
+ # @example Creating email endpoint object
7
+ # # With default config
8
+ # templates = Iterable::Email.new
9
+ # templates.get
10
+ #
11
+ # # With custom config
12
+ # conf = Iterable::Config.new(token: 'new-token')
13
+ # templates = Iterable::Email.new(config)
14
+ class Email < ApiResource
15
+ ##
16
+ #
17
+ # View an email message sent
18
+ #
19
+ # @param email [String] Email of user who received the message to view
20
+ # @param message_id [String|Integer] Message id for message sent
21
+ #
22
+ # @return [Iterable::Response] A response object
23
+ def view(email, message_id)
24
+ params = { email: email, messageId: message_id }
25
+ Iterable.request(conf, '/email/viewInBrowser', params).get
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,54 @@
1
+ module Iterable
2
+ ##
3
+ #
4
+ # Interact with /templates/email API endpoints
5
+ #
6
+ # @example Creating email templates endpoint object
7
+ # # With default config
8
+ # templates = Iterable::EmailTemplates.new
9
+ # templates.get
10
+ #
11
+ # # With custom config
12
+ # conf = Iterable::Config.new(token: 'new-token')
13
+ # templates = Iterable::EmailTemplates.new(config)
14
+ class EmailTemplates < ApiResource
15
+ ##
16
+ #
17
+ # Get an email template
18
+ #
19
+ # @param template_id [String|Integer] An email 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/email/get', params).get
26
+ end
27
+
28
+ ##
29
+ #
30
+ # Update an email template
31
+ #
32
+ # @param template_id [String|Integer] An email 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/email/update').post(attrs)
39
+ end
40
+
41
+ ##
42
+ #
43
+ # Upsert an email 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/email/upsert').post(attrs)
52
+ end
53
+ end
54
+ end