office_autopilot_api 0.1.0
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.
- checksums.yaml +7 -0
- data/.gitignore +6 -0
- data/.rspec +1 -0
- data/Gemfile +4 -0
- data/MIT-LICENSE +20 -0
- data/README.md +71 -0
- data/Rakefile +8 -0
- data/lib/office_autopilot_api.rb +1 -0
- data/lib/office_autopilot_api/client.rb +51 -0
- data/lib/office_autopilot_api/client/contacts.rb +160 -0
- data/lib/office_autopilot_api/error.rb +7 -0
- data/lib/office_autopilot_api/request.rb +11 -0
- data/lib/office_autopilot_api/version.rb +3 -0
- data/office_autopilot_api.gemspec +30 -0
- data/spec/data/contacts_add_response.xml +69 -0
- data/spec/data/contacts_fetch_sequences.xml +4 -0
- data/spec/data/contacts_key_type.xml +99 -0
- data/spec/data/contacts_pull_tags.xml +5 -0
- data/spec/data/contacts_search_multiple_response.xml +198 -0
- data/spec/data/contacts_search_single_response.xml +68 -0
- data/spec/data/invalid_contact_ids_error.xml +3 -0
- data/spec/data/invalid_xml_error_response.xml +3 -0
- data/spec/office_autopilot_api/client/contacts_spec.rb +243 -0
- data/spec/office_autopilot_api/client_spec.rb +54 -0
- data/spec/office_autopilot_api/request_spec.rb +15 -0
- data/spec/spec_helper.rb +25 -0
- metadata +166 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: c7d7c8092131eb0c00fdf8b4f6e6d0056d29489f
|
4
|
+
data.tar.gz: 4c13482acbab47bb54ef2df6207742c116516d92
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 88de50b2078e5548909f52f1d1496523c5eeacced13f025f7b2d2500acb27ed1722b8b9c9d67fe91945fa636f2c7ed2aea5131dcaa2ccf592916b7cd4942594a
|
7
|
+
data.tar.gz: d3143011e8bcc35c5b84f76305fc2b725fbb30f45c4e160c937837a4b9736551a85ecb70746660fa5c16b8dde26d2860bda82b73c16466c60d5551ff03400b81
|
data/.gitignore
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/Gemfile
ADDED
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2011 Prashant Nadarajan
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
The OfficeAutopilot Ruby Gem
|
2
|
+
============================
|
3
|
+
A Ruby wrapper for the OfficeAutopilot API
|
4
|
+
|
5
|
+
Installation
|
6
|
+
------------
|
7
|
+
gem install office_autopilot_api
|
8
|
+
|
9
|
+
Usage Examples
|
10
|
+
--------------
|
11
|
+
require "rubygems"
|
12
|
+
require "office_autopilot_api"
|
13
|
+
|
14
|
+
client = OfficeAutopilotApi::Client.new(:api_id => 'xxx', :api_key => 'yyy')
|
15
|
+
|
16
|
+
# Search Contacts
|
17
|
+
puts client.contacts_search(:field => 'E-Mail', :op => 'e', :value => 'prashant@example.com')
|
18
|
+
# results truncated for brevity but ALL fields (including custom fields) are returned
|
19
|
+
=> [{"id"=>"7",
|
20
|
+
"Contact Information"=>{"First Name"=>"testing", "Last Name"=>"testing", "E-Mail"=>"prashant@example.com"},
|
21
|
+
"Lead Information"=>{"Contact Owner"=>"XXX", "First Referrer"=>"", "Last Referrer"=>""},
|
22
|
+
"Sequences and Tags"=>{"Sequences"=>"*/*", "Contact Tags"=>""},
|
23
|
+
"Purchase History"=>{}
|
24
|
+
}]
|
25
|
+
|
26
|
+
# Add Contact
|
27
|
+
puts client.contacts_add({ 'Contact Information' => {'First Name' => 'Turtle', 'Last Name' => 'Jones', 'E-Mail' => 'mrturtles@example.com'} })
|
28
|
+
=> {"id"=>"24", "Contact Information"=>{"First Name"=>"Turtle", "Last Name"=>"Jones", "E-Mail"=>"mrturtles@example.com"}}
|
29
|
+
|
30
|
+
Documentation
|
31
|
+
-------------
|
32
|
+
|
33
|
+
#### Currently supported API methods:
|
34
|
+
|
35
|
+
**Contacts:**
|
36
|
+
|
37
|
+
* contacts_search
|
38
|
+
|
39
|
+
* contacts_add
|
40
|
+
|
41
|
+
* contacts_pull_tag
|
42
|
+
|
43
|
+
* contacts_fetch_sequences
|
44
|
+
|
45
|
+
* contacts_key
|
46
|
+
|
47
|
+
* contacts_fetch
|
48
|
+
|
49
|
+
|
50
|
+
[**OfficeAutopilot API Docs**](http://wiki.sendpepper.com/w/page/19528683/API-Documentation)
|
51
|
+
|
52
|
+
Todo
|
53
|
+
----
|
54
|
+
|
55
|
+
* support ALL API calls
|
56
|
+
|
57
|
+
Submitting a Pull Request
|
58
|
+
-------------------------
|
59
|
+
1. Fork the project.
|
60
|
+
2. Create a topic branch.
|
61
|
+
3. Implement your feature or bug fix.
|
62
|
+
4. Add documentation for your feature or bug fix.
|
63
|
+
5. Add specs for your feature or bug fix.
|
64
|
+
6. Run <tt>bundle exec rake spec</tt>. If your changes are not 100% covered, go back to step 5.
|
65
|
+
7. Commit and push your changes.
|
66
|
+
8. Submit a pull request. Please do not include changes to the gemspec or version file. (If you want to create your own version for some reason, please do so in a separate commit.)
|
67
|
+
|
68
|
+
Copyright
|
69
|
+
---------
|
70
|
+
Copyright (c) 2011 Prashant Nadarajan.
|
71
|
+
See [LICENSE](https://github.com/parasquid/office_autopilot/blob/master/MIT_LICENSE) for details.
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'office_autopilot_api/client'
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'builder'
|
2
|
+
require 'nokogiri'
|
3
|
+
|
4
|
+
require File.expand_path('../error', __FILE__)
|
5
|
+
require File.expand_path('../request', __FILE__)
|
6
|
+
require File.expand_path('../client/contacts', __FILE__)
|
7
|
+
|
8
|
+
module OfficeAutopilotApi
|
9
|
+
class Client
|
10
|
+
|
11
|
+
include Contacts
|
12
|
+
|
13
|
+
def initialize(options)
|
14
|
+
@api = {
|
15
|
+
:api_id => options[:api_id],
|
16
|
+
:api_key => options[:api_key]
|
17
|
+
}
|
18
|
+
|
19
|
+
raise ArgumentError, "Missing required parameter: api_id" if @api[:api_id].nil?
|
20
|
+
raise ArgumentError, "Missing required parameter: api_key" if @api[:api_key].nil?
|
21
|
+
end
|
22
|
+
|
23
|
+
def api_id
|
24
|
+
@api[:api_id]
|
25
|
+
end
|
26
|
+
|
27
|
+
def api_key
|
28
|
+
@api[:api_key]
|
29
|
+
end
|
30
|
+
|
31
|
+
def auth
|
32
|
+
{ 'Appid' => api_id, 'Key' => api_key }
|
33
|
+
end
|
34
|
+
|
35
|
+
def request(method, path, options)
|
36
|
+
options[:body].merge!(auth)
|
37
|
+
handle_response( OfficeAutopilotApi::Request.send(method, path, options) )
|
38
|
+
end
|
39
|
+
|
40
|
+
def handle_response(response)
|
41
|
+
xml = Nokogiri::XML(response)
|
42
|
+
|
43
|
+
if xml.at_css('result').content =~ /failure/i
|
44
|
+
raise OfficeAutopilotApi::XmlError if xml.at_css('result error').content =~ /Invalid XML/i
|
45
|
+
end
|
46
|
+
|
47
|
+
response
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,160 @@
|
|
1
|
+
module OfficeAutopilotApi
|
2
|
+
class Client
|
3
|
+
module Contacts
|
4
|
+
|
5
|
+
CONTACTS_ENDPOINT = '/cdata.php'
|
6
|
+
|
7
|
+
def contacts_search(options)
|
8
|
+
xml = xml_for_search(options)
|
9
|
+
response = request(:post, CONTACTS_ENDPOINT, :body => {'reqType' => 'search', 'data' => xml})
|
10
|
+
parse_contacts_xml(response)
|
11
|
+
end
|
12
|
+
|
13
|
+
def contacts_add(options)
|
14
|
+
xml = xml_for_contact(options)
|
15
|
+
response = request(:post, CONTACTS_ENDPOINT, :body => {'reqType' => 'add', 'return_id' => '1', 'data' => xml})
|
16
|
+
parse_contacts_xml(response)[0]
|
17
|
+
end
|
18
|
+
|
19
|
+
def contacts_update(options)
|
20
|
+
xml = xml_for_contact(options)
|
21
|
+
response = request(:post, CONTACTS_ENDPOINT, :body => {'reqType' => 'update', 'return_id' => '1', 'data' => xml})
|
22
|
+
parse_contacts_xml(response)[0]
|
23
|
+
end
|
24
|
+
|
25
|
+
def contacts_pull_tag
|
26
|
+
response = request(:post, CONTACTS_ENDPOINT, :body => {'reqType' => 'pull_tag'})
|
27
|
+
parse_xml(response, "tag")
|
28
|
+
end
|
29
|
+
|
30
|
+
def contacts_fetch_sequences
|
31
|
+
response = request(:post, CONTACTS_ENDPOINT, :body => {'reqType' => 'fetch_sequences'})
|
32
|
+
parse_xml(response, "sequence")
|
33
|
+
end
|
34
|
+
|
35
|
+
def contacts_key
|
36
|
+
response = request(:post, CONTACTS_ENDPOINT, :body => {'reqType' => 'key'})
|
37
|
+
parse_contacts_key_xml(response)
|
38
|
+
end
|
39
|
+
|
40
|
+
def contacts_fetch(ids)
|
41
|
+
xml = xml_for_fetch("contact", ids)
|
42
|
+
response = request(:post, CONTACTS_ENDPOINT, :body => {'reqType' => 'fetch', 'data' => xml})
|
43
|
+
parse_contacts_xml(response)
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
def parse_contacts_xml(response)
|
49
|
+
contacts = []
|
50
|
+
xml = Nokogiri::XML(response)
|
51
|
+
xml.css('result contact').each do |node|
|
52
|
+
contact = {}
|
53
|
+
contact['id'] = node['id']
|
54
|
+
|
55
|
+
node.css('Group_Tag').each do |group_tag|
|
56
|
+
group_tag_name = group_tag['name']
|
57
|
+
contact[group_tag_name] = {}
|
58
|
+
|
59
|
+
group_tag.css('field').each do |field|
|
60
|
+
field_name = field['name']
|
61
|
+
contact[group_tag_name][field_name] = field.content
|
62
|
+
end
|
63
|
+
end
|
64
|
+
contacts << contact
|
65
|
+
end
|
66
|
+
contacts
|
67
|
+
end
|
68
|
+
|
69
|
+
def parse_contacts_key_xml(response)
|
70
|
+
groups = {}
|
71
|
+
|
72
|
+
xml = Nokogiri::XML(response)
|
73
|
+
xml.css('result contact Group_Tag').each do |group_tag|
|
74
|
+
group = { 'fields' => {} }
|
75
|
+
group['editable'] = group_tag['editable'] == '1'
|
76
|
+
|
77
|
+
group_tag.css('field').each do |field_node|
|
78
|
+
field_type = field_node['type']
|
79
|
+
field_info = { 'type' => field_type }
|
80
|
+
field_info['editable'] = field_node['editable'] == '1'
|
81
|
+
|
82
|
+
case field_type
|
83
|
+
when 'tdrop'
|
84
|
+
options = []
|
85
|
+
field_info['options'] = options
|
86
|
+
field_node.css('option').each do |option_node|
|
87
|
+
options << option_node.content
|
88
|
+
end
|
89
|
+
when 'list'
|
90
|
+
list = {}
|
91
|
+
field_info['list'] = list
|
92
|
+
field_node.css('list').each do |list_node|
|
93
|
+
list[list_node['id']] = list_node.content
|
94
|
+
end
|
95
|
+
end
|
96
|
+
group['fields'][field_node['name']] = field_info
|
97
|
+
end
|
98
|
+
groups[group_tag['name']] = group
|
99
|
+
end
|
100
|
+
groups
|
101
|
+
end
|
102
|
+
|
103
|
+
def parse_xml(response, element_name)
|
104
|
+
result = {}
|
105
|
+
xml = Nokogiri::XML(response)
|
106
|
+
xml.css("result #{element_name}").each do |node|
|
107
|
+
id = node['id']
|
108
|
+
result[id] = node.content
|
109
|
+
end
|
110
|
+
result
|
111
|
+
end
|
112
|
+
|
113
|
+
def xml_for_contact(options)
|
114
|
+
attrs = {}
|
115
|
+
id = options.delete('id')
|
116
|
+
attrs[:id] = id if id
|
117
|
+
action = options.delete('action')
|
118
|
+
|
119
|
+
xml = Builder::XmlMarkup.new
|
120
|
+
xml.contact(attrs) do
|
121
|
+
options.each_key do |group_tag|
|
122
|
+
xml.Group_Tag(:name => group_tag) do
|
123
|
+
options[group_tag].each do |field, value|
|
124
|
+
xml_params = {:name => field}
|
125
|
+
xml_params[:action] = action unless action.nil? || action.blank?
|
126
|
+
xml.field(value, xml_params)
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
def xml_for_fetch(type, ids)
|
134
|
+
xml = ""
|
135
|
+
ids.each do |id|
|
136
|
+
xml << "<#{type}_id>#{id}</#{type}_id>"
|
137
|
+
end
|
138
|
+
xml
|
139
|
+
end
|
140
|
+
|
141
|
+
def xml_for_search(options)
|
142
|
+
if options.is_a?(Hash)
|
143
|
+
options = [options]
|
144
|
+
end
|
145
|
+
|
146
|
+
xml = Builder::XmlMarkup.new
|
147
|
+
xml.search do
|
148
|
+
options.each do |option|
|
149
|
+
xml.equation do
|
150
|
+
xml.field option[:field]
|
151
|
+
xml.op option[:op]
|
152
|
+
xml.value option[:value]
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "office_autopilot_api/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
|
7
|
+
s.add_development_dependency('rake', '~> 0.8')
|
8
|
+
s.add_development_dependency('rspec', '~> 2.5')
|
9
|
+
s.add_development_dependency('webmock', '~> 1.6')
|
10
|
+
|
11
|
+
s.add_runtime_dependency('httparty', '~> 0.7')
|
12
|
+
s.add_runtime_dependency('builder', '>= 2.1.2')
|
13
|
+
s.add_runtime_dependency('nokogiri', '~> 1.4')
|
14
|
+
|
15
|
+
s.name = "office_autopilot_api"
|
16
|
+
s.version = OfficeAutopilotApi::VERSION
|
17
|
+
s.platform = Gem::Platform::RUBY
|
18
|
+
s.authors = ["Prashant Nadarajan", "parasquid"]
|
19
|
+
s.email = ["prashant.nadarajan@gmail.com", 'parasquid']
|
20
|
+
s.homepage = "https://github.com/parasquid/office_autopilot"
|
21
|
+
s.summary = %q{Ruby wrapper for the OfficeAutopilot API}
|
22
|
+
s.description = %q{A Ruby wrapper for the OfficeAutopilot API}
|
23
|
+
|
24
|
+
s.rubyforge_project = "office_autopilot_api"
|
25
|
+
|
26
|
+
s.files = `git ls-files`.split("\n")
|
27
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
28
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
29
|
+
s.require_paths = ["lib"]
|
30
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
<result>
|
2
|
+
<contact id='7' date='1299671887' dlm='1299674450' score='0.00' purl='prashant' bulk_mail='1'>
|
3
|
+
<Group_Tag name='Contact Information'>
|
4
|
+
<field name="First Name">prashant</field>
|
5
|
+
<field name="Last Name">nadarajan</field>
|
6
|
+
<field name="E-Mail">prashant@example.com</field>
|
7
|
+
<field name="Home Phone"/>
|
8
|
+
<field name="Title"/>
|
9
|
+
<field name="Office Phone"/>
|
10
|
+
<field name="Cell Phone"/>
|
11
|
+
<field name="Fax"/>
|
12
|
+
<field name="Address"/>
|
13
|
+
<field name="Company"/>
|
14
|
+
<field name="Address 2"/>
|
15
|
+
<field name="City"/>
|
16
|
+
<field name="State"/>
|
17
|
+
<field name="Zip Code"/>
|
18
|
+
<field name="Website "/>
|
19
|
+
<field name="Country"/>
|
20
|
+
<field name="Birthday"/>
|
21
|
+
</Group_Tag>
|
22
|
+
<Group_Tag name='Lead Information'>
|
23
|
+
<field name="Contact Owner">Don Corleone</field>
|
24
|
+
<field name="First Referrer"/>
|
25
|
+
<field name="Last Referrer"/>
|
26
|
+
<field name="Lead Source"/>
|
27
|
+
<field name="Campaign"/>
|
28
|
+
<field name="Ad"/>
|
29
|
+
<field name="Media"/>
|
30
|
+
</Group_Tag>
|
31
|
+
<Group_Tag name='Sequences and Tags'>
|
32
|
+
<field name="Sequences">*/*</field>
|
33
|
+
<field name="Contact Tags"/>
|
34
|
+
</Group_Tag>
|
35
|
+
<Group_Tag name='Purchase History'></Group_Tag>
|
36
|
+
<Group_Tag name='Most Recent Charge'>
|
37
|
+
<field name="Charge Amount">$0.00</field>
|
38
|
+
<field name="Charge Invoice #"/>
|
39
|
+
</Group_Tag>
|
40
|
+
<Group_Tag name='Affiliate Data'>
|
41
|
+
<field name="Affiliate Program"/>
|
42
|
+
<field name="Number of Sales"/>
|
43
|
+
<field name="$ Sales">$0.00</field>
|
44
|
+
<field name="Paypal E-mail"/>
|
45
|
+
<field name="Affiliate Paypal"/>
|
46
|
+
</Group_Tag>
|
47
|
+
<Group_Tag
|
48
|
+
name='Most Recent Invoice'>
|
49
|
+
<field name="Invoice #"/>
|
50
|
+
<field name="Total Invoice Amount">$0.00</field>
|
51
|
+
</Group_Tag>
|
52
|
+
<Group_Tag name='Lead Status'>
|
53
|
+
<field name="Lead Status"/>
|
54
|
+
<field name="Preferencia Contacto"/>
|
55
|
+
</Group_Tag>
|
56
|
+
<Group_Tag name='Credit Card'>
|
57
|
+
<field name="Card Type"/>
|
58
|
+
<field name="Card Expiration Month"/>
|
59
|
+
<field name="Charge Result"/>
|
60
|
+
<field name="Card Expiration Year"/>
|
61
|
+
<field name="Card Number (Last 4)"/>
|
62
|
+
<field name="Payment Center Link"/>
|
63
|
+
</Group_Tag>
|
64
|
+
<Group_Tag name='Invoices'></Group_Tag>
|
65
|
+
<Group_Tag name='Subscriptions and Payment Plans'></Group_Tag>
|
66
|
+
<Group_Tag name='Website Subscribers'></Group_Tag>
|
67
|
+
</contact>
|
68
|
+
<status>Success</status>
|
69
|
+
</result>
|