markety 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/markety.rb +8 -0
- data/lib/markety/authentication_header.rb +47 -0
- data/lib/markety/client.rb +145 -0
- data/lib/markety/enums.rb +21 -0
- data/lib/markety/lead_key.rb +29 -0
- data/lib/markety/lead_record.rb +55 -0
- data/lib/markety/version.rb +5 -0
- metadata +83 -0
data/lib/markety.rb
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
module Markety
|
2
|
+
# This class exists only to encapsulate the authentication header part of a soap request to marketo
|
3
|
+
class AuthenticationHeader
|
4
|
+
DIGEST = OpenSSL::Digest::Digest.new('sha1')
|
5
|
+
|
6
|
+
def initialize(access_key, secret_key, time = DateTime.now)
|
7
|
+
@access_key = access_key
|
8
|
+
@secret_key = secret_key
|
9
|
+
@time = time
|
10
|
+
end
|
11
|
+
|
12
|
+
public
|
13
|
+
# time should be a DateTime instance
|
14
|
+
def set_time(time)
|
15
|
+
@time = time
|
16
|
+
end
|
17
|
+
|
18
|
+
def get_mktows_user_id
|
19
|
+
@access_key
|
20
|
+
end
|
21
|
+
|
22
|
+
def get_request_signature
|
23
|
+
calculate_signature
|
24
|
+
end
|
25
|
+
|
26
|
+
def get_request_timestamp
|
27
|
+
@time.to_s
|
28
|
+
end
|
29
|
+
|
30
|
+
def to_hash
|
31
|
+
{ "ns1:AuthenticationHeader" =>
|
32
|
+
{
|
33
|
+
"mktowsUserId" => get_mktows_user_id,
|
34
|
+
"requestSignature" => get_request_signature,
|
35
|
+
"requestTimestamp" => get_request_timestamp
|
36
|
+
}
|
37
|
+
}
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
def calculate_signature
|
42
|
+
request_timestamp = get_request_timestamp
|
43
|
+
string_to_encrypt = request_timestamp + @access_key
|
44
|
+
OpenSSL::HMAC.hexdigest(DIGEST, @secret_key, string_to_encrypt)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,145 @@
|
|
1
|
+
module Markety
|
2
|
+
def self.new_client(access_key, secret_key, end_point, api_version = '2_2')
|
3
|
+
client = Savon.client do
|
4
|
+
endpoint end_point
|
5
|
+
wsdl "http://app.marketo.com/soap/mktows/#{api_version}?WSDL"
|
6
|
+
namespaces("xmlns:ns1" => "http://www.marketo.com/mktows/")
|
7
|
+
end
|
8
|
+
|
9
|
+
Client.new(client, Markety::AuthenticationHeader.new(access_key, secret_key))
|
10
|
+
end
|
11
|
+
|
12
|
+
class Client
|
13
|
+
def initialize(savon_client, authentication_header)
|
14
|
+
@client = savon_client
|
15
|
+
@header = authentication_header
|
16
|
+
end
|
17
|
+
|
18
|
+
public
|
19
|
+
|
20
|
+
def get_lead_by_idnum(idnum)
|
21
|
+
get_lead(LeadKey.new(LeadKeyType::IDNUM, idnum))
|
22
|
+
end
|
23
|
+
|
24
|
+
|
25
|
+
def get_lead_by_email(email)
|
26
|
+
get_lead(LeadKey.new(LeadKeyType::EMAIL, email))
|
27
|
+
end
|
28
|
+
|
29
|
+
def set_logger(logger)
|
30
|
+
@logger = logger
|
31
|
+
end
|
32
|
+
|
33
|
+
def sync_lead(email, first, last, company, mobile)
|
34
|
+
lead_record = LeadRecord.new(email)
|
35
|
+
lead_record.set_attribute('FirstName', first)
|
36
|
+
lead_record.set_attribute('LastName', last)
|
37
|
+
lead_record.set_attribute('Email', email)
|
38
|
+
lead_record.set_attribute('Company', company)
|
39
|
+
lead_record.set_attribute('MobilePhone', mobile)
|
40
|
+
sync_lead_record(lead_record)
|
41
|
+
end
|
42
|
+
|
43
|
+
def sync_lead_record(lead_record)
|
44
|
+
begin
|
45
|
+
attributes = []
|
46
|
+
lead_record.each_attribute_pair do |name, value|
|
47
|
+
attributes << {:attr_name => name, :attr_type => 'string', :attr_value => value}
|
48
|
+
end
|
49
|
+
|
50
|
+
response = send_request(:sync_lead, {
|
51
|
+
:return_lead => true,
|
52
|
+
:lead_record => {
|
53
|
+
:email => lead_record.email,
|
54
|
+
:lead_attribute_list => {
|
55
|
+
:attribute => attributes
|
56
|
+
}
|
57
|
+
}
|
58
|
+
})
|
59
|
+
return LeadRecord.from_hash(response[:success_sync_lead][:result][:lead_record])
|
60
|
+
rescue Exception => e
|
61
|
+
@logger.log(e) if @logger
|
62
|
+
return nil
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def sync_lead_record_on_id(lead_record)
|
67
|
+
idnum = lead_record.idnum
|
68
|
+
raise 'lead record id not set' if idnum.nil?
|
69
|
+
|
70
|
+
begin
|
71
|
+
attributes = []
|
72
|
+
lead_record.each_attribute_pair do |name, value|
|
73
|
+
attributes << {:attr_name => name, :attr_type => 'string', :attr_value => value}
|
74
|
+
end
|
75
|
+
|
76
|
+
attributes << {:attr_name => 'Id', :attr_type => 'string', :attr_value => idnum.to_s}
|
77
|
+
|
78
|
+
response = send_request(:sync_lead, {
|
79
|
+
:return_lead => true,
|
80
|
+
:lead_record =>
|
81
|
+
{
|
82
|
+
:lead_attribute_list => { :attribute => attributes},
|
83
|
+
:id => idnum
|
84
|
+
}
|
85
|
+
})
|
86
|
+
return LeadRecord.from_hash(response[:success_sync_lead][:result][:lead_record])
|
87
|
+
rescue Exception => e
|
88
|
+
@logger.log(e) if @logger
|
89
|
+
return nil
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def add_to_list(list_key, email)
|
94
|
+
list_operation(list_key, ListOperationType::ADD_TO, email)
|
95
|
+
end
|
96
|
+
|
97
|
+
def remove_from_list(list_key, email)
|
98
|
+
list_operation(list_key, ListOperationType::REMOVE_FROM, email)
|
99
|
+
end
|
100
|
+
|
101
|
+
def is_member_of_list?(list_key, email)
|
102
|
+
list_operation(list_key, ListOperationType::IS_MEMBER_OF, email)
|
103
|
+
end
|
104
|
+
|
105
|
+
private
|
106
|
+
def list_operation(list_key, list_operation_type, email)
|
107
|
+
begin
|
108
|
+
response = send_request(:list_operation, {
|
109
|
+
:list_operation => list_operation_type,
|
110
|
+
:list_key => list_key,
|
111
|
+
:strict => 'false',
|
112
|
+
:list_member_list => {
|
113
|
+
:lead_key => [
|
114
|
+
{:key_type => 'EMAIL', :key_value => email}
|
115
|
+
]
|
116
|
+
}
|
117
|
+
})
|
118
|
+
return response
|
119
|
+
rescue Exception => e
|
120
|
+
@logger.log(e) if @logger
|
121
|
+
return nil
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
def get_lead(lead_key)
|
126
|
+
begin
|
127
|
+
response = send_request(:get_lead, {"leadKey" => lead_key.to_hash})
|
128
|
+
return LeadRecord.from_hash(response[:success_get_lead][:result][:lead_record_list][:lead_record])
|
129
|
+
rescue Exception => e
|
130
|
+
@logger.log(e) if @logger
|
131
|
+
return nil
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
def send_request(namespace, message)
|
136
|
+
@header.set_time(DateTime.now)
|
137
|
+
response = request(namespace, message, @header.to_hash)
|
138
|
+
response.to_hash
|
139
|
+
end
|
140
|
+
|
141
|
+
def request(namespace, message, header)
|
142
|
+
@client.call(namespace, :message => message, :soap_header => header)
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Markety
|
2
|
+
# Types of operations you can do on a marketo list
|
3
|
+
module ListOperationType
|
4
|
+
ADD_TO = 'ADDTOLIST'
|
5
|
+
REMOVE_FROM = 'REMOVEFROMLIST'
|
6
|
+
IS_MEMBER_OF = 'ISMEMBEROFLIST'
|
7
|
+
end
|
8
|
+
|
9
|
+
# Types of keys that can be used to look up a lead
|
10
|
+
module LeadKeyType
|
11
|
+
IDNUM = "IDNUM"
|
12
|
+
COOKIE = "COOKIE"
|
13
|
+
EMAIL = "EMAIL"
|
14
|
+
LEADOWNEREMAIL = "LEADOWNEREMAIL"
|
15
|
+
SFDCACCOUNTID = "SFDCACCOUNTID"
|
16
|
+
SFDCCONTACTID = "SFDCCONTACTID"
|
17
|
+
SFDCLEADID = "SFDCLEADID"
|
18
|
+
SFDCLEADOWNERID = "SFDCLEADOWNERID"
|
19
|
+
SFDCOPPTYID = "SFDCOPPTYID"
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Markety
|
2
|
+
# Encapsulates a key used to look up or describe a specific marketo lead.
|
3
|
+
class LeadKey
|
4
|
+
# - *key_type* the type of key to use see LeadKeyType
|
5
|
+
# - *key_value* normally a string value for the given type
|
6
|
+
def initialize(key_type, key_value)
|
7
|
+
@key_type = key_type
|
8
|
+
@key_value = key_value
|
9
|
+
end
|
10
|
+
|
11
|
+
# get the key type
|
12
|
+
def key_type
|
13
|
+
@key_type
|
14
|
+
end
|
15
|
+
|
16
|
+
# get the key value
|
17
|
+
def key_value
|
18
|
+
@key_value
|
19
|
+
end
|
20
|
+
|
21
|
+
# create a hash from this instance, for sending this object to marketo using savon
|
22
|
+
def to_hash
|
23
|
+
{
|
24
|
+
"keyType" => @key_type,
|
25
|
+
"keyValue" => @key_value
|
26
|
+
}
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module Markety
|
2
|
+
# Represents a record of the data known about a lead within marketo
|
3
|
+
class LeadRecord
|
4
|
+
def initialize(email, idnum = nil)
|
5
|
+
@idnum = idnum
|
6
|
+
@attributes = {}
|
7
|
+
set_attribute('Email', email)
|
8
|
+
end
|
9
|
+
|
10
|
+
# hydrates an instance from a savon hash returned form the marketo API
|
11
|
+
def self.from_hash(savon_hash)
|
12
|
+
lead_record = LeadRecord.new(savon_hash[:email], savon_hash[:id].to_i)
|
13
|
+
savon_hash[:lead_attribute_list][:attribute].each do |attribute|
|
14
|
+
lead_record.set_attribute(attribute[:attr_name], attribute[:attr_value])
|
15
|
+
end
|
16
|
+
lead_record
|
17
|
+
end
|
18
|
+
|
19
|
+
# get the record idnum
|
20
|
+
def idnum
|
21
|
+
@idnum
|
22
|
+
end
|
23
|
+
|
24
|
+
# get the record email
|
25
|
+
def email
|
26
|
+
get_attribute('Email')
|
27
|
+
end
|
28
|
+
|
29
|
+
def attributes
|
30
|
+
@attributes
|
31
|
+
end
|
32
|
+
|
33
|
+
# update the value of the named attribute
|
34
|
+
def set_attribute(name, value)
|
35
|
+
@attributes[name] = value
|
36
|
+
end
|
37
|
+
|
38
|
+
# get the value for the named attribute
|
39
|
+
def get_attribute(name)
|
40
|
+
@attributes[name]
|
41
|
+
end
|
42
|
+
|
43
|
+
# will yield pairs of |attribute_name, attribute_value|
|
44
|
+
def each_attribute_pair(&block)
|
45
|
+
@attributes.each_pair do |name, value|
|
46
|
+
block.call(name, value)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def ==(other)
|
51
|
+
@attributes == other.attributes &&
|
52
|
+
@idnum == other.idnum
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
metadata
ADDED
@@ -0,0 +1,83 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: markety
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- David Santoso
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-12-04 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: savon
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 2.3.0
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 2.3.0
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: rspec
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: 2.3.0
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: 2.3.0
|
46
|
+
description: A client to allow easy integration with Marketo's SOAP API
|
47
|
+
email: david.e.santoso@gmail.com
|
48
|
+
executables: []
|
49
|
+
extensions: []
|
50
|
+
extra_rdoc_files: []
|
51
|
+
files:
|
52
|
+
- lib/markety/authentication_header.rb
|
53
|
+
- lib/markety/client.rb
|
54
|
+
- lib/markety/enums.rb
|
55
|
+
- lib/markety/lead_key.rb
|
56
|
+
- lib/markety/lead_record.rb
|
57
|
+
- lib/markety/version.rb
|
58
|
+
- lib/markety.rb
|
59
|
+
homepage: https://github.com/davidsantoso/markety
|
60
|
+
licenses: []
|
61
|
+
post_install_message:
|
62
|
+
rdoc_options: []
|
63
|
+
require_paths:
|
64
|
+
- lib
|
65
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
66
|
+
none: false
|
67
|
+
requirements:
|
68
|
+
- - ! '>='
|
69
|
+
- !ruby/object:Gem::Version
|
70
|
+
version: '0'
|
71
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
72
|
+
none: false
|
73
|
+
requirements:
|
74
|
+
- - ! '>='
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '0'
|
77
|
+
requirements: []
|
78
|
+
rubyforge_project:
|
79
|
+
rubygems_version: 1.8.23
|
80
|
+
signing_key:
|
81
|
+
specification_version: 3
|
82
|
+
summary: Marketo SOAP API integration
|
83
|
+
test_files: []
|