infusionsoft 1.0.2
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.
- 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
|
+
|