infusionsoft 1.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +5 -0
- data/LICENSE.md +21 -0
- data/README.md +100 -0
- data/infusionsoft.gemspec +18 -0
- data/lib/infusionsoft.rb +27 -0
- data/lib/infusionsoft/api.rb +22 -0
- data/lib/infusionsoft/client.rb +25 -0
- data/lib/infusionsoft/client/affiliate.rb +52 -0
- data/lib/infusionsoft/client/contact.rb +143 -0
- data/lib/infusionsoft/client/data.rb +90 -0
- data/lib/infusionsoft/client/email.rb +91 -0
- data/lib/infusionsoft/client/file.rb +29 -0
- data/lib/infusionsoft/client/invoice.rb +128 -0
- data/lib/infusionsoft/client/ticket.rb +18 -0
- data/lib/infusionsoft/client/version.rb +5 -0
- data/lib/infusionsoft/configuration.rb +36 -0
- data/lib/infusionsoft/connection.rb +48 -0
- data/lib/infusionsoft/request.rb +33 -0
- data/lib/infusionsoft/version.rb +4 -0
- data/test/api_infusion_test.rb +8 -0
- metadata +89 -0
data/LICENSE.md
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
Copyright (c) 2011 Nathan Leavitt & Infused Systems
|
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.
|
21
|
+
|
data/README.md
ADDED
@@ -0,0 +1,100 @@
|
|
1
|
+
# The Infusionsoft Ruby Gem
|
2
|
+
A Ruby wrapper for the Infusionsoft API
|
3
|
+
|
4
|
+
## <a name="installation">Installation</a>
|
5
|
+
gem install infusionsoft
|
6
|
+
|
7
|
+
## <a name="documentation">Documentation</a>
|
8
|
+
documentation link here
|
9
|
+
|
10
|
+
## <a name="setup">Setup & Configuration</a>
|
11
|
+
For Rails, create an initilizer in `config\initilizers` called infusionsoft.rb and the following
|
12
|
+
|
13
|
+
Infusionsoft.configure do |config|
|
14
|
+
config.api_url = 'YOUR_INFUSIONSOFT_URL' # example infused.infusionsoft.com
|
15
|
+
config.api_key = 'YOUR_INFUSIONSOFT_API_KEY'
|
16
|
+
end
|
17
|
+
|
18
|
+
## <a name="examples">Usage Examples</a>
|
19
|
+
|
20
|
+
# Get a users first and last name using the DataService
|
21
|
+
Infusionsoft.data_load('Contact', contact_id, [:FirstName, :LastName])
|
22
|
+
|
23
|
+
# Update a contact with specific field values
|
24
|
+
Infusionsoft.contact_upudate(contact_id, { :FirstName => 'first_name', :Email => 'test@test.com' })
|
25
|
+
|
26
|
+
# Add a new Contact
|
27
|
+
Infusionsoft.contact_add({:FirstName => 'first_name', :LastName => 'last_name', :Email => 'test@test.com'})
|
28
|
+
|
29
|
+
# Create a blank Invoice
|
30
|
+
invoice_id = Infusionsoft.invoice_create_blank_order(contact_id, description, Date.today, lead_affiliate_id, sale_affiliate_id)
|
31
|
+
|
32
|
+
# Then add item to invoice
|
33
|
+
Infusionsoft.invoice_add_order_item(invoice_id, product_id, product_type, amount, quantity, description_here, notes)
|
34
|
+
|
35
|
+
# Then charge the invoice
|
36
|
+
Infusionsoft.invoice_charge_invoice(invoice_id, notes, credit_card_id, merchange_id, bypass_commissions)
|
37
|
+
|
38
|
+
|
39
|
+
## <a name="contributing">Contributing</a>
|
40
|
+
In the spirit of [free software](http://www.fsf.org/licensing/essays/free-sw.html), **everyone** is encouraged to help improve this project.
|
41
|
+
|
42
|
+
Here are some ways *you* can contribute:
|
43
|
+
|
44
|
+
* by using alpha, beta, and prerelease versions
|
45
|
+
* by reporting bugs
|
46
|
+
* by suggesting new features
|
47
|
+
* by writing or editing documentation
|
48
|
+
* by writing specifications
|
49
|
+
* by writing code (**no patch is too small**: fix typos, add comments, clean up inconsistent whitespace)
|
50
|
+
* by refactoring code
|
51
|
+
* by closing [issues](https://github.com/nateleavitt/infusionsoft/issues)
|
52
|
+
* by reviewing patches
|
53
|
+
|
54
|
+
## <a name="issues">Submitting an Issue</a>
|
55
|
+
We use the [GitHub issue tracker](https://github.com/nateleavitt/infusionsoft/issues) to track bugs and
|
56
|
+
features. Before submitting a bug report or feature request, check to make sure it hasn't already
|
57
|
+
been submitted. You can indicate support for an existing issuse by voting it up. When submitting a
|
58
|
+
bug report, please include a [Gist](https://gist.github.com/) that includes a stack trace and any
|
59
|
+
details that may be necessary to reproduce the bug, including your gem version, Ruby version, and
|
60
|
+
operating system. Ideally, a bug report should include a pull request with failing specs.
|
61
|
+
|
62
|
+
## <a name="pulls">Submitting a Pull Request</a>
|
63
|
+
1. Fork the project.
|
64
|
+
2. Create a topic branch.
|
65
|
+
3. Implement your feature or bug fix.
|
66
|
+
4. Add documentation for your feature or bug fix.
|
67
|
+
5. Run <tt>bundle exec rake doc:yard</tt>. If your changes are not 100% documented, go back to step 4.
|
68
|
+
6. Add specs for your feature or bug fix.
|
69
|
+
7. Run <tt>bundle exec rake spec</tt>. If your changes are not 100% covered, go back to step 6.
|
70
|
+
8. Commit and push your changes.
|
71
|
+
9. Submit a pull request. Please do not include changes to the gemspec, version, or history file. (If you want to create your own version for some reason, please do so in a separate commit.)
|
72
|
+
|
73
|
+
## <a name="rubies">Supported Rubies</a>
|
74
|
+
This library aims to support the following Ruby implementations:
|
75
|
+
|
76
|
+
* Ruby 1.8.7
|
77
|
+
* Ruby 1.9.1
|
78
|
+
* Ruby 1.9.2
|
79
|
+
* [JRuby](http://www.jruby.org/)
|
80
|
+
* [Rubinius](http://rubini.us/)
|
81
|
+
* [Ruby Enterprise Edition](http://www.rubyenterpriseedition.com/)
|
82
|
+
|
83
|
+
If something doesn't work on one of these interpreters, it should be considered
|
84
|
+
a bug.
|
85
|
+
|
86
|
+
This library may inadvertently work (or seem to work) on other Ruby
|
87
|
+
implementations, however support will only be provided for the versions listed
|
88
|
+
above.
|
89
|
+
|
90
|
+
If you would like this library to support another Ruby version, you may
|
91
|
+
volunteer to be a maintainer. Being a maintainer entails making sure all tests
|
92
|
+
run and pass on that implementation. When something breaks on your
|
93
|
+
implementation, you will be personally responsible for providing patches in a
|
94
|
+
timely fashion. If critical issues for a particular implementation exist at the
|
95
|
+
time of a major release, support for that Ruby version may be dropped.
|
96
|
+
|
97
|
+
## <a name="copyright">Copyright</a>
|
98
|
+
Copyright (c) 2011 Nathan Leavitt & Infused Systems
|
99
|
+
See [LICENSE](https://github.com/nateleavitt/infusionsoft/blob/master/LICENSE.md) for details.
|
100
|
+
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require File.expand_path('../lib/infusionsoft/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.name = 'infusionsoft'
|
6
|
+
gem.summary = %q{Ruby wrapper for the Infusionsoft API}
|
7
|
+
gem.description = 'A Ruby wrapper written for the Infusionsoft API'
|
8
|
+
gem.authors = ["Nathan Leavitt"]
|
9
|
+
gem.email = ['nate@infusedsystems.com']
|
10
|
+
gem.executables = `git ls-files -- bin/*`.split("\n").map{|f| File.basename(f)}
|
11
|
+
gem.files = `git ls-files`.split("\n")
|
12
|
+
gem.homepage = 'https://github.com/nateleavitt/infusionsoft'
|
13
|
+
gem.require_paths = ['lib']
|
14
|
+
gem.required_rubygems_version = Gem::Requirement.new('>= 1.3.6')
|
15
|
+
|
16
|
+
gem.version = Infusionsoft::VERSION.dup
|
17
|
+
end
|
18
|
+
|
data/lib/infusionsoft.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'infusionsoft/api'
|
2
|
+
require 'infusionsoft/client'
|
3
|
+
require 'infusionsoft/configuration'
|
4
|
+
#require 'api_infusionsoft/error'
|
5
|
+
|
6
|
+
module Infusionsoft
|
7
|
+
extend Configuration
|
8
|
+
class << self
|
9
|
+
# Alias for Infusionsoft::Client.new
|
10
|
+
#
|
11
|
+
# @return [Infusionsoft::Client]
|
12
|
+
def new(options={})
|
13
|
+
Infusionsoft::Client.new(options)
|
14
|
+
end
|
15
|
+
|
16
|
+
# Delegate to ApiInfusionsoft::Client
|
17
|
+
def method_missing(method, *args, &block)
|
18
|
+
return super unless new.respond_to?(method)
|
19
|
+
new.send(method, *args, &block)
|
20
|
+
end
|
21
|
+
|
22
|
+
def respond_to?(method, include_private = false)
|
23
|
+
new.respond_to?(method, include_private) || super(method, include_private)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'infusionsoft/configuration'
|
2
|
+
require 'infusionsoft/connection'
|
3
|
+
require 'infusionsoft/request'
|
4
|
+
|
5
|
+
module Infusionsoft
|
6
|
+
|
7
|
+
class Api
|
8
|
+
include Connection
|
9
|
+
include Request
|
10
|
+
|
11
|
+
attr_accessor *Configuration::VALID_OPTION_KEYS
|
12
|
+
|
13
|
+
def initialize(options={})
|
14
|
+
options = Infusionsoft.options.merge(options)
|
15
|
+
Configuration::VALID_OPTION_KEYS.each do |key|
|
16
|
+
send("#{key}=", options[key])
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Infusionsoft
|
2
|
+
# Wrapper for the Infusionsoft API
|
3
|
+
#
|
4
|
+
# @note all services have been separated into different modules
|
5
|
+
class Client < Api
|
6
|
+
# Require client method modules after initializing the Client class in
|
7
|
+
# order to avoid a superclass mismatch error, allowing those modules to be
|
8
|
+
# Client-namespaced.
|
9
|
+
require 'infusionsoft/client/contact'
|
10
|
+
require 'infusionsoft/client/email'
|
11
|
+
require 'infusionsoft/client/invoice'
|
12
|
+
require 'infusionsoft/client/data'
|
13
|
+
require 'infusionsoft/client/affiliate'
|
14
|
+
require 'infusionsoft/client/file'
|
15
|
+
require 'infusionsoft/client/ticket'
|
16
|
+
|
17
|
+
include Infusionsoft::Client::Contact
|
18
|
+
include Infusionsoft::Client::Email
|
19
|
+
include Infusionsoft::Client::Invoice
|
20
|
+
include Infusionsoft::Client::Data
|
21
|
+
include Infusionsoft::Client::Affiliate
|
22
|
+
include Infusionsoft::Client::File
|
23
|
+
include Infusionsoft::Client::Ticket
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module Infusionsoft
|
2
|
+
class Client
|
3
|
+
########################
|
4
|
+
### Affiliate Service ##
|
5
|
+
########################
|
6
|
+
module Affiliate
|
7
|
+
# return all claw backs in a date range
|
8
|
+
#
|
9
|
+
# @affiliate_id [Integer]
|
10
|
+
# @start_date [Date]
|
11
|
+
# @end_date [Date]
|
12
|
+
def affiliate_clawbacks(affiliate_id, start_date, end_date)
|
13
|
+
response = get('APIAffiliateService', 'affClawbacks', affiliate_id, start_date, end_date)
|
14
|
+
end
|
15
|
+
|
16
|
+
# return all commissions in a date range
|
17
|
+
#
|
18
|
+
# @affiliate_id [Integer]
|
19
|
+
# @start_date [Date]
|
20
|
+
# @end_date [Date]
|
21
|
+
def affiliate_commissions(affiliate_id, start_date, end_date)
|
22
|
+
response = get('APIAffiliateService', 'affCommissions', affiliate_id, start_date, end_date)
|
23
|
+
end
|
24
|
+
|
25
|
+
# return all payouts in a date range
|
26
|
+
#
|
27
|
+
# @affiliate_id [Integer]
|
28
|
+
# @start_date [Date]
|
29
|
+
# @end_date [Date]
|
30
|
+
def affiliate_payouts(affiliate_id, start_date, end_date)
|
31
|
+
response = get('APIAffiliateService', 'affPayouts', affiliate_id, start_date, end_date)
|
32
|
+
end
|
33
|
+
|
34
|
+
# returns a list with each row representing a single affiliates totals represented by a map with key
|
35
|
+
# one of the names above, and value being the total for the variable
|
36
|
+
#
|
37
|
+
# @affiliate_list [Array]
|
38
|
+
def affiliate_running_totals(affiliate_list)
|
39
|
+
response = get('APIAffiliateService', 'affRunningTotals', affiliate_list)
|
40
|
+
end
|
41
|
+
|
42
|
+
# return how much the specified affiliates are owed
|
43
|
+
#
|
44
|
+
# @affiliate_list [Array]
|
45
|
+
# @start_date [Date]
|
46
|
+
# @end_date [Date]
|
47
|
+
def affiliate_summary(affiliate_list, start_date, end_date)
|
48
|
+
response = get('APIAffiliateService', 'affSummary', affiliate_list, start_date, end_date)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,143 @@
|
|
1
|
+
module Infusionsoft
|
2
|
+
class Client
|
3
|
+
########################
|
4
|
+
### Contact Service ###
|
5
|
+
########################
|
6
|
+
module Contact
|
7
|
+
# Finds all contacts with the supplied email address in any of the three contact record email addresses
|
8
|
+
#
|
9
|
+
# @email [String]
|
10
|
+
# @selected_fields [Array]
|
11
|
+
def contact_find_by_email(email, selected_fields)
|
12
|
+
response = get('ContactService.findByEmail', email, selected_fields)
|
13
|
+
end
|
14
|
+
|
15
|
+
# Adds a contact to the database, then opts in the email address
|
16
|
+
#
|
17
|
+
# @data = [Hash]
|
18
|
+
# @example data = {:EmailAddress1 => 'test@test.com', :FirstName => 'first_name', :LastName => 'last_name'}
|
19
|
+
# @returns [Integer] This is the id of the newly added contact
|
20
|
+
def contact_add(data)
|
21
|
+
contact_id = get('ContactService.add', data)
|
22
|
+
if data.has_key?("Email"); api_email_optin(data["Email"], "requested information"); end
|
23
|
+
return contact_id
|
24
|
+
end
|
25
|
+
|
26
|
+
# Creates a new recurring order for a contact.
|
27
|
+
#
|
28
|
+
# @contact_id [Integer]
|
29
|
+
# @allow_duplicate [Boolean]
|
30
|
+
# @cprogram_id [Integer]
|
31
|
+
# @merchante_account_id [Integer]
|
32
|
+
# @credit_card_id [Integer]
|
33
|
+
# @affiliate_id [Integer]
|
34
|
+
def contact_add_recurring_order(contact_id, allow_duplicate, cprogram_id, merchant_account_id, credit_card_id, affiliate_id,
|
35
|
+
days_till_charge)
|
36
|
+
response = get('ContactService','addRecurringOrder', contact_id, allow_duplicate, cprogram_id,
|
37
|
+
merchant_account_id, credit_card_id, affiliate_id, days_till_charge)
|
38
|
+
end
|
39
|
+
|
40
|
+
# Adds a contact to a group
|
41
|
+
#
|
42
|
+
# @contact_id [Integer]
|
43
|
+
# @group_id [Integer]
|
44
|
+
def contact_add_to_group(contact_id, group_id)
|
45
|
+
response = get('ContactService', 'addToGroup', contact_id, group_id)
|
46
|
+
end
|
47
|
+
|
48
|
+
def contact_link_contact(remoteApp, remoteId, localId)
|
49
|
+
response = get('ContactService', 'linkContact', remoteApp, remoteId, localId)
|
50
|
+
end
|
51
|
+
|
52
|
+
# Loads a contact from the database
|
53
|
+
#
|
54
|
+
# @id [Integer]
|
55
|
+
# @selected_fields [Array]
|
56
|
+
def contact_load(id, selected_fields)
|
57
|
+
response = get('ContactService', 'load', id, selected_fields)
|
58
|
+
end
|
59
|
+
|
60
|
+
def contact_locate_contact_link(locate_map_id)
|
61
|
+
response = get('ContactService', 'locateContactLink', locate_map_id)
|
62
|
+
end
|
63
|
+
|
64
|
+
def contact_mark_link_updated(locate_map_id)
|
65
|
+
response = get('ContactService', 'markLinkUpdated', locate_map_id)
|
66
|
+
end
|
67
|
+
|
68
|
+
# Adds a contact to a campaign.
|
69
|
+
#
|
70
|
+
# @contact_id [Integer]
|
71
|
+
# @campaign_id [Integer]
|
72
|
+
def contact_add_to_campaign(contact_id, campaign_id)
|
73
|
+
response = get('ContactService','addToCampaign', contact_id, campaign_id)
|
74
|
+
end
|
75
|
+
|
76
|
+
# Pauses a campaign for a given contact.
|
77
|
+
#
|
78
|
+
# @contact_id [Integer]
|
79
|
+
# @campaign_id [Integer]
|
80
|
+
def contact_pause_campaign(contact_id, campaign_id)
|
81
|
+
response = get('ContactService', 'pauseCampaign', contact_id, campaign_id)
|
82
|
+
end
|
83
|
+
|
84
|
+
# Removes a contact from a given campaign.
|
85
|
+
#
|
86
|
+
# @contact_id [Integer]
|
87
|
+
# @campaign_id [Integer]
|
88
|
+
def contact_remove_from_campaign(contact_id, campaign_id)
|
89
|
+
response = get('ContactService', 'removeFromCampaign', contact_id, campaign_id)
|
90
|
+
end
|
91
|
+
|
92
|
+
# returns the next step in a campaign
|
93
|
+
#
|
94
|
+
# @contact_id [Integer]
|
95
|
+
# @campaign_id [Integer]
|
96
|
+
def contact_get_next_campaign_step(contact_id, campaign_id)
|
97
|
+
response = get('ContactService', 'getNextCampaignStep', contact_id, campaign_id)
|
98
|
+
end
|
99
|
+
|
100
|
+
# Reschedules a campaign step for a list of contacts
|
101
|
+
#
|
102
|
+
# @list_of_contacts [Array]
|
103
|
+
# @campaign_id [Integer]
|
104
|
+
def contact_reschedule_campaign_step(list_of_contacts, campaign_id)
|
105
|
+
response = get('ContactService', 'reschedulteCampaignStep', list_of_contacts, campaign_id)
|
106
|
+
end
|
107
|
+
|
108
|
+
# Removes a contact from a given group.
|
109
|
+
#
|
110
|
+
# @contact_id [Integer]
|
111
|
+
# @group_id [Integer]
|
112
|
+
def contact_remove_from_group(contact_id, group_id)
|
113
|
+
response = get('ContactService', 'removeFromGroup', contact_id, group_id)
|
114
|
+
end
|
115
|
+
|
116
|
+
# Executes an action sequence for a given contact
|
117
|
+
def contact_run_action_set(contact_id, action_set_id)
|
118
|
+
response = get('ContactService', 'runActionSequence', contact_id, action_set_id)
|
119
|
+
end
|
120
|
+
|
121
|
+
# Executes an action sequence for a given contact, passing in
|
122
|
+
# runtime params for running affiliate signup actions, etc
|
123
|
+
#
|
124
|
+
# @contact_id [Integer]
|
125
|
+
# @action_set_id [Integer]
|
126
|
+
# @params [Hash]
|
127
|
+
def contact_run_action_set_with_params(contact_id, action_set_id, params)
|
128
|
+
response = get('ContactService', 'runActionSequence', contact_id, action_set_id, params)
|
129
|
+
end
|
130
|
+
|
131
|
+
# Updates a contact in the database.
|
132
|
+
#
|
133
|
+
# @contact_id [Integer]
|
134
|
+
# @data [Hash]
|
135
|
+
# @example {:FirstName => 'first_name', :StreetAddress1 => '123 N Street'}
|
136
|
+
def contact_update(contact_id, data)
|
137
|
+
bool = get('ContactService', 'update', contact_id, data)
|
138
|
+
if data.has_key?("Email"); api_email_optin(data["Email"], "requested information"); end
|
139
|
+
return bool
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
module Infusionsoft
|
2
|
+
class Client
|
3
|
+
########################
|
4
|
+
### Data Service ###
|
5
|
+
########################
|
6
|
+
module Data
|
7
|
+
# Adds a record to the database. If you attempt to set fields that are marked read-only
|
8
|
+
# by the Data Spec, this operation will simply ignore those fields - not throw an error
|
9
|
+
#
|
10
|
+
# @table [String]
|
11
|
+
# @values [Hash]
|
12
|
+
def data_add(table, values)
|
13
|
+
response = get('DataService.add', table, values)
|
14
|
+
end
|
15
|
+
|
16
|
+
# This will locate all records in a given table that match the criteria for a given field.
|
17
|
+
#
|
18
|
+
# @table [String]
|
19
|
+
# @limit [Integer]
|
20
|
+
# @page [Integer]
|
21
|
+
# @field_name [String]
|
22
|
+
# @field_value [String]
|
23
|
+
# @selected_fields [Array]
|
24
|
+
def data_find_by_field(table, limit, page, field_name, field_value, selected_fields)
|
25
|
+
response = get('DataService.findByField', table, limit, page, field_name,
|
26
|
+
field_value, selected_fields)
|
27
|
+
end
|
28
|
+
|
29
|
+
# This method will load a record from the database given the primary key
|
30
|
+
#
|
31
|
+
# @table [String]
|
32
|
+
# @id [Integer]
|
33
|
+
# @selected_fields [Array]
|
34
|
+
def data_load(table, id, selected_fields)
|
35
|
+
response = get('DataService.load', table, id, selected_fields)
|
36
|
+
end
|
37
|
+
|
38
|
+
# Queries records in a given table to find matches on certain fields
|
39
|
+
#
|
40
|
+
# @table [String]
|
41
|
+
# @limit [Integer]
|
42
|
+
# @page [Integer]
|
43
|
+
# @data [Hash] The data you would like to query on. { :FirstName => 'first_name' }
|
44
|
+
# @selected_fields [Array]
|
45
|
+
def data_query(table, limit, page, data, selected_fields)
|
46
|
+
response = get('DataService.query', table, limit, page, data, selected_fields)
|
47
|
+
end
|
48
|
+
|
49
|
+
# Updates a given record to the database
|
50
|
+
#
|
51
|
+
# @table [String]
|
52
|
+
# @id [Integer]
|
53
|
+
# @values [Hash] This is the fields and values you would like to update
|
54
|
+
# @example { :FirstName => 'first_name', :EmailAddress1 => 'test@test.com' }
|
55
|
+
def data_update(table, id, values)
|
56
|
+
response = get('DataService.update', table, id, values)
|
57
|
+
end
|
58
|
+
|
59
|
+
# Adds a custom field to Infusionsoft
|
60
|
+
#
|
61
|
+
# @context [String]
|
62
|
+
# @label [String]
|
63
|
+
# @data_type [String]
|
64
|
+
# @group_id [Integer]
|
65
|
+
def data_add_custom_field(context, label, data_type, group_id)
|
66
|
+
response = get('DataService.addCustomField', context, label, data_type, group_id)
|
67
|
+
end
|
68
|
+
|
69
|
+
# Updates a custom field
|
70
|
+
#
|
71
|
+
# @field_id [Integer]
|
72
|
+
# @field_value
|
73
|
+
def data_update_custom_field(field_id, field_value)
|
74
|
+
response = get('DataService.updateCustomField', field_id, field_value)
|
75
|
+
end
|
76
|
+
|
77
|
+
# Authenticates a user account in Infusionsoft
|
78
|
+
#
|
79
|
+
# @username [String]
|
80
|
+
# @password [String]
|
81
|
+
def data_authenticate_user(username, password)
|
82
|
+
response = get('DataService.authenticateUser', username, password)
|
83
|
+
end
|
84
|
+
|
85
|
+
def data_echo(text)
|
86
|
+
response = get('DataService.echo', text)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
module Infusionsoft
|
2
|
+
class Client
|
3
|
+
########################
|
4
|
+
### Email Service ###
|
5
|
+
########################
|
6
|
+
module Email
|
7
|
+
# Enables you to opt contacts in
|
8
|
+
#
|
9
|
+
# @email [String]
|
10
|
+
# @reason [String]
|
11
|
+
def email_optin(email, reason)
|
12
|
+
response = get('APIEmailService', 'optIn', email, reason)
|
13
|
+
end
|
14
|
+
|
15
|
+
# Enables you to opt contacts out
|
16
|
+
#
|
17
|
+
# @email [String]
|
18
|
+
# @reason [String]
|
19
|
+
def email_optout(email, reason)
|
20
|
+
response = get('APIEmailService', 'optOut', email, reason)
|
21
|
+
end
|
22
|
+
|
23
|
+
# Sends an email through infusion
|
24
|
+
#
|
25
|
+
# @contact_list [Array] List of contact ids you want to send this email to
|
26
|
+
# @from_address [String]
|
27
|
+
# @to_address [String]
|
28
|
+
# @cc_address [String]
|
29
|
+
# @bcc_address [String]
|
30
|
+
# @content_type [String] this must be one of the following Text, HTML, or Multipart
|
31
|
+
# @subject [String]
|
32
|
+
# @html_body [Text]
|
33
|
+
# @text_body [Text]
|
34
|
+
def email_send(contact_list, from_address, to_address, cc_addresses, bcc_addresses, content_type, subject, html_body, text_body)
|
35
|
+
response = get('APIEmailService', 'sendEmail', contact_list, from_address, to_address, cc_addresses, bcc_addresses, content_type, subject, html_body, text_body)
|
36
|
+
end
|
37
|
+
|
38
|
+
# adds an email template for future use
|
39
|
+
#
|
40
|
+
# @title [String]
|
41
|
+
# @categories [String] a comma separated list of the categories you wan this template in Infusionsoft
|
42
|
+
# @content_type [String] can be Text, HTML, Multipart
|
43
|
+
# @text_body [Text]
|
44
|
+
# @html_body [Text]
|
45
|
+
# @merge_context [String] can be Contact, ServiceCall, Opportunity, CreditCard
|
46
|
+
def email_add(title, categories, from, to, cc, bcc, subject, text_body, html_body, content_type, merge_context)
|
47
|
+
response = get('APIEmailService', 'addEmailTemplate', title, categories, from, to, cc, bcc, subject, text_body, html_body, content_type, merge_context)
|
48
|
+
end
|
49
|
+
|
50
|
+
# Attaches an email to a contact record
|
51
|
+
def email_attach(contact_id, from_name, from_address, to_address, cc_addresses, bcc_addresses, content_type, subject, html_body, txt_body, header, receive_date, send_date)
|
52
|
+
response = get('APIEmailService', 'attachEmail', contact_id, from_name, from_address, to_address, cc_addresses, bcc_addresses, content_type, subject, html_body, txt_body, header, receive_date, send_date)
|
53
|
+
end
|
54
|
+
|
55
|
+
# Creates an email template
|
56
|
+
def email_create_template(title, user_id, from_address, to_addres, cc_addresses, bcc_addresses, content_type, subject, html_body, txt_body)
|
57
|
+
response = get('APIEmailService', 'createEmailTemplate', title, user_id, from_address, to_addres, cc_addresses, bcc_addresses, content_type, subject, html_body, txt_body)
|
58
|
+
end
|
59
|
+
|
60
|
+
# updates an email template for future use
|
61
|
+
#
|
62
|
+
# @categories [String] a comma separated list of the categories you wan this template in Infusionsoft
|
63
|
+
# @content_type [String] can be Text, HTML, Multipart
|
64
|
+
# @merge_context [String] can be Contact, ServiceCall, Opportunity, CreditCard
|
65
|
+
def email_update_template(id, title, categories, from, to, cc, bcc, subject, text_body, html_body, content_type, merge_context)
|
66
|
+
response = get('APIEmailService', 'updateEmailTemplate', title, categories, from, to, cc, bcc, subject, text_body, html_body, content_type)
|
67
|
+
end
|
68
|
+
|
69
|
+
# returns an email template
|
70
|
+
def email_get_template(id)
|
71
|
+
response = get('APIEmailService', 'getEmailTemplate', id)
|
72
|
+
end
|
73
|
+
|
74
|
+
# gets the opt-in status of the provided email address
|
75
|
+
#
|
76
|
+
# email_address [String]
|
77
|
+
# @returns 0 = opted out; 1 = single opt-in; 2 = double opt-in
|
78
|
+
def email_get_opt_status(email_address)
|
79
|
+
response = get('APIEmailService', 'getOptStatus', email_address)
|
80
|
+
end
|
81
|
+
|
82
|
+
# returns a string of merge fields for a given context
|
83
|
+
#
|
84
|
+
# @merge_context [String] could include Contact, ServiceCall, Opportunity, CreditCard
|
85
|
+
def email_get_available_merge_fields(merge_context)
|
86
|
+
response = get('APIEmailService', 'getAvailableMergeFields', merge_context)
|
87
|
+
end
|
88
|
+
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Infusionsoft
|
2
|
+
class Client
|
3
|
+
########################
|
4
|
+
### File Service ###
|
5
|
+
########################
|
6
|
+
module File
|
7
|
+
def file_upload(contact_id, file_name, encoded_file_base64)
|
8
|
+
response = get('FileService', 'uploadFile', contact_id, file_name, encoded_file_base64)
|
9
|
+
end
|
10
|
+
|
11
|
+
# returns the Base64 encoded file contents
|
12
|
+
def file_get(id)
|
13
|
+
response = get('FileService', 'getFile', id)
|
14
|
+
end
|
15
|
+
|
16
|
+
def file_url(id)
|
17
|
+
response = get('FileService', 'getDownloadUrl', id)
|
18
|
+
end
|
19
|
+
|
20
|
+
def file_rename(id, new_name)
|
21
|
+
response = get('FileService', 'renameFile', id, new_name)
|
22
|
+
end
|
23
|
+
|
24
|
+
def file_replace(id, encoded_file_base64)
|
25
|
+
response = get('FileService', 'replaceFile', id, encoded_file_base64)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,128 @@
|
|
1
|
+
module Infusionsoft
|
2
|
+
class Client
|
3
|
+
########################
|
4
|
+
### Invoice Service ###
|
5
|
+
########################
|
6
|
+
module Invoice
|
7
|
+
def invoice_update_recurring_next_bill_date(job_recurring_id, new_bill_date)
|
8
|
+
response = get('InvoiceService', 'updateJobRecurringNextBillDate', job_recurring_id, new_bill_date)
|
9
|
+
end
|
10
|
+
|
11
|
+
# Adds a payment to an invoice without actually processing a charge through a merchant.
|
12
|
+
#
|
13
|
+
# @invoice_id [Integer]
|
14
|
+
# @amount [Float]
|
15
|
+
# @date [Date]
|
16
|
+
# @type [String] Cash, Check, Credit Card, Money Order, PayPal, etc.
|
17
|
+
# @description [String]
|
18
|
+
# @bypass_commissions [Boolean]
|
19
|
+
# @return [Boolean]
|
20
|
+
def invoice_add_manual_payment(invoice_id, amount, date, type, description, bypass_commissions)
|
21
|
+
response = get('InvoiceService', 'addManualPayment', invoice_id, amount, date, type,
|
22
|
+
description, bypass_commissions)
|
23
|
+
end
|
24
|
+
|
25
|
+
# Adds a commission override to a one time order, using a combination of percentage and hard-coded amounts.
|
26
|
+
def invoice_add_order_commission_override(invoice_id, affiliate_id, product_id, percentage, amount, payout_type,
|
27
|
+
description, date)
|
28
|
+
response = get('InvoiceService', 'addOrderCommissionOverride', invoice_id, affiliate_id, product_id,
|
29
|
+
percentage, amount, payout_type, description, date)
|
30
|
+
end
|
31
|
+
|
32
|
+
# Adds an item to an existing order.
|
33
|
+
#
|
34
|
+
# @order_id [Integer] This is the invoice id
|
35
|
+
# @product_id [Integer]
|
36
|
+
# @type [Integer] UNKNOWN = 0, SHIPPING = 1, TAX = 2, SERVICE = 3, PRODUCT = 4, UPSELL = 5, FINANCECHARGE = 6, SPECIAL = 7
|
37
|
+
# @price [Float]
|
38
|
+
# @quantity [Integer]
|
39
|
+
# @description [String]
|
40
|
+
# @notes [String]
|
41
|
+
# @return [Boolean] returns true or false if it was added successfully or not
|
42
|
+
def invoice_add_order_item(order_id, product_id, type, price, quantity, description, notes)
|
43
|
+
response = get('InvoiceService', 'addOrderItem', order_id, product_id, type, price,
|
44
|
+
quantity, description, notes)
|
45
|
+
end
|
46
|
+
|
47
|
+
# Adds a payment plan to an existing invoice.
|
48
|
+
def invoice_add_payment_plan(order_id, auto_charge, credit_card_id, merchant_account_id, days_between_retry, max_retry,
|
49
|
+
initial_payment_amount, plan_start_date, number_of_payments, days_between_payments)
|
50
|
+
response = get('InvoiceService', 'addPaymentPlan', order_id, auto_charge, credit_card_id, merchant_account_id,
|
51
|
+
days_between_retry, max_retry, initial_payment_amount, plan_start_date, number_of_payments,
|
52
|
+
days_between_payments)
|
53
|
+
end
|
54
|
+
|
55
|
+
# Adds a commission override to a recurring order.
|
56
|
+
def invoice_add_recurring_commission_override(recurringorder_id, affiliate_id, amount, payout_type, description)
|
57
|
+
response = get('InvoiceService', 'addRecurringCommissionOverride', recurringorder_id, affiliate_id, amount,
|
58
|
+
payout_type, description)
|
59
|
+
end
|
60
|
+
|
61
|
+
# Adds a recurring order to the database.
|
62
|
+
def invoice_add_recurring_order(contact_id, allow_duplicate, cprogram_id, merchant_account_id, credit_card_id, affiliate_id,
|
63
|
+
days_till_charge)
|
64
|
+
response = get('InvoiceService', 'addRecurringOrder', contact_id, allow_duplicate, cprogram_id,
|
65
|
+
merchant_account_id, credit_card_id, affiliate_id, days_till_charge)
|
66
|
+
end
|
67
|
+
|
68
|
+
# Adds a recurring order to the database.
|
69
|
+
def invoice_add_recurring_order_with_price(contact_id, allow_duplicate, cprogram_id, qty, price, allow_tax, merchant_account_id, credit_card_id, affiliate_id, days_till_charge)
|
70
|
+
response = get('InvoiceService', 'addRecurringOrder', contact_id, allow_duplicate, cprogram_id, qty, price, allow_tax, merchant_account_id, credit_card_id, affiliate_id, days_till_charge)
|
71
|
+
end
|
72
|
+
|
73
|
+
# Calculates the amount owed for a given invoice.
|
74
|
+
def invoice_calculate_amount_owed(invoice_id)
|
75
|
+
response = get('InvoiceService', 'calculateAmountOwed', invoice_id)
|
76
|
+
end
|
77
|
+
|
78
|
+
# Will charge an invoice with the amount currently due on it.
|
79
|
+
#
|
80
|
+
# @invoice_id [Integer]
|
81
|
+
# @notes [String]
|
82
|
+
# @credit_card_id [Integer]
|
83
|
+
# @merchant_account_id [Integer]
|
84
|
+
# @bypass_commission [Boolean]
|
85
|
+
# @return [Hash] containing the following keys
|
86
|
+
# {'Successful => [Boolean], 'Code' => [String], 'RefNum' => [String], 'Message' => [String]}
|
87
|
+
def invoice_charge_invoice(invoice_id, notes, credit_card_id, merchant_account_id, bypass_commissions)
|
88
|
+
response = get('InvoiceService', 'chargeInvoice', invoice_id, notes, credit_card_id,
|
89
|
+
merchant_account_id, bypass_commissions)
|
90
|
+
end
|
91
|
+
|
92
|
+
# returns the invoice id from a one time order
|
93
|
+
def invoice_get_invoice_id(order_id)
|
94
|
+
response = get('InvoiceService', 'getinvoice_id', order_id)
|
95
|
+
end
|
96
|
+
|
97
|
+
# Creates a blank order with no items.
|
98
|
+
#
|
99
|
+
# @return [Integer] returns the invoice id
|
100
|
+
def invoice_create_blank_order(contact_id, description, order_date, lead_affiliate_id, sale_affiliate_id)
|
101
|
+
response = get('InvoiceService', 'createBlankOrder', contact_id, description, order_date,
|
102
|
+
lead_affiliate_id, sale_affiliate_id)
|
103
|
+
end
|
104
|
+
|
105
|
+
# This will create an invoice for all charges due on a recurring order.
|
106
|
+
def invoice_create_invoice_for_recurring(recurringorder_id)
|
107
|
+
response = get('InvoiceService', 'createInvoiceForRecurring', recurringorder_id)
|
108
|
+
end
|
109
|
+
|
110
|
+
# Locates an existing card in the system for a contact, using the
|
111
|
+
def invoice_locate_existing_card(contact_id, last4)
|
112
|
+
# last 4 digits of the card.
|
113
|
+
response = get('InvoiceService', 'locateExistingCard', contact_id, last4)
|
114
|
+
end
|
115
|
+
|
116
|
+
# This will validate a credit card in the system.
|
117
|
+
def invoice_validate_card(credit_card_id)
|
118
|
+
response = get('InvoiceService', 'validateCreditCard', credit_card_id)
|
119
|
+
end
|
120
|
+
|
121
|
+
# This will validate a credit card by passing in values of the
|
122
|
+
# card directly (this card doesn't have to be added to the system)
|
123
|
+
def invoice_validate_card(creditCard)
|
124
|
+
response = get('InvoiceService', 'validateCreditCard', creditCard)
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Infusionsoft
|
2
|
+
class Client
|
3
|
+
########################
|
4
|
+
### Ticket Service ###
|
5
|
+
########################
|
6
|
+
module Ticket
|
7
|
+
# add move notes to existing tickets
|
8
|
+
def ticket_add_move_notes(ticket_list, move_notes, move_to_stage_id, notify_ids)
|
9
|
+
response = get('ServiceCallService', 'addMoveNotes', ticket_list, move_notes, move_to_stage_id, notify_ids)
|
10
|
+
end
|
11
|
+
|
12
|
+
# add move notes to existing tickets
|
13
|
+
def ticket_move_stage(ticket_id, ticket_stage, move_notes, notify_ids)
|
14
|
+
response = get('ServiceCallService', 'moveTicketStage', ticket_id, ticket_stage, move_notes, notify_ids)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module Infusionsoft
|
2
|
+
|
3
|
+
module Configuration
|
4
|
+
VALID_OPTION_KEYS = [
|
5
|
+
:api_url,
|
6
|
+
:api_key
|
7
|
+
].freeze
|
8
|
+
|
9
|
+
# @private
|
10
|
+
attr_accessor *VALID_OPTION_KEYS
|
11
|
+
|
12
|
+
# When this module is extended, set all configuration options to their default values
|
13
|
+
#def self.extended(base)
|
14
|
+
#base.reset
|
15
|
+
#end
|
16
|
+
|
17
|
+
# Convenience method to allow configuration options to be set in a block
|
18
|
+
def configure
|
19
|
+
yield self
|
20
|
+
end
|
21
|
+
|
22
|
+
# Create a hash of options and their values
|
23
|
+
def options
|
24
|
+
options = {}
|
25
|
+
VALID_OPTION_KEYS.each{|k| options[k] = send(k)}
|
26
|
+
options
|
27
|
+
end
|
28
|
+
|
29
|
+
#def reset
|
30
|
+
#self.url = ''
|
31
|
+
#self.api_key = 'na'
|
32
|
+
#end
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require "xmlrpc/client"
|
2
|
+
|
3
|
+
module Infusionsoft
|
4
|
+
module Connection
|
5
|
+
private
|
6
|
+
|
7
|
+
def connection(service_call, *args)
|
8
|
+
server = XMLRPC::Client.new3({
|
9
|
+
'host' => api_url,
|
10
|
+
'path' => "/api/xmlrpc",
|
11
|
+
'port' => 443,
|
12
|
+
'use_ssl' => true
|
13
|
+
})
|
14
|
+
begin
|
15
|
+
result = server.call("#{service_call}", api_key, *args)
|
16
|
+
rescue XMLRPC::FaultException => e
|
17
|
+
puts "*** INFUSION API ERROR: #{e.faultCode} - #{e.faultString} ***"
|
18
|
+
end
|
19
|
+
return result
|
20
|
+
end
|
21
|
+
|
22
|
+
#end
|
23
|
+
#if result.nil?; raise RetryException.new(true, @retry_count), "transient read error" end
|
24
|
+
#rescue RetryException => detail
|
25
|
+
## Catch for transietn Infusionsoft connection errors
|
26
|
+
#puts "*** INFUSION API ERROR: Transient read error *** retrying: #{@retry_count}"
|
27
|
+
#self.retry_count += 1
|
28
|
+
#retry if detail.ok_to_retry
|
29
|
+
#rescue XMLRPC::FaultException => e
|
30
|
+
#puts "*** INFUSION API ERROR: #{e.faultCode} - #{e.faultString} ***"
|
31
|
+
#rescue Timeout::Error
|
32
|
+
#detail = RetryException.new(true, @retry_count)
|
33
|
+
#puts "*** INFUSION API ERROR: Timeout *** retrying #{@retry_count}"
|
34
|
+
#@retry_count += 1
|
35
|
+
#retry if detail.ok_to_retry
|
36
|
+
#rescue
|
37
|
+
#detail = RetryException.new(true, @retry_count)
|
38
|
+
## This is most likely a catch for the infamous Content-Type bug from Infusionsoft.
|
39
|
+
## Their response has an issue where it isn't sending back a Content-Type in the header,
|
40
|
+
## which throws an nill error in the xml-rpc client in Ruby.
|
41
|
+
## see xmlrcp/client.rb:552 and xmlrpc/utils.rb:159 in Ruby Standard Library.
|
42
|
+
#puts "*** INFUSION API ERROR: Content Type is nil back from Infusionsoft *** retrying: #{@retry_count}"
|
43
|
+
#@retry_count += 1
|
44
|
+
#retry if detail.ok_to_retry
|
45
|
+
#end
|
46
|
+
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Infusionsoft
|
2
|
+
module Request
|
3
|
+
# Perform an GET request
|
4
|
+
def get(service_call, *args)
|
5
|
+
request(:get, service_call, *args)
|
6
|
+
end
|
7
|
+
|
8
|
+
def post(path, params={}, options={})
|
9
|
+
request(:post, path, params, options)
|
10
|
+
end
|
11
|
+
|
12
|
+
# Perform an HTTP PUT request
|
13
|
+
def put(path, params={}, options={})
|
14
|
+
request(:put, path, params, options)
|
15
|
+
end
|
16
|
+
|
17
|
+
# Perform an HTTP DELETE request
|
18
|
+
def delete(path, params={}, options={})
|
19
|
+
request(:delete, path, params, options)
|
20
|
+
end
|
21
|
+
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
# Perform request
|
26
|
+
def request(method, service_call, *args)
|
27
|
+
case method.to_sym
|
28
|
+
when :get
|
29
|
+
response = connection(service_call, *args)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
metadata
ADDED
@@ -0,0 +1,89 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: infusionsoft
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 19
|
5
|
+
prerelease:
|
6
|
+
segments:
|
7
|
+
- 1
|
8
|
+
- 0
|
9
|
+
- 2
|
10
|
+
version: 1.0.2
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Nathan Leavitt
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2011-09-26 00:00:00 -07:00
|
19
|
+
default_executable:
|
20
|
+
dependencies: []
|
21
|
+
|
22
|
+
description: A Ruby wrapper written for the Infusionsoft API
|
23
|
+
email:
|
24
|
+
- nate@infusedsystems.com
|
25
|
+
executables: []
|
26
|
+
|
27
|
+
extensions: []
|
28
|
+
|
29
|
+
extra_rdoc_files: []
|
30
|
+
|
31
|
+
files:
|
32
|
+
- .gitignore
|
33
|
+
- LICENSE.md
|
34
|
+
- README.md
|
35
|
+
- infusionsoft.gemspec
|
36
|
+
- lib/infusionsoft.rb
|
37
|
+
- lib/infusionsoft/api.rb
|
38
|
+
- lib/infusionsoft/client.rb
|
39
|
+
- lib/infusionsoft/client/affiliate.rb
|
40
|
+
- lib/infusionsoft/client/contact.rb
|
41
|
+
- lib/infusionsoft/client/data.rb
|
42
|
+
- lib/infusionsoft/client/email.rb
|
43
|
+
- lib/infusionsoft/client/file.rb
|
44
|
+
- lib/infusionsoft/client/invoice.rb
|
45
|
+
- lib/infusionsoft/client/ticket.rb
|
46
|
+
- lib/infusionsoft/client/version.rb
|
47
|
+
- lib/infusionsoft/configuration.rb
|
48
|
+
- lib/infusionsoft/connection.rb
|
49
|
+
- lib/infusionsoft/request.rb
|
50
|
+
- lib/infusionsoft/version.rb
|
51
|
+
- test/api_infusion_test.rb
|
52
|
+
has_rdoc: true
|
53
|
+
homepage: https://github.com/nateleavitt/infusionsoft
|
54
|
+
licenses: []
|
55
|
+
|
56
|
+
post_install_message:
|
57
|
+
rdoc_options: []
|
58
|
+
|
59
|
+
require_paths:
|
60
|
+
- lib
|
61
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
62
|
+
none: false
|
63
|
+
requirements:
|
64
|
+
- - ">="
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
hash: 3
|
67
|
+
segments:
|
68
|
+
- 0
|
69
|
+
version: "0"
|
70
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
71
|
+
none: false
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
hash: 23
|
76
|
+
segments:
|
77
|
+
- 1
|
78
|
+
- 3
|
79
|
+
- 6
|
80
|
+
version: 1.3.6
|
81
|
+
requirements: []
|
82
|
+
|
83
|
+
rubyforge_project:
|
84
|
+
rubygems_version: 1.5.0
|
85
|
+
signing_key:
|
86
|
+
specification_version: 3
|
87
|
+
summary: Ruby wrapper for the Infusionsoft API
|
88
|
+
test_files: []
|
89
|
+
|