unresponsys 0.0.3 → 0.0.5
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 +4 -4
- data/lib/unresponsys.rb +12 -0
- data/lib/unresponsys/client.rb +70 -0
- data/lib/unresponsys/errors.rb +6 -0
- data/lib/unresponsys/event.rb +35 -0
- data/lib/unresponsys/folder.rb +27 -0
- data/lib/unresponsys/helpers.rb +76 -0
- data/lib/unresponsys/list.rb +39 -0
- data/lib/unresponsys/member.rb +132 -0
- data/lib/unresponsys/row.rb +62 -0
- data/lib/unresponsys/table.rb +36 -0
- data/lib/unresponsys/version.rb +3 -0
- metadata +14 -13
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9ab97914beb02ad40643f37e22de5b06a9e7070d
|
4
|
+
data.tar.gz: e0926c1dfbf45986635cc7933f4b5712da8f3d8c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9b7130d8de52d61196231af0db584e5ef2c661c5c2877e70605df10fb54aaf80e28d205993bb05a8b2add846bcf9d038f5d90fa0882f46ed6409304599c3b1f0
|
7
|
+
data.tar.gz: a71246553a866bc3ceada31664ff8bbd7f257485d360f03c6b095e6a51a8187dc0e7959ed2397763b4b014924e1e85b5e3690fec4e5f67bce35e51ad08e0a639
|
data/lib/unresponsys.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'active_support'
|
2
|
+
require 'active_support/all'
|
3
|
+
require 'unresponsys/client'
|
4
|
+
require 'unresponsys/event'
|
5
|
+
require 'unresponsys/errors'
|
6
|
+
require 'unresponsys/folder'
|
7
|
+
require 'unresponsys/helpers'
|
8
|
+
require 'unresponsys/list'
|
9
|
+
require 'unresponsys/member'
|
10
|
+
require 'unresponsys/row'
|
11
|
+
require 'unresponsys/table'
|
12
|
+
require 'unresponsys/version'
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require 'httparty'
|
2
|
+
|
3
|
+
class Unresponsys
|
4
|
+
class Client
|
5
|
+
include HTTParty
|
6
|
+
|
7
|
+
def initialize(options = {})
|
8
|
+
@@username ||= options[:username]
|
9
|
+
@@password ||= options[:password]
|
10
|
+
raise Unresponsys::Error, 'Could not authenticate' unless authenticate
|
11
|
+
self.class.debug_output($stdout) if options[:debug]
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.get(path, options = {}, &block)
|
15
|
+
begin
|
16
|
+
r = perform_request Net::HTTP::Get, path, options, &block
|
17
|
+
handle_error(r)
|
18
|
+
rescue Unresponsys::Retry
|
19
|
+
r = perform_request Net::HTTP::Get, path, options, &block
|
20
|
+
handle_error(r)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.post(path, options = {}, &block)
|
25
|
+
begin
|
26
|
+
r = perform_request Net::HTTP::Post, path, options, &block
|
27
|
+
handle_error(r)
|
28
|
+
rescue Unresponsys::Retry
|
29
|
+
r = perform_request Net::HTTP::Post, path, options, &block
|
30
|
+
handle_error(r)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.delete(path, options = {}, &block)
|
35
|
+
begin
|
36
|
+
r = perform_request Net::HTTP::Delete, path, options, &block
|
37
|
+
handle_error(r)
|
38
|
+
rescue Unresponsys::Retry
|
39
|
+
r = perform_request Net::HTTP::Delete, path, options, &block
|
40
|
+
handle_error(r)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
def self.handle_error(response)
|
47
|
+
if response.is_a?(Hash) && response.keys.include?('errorCode')
|
48
|
+
if response['title'].include?('token expired')
|
49
|
+
self.new
|
50
|
+
raise Unresponsys::Retry
|
51
|
+
end
|
52
|
+
if response['title'].include?('not found')
|
53
|
+
raise Unresponsys::NotFoundError, response['detail']
|
54
|
+
end
|
55
|
+
raise Unresponsys::Error, "#{response['title']} - #{response['detail']}"
|
56
|
+
end
|
57
|
+
response
|
58
|
+
end
|
59
|
+
|
60
|
+
def authenticate
|
61
|
+
self.class.headers('Content-Type' => 'application/x-www-form-urlencoded')
|
62
|
+
body = { user_name: @@username, password: @@password, auth_type: 'password' }
|
63
|
+
r = self.class.post('https://login2.responsys.net/rest/api/v1/auth/token', body: body)
|
64
|
+
return false unless r.success?
|
65
|
+
self.class.headers('Authorization' => r['authToken'], 'Content-Type' => 'application/json')
|
66
|
+
self.class.base_uri("#{r['endPoint']}/rest/api/v1")
|
67
|
+
true
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
class Unresponsys
|
2
|
+
class Event
|
3
|
+
|
4
|
+
def initialize(options = {})
|
5
|
+
@event_name = options[:event]
|
6
|
+
@member = options[:member]
|
7
|
+
@properties = options[:properties]
|
8
|
+
end
|
9
|
+
|
10
|
+
def save
|
11
|
+
body = {
|
12
|
+
customEvent: {},
|
13
|
+
recipientData: [{
|
14
|
+
recipient: {
|
15
|
+
listName: { objectName: @member.list },
|
16
|
+
recipientId: @member.riid,
|
17
|
+
}
|
18
|
+
}]
|
19
|
+
}
|
20
|
+
|
21
|
+
# API throws an non-descriptive error if optionalData is present but empty
|
22
|
+
if @properties.present?
|
23
|
+
body[:recipientData].first[:optionalData] = []
|
24
|
+
@properties.each_pair do |key, val|
|
25
|
+
body[:recipientData].first[:optionalData] << { name: key.to_s, value: val.to_s }
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
r = Unresponsys::Client.post("/events/#{@event_name}", body: body.to_json)
|
30
|
+
return false if r.first['errorMessage'].present?
|
31
|
+
true
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
class Unresponsys
|
2
|
+
class Folder
|
3
|
+
attr_reader :name
|
4
|
+
|
5
|
+
def self.find(name)
|
6
|
+
self.new(name)
|
7
|
+
end
|
8
|
+
|
9
|
+
def initialize(name)
|
10
|
+
@name = name
|
11
|
+
end
|
12
|
+
|
13
|
+
def tables
|
14
|
+
@tables ||= Tables.new(self)
|
15
|
+
end
|
16
|
+
|
17
|
+
class Tables
|
18
|
+
def initialize(folder)
|
19
|
+
@folder = folder
|
20
|
+
end
|
21
|
+
|
22
|
+
def find(table_name)
|
23
|
+
Unresponsys::Table.new(@folder, table_name)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
class Object
|
2
|
+
def to_responsys
|
3
|
+
self.to_s
|
4
|
+
end
|
5
|
+
|
6
|
+
def to_ruby
|
7
|
+
self
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
class String
|
12
|
+
def is_i?
|
13
|
+
return false if self.include?('.')
|
14
|
+
!!Integer(self) rescue false
|
15
|
+
end
|
16
|
+
|
17
|
+
def is_f?
|
18
|
+
!!Float(self) rescue false
|
19
|
+
end
|
20
|
+
|
21
|
+
def is_time?
|
22
|
+
return false if /[[:alpha:]]/.match(self).present?
|
23
|
+
!!Time.parse(self) rescue false
|
24
|
+
end
|
25
|
+
|
26
|
+
def to_time
|
27
|
+
Time.parse(self)
|
28
|
+
end
|
29
|
+
|
30
|
+
def is_bool?
|
31
|
+
return false unless self.length == 1
|
32
|
+
%w(T F).include?(self)
|
33
|
+
end
|
34
|
+
|
35
|
+
def to_bool
|
36
|
+
self == 'T'
|
37
|
+
end
|
38
|
+
|
39
|
+
def to_ruby
|
40
|
+
return self.to_i if self.is_i?
|
41
|
+
return self.to_f if self.is_f?
|
42
|
+
return self.to_time if self.is_time?
|
43
|
+
return self.to_bool if self.is_bool?
|
44
|
+
self
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
class Date
|
49
|
+
def to_responsys
|
50
|
+
self.strftime('%Y-%m-%d %H:%M:%S')
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
class DateTime
|
55
|
+
def to_responsys
|
56
|
+
self.strftime('%Y-%m-%d %H:%M:%S')
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
class Time
|
61
|
+
def to_responsys
|
62
|
+
self.strftime('%Y-%m-%d %H:%M:%S')
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
class TrueClass
|
67
|
+
def to_responsys
|
68
|
+
'T'
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
class FalseClass
|
73
|
+
def to_responsys
|
74
|
+
'F'
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
class Unresponsys
|
2
|
+
class List
|
3
|
+
attr_reader :name
|
4
|
+
|
5
|
+
def self.find(name)
|
6
|
+
self.new(name)
|
7
|
+
end
|
8
|
+
|
9
|
+
def initialize(name)
|
10
|
+
@name = name
|
11
|
+
end
|
12
|
+
|
13
|
+
def members
|
14
|
+
@members ||= Members.new(self)
|
15
|
+
end
|
16
|
+
|
17
|
+
class Members
|
18
|
+
def initialize(list)
|
19
|
+
@list = list
|
20
|
+
end
|
21
|
+
|
22
|
+
def find(email)
|
23
|
+
options = { query: { qa: 'e', id: email.to_responsys, fs: 'all' } }
|
24
|
+
r = Unresponsys::Client.get("/lists/#{@list.name}/members", options)
|
25
|
+
|
26
|
+
fields = {}
|
27
|
+
r['recordData']['fieldNames'].each_with_index do |field, index|
|
28
|
+
fields[field] = r['recordData']['records'][0][index]
|
29
|
+
end
|
30
|
+
|
31
|
+
Unresponsys::Member.new(@list, fields)
|
32
|
+
end
|
33
|
+
|
34
|
+
def new(email)
|
35
|
+
Unresponsys::Member.new(@list, { 'EMAIL_ADDRESS_' => email })
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,132 @@
|
|
1
|
+
class Unresponsys
|
2
|
+
class Member
|
3
|
+
DEFAULT_FIELDS = {
|
4
|
+
'RIID_' => '',
|
5
|
+
'EMAIL_ADDRESS_' => '',
|
6
|
+
'MOBILE_NUMBER_' => '',
|
7
|
+
'CUSTOMER_ID_' => '',
|
8
|
+
'EMAIL_PERMISSION_STATUS_' => '',
|
9
|
+
'EMAIL_PERMISSION_REASON_' => '',
|
10
|
+
'POSTAL_STREET_1_' => '',
|
11
|
+
'POSTAL_STREET_2_' => '',
|
12
|
+
'CITY_' => '',
|
13
|
+
'STATE_' => '',
|
14
|
+
'POSTAL_CODE_' => '',
|
15
|
+
'COUNTRY_' => '',
|
16
|
+
'EMAIL_MD5_HASH_' => '',
|
17
|
+
'EMAIL_SHA256_HASH_' => ''
|
18
|
+
}
|
19
|
+
|
20
|
+
IMMUTABLE_FIELDS = %w(
|
21
|
+
RIID_
|
22
|
+
EMAIL_ADDRESS_
|
23
|
+
MOBILE_NUMBER_
|
24
|
+
EMAIL_MD5_HASH_
|
25
|
+
EMAIL_SHA256_HASH_
|
26
|
+
)
|
27
|
+
|
28
|
+
MERGE_RULE = {
|
29
|
+
insertOnNoMatch: true,
|
30
|
+
updateOnMatch: 'REPLACE_ALL',
|
31
|
+
matchColumnName1: 'EMAIL_ADDRESS_',
|
32
|
+
matchColumnName2: nil,
|
33
|
+
matchOperator: nil,
|
34
|
+
optinValue: 'I',
|
35
|
+
optoutValue: 'O',
|
36
|
+
defaultPermissionStatus: 'OPTIN',
|
37
|
+
htmlValue: 'H',
|
38
|
+
textValue: 'T',
|
39
|
+
rejectRecordIfChannelEmpty: nil,
|
40
|
+
}
|
41
|
+
|
42
|
+
def initialize(list, fields)
|
43
|
+
@fields = DEFAULT_FIELDS.merge(fields)
|
44
|
+
@list = list
|
45
|
+
@changed = ['EMAIL_ADDRESS_']
|
46
|
+
|
47
|
+
@fields.each_pair do |key, val|
|
48
|
+
str = key.downcase.chomp('_')
|
49
|
+
var = "@#{str}".to_sym
|
50
|
+
val = val.to_ruby
|
51
|
+
self.instance_variable_set(var, val)
|
52
|
+
|
53
|
+
# getter
|
54
|
+
self.class.send(:attr_reader, str)
|
55
|
+
|
56
|
+
# setter
|
57
|
+
next if IMMUTABLE_FIELDS.include?(key)
|
58
|
+
self.class.send(:define_method, "#{str}=") do |val|
|
59
|
+
@changed << key
|
60
|
+
val = val.to_ruby
|
61
|
+
self.instance_variable_set(var, val)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def email
|
67
|
+
email_address
|
68
|
+
end
|
69
|
+
|
70
|
+
def list
|
71
|
+
@list.name
|
72
|
+
end
|
73
|
+
|
74
|
+
def save
|
75
|
+
record_data = { fieldNames: [], records: [[]], mapTemplateName: nil }
|
76
|
+
@fields.each_pair do |key, val|
|
77
|
+
# can't send unless val changed or API breaks
|
78
|
+
next unless @changed.include?(key)
|
79
|
+
|
80
|
+
record_data[:fieldNames] << key
|
81
|
+
var = "@#{key.downcase.chomp('_')}".to_sym
|
82
|
+
val = self.instance_variable_get(var)
|
83
|
+
val = val.to_responsys
|
84
|
+
record_data[:records][0] << val
|
85
|
+
end
|
86
|
+
|
87
|
+
options = { body: { recordData: record_data, mergeRule: MERGE_RULE.dup }.to_json }
|
88
|
+
r = Unresponsys::Client.post("/lists/#{@list.name}/members", options)
|
89
|
+
return false if r['recordData']['records'][0][0].include?('MERGEFAILED')
|
90
|
+
@changed = ['EMAIL_ADDRESS_']
|
91
|
+
self.instance_variable_set(:@riid, r['recordData']['records'][0][0])
|
92
|
+
true
|
93
|
+
end
|
94
|
+
|
95
|
+
def delete
|
96
|
+
self.email_permission_status = 'O'
|
97
|
+
self.save
|
98
|
+
end
|
99
|
+
|
100
|
+
# allow to access custom fields on new record
|
101
|
+
def method_missing(sym, *args, &block)
|
102
|
+
setter = sym.to_s.include?('=')
|
103
|
+
str = sym.to_s.chomp('=')
|
104
|
+
var = "@#{str}".to_sym
|
105
|
+
val = args.first
|
106
|
+
|
107
|
+
if setter
|
108
|
+
field_name = str.upcase
|
109
|
+
@fields[field_name] = ''
|
110
|
+
@changed << field_name
|
111
|
+
val = val.to_ruby
|
112
|
+
self.instance_variable_set(var, val)
|
113
|
+
else
|
114
|
+
self.instance_variable_get(var)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
def events
|
119
|
+
@events ||= Events.new(self)
|
120
|
+
end
|
121
|
+
|
122
|
+
class Events
|
123
|
+
def initialize(member)
|
124
|
+
@member = member
|
125
|
+
end
|
126
|
+
|
127
|
+
def new(event, properties = {})
|
128
|
+
Event.new(member: @member, event: event, properties: properties)
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
class Unresponsys
|
2
|
+
class Row
|
3
|
+
def initialize(table, fields)
|
4
|
+
@table = table
|
5
|
+
@fields = fields
|
6
|
+
|
7
|
+
@fields.each_pair do |key, val|
|
8
|
+
str = key.downcase.chomp('_')
|
9
|
+
var = "@#{str}".to_sym
|
10
|
+
val = val.to_ruby
|
11
|
+
self.instance_variable_set(var, val)
|
12
|
+
|
13
|
+
if key == 'ID_'
|
14
|
+
self.class.send(:attr_reader, str)
|
15
|
+
else
|
16
|
+
self.class.send(:define_method, "#{str}=") do |val|
|
17
|
+
val = val.to_ruby
|
18
|
+
self.instance_variable_set(var, val)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def save
|
25
|
+
record_data = { fieldNames: [], records: [[]], mapTemplateName: nil }
|
26
|
+
@fields.each_pair do |key, val|
|
27
|
+
record_data[:fieldNames] << key
|
28
|
+
var = "@#{key.downcase.chomp('_')}".to_sym
|
29
|
+
val = self.instance_variable_get(var)
|
30
|
+
val = val.to_responsys
|
31
|
+
record_data[:records][0] << val
|
32
|
+
end
|
33
|
+
|
34
|
+
options = { body: { recordData: record_data, insertOnNoMatch: true, updateOnMatch: 'REPLACE_ALL' }.to_json }
|
35
|
+
r = Unresponsys::Client.post("/folders/#{@table.folder.name}/suppData/#{@table.name}/members", options)
|
36
|
+
r['recordData']['records'][0][0].exclude?('MERGEFAILED')
|
37
|
+
end
|
38
|
+
|
39
|
+
def delete
|
40
|
+
options = { query: { qa: 'ID_', id: @fields.primary_key } }
|
41
|
+
r = Unresponsys::Client.delete("/folders/#{@table.folder.name}/suppData/#{@table.name}/members", options)
|
42
|
+
r['recordData']['records'][0][0].exclude?('DELETEFAILED')
|
43
|
+
end
|
44
|
+
|
45
|
+
# allow to access custom fields on new record
|
46
|
+
def method_missing(sym, *args, &block)
|
47
|
+
setter = sym.to_s.include?('=')
|
48
|
+
str = sym.to_s.chomp('=')
|
49
|
+
var = "@#{str}".to_sym
|
50
|
+
val = args.first
|
51
|
+
|
52
|
+
if setter
|
53
|
+
field_name = str.upcase
|
54
|
+
@fields[field_name] = ''
|
55
|
+
val = val.to_ruby
|
56
|
+
self.instance_variable_set(var, val)
|
57
|
+
else
|
58
|
+
self.instance_variable_get(var)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
class Unresponsys
|
2
|
+
class Table
|
3
|
+
attr_reader :folder, :name
|
4
|
+
|
5
|
+
def initialize(folder, table_name)
|
6
|
+
@folder = folder
|
7
|
+
@name = table_name
|
8
|
+
end
|
9
|
+
|
10
|
+
def rows
|
11
|
+
@rows ||= Rows.new(self)
|
12
|
+
end
|
13
|
+
|
14
|
+
class Rows
|
15
|
+
def initialize(table)
|
16
|
+
@table = table
|
17
|
+
end
|
18
|
+
|
19
|
+
def find(primary_key)
|
20
|
+
options = { query: { qa: 'ID_', id: primary_key.to_responsys, fs: 'all' } }
|
21
|
+
r = Unresponsys::Client.get("/folders/#{@table.folder.name}/suppData/#{@table.name}/members", options)
|
22
|
+
|
23
|
+
fields = {}
|
24
|
+
r['recordData']['fieldNames'].each_with_index do |field, index|
|
25
|
+
fields[field] = r['recordData']['records'][0][index]
|
26
|
+
end
|
27
|
+
|
28
|
+
Unresponsys::Row.new(@table, fields)
|
29
|
+
end
|
30
|
+
|
31
|
+
def new(primary_key)
|
32
|
+
Unresponsys::Row.new(@table, { 'ID_' => primary_key })
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: unresponsys
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kevin Kimball
|
@@ -114,24 +114,25 @@ email:
|
|
114
114
|
executables: []
|
115
115
|
extensions: []
|
116
116
|
extra_rdoc_files: []
|
117
|
-
files:
|
117
|
+
files:
|
118
|
+
- lib/unresponsys.rb
|
119
|
+
- lib/unresponsys/client.rb
|
120
|
+
- lib/unresponsys/errors.rb
|
121
|
+
- lib/unresponsys/event.rb
|
122
|
+
- lib/unresponsys/folder.rb
|
123
|
+
- lib/unresponsys/helpers.rb
|
124
|
+
- lib/unresponsys/list.rb
|
125
|
+
- lib/unresponsys/member.rb
|
126
|
+
- lib/unresponsys/row.rb
|
127
|
+
- lib/unresponsys/table.rb
|
128
|
+
- lib/unresponsys/version.rb
|
118
129
|
homepage:
|
119
130
|
licenses: []
|
120
131
|
metadata: {}
|
121
132
|
post_install_message: responsys sucks :(
|
122
133
|
rdoc_options: []
|
123
134
|
require_paths:
|
124
|
-
- lib
|
125
|
-
- lib/unresponsys/client
|
126
|
-
- lib/unresponsys/errors
|
127
|
-
- lib/unresponsys/event
|
128
|
-
- lib/unresponsys/folder
|
129
|
-
- lib/unresponsys/helpers
|
130
|
-
- lib/unresponsys/list
|
131
|
-
- lib/unresponsys/member
|
132
|
-
- lib/unresponsys/row
|
133
|
-
- lib/unresponsys/table
|
134
|
-
- lib/unresponsys/version
|
135
|
+
- lib
|
135
136
|
required_ruby_version: !ruby/object:Gem::Requirement
|
136
137
|
requirements:
|
137
138
|
- - ">="
|