unresponsys 0.0.3 → 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
- - ">="
|