contactology 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +5 -0
- data/.infinity_test +16 -0
- data/.rspec +3 -0
- data/.rvmrc +41 -0
- data/.watchr +36 -0
- data/Gemfile +6 -0
- data/Rakefile +1 -0
- data/contactology.gemspec +28 -0
- data/lib/contactology.rb +125 -0
- data/lib/contactology/api.rb +80 -0
- data/lib/contactology/basic_object.rb +21 -0
- data/lib/contactology/campaign.rb +127 -0
- data/lib/contactology/campaign/preview.rb +11 -0
- data/lib/contactology/campaigns.rb +2 -0
- data/lib/contactology/campaigns/standard.rb +80 -0
- data/lib/contactology/campaigns/transactional.rb +58 -0
- data/lib/contactology/configuration.rb +42 -0
- data/lib/contactology/contact.rb +193 -0
- data/lib/contactology/errors.rb +4 -0
- data/lib/contactology/issue.rb +24 -0
- data/lib/contactology/issues.rb +18 -0
- data/lib/contactology/list.rb +192 -0
- data/lib/contactology/list_proxy.rb +25 -0
- data/lib/contactology/parser.rb +5 -0
- data/lib/contactology/send_result.rb +35 -0
- data/lib/contactology/stash.rb +29 -0
- data/lib/contactology/transactional_message.rb +38 -0
- data/lib/contactology/version.rb +3 -0
- data/spec/factories/campaigns.rb +18 -0
- data/spec/factories/contacts.rb +3 -0
- data/spec/factories/issues.rb +9 -0
- data/spec/factories/lists.rb +3 -0
- data/spec/factories/transactional_messages.rb +5 -0
- data/spec/fixtures/net/campaign/destroy.yml +246 -0
- data/spec/fixtures/net/campaign/find/failure.yml +36 -0
- data/spec/fixtures/net/campaign/find/success.yml +176 -0
- data/spec/fixtures/net/campaign/find_by_name/failure.yml +36 -0
- data/spec/fixtures/net/campaign/find_by_name/success.yml +211 -0
- data/spec/fixtures/net/campaign/preview.yml +106 -0
- data/spec/fixtures/net/campaigns/standard/create/failure.yml +106 -0
- data/spec/fixtures/net/campaigns/standard/create/invalid.yml +141 -0
- data/spec/fixtures/net/campaigns/standard/create/success.yml +176 -0
- data/spec/fixtures/net/campaigns/standard/send_campaign/failure.yml +316 -0
- data/spec/fixtures/net/campaigns/standard/send_campaign/success.yml +316 -0
- data/spec/fixtures/net/campaigns/transactional/create/failure.yml +36 -0
- data/spec/fixtures/net/campaigns/transactional/create/success.yml +71 -0
- data/spec/fixtures/net/contact/active.yml +106 -0
- data/spec/fixtures/net/contact/change_email/success.yml +176 -0
- data/spec/fixtures/net/contact/change_email/unknown.yml +36 -0
- data/spec/fixtures/net/contact/create.yml +106 -0
- data/spec/fixtures/net/contact/destroy.yml +141 -0
- data/spec/fixtures/net/contact/find/active.yml +106 -0
- data/spec/fixtures/net/contact/find/suppressed.yml +141 -0
- data/spec/fixtures/net/contact/find/unknown.yml +36 -0
- data/spec/fixtures/net/contact/lists/empty.yml +106 -0
- data/spec/fixtures/net/contact/lists/full.yml +246 -0
- data/spec/fixtures/net/contact/lists/unknown.yml +71 -0
- data/spec/fixtures/net/contact/suppress.yml +141 -0
- data/spec/fixtures/net/list/all.yml +141 -0
- data/spec/fixtures/net/list/create.yml +106 -0
- data/spec/fixtures/net/list/destroy.yml +176 -0
- data/spec/fixtures/net/list/find/success.yml +141 -0
- data/spec/fixtures/net/list/find/unknown.yml +36 -0
- data/spec/fixtures/net/list/import/success.yml +351 -0
- data/spec/fixtures/net/list/subscribe/success.yml +211 -0
- data/spec/fixtures/net/list/unsubscribe/success.yml +246 -0
- data/spec/fixtures/net/transactional_message/send_message/failure.yml +176 -0
- data/spec/fixtures/net/transactional_message/send_message/success.yml +176 -0
- data/spec/models/contactology/api_spec.rb +51 -0
- data/spec/models/contactology/campaign_spec.rb +75 -0
- data/spec/models/contactology/campaigns/standard_spec.rb +84 -0
- data/spec/models/contactology/campaigns/transactional_spec.rb +28 -0
- data/spec/models/contactology/configuration_spec.rb +29 -0
- data/spec/models/contactology/contact_spec.rb +175 -0
- data/spec/models/contactology/issues_spec.rb +34 -0
- data/spec/models/contactology/list_spec.rb +125 -0
- data/spec/models/contactology/send_result_spec.rb +65 -0
- data/spec/models/contactology/stash_spec.rb +65 -0
- data/spec/models/contactology/transactional_message_spec.rb +65 -0
- data/spec/models/contactology_spec.rb +67 -0
- data/spec/requests/contacts_spec.rb +4 -0
- data/spec/spec_helper.rb +15 -0
- data/spec/support/contactology.rb +34 -0
- data/spec/support/factory_girl.rb +19 -0
- data/spec/support/vcr.rb +11 -0
- metadata +282 -0
@@ -0,0 +1,80 @@
|
|
1
|
+
require 'contactology/campaign'
|
2
|
+
require 'contactology/campaigns'
|
3
|
+
|
4
|
+
class Contactology::Campaigns::Standard < Contactology::Campaign
|
5
|
+
property :content, :required => true
|
6
|
+
property :name, :from => :campaignName, :required => true
|
7
|
+
property :recipients, :required => true
|
8
|
+
property :sender_email, :from => :senderEmail, :required => true
|
9
|
+
property :sender_name, :from => :senderName, :required => true
|
10
|
+
property :subject, :required => true
|
11
|
+
|
12
|
+
|
13
|
+
def []=(property, value)
|
14
|
+
if property.to_s == 'recipients'
|
15
|
+
super 'recipients', normalize_recipients(value)
|
16
|
+
else
|
17
|
+
super
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def save(options = {})
|
22
|
+
self.class.query('Campaign_Create_Standard', options.merge({
|
23
|
+
'recipients' => recipients,
|
24
|
+
'campaignName' => name,
|
25
|
+
'subject' => subject,
|
26
|
+
'senderEmail' => sender_email,
|
27
|
+
'senderName' => sender_name,
|
28
|
+
'content' => content,
|
29
|
+
'optionalParameters' => {
|
30
|
+
'authenticate' => authenticate,
|
31
|
+
'replyToEmail' => reply_to_email,
|
32
|
+
'replyToName' => reply_to_name,
|
33
|
+
'trackReplies' => track_replies,
|
34
|
+
'recipientName' => recipient_name,
|
35
|
+
'showInArchive' => show_in_archive,
|
36
|
+
'viewInBrowser' => view_in_browser,
|
37
|
+
'trackOpens' => track_opens,
|
38
|
+
'trackClickThruHTML' => track_click_thru_html,
|
39
|
+
'trackClickThruText' => track_click_thru_text,
|
40
|
+
'googleAnalyticsName' => google_analytics_name,
|
41
|
+
'clickTaleName' => click_tale_name,
|
42
|
+
'clickTaleCustomFields' => click_tale_custom_fields,
|
43
|
+
'automaticTweet' => automatic_tweet
|
44
|
+
},
|
45
|
+
:on_error => false,
|
46
|
+
:on_timeout => false,
|
47
|
+
:on_success => Proc.new { |response| self.id = response; self }
|
48
|
+
}))
|
49
|
+
end
|
50
|
+
|
51
|
+
##
|
52
|
+
# Public: Sends the campaign.
|
53
|
+
#
|
54
|
+
# Returns an empty collection when successful.
|
55
|
+
# Returns a collection of issues when unsuccessful.
|
56
|
+
#
|
57
|
+
def send_campaign(options = {})
|
58
|
+
self.class.query('Campaign_Send', options.merge({
|
59
|
+
'campaignId' => id,
|
60
|
+
:on_error => Proc.new { |response| process_send_campaign_result response },
|
61
|
+
:on_timeout => process_send_campaign_result({'success' => false, 'issues' => [{'text' => 'Connection timeout'}]}),
|
62
|
+
:on_success => Proc.new { |response| process_send_campaign_result response }
|
63
|
+
}))
|
64
|
+
end
|
65
|
+
|
66
|
+
|
67
|
+
private
|
68
|
+
|
69
|
+
|
70
|
+
def normalize_recipients(input)
|
71
|
+
input = [input].flatten.compact.uniq
|
72
|
+
input = input.select { |i| i.kind_of?(Contactology::List) }.collect { |list| list.id }
|
73
|
+
input = {'list' => input.size == 1 ? input.first : input}
|
74
|
+
input
|
75
|
+
end
|
76
|
+
|
77
|
+
def process_send_campaign_result(data)
|
78
|
+
Contactology::SendResult.new(data)
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'contactology/campaign'
|
2
|
+
require 'contactology/campaigns'
|
3
|
+
|
4
|
+
class Contactology::Campaigns::Transactional < Contactology::Campaign
|
5
|
+
property :test_contact, :from => :testContact
|
6
|
+
property :test_replacements, :from => :testReplacements
|
7
|
+
|
8
|
+
|
9
|
+
def self.create(attributes, options = {})
|
10
|
+
new(attributes).save(options)
|
11
|
+
end
|
12
|
+
|
13
|
+
|
14
|
+
##
|
15
|
+
# Public: Stores the campaign information onto Contactology.
|
16
|
+
#
|
17
|
+
# Returns a Transactional instance with the campaign ID when successful.
|
18
|
+
# Returns a Contactology::SendResult instance with issues on failure.
|
19
|
+
#
|
20
|
+
def save(options = {})
|
21
|
+
self.class.query('Campaign_Create_Transactional', options.merge({
|
22
|
+
'campaignName' => name,
|
23
|
+
'content' => content,
|
24
|
+
'senderEmail' => sender_email,
|
25
|
+
'senderName' => sender_name,
|
26
|
+
'subject' => subject,
|
27
|
+
'testContact' => test_contact,
|
28
|
+
'testReplacements' => test_replacements,
|
29
|
+
'optionalParameters' => {
|
30
|
+
'authenticate' => authenticate,
|
31
|
+
'automaticTweet' => automatic_tweet,
|
32
|
+
'clickTaleCustomFields' => click_tale_custom_fields,
|
33
|
+
'clickTaleName' => click_tale_name,
|
34
|
+
'googleAnalyticsName' => google_analytics_name,
|
35
|
+
'recipientName' => recipient_name,
|
36
|
+
'replyToEmail' => reply_to_email,
|
37
|
+
'replyToName' => reply_to_name,
|
38
|
+
'showInArchive' => show_in_archive,
|
39
|
+
'trackClickThruHTML' => track_click_thru_html,
|
40
|
+
'trackClickThruText' => track_click_thru_text,
|
41
|
+
'trackOpens' => track_opens,
|
42
|
+
'trackReplies' => track_replies,
|
43
|
+
'viewInBrowser' => view_in_browser
|
44
|
+
},
|
45
|
+
:on_error => Proc.new { |response| process_send_campaign_result response },
|
46
|
+
:on_timeout => process_send_campaign_result('success' => false, 'issues' => [{'text' => 'Connection error'}]),
|
47
|
+
:on_success => Proc.new { |response| self.id = response; self }
|
48
|
+
}))
|
49
|
+
end
|
50
|
+
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
|
55
|
+
def process_send_campaign_result(data)
|
56
|
+
Contactology::SendResult.new(data)
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
##
|
2
|
+
# Holds configuration objects used by the library. The Contactology module
|
3
|
+
# holds reference to a default Configuration, which will be used when no
|
4
|
+
# explicit configurations are given to a particular query.
|
5
|
+
#
|
6
|
+
class Contactology::Configuration
|
7
|
+
##
|
8
|
+
# Public: Set the API endpoint to be used.
|
9
|
+
#
|
10
|
+
# endpoint - The String to use for the API endpoint.
|
11
|
+
#
|
12
|
+
# Returns nothing.
|
13
|
+
#
|
14
|
+
attr_writer :endpoint
|
15
|
+
|
16
|
+
##
|
17
|
+
# Public: Get the API key used for queries.
|
18
|
+
#
|
19
|
+
# Returns the String of the key.
|
20
|
+
#
|
21
|
+
attr_reader :key
|
22
|
+
#
|
23
|
+
##
|
24
|
+
# Public: Set the API key used for queries.
|
25
|
+
#
|
26
|
+
# key - The String to use for the API key.
|
27
|
+
#
|
28
|
+
# Returns nothing.
|
29
|
+
#
|
30
|
+
attr_writer :key
|
31
|
+
|
32
|
+
##
|
33
|
+
# Public: Get the API endpoint used by the configuration. Unless explicitly
|
34
|
+
# set, the endpoint will default to the official production endpoint at
|
35
|
+
# "https://api.emailcampaigns.net/2/REST/".
|
36
|
+
#
|
37
|
+
# Returns the String for the API endpoint.
|
38
|
+
#
|
39
|
+
def endpoint
|
40
|
+
@endpoint ||= 'https://api.emailcampaigns.net/2/REST/'
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,193 @@
|
|
1
|
+
require 'contactology/stash'
|
2
|
+
require 'contactology/api'
|
3
|
+
|
4
|
+
module Contactology
|
5
|
+
##
|
6
|
+
# Represents a Contact on Contactology. Contacts always must have an email
|
7
|
+
# address and then may optionally carry other custom fields.
|
8
|
+
#
|
9
|
+
class Contact < Contactology::Stash
|
10
|
+
extend API
|
11
|
+
|
12
|
+
property :id, :from => :contactId
|
13
|
+
property :email, :required => true
|
14
|
+
property :status
|
15
|
+
property :source
|
16
|
+
property :custom_fields, :from => :customFields
|
17
|
+
|
18
|
+
|
19
|
+
##
|
20
|
+
# Public: Create a new contact. The only required attribute is an :email
|
21
|
+
# address.
|
22
|
+
#
|
23
|
+
# Examples
|
24
|
+
#
|
25
|
+
# Contactology::Contact.create(:email => 'joe@example.local')
|
26
|
+
# # => #<Contactology::Contact:0x000... @email="joe@example.com" ...>
|
27
|
+
#
|
28
|
+
# Returns a Contactology::Contact instance when successful.
|
29
|
+
# Returns false when unsuccessful or a network error occurs.
|
30
|
+
#
|
31
|
+
def self.create(attributes, options = {})
|
32
|
+
contact = new(attributes)
|
33
|
+
contact.save(options) ? contact : false
|
34
|
+
end
|
35
|
+
|
36
|
+
##
|
37
|
+
# Public: Lookup a contact's information by email address.
|
38
|
+
#
|
39
|
+
# Examples
|
40
|
+
#
|
41
|
+
# Contactology::Contact.find('joe@example.local')
|
42
|
+
# # => #<Contactology::Contact:0x000... @email="joe@example.local" ...>
|
43
|
+
#
|
44
|
+
# Returns a Contactology::Contact instance when a match is found. Otherise,
|
45
|
+
# returns nil.
|
46
|
+
#
|
47
|
+
def self.find(email, options = {})
|
48
|
+
query('Contact_Get', options.merge({
|
49
|
+
'email' => email,
|
50
|
+
'optionalParameters' => {'getAllCustomFields' => true},
|
51
|
+
:on_timeout => nil,
|
52
|
+
:on_error => nil,
|
53
|
+
:on_success => Proc.new { |response|
|
54
|
+
Contact.new(response.values.first) if response.respond_to?(:values)
|
55
|
+
}
|
56
|
+
}))
|
57
|
+
end
|
58
|
+
|
59
|
+
|
60
|
+
##
|
61
|
+
# Public: Indicates whether or not the contact is active. Active contacts
|
62
|
+
# may receive mailings from your campaigns.
|
63
|
+
#
|
64
|
+
# Returns true if active.
|
65
|
+
# Returns false if non-active.
|
66
|
+
#
|
67
|
+
def active?
|
68
|
+
status == 'active'
|
69
|
+
end
|
70
|
+
|
71
|
+
##
|
72
|
+
# Public: Indicates whether or not the contact has a bounced address. This
|
73
|
+
# means that mail delivery has failed in a way that Contactology is no
|
74
|
+
# longer sending mailings to this contact.
|
75
|
+
#
|
76
|
+
# Returns true if bounced.
|
77
|
+
# Returns false if non-bounced.
|
78
|
+
#
|
79
|
+
def bounced?
|
80
|
+
status == 'bounced'
|
81
|
+
end
|
82
|
+
|
83
|
+
##
|
84
|
+
# Public: Changes the contact's email address to the new address given.
|
85
|
+
#
|
86
|
+
# Examples
|
87
|
+
#
|
88
|
+
# contact = Contactology::Contact.find('joe@example.local')
|
89
|
+
# # => #<Contactology::Contact:0x000... @email="joe@example.local" ...>
|
90
|
+
# contact.change_email('jim@example.local')
|
91
|
+
# # => true
|
92
|
+
# contact.email
|
93
|
+
# # => 'jim@example.local'
|
94
|
+
#
|
95
|
+
# Returns true when successful.
|
96
|
+
# Returns false when unsuccessful or for a network failure.
|
97
|
+
#
|
98
|
+
def change_email(new_email, options = {})
|
99
|
+
self.class.query('Contact_Change_Email', options.merge({
|
100
|
+
'email' => email,
|
101
|
+
'newEmail' => new_email,
|
102
|
+
:on_timeout => false,
|
103
|
+
:on_error => false,
|
104
|
+
:on_success => Proc.new { |response| self.email = new_email; true }
|
105
|
+
}))
|
106
|
+
end
|
107
|
+
|
108
|
+
def deleted?
|
109
|
+
status == 'deleted'
|
110
|
+
end
|
111
|
+
|
112
|
+
##
|
113
|
+
# Public: Removes the contact from Contactology and from your account.
|
114
|
+
#
|
115
|
+
# Examples
|
116
|
+
#
|
117
|
+
# contact = Contactology::Contact.find('joe@example.local')
|
118
|
+
# # => #<Contactology::Contact:0x000... @email="joe@example.local" ...>
|
119
|
+
# contact.destroy
|
120
|
+
# # => true
|
121
|
+
#
|
122
|
+
# Returns true when successful.
|
123
|
+
# Returns false when unsuccessful or for a network failure.
|
124
|
+
#
|
125
|
+
def destroy(options = {})
|
126
|
+
self.class.query('Contact_Delete', options.merge({
|
127
|
+
:email => email,
|
128
|
+
:on_timeout => false,
|
129
|
+
:on_error => false,
|
130
|
+
:on_success => Proc.new { |r| self.status = 'deleted'; true }
|
131
|
+
}))
|
132
|
+
end
|
133
|
+
|
134
|
+
def lists(options = {})
|
135
|
+
self.class.query('Contact_Get_Subscriptions', options.merge({
|
136
|
+
'email' => email,
|
137
|
+
:on_timeout => [],
|
138
|
+
:on_error => [],
|
139
|
+
:on_success => Proc.new { |response|
|
140
|
+
response.collect { |listid| ListProxy.new(listid) }
|
141
|
+
}
|
142
|
+
}))
|
143
|
+
end
|
144
|
+
|
145
|
+
def save(options = {})
|
146
|
+
self.class.query('Contact_Add', {
|
147
|
+
'email' => email,
|
148
|
+
'customFields' => custom_fields,
|
149
|
+
'optionalParameters' => {'updateCustomFields' => true},
|
150
|
+
:on_timeout => false,
|
151
|
+
:on_error => false,
|
152
|
+
:on_success => Proc.new { |response| self.status = 'active'; self }
|
153
|
+
})
|
154
|
+
end
|
155
|
+
|
156
|
+
def save!(options = {})
|
157
|
+
save(options) || raise(InvalidObjectError)
|
158
|
+
end
|
159
|
+
|
160
|
+
##
|
161
|
+
# Public: Suppresses the contact, removing them from receiving campaign
|
162
|
+
# mailings.
|
163
|
+
#
|
164
|
+
# Returns true when successful.
|
165
|
+
# Returns false when unsuccessful.
|
166
|
+
#
|
167
|
+
def suppress(options = {})
|
168
|
+
response = self.class.query('Contact_Suppress', options.merge({
|
169
|
+
:email => email,
|
170
|
+
:on_timeout => false,
|
171
|
+
:on_error => false,
|
172
|
+
:on_success => Proc.new { |response| response }
|
173
|
+
}))
|
174
|
+
|
175
|
+
if response
|
176
|
+
self.status = 'suppressed'
|
177
|
+
end
|
178
|
+
|
179
|
+
response
|
180
|
+
end
|
181
|
+
|
182
|
+
##
|
183
|
+
# Public: Indicates whether or not the contact is suppressed. Suppressed
|
184
|
+
# contacts may not receive mailings from your campaigns.
|
185
|
+
#
|
186
|
+
# Returns true if suppressed.
|
187
|
+
# Returns false if non-suppressed.
|
188
|
+
#
|
189
|
+
def suppressed?
|
190
|
+
status == 'suppressed'
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Contactology
|
2
|
+
class Issue
|
3
|
+
attr_reader :type
|
4
|
+
attr_reader :text
|
5
|
+
attr_reader :message
|
6
|
+
attr_reader :context
|
7
|
+
attr_reader :col
|
8
|
+
attr_reader :deduction
|
9
|
+
|
10
|
+
def initialize(details)
|
11
|
+
details = Hash.new unless details.kind_of?(Hash)
|
12
|
+
@type = details['type']
|
13
|
+
@text = details['text']
|
14
|
+
@message = details['message']
|
15
|
+
@context = details['context']
|
16
|
+
@col = details['col']
|
17
|
+
@deduction = details['deduction']
|
18
|
+
end
|
19
|
+
|
20
|
+
def to_s
|
21
|
+
"%s: %s, %d point deduction" % [type, text || message, deduction]
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'contactology/issue'
|
2
|
+
|
3
|
+
module Contactology
|
4
|
+
class Issues < Array
|
5
|
+
attr_reader :score
|
6
|
+
|
7
|
+
def initialize(data = nil)
|
8
|
+
data = Hash.new unless data.kind_of?(Hash)
|
9
|
+
@score = data['score'] || 0
|
10
|
+
(data['issues'] || []).each { |i| self << i }
|
11
|
+
end
|
12
|
+
|
13
|
+
|
14
|
+
def <<(o)
|
15
|
+
super(Issue.new(o))
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,192 @@
|
|
1
|
+
require 'contactology/stash'
|
2
|
+
require 'contactology/api'
|
3
|
+
|
4
|
+
module Contactology
|
5
|
+
##
|
6
|
+
# Represents a subscription List in Contactology. Lists are a convenient way
|
7
|
+
# to organize groups of Contacts in order to send large numbers of contacts
|
8
|
+
# a Campaign, easily.
|
9
|
+
#
|
10
|
+
class List < Contactology::Stash
|
11
|
+
extend API
|
12
|
+
|
13
|
+
property :id, :from => :listId
|
14
|
+
property :name, :required => true
|
15
|
+
property :description
|
16
|
+
property :type
|
17
|
+
property :opt_in, :from => :optIn
|
18
|
+
|
19
|
+
|
20
|
+
##
|
21
|
+
# Public: Returns a collection of all active lists on your account.
|
22
|
+
#
|
23
|
+
# Returns a collection of Contactology::List instances.
|
24
|
+
#
|
25
|
+
def self.all(options = {})
|
26
|
+
query('List_Get_Active_Lists', options.merge({
|
27
|
+
:on_timeout => [],
|
28
|
+
:on_error => [],
|
29
|
+
:on_success => Proc.new { |response| response.values.collect { |list| List.new(list) }}
|
30
|
+
}))
|
31
|
+
end
|
32
|
+
|
33
|
+
##
|
34
|
+
# Public: Creates a new, public list on Contactology. The new list's :name
|
35
|
+
# is the only required attribute.
|
36
|
+
#
|
37
|
+
# Returns a Contactology::List instance when successful.
|
38
|
+
# Returns false when unsuccessful or a network failure occurs.
|
39
|
+
#
|
40
|
+
def self.create(attributes, options = {})
|
41
|
+
raise ArgumentError, 'Expected an :name attribute' unless attributes.has_key?(:name)
|
42
|
+
new(attributes).save(options)
|
43
|
+
end
|
44
|
+
|
45
|
+
##
|
46
|
+
# Public: Loads a Contactology list by ID.
|
47
|
+
#
|
48
|
+
# Returns a Contactology::List instance on success.
|
49
|
+
# Returns nil for an unknown ID or network error.
|
50
|
+
#
|
51
|
+
def self.find(id, options = {})
|
52
|
+
query('List_Get_Info', options.merge({
|
53
|
+
'listId' => id,
|
54
|
+
:on_timeout => nil,
|
55
|
+
:on_error => nil,
|
56
|
+
:on_success => Proc.new { |response| new(response) if response.kind_of?(Hash) }
|
57
|
+
}))
|
58
|
+
end
|
59
|
+
|
60
|
+
|
61
|
+
##
|
62
|
+
# Public: Removes a list from Contactology.
|
63
|
+
#
|
64
|
+
# Returns true when successful.
|
65
|
+
# Returns false when unsuccessful.
|
66
|
+
#
|
67
|
+
def destroy(options = {})
|
68
|
+
self.class.query('List_Delete', options.merge({
|
69
|
+
'listId' => id,
|
70
|
+
:on_timeout => false,
|
71
|
+
:on_error => false,
|
72
|
+
:on_success => Proc.new { |response| response }
|
73
|
+
}))
|
74
|
+
end
|
75
|
+
|
76
|
+
##
|
77
|
+
# Public: Imports contacts into a list using a prescribed contact
|
78
|
+
# collection format.
|
79
|
+
#
|
80
|
+
# Examples
|
81
|
+
#
|
82
|
+
# list = Contactology::List.create :name => 'import-test'
|
83
|
+
# # => #<Contactology::List:0x000... @name="import-test" ...>
|
84
|
+
# list.import([{'email' => 'import@example.local', 'first_name' => 'Imp', 'last_name' => 'Orted'}, {...}])
|
85
|
+
# # => true
|
86
|
+
#
|
87
|
+
# Returns true if all contacts imported successfully.
|
88
|
+
# Returns false if any contact import failed or a network error occurred.
|
89
|
+
#
|
90
|
+
def import(contacts, options = {})
|
91
|
+
self.class.query('List_Import_Contacts', options.merge({
|
92
|
+
'listId' => id,
|
93
|
+
'source' => options[:source] || 'Manual Entry',
|
94
|
+
'contacts' => contacts,
|
95
|
+
'optionalParameters' => {
|
96
|
+
'activateDeleted' => true,
|
97
|
+
'updateCustomFields' => true
|
98
|
+
},
|
99
|
+
:on_timeout => false,
|
100
|
+
:on_error => false,
|
101
|
+
:on_success => Proc.new { |response|
|
102
|
+
response.kind_of?(Hash) && response['success'] == contacts.size
|
103
|
+
}
|
104
|
+
}))
|
105
|
+
end
|
106
|
+
|
107
|
+
def internal?
|
108
|
+
type == 'internal'
|
109
|
+
end
|
110
|
+
|
111
|
+
def opt_in?
|
112
|
+
opt_in
|
113
|
+
end
|
114
|
+
|
115
|
+
def public?
|
116
|
+
type == 'public'
|
117
|
+
end
|
118
|
+
|
119
|
+
def private?
|
120
|
+
type == 'private'
|
121
|
+
end
|
122
|
+
|
123
|
+
def save(options = {})
|
124
|
+
self.class.query('List_Add_Public', options.merge({
|
125
|
+
'listId' => id,
|
126
|
+
'name' => name,
|
127
|
+
'description' => description,
|
128
|
+
'optionalParameters' => {
|
129
|
+
'optIn' => opt_in
|
130
|
+
},
|
131
|
+
:on_timeout => false,
|
132
|
+
:on_error => false,
|
133
|
+
:on_success => Proc.new { |response|
|
134
|
+
data = self.class.find(response)
|
135
|
+
self.id = data.id
|
136
|
+
self.description = data.description
|
137
|
+
self.name = data.name
|
138
|
+
self.type = data.type
|
139
|
+
self.opt_in = data.opt_in
|
140
|
+
self
|
141
|
+
}
|
142
|
+
}))
|
143
|
+
end
|
144
|
+
|
145
|
+
def save!(options = {})
|
146
|
+
save(options) || raise(InvalidObjectError)
|
147
|
+
end
|
148
|
+
|
149
|
+
##
|
150
|
+
# Public: Adds an email address to the list.
|
151
|
+
#
|
152
|
+
# Examples
|
153
|
+
#
|
154
|
+
# list = Contactology::List.find 1
|
155
|
+
# # => #<Contactology::List:0x000... @id="1" ...>
|
156
|
+
# list.subscribe 'new@example.local'
|
157
|
+
# # => true
|
158
|
+
#
|
159
|
+
# Returns true when the address is successfully added.
|
160
|
+
# Returns false when the subscription fails or a network error occurs.
|
161
|
+
#
|
162
|
+
def subscribe(email, options = {})
|
163
|
+
self.class.query('List_Subscribe', options.merge({
|
164
|
+
'listId' => id,
|
165
|
+
'email' => email.respond_to?(:email) ? email.email : email,
|
166
|
+
:on_timeout => false,
|
167
|
+
:on_error => false,
|
168
|
+
:on_success => Proc.new { |response| response }
|
169
|
+
}))
|
170
|
+
end
|
171
|
+
|
172
|
+
def test?
|
173
|
+
type == 'test'
|
174
|
+
end
|
175
|
+
|
176
|
+
##
|
177
|
+
# Public: Unsubscribes an email address from the Contactology::List.
|
178
|
+
#
|
179
|
+
# Returns true when the address is removed.
|
180
|
+
# Returns false when the removal fails or a network error occurs.
|
181
|
+
#
|
182
|
+
def unsubscribe(email, options = {})
|
183
|
+
self.class.query('List_Unsubscribe', options.merge({
|
184
|
+
'listId' => id,
|
185
|
+
'email' => email,
|
186
|
+
:on_timeout => false,
|
187
|
+
:on_error => false,
|
188
|
+
:on_success => Proc.new { |response| response }
|
189
|
+
}))
|
190
|
+
end
|
191
|
+
end
|
192
|
+
end
|