constantcontact 1.0.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 +2 -0
- data/README.md +132 -0
- data/constantcontact.gemspec +32 -0
- data/lib/constantcontact.rb +75 -0
- data/lib/constantcontact/api.rb +541 -0
- data/lib/constantcontact/auth/oauth2.rb +82 -0
- data/lib/constantcontact/auth/session_data_store.rb +69 -0
- data/lib/constantcontact/components/account/verified_email_address.rb +27 -0
- data/lib/constantcontact/components/activities/activity.rb +44 -0
- data/lib/constantcontact/components/activities/activity_error.rb +27 -0
- data/lib/constantcontact/components/activities/add_contacts.rb +117 -0
- data/lib/constantcontact/components/activities/add_contacts_import_data.rb +45 -0
- data/lib/constantcontact/components/activities/export_contacts.rb +30 -0
- data/lib/constantcontact/components/component.rb +23 -0
- data/lib/constantcontact/components/contacts/address.rb +28 -0
- data/lib/constantcontact/components/contacts/contact.rb +86 -0
- data/lib/constantcontact/components/contacts/contact_list.rb +27 -0
- data/lib/constantcontact/components/contacts/custom_field.rb +27 -0
- data/lib/constantcontact/components/contacts/email_address.rb +34 -0
- data/lib/constantcontact/components/contacts/note.rb +25 -0
- data/lib/constantcontact/components/email_marketing/campaign.rb +83 -0
- data/lib/constantcontact/components/email_marketing/click_through_details.rb +28 -0
- data/lib/constantcontact/components/email_marketing/message_footer.rb +30 -0
- data/lib/constantcontact/components/email_marketing/schedule.rb +29 -0
- data/lib/constantcontact/components/email_marketing/test_send.rb +45 -0
- data/lib/constantcontact/components/result_set.rb +27 -0
- data/lib/constantcontact/components/tracking/bounce_activity.rb +29 -0
- data/lib/constantcontact/components/tracking/click_activity.rb +28 -0
- data/lib/constantcontact/components/tracking/forward_activity.rb +28 -0
- data/lib/constantcontact/components/tracking/open_activity.rb +28 -0
- data/lib/constantcontact/components/tracking/send_activity.rb +28 -0
- data/lib/constantcontact/components/tracking/tracking_activity.rb +27 -0
- data/lib/constantcontact/components/tracking/tracking_summary.rb +28 -0
- data/lib/constantcontact/components/tracking/unsubscribe_activity.rb +29 -0
- data/lib/constantcontact/exceptions/ctct_exception.rb +25 -0
- data/lib/constantcontact/exceptions/illegal_argument_exception.rb +11 -0
- data/lib/constantcontact/exceptions/oauth2_exception.rb +11 -0
- data/lib/constantcontact/services/account_service.rb +29 -0
- data/lib/constantcontact/services/activity_service.rb +107 -0
- data/lib/constantcontact/services/base_service.rb +37 -0
- data/lib/constantcontact/services/campaign_schedule_service.rb +107 -0
- data/lib/constantcontact/services/campaign_tracking_service.rb +159 -0
- data/lib/constantcontact/services/contact_service.rb +114 -0
- data/lib/constantcontact/services/contact_tracking_service.rb +159 -0
- data/lib/constantcontact/services/email_marketing_service.rb +87 -0
- data/lib/constantcontact/services/list_service.rb +85 -0
- data/lib/constantcontact/util/config.rb +140 -0
- data/lib/constantcontact/util/helpers.rb +27 -0
- data/lib/constantcontact/version.rb +12 -0
- data/spec/constantcontact/api_spec.rb +183 -0
- data/spec/constantcontact/auth/oauth2_spec.rb +48 -0
- data/spec/constantcontact/components/contacts/address_spec.rb +18 -0
- data/spec/constantcontact/components/contacts/contact_list_spec.rb +18 -0
- data/spec/constantcontact/components/contacts/contact_spec.rb +18 -0
- data/spec/constantcontact/components/contacts/custom_field_spec.rb +18 -0
- data/spec/constantcontact/components/contacts/email_address_spec.rb +18 -0
- data/spec/constantcontact/services/contact_service_spec.rb +105 -0
- data/spec/constantcontact/services/list_service_spec.rb +69 -0
- data/spec/spec_helper.rb +13 -0
- metadata +134 -0
@@ -0,0 +1,82 @@
|
|
1
|
+
#
|
2
|
+
# oauth2.rb
|
3
|
+
# ConstantContact
|
4
|
+
#
|
5
|
+
# Copyright (c) 2013 Constant Contact. All rights reserved.
|
6
|
+
|
7
|
+
module ConstantContact
|
8
|
+
module Auth
|
9
|
+
class OAuth2
|
10
|
+
attr_accessor :client_id, :client_secret, :redirect_uri, :props
|
11
|
+
|
12
|
+
|
13
|
+
# Class constructor
|
14
|
+
# @param [Hash] opts - the options to create an OAuth2 object with
|
15
|
+
# @option opts [String] :api_key - the Constant Contact API Key
|
16
|
+
# @option opts [String] :api_secret - the Constant Contact secret key
|
17
|
+
# @option opts [String] :redirect_url - the URL where Constact Contact is returning the authorization code
|
18
|
+
# @return
|
19
|
+
def initialize(opts)
|
20
|
+
@client_id = opts[:api_key]
|
21
|
+
@client_secret = opts[:api_secret]
|
22
|
+
@redirect_uri = opts[:redirect_url]
|
23
|
+
end
|
24
|
+
|
25
|
+
|
26
|
+
# Get the URL at which the user can authenticate and authorize the requesting application
|
27
|
+
# @param [Boolean] server - whether or not to use OAuth2 server flow, alternative is client flow
|
28
|
+
# @return [String] the authorization URL
|
29
|
+
def get_authorization_url(server = true)
|
30
|
+
response_type = server ? Util::Config.get('auth.response_type_code') : Util::Config.get('auth.response_type_token')
|
31
|
+
params = {
|
32
|
+
:response_type => response_type,
|
33
|
+
:client_id => @client_id,
|
34
|
+
:redirect_uri => @redirect_uri
|
35
|
+
}
|
36
|
+
[
|
37
|
+
Util::Config.get('auth.base_url'),
|
38
|
+
Util::Config.get('auth.authorization_endpoint'),
|
39
|
+
'?',
|
40
|
+
Util::Helpers.http_build_query(params)
|
41
|
+
].join
|
42
|
+
end
|
43
|
+
|
44
|
+
|
45
|
+
# Obtain an access token
|
46
|
+
# @param [String] code - the code returned from Constant Contact after a user has granted access to his account
|
47
|
+
# @return [String] the access token
|
48
|
+
def get_access_token(code)
|
49
|
+
params = {
|
50
|
+
:grant_type => Util::Config.get('auth.authorization_code_grant_type'),
|
51
|
+
:client_id => @client_id,
|
52
|
+
:client_secret => @client_secret,
|
53
|
+
:code => code,
|
54
|
+
:redirect_uri => @redirect_uri
|
55
|
+
}
|
56
|
+
|
57
|
+
url = [
|
58
|
+
Util::Config.get('auth.base_url'),
|
59
|
+
Util::Config.get('auth.token_endpoint')
|
60
|
+
].join
|
61
|
+
|
62
|
+
response_body = ''
|
63
|
+
begin
|
64
|
+
response = RestClient.post(url, params)
|
65
|
+
response_body = JSON.parse(response)
|
66
|
+
rescue => e
|
67
|
+
response_body = e.respond_to?(:response) ?
|
68
|
+
JSON.parse(e.response) :
|
69
|
+
{'error' => '', 'error_description' => e.message}
|
70
|
+
end
|
71
|
+
|
72
|
+
if response_body['error_description']
|
73
|
+
error = response_body['error_description']
|
74
|
+
raise Exceptions::OAuth2Exception, error
|
75
|
+
end
|
76
|
+
|
77
|
+
response_body
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
#
|
2
|
+
# session_data_store.rb
|
3
|
+
# ConstantContact
|
4
|
+
#
|
5
|
+
# Copyright (c) 2013 Constant Contact. All rights reserved.
|
6
|
+
|
7
|
+
module ConstantContact
|
8
|
+
module Auth
|
9
|
+
class Session
|
10
|
+
attr_accessor :session
|
11
|
+
|
12
|
+
# Create and initialize the session
|
13
|
+
def initialize
|
14
|
+
cgi = CGI.new('html4')
|
15
|
+
|
16
|
+
# We make sure to delete an old session if one exists,
|
17
|
+
# not just to free resources, but to prevent the session
|
18
|
+
# from being maliciously hijacked later on.
|
19
|
+
begin
|
20
|
+
@session = CGI::Session.new(cgi, 'database_manager' => CGI::Session::PStore, 'new_session' => false)
|
21
|
+
@session.delete
|
22
|
+
rescue ArgumentError # if no old session
|
23
|
+
end
|
24
|
+
@session = CGI::Session.new(cgi, 'database_manager' => CGI::Session::PStore, 'new_session' => true)
|
25
|
+
@session['datastore'] = {}
|
26
|
+
end
|
27
|
+
|
28
|
+
# Add a new user to the data store
|
29
|
+
# @param [String] username - Constant Contact username
|
30
|
+
# @param [Hash] params - additional parameters
|
31
|
+
# @return
|
32
|
+
def add_user(username, params)
|
33
|
+
@session['datastore'][username] = params
|
34
|
+
end
|
35
|
+
|
36
|
+
# Get an existing user from the data store
|
37
|
+
# @param [String] username - Constant Contact username key
|
38
|
+
# @return [String] The username value
|
39
|
+
def get_user(username)
|
40
|
+
@session['datastore'].has_key?(username) ? @session['datastore'][username] : false
|
41
|
+
end
|
42
|
+
|
43
|
+
# Update an existing user in the data store
|
44
|
+
# @param [String] username - Constant Contact username
|
45
|
+
# @param [Hash] params - additional parameters
|
46
|
+
# @return
|
47
|
+
def update_user(username, params)
|
48
|
+
if @session['datastore'].has_key?(username)
|
49
|
+
@session['datastore'][username] = params
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
# Delete an existing user from the data store
|
54
|
+
# @param [String] username - Constant Contact username
|
55
|
+
# @return
|
56
|
+
def delete_user(username)
|
57
|
+
@session['datastore'][username] = nil
|
58
|
+
end
|
59
|
+
|
60
|
+
# Close current session
|
61
|
+
# @return
|
62
|
+
def close
|
63
|
+
@session.close
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
@@ -0,0 +1,27 @@
|
|
1
|
+
#
|
2
|
+
# verified_email_address.rb
|
3
|
+
# ConstantContact
|
4
|
+
#
|
5
|
+
# Copyright (c) 2013 Constant Contact. All rights reserved.
|
6
|
+
|
7
|
+
module ConstantContact
|
8
|
+
module Components
|
9
|
+
class VerifiedEmailAddress < Component
|
10
|
+
attr_accessor :status, :email_address
|
11
|
+
|
12
|
+
# Factory method to create a VerifiedEmailAddress object from a json string
|
13
|
+
# @param [Hash] props - array of properties to create object from
|
14
|
+
# @return [VerifiedEmailAddress]
|
15
|
+
def self.create(props)
|
16
|
+
email_address = VerifiedEmailAddress.new
|
17
|
+
if props
|
18
|
+
props.each do |key, value|
|
19
|
+
email_address.send("#{key}=", value)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
email_address
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
#
|
2
|
+
# activity.rb
|
3
|
+
# ConstantContact
|
4
|
+
#
|
5
|
+
# Copyright (c) 2013 Constant Contact. All rights reserved.
|
6
|
+
|
7
|
+
module ConstantContact
|
8
|
+
module Components
|
9
|
+
class Activity < Component
|
10
|
+
attr_accessor :id, :type, :status, :start_date, :finish_date, :file_name, :created_date,
|
11
|
+
:error_count, :errors, :warnings, :contact_count
|
12
|
+
|
13
|
+
# Factory method to create an Activity object from a json string
|
14
|
+
# @param [Hash] props - hash of properties to create object from
|
15
|
+
# @return [Activity]
|
16
|
+
def self.create(props)
|
17
|
+
activity = Activity.new
|
18
|
+
if props
|
19
|
+
props.each do |key, value|
|
20
|
+
if key == 'errors'
|
21
|
+
if value
|
22
|
+
activity.errors = []
|
23
|
+
value.each do |error|
|
24
|
+
activity.errors << Components::ActivityError.create(error)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
elsif key == 'warnings'
|
28
|
+
if value
|
29
|
+
activity.warnings = []
|
30
|
+
value.each do |error|
|
31
|
+
activity.warnings << Components::ActivityError.create(error)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
else
|
35
|
+
activity.send("#{key}=", value)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
activity
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
#
|
2
|
+
# activity_error.rb
|
3
|
+
# ConstantContact
|
4
|
+
#
|
5
|
+
# Copyright (c) 2013 Constant Contact. All rights reserved.
|
6
|
+
|
7
|
+
module ConstantContact
|
8
|
+
module Components
|
9
|
+
class ActivityError < Component
|
10
|
+
attr_accessor :message, :line_number, :email_address
|
11
|
+
|
12
|
+
# Factory method to create an ActivityError object from an array
|
13
|
+
# @param [Hash] props - hash of properties to create object from
|
14
|
+
# @return [ActivityError]
|
15
|
+
def self.create(props)
|
16
|
+
activity_error = ActivityError.new
|
17
|
+
if props
|
18
|
+
props.each do |key, value|
|
19
|
+
activity_error.send("#{key}=", value)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
activity_error
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,117 @@
|
|
1
|
+
#
|
2
|
+
# add_contacts.rb
|
3
|
+
# ConstantContact
|
4
|
+
#
|
5
|
+
# Copyright (c) 2013 Constant Contact. All rights reserved.
|
6
|
+
|
7
|
+
module ConstantContact
|
8
|
+
module Components
|
9
|
+
class AddContacts < Component
|
10
|
+
attr_accessor :import_data, :lists, :column_names
|
11
|
+
|
12
|
+
# Constructor to create an AddContacts object from the given contacts and contact lists
|
13
|
+
# @param [Array<Contact>] contacts - contacts array
|
14
|
+
# @param [Array<ContactList>] lists - contact lists array]
|
15
|
+
# @param [Array<String>] column_names - array of column names
|
16
|
+
# @return [AddContacts]
|
17
|
+
def initialize(contacts, lists, column_names = [])
|
18
|
+
if !contacts.empty?
|
19
|
+
if contacts[0].instance_of?(Components::AddContactsImportData)
|
20
|
+
@import_data = contacts
|
21
|
+
else
|
22
|
+
raise Exceptions::IllegalArgumentException, sprintf(Util::Config.get('errors.id_or_object'), 'AddContactsImportData')
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
@lists = lists
|
27
|
+
@column_names = column_names
|
28
|
+
|
29
|
+
# attempt to determine the column names being used if they are not provided
|
30
|
+
if column_names.empty?
|
31
|
+
used_columns = [Util::Config.get('activities_columns.email')]
|
32
|
+
|
33
|
+
contact = contacts[0]
|
34
|
+
|
35
|
+
if !contact.first_name.nil?
|
36
|
+
used_columns << Util::Config.get('activities_columns.first_name')
|
37
|
+
end
|
38
|
+
|
39
|
+
if !contact.middle_name.nil?
|
40
|
+
used_columns << Util::Config.get('activities_columns.middle_name')
|
41
|
+
end
|
42
|
+
|
43
|
+
if !contact.last_name.nil?
|
44
|
+
used_columns << Util::Config.get('activities_columns.last_name')
|
45
|
+
end
|
46
|
+
|
47
|
+
if !contact.job_title.nil?
|
48
|
+
used_columns << Util::Config.get('activities_columns.job_title')
|
49
|
+
end
|
50
|
+
|
51
|
+
if !contact.company_name.nil?
|
52
|
+
used_columns << Util::Config.get('activities_columns.company_name')
|
53
|
+
end
|
54
|
+
|
55
|
+
if !contact.work_phone.nil?
|
56
|
+
used_columns << Util::Config.get('activities_columns.work_phone')
|
57
|
+
end
|
58
|
+
|
59
|
+
if !contact.home_phone.nil?
|
60
|
+
used_columns << Util::Config.get('activities_columns.home_phone')
|
61
|
+
end
|
62
|
+
|
63
|
+
address = contact.addresses[0]
|
64
|
+
|
65
|
+
if !address.line1.nil?
|
66
|
+
used_columns << Util::Config.get('activities_columns.address1')
|
67
|
+
end
|
68
|
+
|
69
|
+
if !address.line2.nil?
|
70
|
+
used_columns << Util::Config.get('activities_columns.address2')
|
71
|
+
end
|
72
|
+
|
73
|
+
if !address.line3.nil?
|
74
|
+
used_columns << Util::Config.get('activities_columns.address3')
|
75
|
+
end
|
76
|
+
|
77
|
+
if !address.city.nil?
|
78
|
+
used_columns << Util::Config.get('activities_columns.city')
|
79
|
+
end
|
80
|
+
|
81
|
+
if !address.state_code.nil?
|
82
|
+
used_columns << Util::Config.get('activities_columns.state')
|
83
|
+
end
|
84
|
+
|
85
|
+
if !address.state_code.nil?
|
86
|
+
used_columns << Util::Config.get('activities_columns.state_province')
|
87
|
+
end
|
88
|
+
|
89
|
+
if !address.country_code.nil?
|
90
|
+
used_columns << Util::Config.get('activities_columns.country')
|
91
|
+
end
|
92
|
+
|
93
|
+
if !address.postal_code.nil?
|
94
|
+
used_columns << Util::Config.get('activities_columns.postal_code')
|
95
|
+
end
|
96
|
+
|
97
|
+
if !address.sub_postal_code.nil?
|
98
|
+
used_columns << Util::Config.get('activities_columns.sub_postal_code')
|
99
|
+
end
|
100
|
+
|
101
|
+
# Custom Fields
|
102
|
+
if !contact.custom_fields.nil?
|
103
|
+
contact.custom_fields.each do |custom_field|
|
104
|
+
if custom_field.name.match('custom_field_')
|
105
|
+
custom_field_number = custom_field.name[13, custom_field.length]
|
106
|
+
used_columns << Util::Config.get('activities_columns.custom_field_' + custom_field_number)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
@column_names = used_columns
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
#
|
2
|
+
# add_contacts_import_data.rb
|
3
|
+
# ConstantContact
|
4
|
+
#
|
5
|
+
# Copyright (c) 2013 Constant Contact. All rights reserved.
|
6
|
+
|
7
|
+
module ConstantContact
|
8
|
+
module Components
|
9
|
+
class AddContactsImportData < Component
|
10
|
+
attr_accessor :first_name, :middle_name, :last_name, :job_title, :company_name,
|
11
|
+
:work_phone, :home_phone, :email_addresses, :addresses, :custom_fields
|
12
|
+
|
13
|
+
|
14
|
+
# Constructor to create an AddContactsImportData object from the given hash
|
15
|
+
# @param [Hash] props - the hash with properties
|
16
|
+
# @return [AddContactsImportData]
|
17
|
+
def initialize(props = {})
|
18
|
+
instance_variables.each do |property, value|
|
19
|
+
send("#{property}=", get_value(props, property))
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
# Setter
|
24
|
+
def add_custom_field(custom_field)
|
25
|
+
@custom_fields = [] if @custom_fields.nil?
|
26
|
+
@custom_fields << custom_field
|
27
|
+
end
|
28
|
+
|
29
|
+
|
30
|
+
# Setter
|
31
|
+
def add_address(address)
|
32
|
+
@addresses = [] if @addresses.nil?
|
33
|
+
@addresses << address
|
34
|
+
end
|
35
|
+
|
36
|
+
|
37
|
+
# Setter
|
38
|
+
def add_email(email_address)
|
39
|
+
@email_addresses = [] if @email_addresses.nil?
|
40
|
+
@email_addresses << email_address
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
#
|
2
|
+
# export_contacts.rb
|
3
|
+
# ConstantContact
|
4
|
+
#
|
5
|
+
# Copyright (c) 2013 Constant Contact. All rights reserved.
|
6
|
+
|
7
|
+
module ConstantContact
|
8
|
+
module Components
|
9
|
+
class ExportContacts < Component
|
10
|
+
attr_accessor :file_type, :sort_by, :export_date_added,
|
11
|
+
:export_added_by, :lists, :column_names
|
12
|
+
|
13
|
+
|
14
|
+
# Constructor to create an ExportContacts object
|
15
|
+
# @param [Array] lists - array of lists ids
|
16
|
+
# @return [ExportContacts]
|
17
|
+
def initialize(lists = nil)
|
18
|
+
if !lists.nil?
|
19
|
+
@lists = lists
|
20
|
+
end
|
21
|
+
@file_type = 'CSV'
|
22
|
+
@sort_by = 'EMAIL_ADDRESS'
|
23
|
+
@export_date_added = true
|
24
|
+
@export_added_by = true
|
25
|
+
@column_names = ['Email Address', 'First Name', 'Last Name']
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|