responsys-api 0.0.3 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/.gitignore +1 -0
- data/Gemfile +1 -1
- data/README.md +82 -10
- data/lib/responsys/api/all.rb +17 -0
- data/lib/responsys/api/campaign.rb +26 -0
- data/lib/responsys/api/client.rb +70 -0
- data/lib/responsys/api/folder.rb +25 -0
- data/lib/responsys/api/list.rb +39 -0
- data/lib/responsys/api/object/all.rb +11 -0
- data/lib/responsys/api/object/email_format.rb +23 -0
- data/lib/responsys/api/object/field.rb +20 -0
- data/lib/responsys/api/object/field_type.rb +23 -0
- data/lib/responsys/api/object/interact_object.rb +18 -0
- data/lib/responsys/api/object/list_merge_rule.rb +41 -0
- data/lib/responsys/api/object/optional_data.rb +23 -0
- data/lib/responsys/api/object/query_column.rb +23 -0
- data/lib/responsys/api/object/recipient.rb +30 -0
- data/lib/responsys/api/object/recipient_data.rb +21 -0
- data/lib/responsys/api/object/record.rb +19 -0
- data/lib/responsys/api/object/record_data.rb +31 -0
- data/lib/responsys/api/session.rb +30 -0
- data/lib/responsys/api/table.rb +49 -0
- data/lib/responsys/configuration.rb +3 -3
- data/lib/responsys/exceptions/all.rb +1 -0
- data/lib/responsys/exceptions/parameter_exception.rb +7 -0
- data/lib/responsys/helper.rb +78 -2
- data/lib/responsys/i18n/en.yml +20 -0
- data/lib/responsys/member.rb +80 -0
- data/lib/responsys_api.rb +11 -4
- data/responsys-api.gemspec +12 -9
- data/spec/api/campaign_spec.rb +27 -0
- data/spec/api/client_spec.rb +107 -0
- data/spec/api/list_spec.rb +71 -0
- data/spec/api/object/recipient_data_spec.rb +43 -0
- data/spec/api/object/recipient_spec.rb +68 -0
- data/spec/api/object/record_data_spec.rb +28 -0
- data/spec/api/table_spec.rb +111 -0
- data/spec/fixtures/vcr_cassettes/api/campaign/login.yml +940 -0
- data/spec/fixtures/vcr_cassettes/api/client/expired_session.yml +1030 -0
- data/spec/fixtures/vcr_cassettes/api/list/login.yml +982 -0
- data/spec/fixtures/vcr_cassettes/api/list/merge.yml +134 -0
- data/spec/fixtures/vcr_cassettes/api/list/retrieve.yml +46 -0
- data/spec/fixtures/vcr_cassettes/api/list/retrieve_single.yml +133 -0
- data/spec/fixtures/vcr_cassettes/api/list/retrieve_single_single.yml +45 -0
- data/spec/fixtures/vcr_cassettes/api/profile_extension/login.yml +982 -0
- data/spec/fixtures/vcr_cassettes/api/profile_extension/merge_profile_extension_records.yml +46 -0
- data/spec/fixtures/vcr_cassettes/api/profile_extension/retrieve_profile_extension_records.yml +45 -0
- data/spec/fixtures/vcr_cassettes/api/table/create.yml +45 -0
- data/spec/fixtures/vcr_cassettes/api/table/create_with_pk.yml +45 -0
- data/spec/fixtures/vcr_cassettes/api/table/delete.yml +45 -0
- data/spec/fixtures/vcr_cassettes/api/table/delete_with_pk.yml +45 -0
- data/spec/fixtures/vcr_cassettes/member/present1.yml +982 -0
- data/spec/fixtures/vcr_cassettes/member/present2.yml +45 -0
- data/spec/fixtures/vcr_cassettes/member/present3.yml +48 -0
- data/spec/fixtures/vcr_cassettes/member/present4.yml +48 -0
- data/spec/fixtures/vcr_cassettes/member/present5.yml +48 -0
- data/spec/fixtures/vcr_cassettes/member/retrieve_profile_extension.yml +87 -0
- data/spec/member_spec.rb +136 -0
- data/spec/spec_helper.rb +28 -2
- metadata +136 -19
- data/lib/responsys/responsys_api.rb +0 -41
- data/lib/savon/savon_api.rb +0 -22
- data/spec/responsys_api_spec.rb +0 -4
@@ -0,0 +1,23 @@
|
|
1
|
+
module Responsys
|
2
|
+
module Api
|
3
|
+
module Object
|
4
|
+
class OptionalData
|
5
|
+
include Responsys::Exceptions
|
6
|
+
attr_accessor :name, :value
|
7
|
+
|
8
|
+
def initialize(name = "", value = "")
|
9
|
+
raise ParameterException, I18n.t("api.object.optional_data.incorrect_optional_data_type") unless (name.is_a? String) && (value.is_a? String)
|
10
|
+
@name = name
|
11
|
+
@value = value
|
12
|
+
end
|
13
|
+
|
14
|
+
def to_api
|
15
|
+
{
|
16
|
+
Name: @name,
|
17
|
+
Value: @value
|
18
|
+
}
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Responsys
|
2
|
+
module Api
|
3
|
+
module Object
|
4
|
+
class QueryColumn
|
5
|
+
include Responsys::Exceptions
|
6
|
+
attr_accessor :query_column_string
|
7
|
+
AVAILABLE_QUERY_COLUMN = %w(RIID CUSTOMER_ID EMAIL_ADDRESS MOBILE_NUMBER)
|
8
|
+
|
9
|
+
def initialize(query_column)
|
10
|
+
if AVAILABLE_QUERY_COLUMN.include? query_column
|
11
|
+
@query_column_string = query_column
|
12
|
+
else
|
13
|
+
raise ParameterException, I18n.t("api.object.query_column.incorrect_query_column")
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def to_api
|
18
|
+
@query_column_string
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Responsys
|
2
|
+
module Api
|
3
|
+
module Object
|
4
|
+
class Recipient
|
5
|
+
include Responsys::Api::Object
|
6
|
+
attr_accessor :list_name, :recipient_id, :customer_id, :email_address, :mobile_number, :email_format
|
7
|
+
|
8
|
+
def initialize(options = {})
|
9
|
+
@list_name = options[:listName] || InteractObject.new("", "")
|
10
|
+
@recipient_id = options[:recipientId] || ""
|
11
|
+
@customer_id = options[:customerId] || ""
|
12
|
+
@email_address = options[:emailAddress] || ""
|
13
|
+
@mobile_number = options[:mobileNumber] || ""
|
14
|
+
@email_format = options[:emailFormat] || EmailFormat.new
|
15
|
+
end
|
16
|
+
|
17
|
+
def to_api
|
18
|
+
{
|
19
|
+
listName: @list_name.to_api,
|
20
|
+
recipientId: @recipient_id.to_i,
|
21
|
+
customerId: @customer_id.to_s,
|
22
|
+
emailAddress: @email_address.to_s,
|
23
|
+
mobileNumber: @mobile_number.to_s,
|
24
|
+
emailFormat: @email_format.to_api
|
25
|
+
}
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Responsys
|
2
|
+
module Api
|
3
|
+
module Object
|
4
|
+
class RecipientData
|
5
|
+
attr_accessor :recipient, :optional_data
|
6
|
+
|
7
|
+
def initialize(recipient, optional_data = Responsys::Api::Object::OptionalData.new)
|
8
|
+
@recipient = recipient
|
9
|
+
@optional_data = optional_data
|
10
|
+
end
|
11
|
+
|
12
|
+
def to_api
|
13
|
+
{
|
14
|
+
recipient: @recipient.to_api,
|
15
|
+
optionalData: @optional_data.to_api
|
16
|
+
}
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Responsys
|
2
|
+
module Api
|
3
|
+
module Object
|
4
|
+
class Record
|
5
|
+
include Responsys::Exceptions
|
6
|
+
attr_accessor :field_values
|
7
|
+
|
8
|
+
def initialize(field_values)
|
9
|
+
raise ParameterException, I18n.t("api.object.record.incorrect_field_values_type") unless field_values.is_a? Array
|
10
|
+
@field_values = field_values
|
11
|
+
end
|
12
|
+
|
13
|
+
def to_api
|
14
|
+
{ fieldValues: @field_values }
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Responsys
|
2
|
+
module Api
|
3
|
+
module Object
|
4
|
+
class RecordData
|
5
|
+
include Responsys::Exceptions
|
6
|
+
include Responsys::Api::Object
|
7
|
+
attr_accessor :field_names, :records
|
8
|
+
|
9
|
+
def initialize(data)
|
10
|
+
raise ParameterException, I18n.t("api.object.record_data.incorrect_record_data_type") unless data.is_a? Array
|
11
|
+
|
12
|
+
self.field_names = data.map { |record| record.keys }.flatten.uniq
|
13
|
+
|
14
|
+
new_data = []
|
15
|
+
field_names.each { |field_name|
|
16
|
+
data.each_with_index { |entity, index|
|
17
|
+
new_data[index] ||= Record.new([])
|
18
|
+
new_data[index].field_values << (entity.has_key?(field_name) ? entity[field_name.to_sym] : "")
|
19
|
+
}
|
20
|
+
}
|
21
|
+
|
22
|
+
self.records = new_data
|
23
|
+
end
|
24
|
+
|
25
|
+
def to_api
|
26
|
+
{ fieldNames: field_names, records: records.map(&:to_api) }
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Responsys
|
2
|
+
module Api
|
3
|
+
module Session
|
4
|
+
def login
|
5
|
+
response = run("login", credentials)
|
6
|
+
establish_session_id(response)
|
7
|
+
establish_jsession_id(response)
|
8
|
+
set_session_credentials
|
9
|
+
end
|
10
|
+
|
11
|
+
def logout
|
12
|
+
api_method(:logout)
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def establish_session_id(login_response)
|
18
|
+
@session_id = login_response.body[:login_response][:result][:session_id]
|
19
|
+
end
|
20
|
+
|
21
|
+
def establish_jsession_id(login_response)
|
22
|
+
@jsession_id = login_response.http.cookies[0]
|
23
|
+
end
|
24
|
+
|
25
|
+
def set_session_credentials
|
26
|
+
@header = { SessionHeader: { sessionId: session_id } }
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module Responsys
|
2
|
+
module Api
|
3
|
+
module Table
|
4
|
+
def create_table(interact_object, fields)
|
5
|
+
api_method(:create_table, { table: interact_object.to_api, fields: fields.map(&:to_api) })
|
6
|
+
end
|
7
|
+
|
8
|
+
def create_table_with_pk(interact_object, fields, primary_keys)
|
9
|
+
api_method(:create_table_with_pk, { table: interact_object.to_api, fields: fields.map(&:to_api), primaryKeys: primary_keys })
|
10
|
+
end
|
11
|
+
|
12
|
+
def delete_table(interact_object)
|
13
|
+
api_method(:delete_table, { table: interact_object.to_api })
|
14
|
+
end
|
15
|
+
|
16
|
+
def merge_into_profile_extension(interact_object, record_data, match_column, insert_on_no_match = false, update_on_match = "REPLACE_ALL")
|
17
|
+
api_method(:merge_into_profile_extension, { profileExtension: interact_object.to_api, recordData: record_data.to_api, matchColumn: match_column, insertOnNoMatch: insert_on_no_match, updateOnMatch: update_on_match })
|
18
|
+
end
|
19
|
+
|
20
|
+
def retrieve_profile_extension_records(interact_object, query_column, field_list, ids_to_retrieve)
|
21
|
+
api_method(:retrieve_profile_extension_records, { profileExtension: interact_object.to_api, queryColumn: query_column.to_api, fieldList: field_list, idsToRetrieve: ids_to_retrieve })
|
22
|
+
end
|
23
|
+
|
24
|
+
def delete_profile_extension_members(interact_object, query_column, ids_to_delete)
|
25
|
+
api_method(:delete_profile_extension_members, { profileExtension: interact_object.to_api, queryColumn: query_column.to_api, idsToDelete: ids_to_delete })
|
26
|
+
end
|
27
|
+
|
28
|
+
def merge_table_records
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
def merge_table_records_with_pk
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
def delete_table_records
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
def retrieve_table_records
|
41
|
+
|
42
|
+
end
|
43
|
+
|
44
|
+
def truncate_table
|
45
|
+
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -1,13 +1,13 @@
|
|
1
|
-
|
1
|
+
module Responsys
|
2
2
|
class Configuration
|
3
3
|
attr_accessor :settings
|
4
|
-
# Put all these constants into a configurable setting hash
|
5
4
|
|
6
5
|
def initialize
|
7
6
|
@settings = {
|
8
7
|
username: nil,
|
9
8
|
password: nil,
|
10
|
-
wsdl: ""
|
9
|
+
wsdl: "",
|
10
|
+
debug: false
|
11
11
|
}
|
12
12
|
end
|
13
13
|
end
|
@@ -0,0 +1 @@
|
|
1
|
+
require "responsys/exceptions/parameter_exception"
|
data/lib/responsys/helper.rb
CHANGED
@@ -1,7 +1,83 @@
|
|
1
|
-
|
1
|
+
module Responsys
|
2
2
|
module Helper
|
3
|
-
def self.
|
3
|
+
def self.format_response_result(response, action)
|
4
4
|
response.body[("#{action}_response").to_sym][:result]
|
5
5
|
end
|
6
|
+
|
7
|
+
def self.format_response_hash(response, action)
|
8
|
+
formatted_response = { status: "ok" }
|
9
|
+
|
10
|
+
return formatted_response unless response.body.has_key? "#{action}_response".to_sym
|
11
|
+
|
12
|
+
if response.body["#{action}_response".to_sym].has_key?(:result) and response.body["#{action}_response".to_sym][:result].is_a? Hash
|
13
|
+
formatted_response[:data] = handle_response_types(response.body["#{action}_response".to_sym])
|
14
|
+
elsif response.body["#{action}_response".to_sym].has_key?(:result)
|
15
|
+
formatted_response[:result] = response.body["#{action}_response".to_sym][:result]
|
16
|
+
elsif response.body["#{action}_response".to_sym].is_a? Hash and !response.body["#{action}_response".to_sym].empty?
|
17
|
+
formatted_response[:result] = response.body["#{action}_response".to_sym].values[0]
|
18
|
+
end
|
19
|
+
|
20
|
+
formatted_response
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.format_record_data(record_data)
|
24
|
+
field_names = record_data[:field_names]
|
25
|
+
records = record_data[:records]
|
26
|
+
|
27
|
+
data = []
|
28
|
+
if records.is_a? Array
|
29
|
+
records.each do |record|
|
30
|
+
data << format_field_values(record, field_names)
|
31
|
+
end
|
32
|
+
else
|
33
|
+
data << format_field_values(records, field_names)
|
34
|
+
end
|
35
|
+
|
36
|
+
data
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.format_field_values(record, field_names)
|
40
|
+
values = {}
|
41
|
+
|
42
|
+
if record.is_a? Hash and record[:field_values].is_a? Array
|
43
|
+
record[:field_values].each_with_index do |value, index|
|
44
|
+
values[field_names[index].to_sym] = value
|
45
|
+
end
|
46
|
+
elsif record.is_a? Hash
|
47
|
+
values[field_names.to_sym] = record[:field_values]
|
48
|
+
end
|
49
|
+
|
50
|
+
values
|
51
|
+
end
|
52
|
+
|
53
|
+
def self.handle_response_types(response_body)
|
54
|
+
data = []
|
55
|
+
|
56
|
+
if response_body[:result].has_key? :record_data
|
57
|
+
data = format_record_data(response_body[:result][:record_data])
|
58
|
+
else
|
59
|
+
data << response_body
|
60
|
+
end
|
61
|
+
|
62
|
+
data
|
63
|
+
end
|
64
|
+
|
65
|
+
def self.format_response_with_errors(error)
|
66
|
+
error_response = { status: "failure" }
|
67
|
+
|
68
|
+
if error.to_hash[:fault].has_key?(:detail) and !error.to_hash[:fault][:detail].nil?
|
69
|
+
key = error.to_hash[:fault][:detail].keys[0]
|
70
|
+
error_response[:error] = { http_status_code: error.http.code, code: error.to_hash[:fault][:detail][key][:exception_code], message: error.to_hash[:fault][:detail][key][:exception_message] }
|
71
|
+
error_response[:error][:trace] = error.to_hash[:fault][:detail][:source] if error.to_hash[:fault][:detail].has_key?(:source)
|
72
|
+
else
|
73
|
+
error_response[:error] = { http_status_code: error.http.code, code: error.to_hash[:fault][:faultcode], message: error.to_hash[:fault][:faultstring] }
|
74
|
+
end
|
75
|
+
|
76
|
+
error_response
|
77
|
+
end
|
78
|
+
|
79
|
+
def self.format_response_with_message(i18n_key)
|
80
|
+
{ status: "failure", error: { http_status_code: "", code: i18n_key.split('.')[-1], message: I18n.t(i18n_key) } }
|
81
|
+
end
|
6
82
|
end
|
7
83
|
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
en:
|
2
|
+
api:
|
3
|
+
object:
|
4
|
+
field_type:
|
5
|
+
incorrect_field_type: The field type string you provided is incorrect
|
6
|
+
query_column:
|
7
|
+
incorrect_query_column: The query column you provided is incorrect
|
8
|
+
record_data:
|
9
|
+
incorrect_record_data_type: The data you provided is not an array
|
10
|
+
optional_data:
|
11
|
+
incorrect_optional_data_type: The name and value need to be Strings
|
12
|
+
email_format:
|
13
|
+
incorrect_email_format: The email format is not supported
|
14
|
+
record:
|
15
|
+
incorrect_field_values_type: The field_values must be an array
|
16
|
+
campaign:
|
17
|
+
incorrect_recipients_type: Recipients parameter must be an array
|
18
|
+
member:
|
19
|
+
riid_missing: Variable riid is not provided to the member
|
20
|
+
record_not_found: The member has not been found in the list
|
@@ -0,0 +1,80 @@
|
|
1
|
+
require "responsys/api/all"
|
2
|
+
require "responsys/api/object/all"
|
3
|
+
|
4
|
+
module Responsys
|
5
|
+
class Member
|
6
|
+
include Responsys::Api
|
7
|
+
include Responsys::Api::Object
|
8
|
+
attr_accessor :email, :user_riid
|
9
|
+
|
10
|
+
def initialize(email, riid = nil)
|
11
|
+
@email = email
|
12
|
+
@user_riid = riid
|
13
|
+
@client = Client.instance
|
14
|
+
end
|
15
|
+
|
16
|
+
def add_to_list(list, subscribe = false)
|
17
|
+
data = { EMAIL_ADDRESS_: @email, EMAIL_PERMISSION_STATUS_: subscribe ? "I" : "O" }
|
18
|
+
record = RecordData.new([data])
|
19
|
+
|
20
|
+
@client.merge_list_members_riid(list, record, ListMergeRule.new(insertOnNoMatch: true, updateOnMatch: "NO_UPDATE"))
|
21
|
+
end
|
22
|
+
|
23
|
+
def retrieve_profile_extension(profile_extension, fields)
|
24
|
+
return Responsys::Helper.format_response_with_message("member.riid_missing") if @user_riid.nil?
|
25
|
+
return Responsys::Helper.format_response_with_message("member.record_not_found") unless present_in_profile?(profile_extension)
|
26
|
+
|
27
|
+
@client.retrieve_profile_extension_records(profile_extension, QueryColumn.new("RIID"), fields, [@user_riid])
|
28
|
+
end
|
29
|
+
|
30
|
+
def subscribe(list)
|
31
|
+
update(list, [{ EMAIL_ADDRESS_: @email, EMAIL_PERMISSION_STATUS_: "I" }])
|
32
|
+
end
|
33
|
+
|
34
|
+
def unsubscribe(list)
|
35
|
+
update(list, [{ EMAIL_ADDRESS_: @email, EMAIL_PERMISSION_STATUS_: "O" }])
|
36
|
+
end
|
37
|
+
|
38
|
+
def update(list, data)
|
39
|
+
return Responsys::Helper.format_response_with_message("member.record_not_found") unless present_in_list?(list)
|
40
|
+
|
41
|
+
record = RecordData.new(data)
|
42
|
+
@client.merge_list_members(list, record)
|
43
|
+
end
|
44
|
+
|
45
|
+
def present_in_profile?(list)
|
46
|
+
return Responsys::Helper.format_response_with_message("member.riid_missing") if @user_riid.nil?
|
47
|
+
|
48
|
+
response = lookup_profile_via_key(list, "RIID", @user_riid)
|
49
|
+
|
50
|
+
!(response[:status] == "failure" && response[:error][:code] == "RECORD_NOT_FOUND")
|
51
|
+
end
|
52
|
+
|
53
|
+
def present_in_list?(list)
|
54
|
+
if !@user_riid.nil?
|
55
|
+
response = lookup_list_via_key(list, "RIID", @user_riid)
|
56
|
+
else
|
57
|
+
response = lookup_list_via_key(list, "EMAIL_ADDRESS", @email)
|
58
|
+
end
|
59
|
+
|
60
|
+
!(response[:status] == "failure" && response[:error][:code] == "RECORD_NOT_FOUND")
|
61
|
+
end
|
62
|
+
|
63
|
+
def subscribed?(list)
|
64
|
+
return Responsys::Helper.format_response_with_message("member.record_not_found") unless present_in_list?(list)
|
65
|
+
|
66
|
+
response = @client.retrieve_list_members(list, QueryColumn.new("EMAIL_ADDRESS"), %w(EMAIL_PERMISSION_STATUS_), [@email])
|
67
|
+
response[:data][0][:EMAIL_PERMISSION_STATUS_] == "I"
|
68
|
+
end
|
69
|
+
|
70
|
+
private
|
71
|
+
|
72
|
+
def lookup_profile_via_key(profile_extension, key, value)
|
73
|
+
@client.retrieve_profile_extension_records(profile_extension, QueryColumn.new(key), %w(RIID_), [value])
|
74
|
+
end
|
75
|
+
|
76
|
+
def lookup_list_via_key(list, key, value)
|
77
|
+
@client.retrieve_list_members(list, QueryColumn.new(key), %w(EMAIL_PERMISSION_STATUS_), [value])
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|