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