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.
@@ -0,0 +1,5 @@
1
+ *.gem
2
+ log/*.log
3
+ tmp/**/*
4
+ .DS_Store
5
+ rdoc/
@@ -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
+
@@ -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
+
@@ -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,5 @@
1
+ module Infusionsoft
2
+ # The version of the gem
3
+ VERSION = '1.0.0'.freeze unless defined?(::Infusionsoft::VERSION)
4
+ end
5
+
@@ -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
@@ -0,0 +1,4 @@
1
+ module Infusionsoft
2
+ # The version of the gem
3
+ VERSION = '1.0.2'.freeze unless defined?(::Infusionsoft::VERSION)
4
+ end
@@ -0,0 +1,8 @@
1
+ require 'test/unit'
2
+
3
+ class ApiInfusionTest < Test::Unit::TestCase
4
+ # Replace this with your real tests.
5
+ def test_this_plugin
6
+ flunk # will implement later :(
7
+ end
8
+ 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
+