acts_as_icontact 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
data/.gitignore ADDED
@@ -0,0 +1,6 @@
1
+ *.sw?
2
+ *.tmproj
3
+ .DS_Store
4
+ coverage
5
+ rdoc
6
+ pkg
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Stephen Eley
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.markdown ADDED
@@ -0,0 +1,196 @@
1
+ ActsAsIcontact
2
+ ==============
3
+ ActsAsIcontact connects Ruby applications with the [iContact e-mail marketing service](http://icontact.com) using the iContact API v2.0. Building on the [RestClient](http://rest-client.heroku.com) gem, it offers two significant feature sets:
4
+
5
+ * Simple, consistent access to all resources in the iContact API; and
6
+ * Automatic synchronizing between ActiveRecord models and iContact contact lists for Rails applications.
7
+
8
+ Prerequisites
9
+ -------------
10
+ You'll need the following to use this gem properly:
11
+
12
+ 1. **Ruby 1.9** Yeah, we know, change is _scary_ and a zillion of your other gems only work in 1.8. But ActsAsIcontact makes use of a few 1.9 features for efficiency, such as Enumerators. It's _possible_ that this might work in 1.8.7 if you install the **JSON** gem and `require 'enumerator'` explicitly -- but the author hasn't tested it. If you need it to work in 1.8, speak up. Or better yet, make it work and submit a patch.
13
+
14
+ 2. **Rails 2.1** _(If using Rails integration)_ We use ActiveRecord's 'dirty fields' feature that first appeared in 2.1 to determine whether iContact needs updating. If you're on a version of Rails older than this, it's probably worth your while to update anyway.
15
+
16
+ 3. **rest-client** This gem _should_ install when you install the **acts\_as\_icontact** gem. But we include it here for completeness.
17
+
18
+ Setting Up
19
+ ----------
20
+ Using ActsAsIcontact is easy, but going through iContact's authorization process requires jumping a couple of hoops. Here's how to get going quickly:
21
+
22
+ 1. Install the gem.
23
+
24
+ $ sudo gem install acts_as_icontact
25
+
26
+ 2. _Optional but recommended:_ Go to <http://beta.icontact.com> and sign up for an iContact Beta account. This will let you test your app without risk of blowing away your production mailing lists.
27
+
28
+ 3. Enable the ActsAsIcontact gem for use with your iContact account. The URL and credentials you'll use are different between the beta and production environments:
29
+
30
+ * **BETA:** Go to <http://app.beta.icontact.com/icp/core/externallogin> and enter `Ml5SnuFhnoOsuZeTOuZQnLUHTbzeUyhx` for the Application Id. Choose a password for ActsAsIcontact that's different from your account password.
31
+
32
+ * **PRODUCTION:** Go to <http://app.icontact.com/icp/core/externallogin> and enter `IYDOhgaZGUKNjih3hl1ItLln7zpAtWN2` for the Application Id. Choose a password for ActsAsIcontact that's different from your account password.
33
+
34
+ 4. Set your _(beta, if applicable)_ account username and the password you just chose for API access. You can either set the environment variables `ICONTACT_MODE`, `ICONTACT_USERNAME`, and `ICONTACT_PASSWORD`, or you can explicitly do it with calls to the Config module:
35
+
36
+ require 'rubygems'
37
+ require 'acts_as_icontact'
38
+
39
+ ActsAsIcontact::Config.mode = :beta
40
+ ActsAsIcontact::Config.username = my_beta_username
41
+ ActsAsIcontact::Config.password = my_api_password
42
+
43
+ If you're using Rails, the recommended approach is to require the gem with `config.gem 'acts_as_icontact'` in your **config/environment.rb** file, and then set up an initializer (i.e. **config/initializers/acts\_as\_icontact.rb**) with the above code. See more about Rails below.
44
+
45
+ 5. Rinse and repeat with production credentials when you're ready to move out of the beta environment.
46
+
47
+ API Access
48
+ ----------
49
+ Whether or not you're using Rails, retrieving and modifying iContact resources is simple. The gem autodiscovers your account and client folder IDs (you only have one of each unless you're an 'agency' account), so you can jump straight to the good parts:
50
+
51
+ contacts = ActsAsIcontact::Contact.find(:all) # => <#ActsAsIcontact::ResourceCollection>
52
+ c = contacts.first # => <#ActsAsIcontact.Contact>
53
+ c.firstName # => "Bob"
54
+ c.lastName # => "Smith"
55
+ c.email # => "bob@example.org"
56
+ c.lastName = "Smith-Jones" # Bob gets married and changes his name
57
+ c.save # => true
58
+ history = c.actions # => <#ActsAsIcontact::ResourceCollection>
59
+ a = history.first # => <#ActsAsIcontact::Action>
60
+ a.actionType # => "EditFields"
61
+
62
+
63
+ ### Nesting
64
+ The interface is deliberately as "ActiveRecord-like" as possible, with methods linking resources that are either nested in iContact's URLs or logically related. Messages have a Message#bounces method. Lists have List#subscribers to list the Contacts subscribed to them, and Contacts have Contact#lists. Read the documentation for each class to find out what you can do:
65
+
66
+ * ActsAsIcontact::Account
67
+ * ActsAsIcontact::ClientFolder
68
+ * ActsAsIcontact::Contact
69
+ * ActsAsIcontact::History _(documented as "Contact History")_
70
+ * ActsAsIcontact::Message
71
+ * ActsAsIcontact::Bounce
72
+ * ActsAsIcontact::Click
73
+ * ActsAsIcontact::Open
74
+ * ActsAsIcontact::Unsubscribe
75
+ * ActsAsIcontact::Statistics
76
+ * ActsAsIcontact::List
77
+ * ActsAsIcontact::Segment
78
+ * ActsAsIcontact::Criterion _(documented as "Segment Criteria")_
79
+ * ActsAsIcontact::Subscription
80
+ * ActsAsIcontact::Campaign
81
+ * ActsAsIcontact::CustomField
82
+ * ActsAsIcontact::Send
83
+ * ActsAsIcontact::Upload
84
+ * ActsAsIcontact::User
85
+ * ActsAsIcontact::Permission
86
+ * ActsAsIcontact::Time
87
+
88
+ ### Searching
89
+ Searches are handled in a sane way using the same query options that iContact accepts. The following are all valid:
90
+
91
+ `Messages.all` -- *Same as `Messages.find(:all)`*
92
+ `Messages.first` -- *Same as `Messages.find(:first)`*
93
+ `Messages.find(:all, :limit => 20)` -- *First 20 messages*
94
+ `Messages.find(:all, :limit => 20, :offset => 40)` -- *Messages 41-60*
95
+ `Messages.first(:subject => "Fnord")` -- *First message with the given subject*
96
+ `Messages.all(:orderby => createDate, :desc => true)` -- *Messages ordered by most recent first*
97
+ `Messages.all(:messageType => "welcome", :campaignId => 11)` -- *Welcome messages from the given campaign*
98
+
99
+ At this time, special searches are not yet supported. Fields requiring dates must also be given a string corresponding to the ISO8601 timestamp (e.g. `2006-09-16T14:30:00-06:00`). Proper date/time conversion will happen soon.
100
+
101
+ ### Updating
102
+
103
+ Again, think ActiveRecord. When you initialize an object, you can optionally pass it a hash of values:
104
+
105
+ c = Contact.new(:firstName => "Bob",
106
+ :lastName => "Smith-Jones",
107
+ :email => "bob@example.org")
108
+ c.address = "123 Test Street"
109
+
110
+ Each resource class has a `#save` method which returns true or false. If false, the `#error` method contains the reply back from iContact about what went wrong. (Which may or may not be informative, but we can't tell you more than they do.) There's also a`#save!`method which throws an exception instead.
111
+
112
+ Nested resources can be created using the `build_` method (which returns an object but doesn't save it right away) or `create_` method (which does save it upon creation). The full panoply of ActiveRecord association methods are not implemented yet. (Hey, we said it was AR-_like._)
113
+
114
+ The `#delete` method on each class works as you'd expect, assuming iContact allows deletes on that resource. Resource collections containing the resource are not updated, however, so you may need to requery.
115
+
116
+ Multiple-record updates are not implemented at this time.
117
+
118
+ Rails Integration
119
+ -----------------
120
+ The _real_ power of ActsAsIcontact is its automatic syncing with ActiveRecord. At this time this feature is focused entirely on Contacts.
121
+
122
+ ### Activation
123
+ First add the line `config.gem 'acts_as_icontact'` to your **config/environment.rb** file. Then create an initializer (e.g. **config/initializers/acts\_as\_icontact.rb**) and set it up with your username and password. If applicable, you can give it both the beta _and_ production credentials:
124
+
125
+ module ActsAsIcontact
126
+ case Config.mode
127
+ when :beta
128
+ Config.username = my_beta_username
129
+ Config.password = my_beta_password
130
+ when :production
131
+ Config.username = my_production_username
132
+ Config.password = my_production_password
133
+ end
134
+ end
135
+
136
+ If ActsAsIcontact detects that it's running in a Rails app, the default behavior is to set the mode to `:production` if RAILS\_ENV is equal to "production" and `:beta` if RAILS\_ENV is set to anything else. (Incidentally, if you're _not_ in a Rails app but running Rack, the same logic applies for the RACK\_ENV environment variable.)
137
+
138
+ Finally, enable one of your models to synchronize with iContact with a simple declaration:
139
+
140
+ class Person < ActiveRecord::Base
141
+ acts_as_icontact
142
+ end
143
+
144
+ There are some options, of course; we'll get to those in a bit.
145
+
146
+ ### What Happens
147
+ When you call the `acts_as_icontact` method in an ActiveRecord class declaration, the gem does several useful things:
148
+
149
+ 1. Creates callbacks to post changes to iContact's API after a record is saved or deleted.
150
+ 2. Defines an `icontact_sync!` method to pull the contact's data _from_ iContact and make any changes.
151
+ 3. Defines other methods such as `icontact_lists` and `icontact_history` to make related data accessible.
152
+ 4. If an `icontact_status` field exists, creates named scopes on the model class for each iContact status. _(Pending)_
153
+
154
+ ### Options
155
+ Option values and field mappings can be passed to the `acts_as_icontact` declaration to set default behavior for the model class. Right now there's only one option:
156
+
157
+ `default_lists` -- _The name or ID number of a list to subscribe new contacts to automatically, or an array of said names or numbers_
158
+
159
+ ### Field Mappings
160
+ You can add contact integration to any ActiveRecord model that tracks an email address. (If your model _doesn't_ include email but you want to use iContact with it, you are very, very confused.)
161
+
162
+ Any fields that are named the same as iContact's personal information fields, or custom fields you've previously declared, will be autodiscovered. Otherwise you can map them:
163
+
164
+ class Customer < ActiveRecord::Base
165
+ acts_as_icontact :default_lists => ['New Customers', 'All Users'] # Puts new contact on two lists
166
+ :given_name => :firstName, # Key is Rails field, value is iContact field
167
+ :family_name => :lastName,
168
+ :address1 => :street,
169
+ :address2 => :street2,
170
+ :id => :rails_id, # Custom field created in iContact
171
+ :preferred? => :preferred_customer # Custom field
172
+ end
173
+
174
+ A few iContact-specific fields are exceptions, and have different autodiscovery names to avoid collisions with other attributes in your application:
175
+
176
+ `icontact_id` -- _Corresponds to `contactId` in iContact. Highly recommended._
177
+ `icontact_status` -- _Corresponds to `status` in iContact._
178
+ `icontact_created` -- _Corresponds to `createDate` in iContact._
179
+ `icontact_bounces` -- _Corresponds to `bounceCount` in iContact._
180
+
181
+ You are welcome to create these fields in your model or omit them. However, we _strongly_ recommend that you either include the `icontact_id` field to track iContact's primary key in your application, or map your own model's primary key to a custom field in iContact. You can also do both for two-way associations. If you don't establish a relationship with at least one ID, ActsAsIcontact will resort to using the email address for lookups -- which will be a problem if the email address changes.
182
+
183
+ ### Lists
184
+ The reason to add contacts to iContact is to put them on mailing lists. We know this. The `default_list` option (see above) is one way to do it automatically. The following methods are also defined on the model for your convenience:
185
+
186
+ `icontact_lists` -- _An array of List objects to which the contact is currently subscribed_
187
+ `icontact_subscribe(list)` -- _Given a list name or ID number, subscribes the contact to that list immediately_
188
+ `icontact_unsubscribe(list)` -- _Given a list name or ID number, unsubscribes the contact from that list_
189
+
190
+
191
+ ### Why Just Contacts?
192
+ iContact's interface is really quite good at handling pretty much every other resource. Campaigns, segments, etc. can usually stand alone. It's less likely that you'll need to keep copies of them in your Rails app. But contacts are highly entangled. If you're using iContact to communicate with your app's users or subjects, you'll want to keep iContact up-to-date when they change. And if someone bounces or unsubscribes in iContact, odds are good you'll want to know about it. So this is the strongest point of coupling and the highest priority feature. (Lists will likely come next, followed by messages.)
193
+
194
+ Copyright
195
+ ---------
196
+ Copyright (c) 2009 Stephen Eley. See LICENSE for details.
data/Rakefile ADDED
@@ -0,0 +1,57 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "acts_as_icontact"
8
+ gem.summary = "Automatic bridge between iContact e-mail marketing service and Rails ActiveRecord"
9
+ gem.email = "sfeley@gmail.com"
10
+ gem.homepage = "http://github.com/SFEley/acts_as_icontact"
11
+ gem.authors = ["Stephen Eley"]
12
+ gem.rubyforge_project = "actsasicontact"
13
+ gem.extra_rdoc_files = ["README.markdown"]
14
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
15
+ gem.description = <<ENDDESC
16
+ ActsAsIcontact connects Ruby applications with the iContact e-mail marketing service using the iContact API v2.0. Building on the RestClient gem, it offers two significant feature sets:
17
+
18
+ * Simple, consistent access to all resources in the iContact API; and
19
+ * Automatic synchronizing between ActiveRecord models and iContact contact lists for Rails applications.
20
+ ENDDESC
21
+ end
22
+
23
+ Jeweler::RubyforgeTasks.new
24
+ rescue LoadError
25
+ puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
26
+ end
27
+
28
+ require 'spec/rake/spectask'
29
+ Spec::Rake::SpecTask.new(:spec) do |spec|
30
+ spec.libs << 'lib' << 'spec'
31
+ spec.spec_files = FileList['spec/**/*_spec.rb']
32
+ end
33
+
34
+ Spec::Rake::SpecTask.new(:rcov) do |spec|
35
+ spec.libs << 'lib' << 'spec'
36
+ spec.pattern = 'spec/**/*_spec.rb'
37
+ spec.rcov = true
38
+ end
39
+
40
+
41
+ task :default => :spec
42
+
43
+ require 'hanna/rdoctask'
44
+ Rake::RDocTask.new do |rdoc|
45
+ if File.exist?('VERSION.yml')
46
+ config = YAML.load(File.read('VERSION.yml'))
47
+ version = "#{config[:major]}.#{config[:minor]}.#{config[:patch]}"
48
+ else
49
+ version = ""
50
+ end
51
+
52
+ rdoc.rdoc_dir = 'rdoc'
53
+ rdoc.title = "acts_as_icontact #{version}"
54
+ rdoc.rdoc_files.include('README*')
55
+ rdoc.rdoc_files.include('lib/**/*.rb')
56
+ end
57
+
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.1
@@ -0,0 +1,74 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{acts_as_icontact}
5
+ s.version = "0.1.1"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["Stephen Eley"]
9
+ s.date = %q{2009-07-24}
10
+ s.description = %q{ActsAsIcontact connects Ruby applications with the iContact e-mail marketing service using the iContact API v2.0. Building on the RestClient gem, it offers two significant feature sets:
11
+
12
+ * Simple, consistent access to all resources in the iContact API; and
13
+ * Automatic synchronizing between ActiveRecord models and iContact contact lists for Rails applications.
14
+ }
15
+ s.email = %q{sfeley@gmail.com}
16
+ s.extra_rdoc_files = [
17
+ "README.markdown"
18
+ ]
19
+ s.files = [
20
+ ".document",
21
+ ".gitignore",
22
+ "LICENSE",
23
+ "README.markdown",
24
+ "Rakefile",
25
+ "VERSION",
26
+ "acts_as_icontact.gemspec",
27
+ "lib/acts_as_icontact.rb",
28
+ "lib/acts_as_icontact/config.rb",
29
+ "lib/acts_as_icontact/connection.rb",
30
+ "lib/acts_as_icontact/exceptions.rb",
31
+ "lib/acts_as_icontact/resource.rb",
32
+ "lib/acts_as_icontact/resource_collection.rb",
33
+ "lib/acts_as_icontact/resources/account.rb",
34
+ "lib/acts_as_icontact/resources/client.rb",
35
+ "lib/acts_as_icontact/resources/contact.rb",
36
+ "spec/config_spec.rb",
37
+ "spec/connection_spec.rb",
38
+ "spec/resource_collection_spec.rb",
39
+ "spec/resource_spec.rb",
40
+ "spec/resources/account_spec.rb",
41
+ "spec/resources/client_spec.rb",
42
+ "spec/resources/contact_spec.rb",
43
+ "spec/spec.opts",
44
+ "spec/spec_fakeweb.rb",
45
+ "spec/spec_helper.rb"
46
+ ]
47
+ s.homepage = %q{http://github.com/SFEley/acts_as_icontact}
48
+ s.rdoc_options = ["--charset=UTF-8"]
49
+ s.require_paths = ["lib"]
50
+ s.rubyforge_project = %q{actsasicontact}
51
+ s.rubygems_version = %q{1.3.4}
52
+ s.summary = %q{Automatic bridge between iContact e-mail marketing service and Rails ActiveRecord}
53
+ s.test_files = [
54
+ "spec/config_spec.rb",
55
+ "spec/connection_spec.rb",
56
+ "spec/resource_collection_spec.rb",
57
+ "spec/resource_spec.rb",
58
+ "spec/resources/account_spec.rb",
59
+ "spec/resources/client_spec.rb",
60
+ "spec/resources/contact_spec.rb",
61
+ "spec/spec_fakeweb.rb",
62
+ "spec/spec_helper.rb"
63
+ ]
64
+
65
+ if s.respond_to? :specification_version then
66
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
67
+ s.specification_version = 3
68
+
69
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
70
+ else
71
+ end
72
+ else
73
+ end
74
+ end
@@ -0,0 +1,19 @@
1
+ require 'rubygems'
2
+ require 'rest_client'
3
+ require 'json'
4
+
5
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
6
+ require 'acts_as_icontact/exceptions'
7
+ require 'acts_as_icontact/config'
8
+ require 'acts_as_icontact/connection'
9
+ require 'acts_as_icontact/resource'
10
+ require 'acts_as_icontact/resource_collection'
11
+
12
+ # Load all of our resource files
13
+ Dir[File.join(File.dirname(__FILE__), 'acts_as_icontact', 'resources', '*.rb')].sort.each do |path|
14
+ filename = File.basename(path, '.rb')
15
+ require "acts_as_icontact/resources/#{filename}"
16
+ end
17
+
18
+ module ActsAsIcontact
19
+ end
@@ -0,0 +1,106 @@
1
+ module ActsAsIcontact
2
+ # Predefined and user-supplied parameters for interfacing with iContact. Most of these are
3
+ # required by the iContact API for authentication.
4
+ module Config
5
+
6
+ # Sets :production or :beta. This changes the AppId and URL.
7
+ def self.mode=(val)
8
+ @mode = val
9
+ end
10
+
11
+ # Determines whether to return the beta or production AppId and URL.
12
+ # If not explicitly set, it will first look for an ICONTACT_MODE environment variable.
13
+ # If it doesn't find one, it will attempt to detect a Rails or Rack environment; in either
14
+ # case it will default to :production if RAILS_ENV or RACK_ENV is 'production', and :beta
15
+ # otherwise. If none of these conditions apply, it assumes :production. (Because that
16
+ # probably means someone's doing ad hoc queries.)
17
+ def self.mode
18
+ @mode ||= case
19
+ when ENV["ICONTACT_MODE"]
20
+ ENV["ICONTACT_MODE"].to_sym
21
+ when Object.const_defined?(:Rails)
22
+ (ENV["RAILS_ENV"] == 'production' ? :production : :beta)
23
+ when Object.const_defined?(:Rack)
24
+ (ENV["RACK_ENV"] == 'production' ? :production : :beta)
25
+ else
26
+ :production
27
+ end
28
+ end
29
+
30
+
31
+ # Passed in the header of every request as the *API-AppId:* parameter. You should not need
32
+ # to change this. Ever.
33
+ def self.app_id
34
+ case mode
35
+ when :beta
36
+ "Ml5SnuFhnoOsuZeTOuZQnLUHTbzeUyhx"
37
+ when :production
38
+ "IYDOhgaZGUKNjih3hl1ItLln7zpAtWN2"
39
+ end
40
+ end
41
+
42
+ # The API version that this code is designed to interface with.
43
+ def self.api_version
44
+ 2.0
45
+ end
46
+
47
+ # Prefixed to the beginning of every API request. You can override this if you have some special
48
+ # need (e.g. working against a testing server, or if iContact takes their API out of beta and
49
+ # changes the URI before the gem gets updated), but for the most part you can leave it alone.
50
+ def self.url
51
+ @url ||= case mode
52
+ when :beta
53
+ "https://app.beta.icontact.com/icp/"
54
+ when :production
55
+ "https://app.icontact.com/icp/"
56
+ end
57
+ end
58
+
59
+ # Overrides the base URL for the API request.
60
+ def self.url=(val)
61
+ @url = val
62
+ end
63
+
64
+ # Used in the "Accept:" and "Content-Type:" headers of every API request. Defaults to JSON, and
65
+ # if you're simply using the gem methods there's no reason you should ever change this, as the
66
+ # results are auto-parsed into Ruby structures. But you can set it to text/xml if you want to.
67
+ def self.content_type
68
+ @content_type ||= "application/json"
69
+ end
70
+
71
+ # If you change this to anything other than application/json or text/xml you'll get an error.
72
+ # So sayeth iContact; so say we all.
73
+ def self.content_type=(val)
74
+ case val
75
+ when "text/xml"
76
+ @content_type = val
77
+ when "application/json"
78
+ @content_type = val
79
+ else
80
+ raise ActsAsIcontact::ConfigError, "Content Type must be application/json or text/xml"
81
+ end
82
+ end
83
+
84
+ # Required for every API request. If you're using these methods in a Rails app, the recommended
85
+ # way to set the username is in a Rails initializer file. You can also set the ICONTACT_USERNAME
86
+ # environment variable.
87
+ def self.username
88
+ @username ||= ENV['ICONTACT_USERNAME']
89
+ end
90
+
91
+ def self.username=(val)
92
+ @username = val
93
+ end
94
+
95
+ # Required for every API request. If you're using these methods in a Rails app, the recommended
96
+ # way to set the password is in a Rails initializer file. You can also set the ICONTACT_PASSWORD
97
+ # environment variable.
98
+ def self.password
99
+ @password ||= ENV['ICONTACT_PASSWORD']
100
+ end
101
+
102
+ def self.password=(val)
103
+ @password = val
104
+ end
105
+ end
106
+ end