riq 0.8.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +41 -0
- data/.yardopts +2 -0
- data/Gemfile +8 -0
- data/lib/relateiq.rb +3 -0
- data/lib/relateiq/account.rb +79 -0
- data/lib/relateiq/batch_manager.rb +187 -0
- data/lib/relateiq/client.rb +152 -0
- data/lib/relateiq/contact.rb +139 -0
- data/lib/relateiq/error.rb +53 -0
- data/lib/relateiq/events.rb +104 -0
- data/lib/relateiq/list.rb +87 -0
- data/lib/relateiq/list_item_manager.rb +13 -0
- data/lib/relateiq/listitem.rb +115 -0
- data/lib/relateiq/riq_obj.rb +142 -0
- data/lib/relateiq/user.rb +36 -0
- data/test/test.rb +4 -0
- data/test/test_account.rb +39 -0
- data/test/test_batch_manager.rb +45 -0
- data/test/test_contact.rb +50 -0
- metadata +96 -0
@@ -0,0 +1,139 @@
|
|
1
|
+
require_relative 'riq_obj'
|
2
|
+
|
3
|
+
module RIQ
|
4
|
+
class Contact < RIQObject
|
5
|
+
attr_accessor :properties
|
6
|
+
|
7
|
+
# (see RIQObject#node)
|
8
|
+
def node
|
9
|
+
self.class.node(@id)
|
10
|
+
end
|
11
|
+
|
12
|
+
# (see RIQObject#node)
|
13
|
+
def self.node(id = nil)
|
14
|
+
"contacts/#{id}"
|
15
|
+
end
|
16
|
+
|
17
|
+
# (see RIQObject#data)
|
18
|
+
def data
|
19
|
+
{
|
20
|
+
id: @id,
|
21
|
+
properties: @properties
|
22
|
+
}
|
23
|
+
end
|
24
|
+
|
25
|
+
# @!macro [new] prop
|
26
|
+
# @return [Array] all of the values for $0
|
27
|
+
def name
|
28
|
+
get_prop(:name)
|
29
|
+
end
|
30
|
+
|
31
|
+
# @macro prop
|
32
|
+
def phone
|
33
|
+
get_prop(:phone)
|
34
|
+
end
|
35
|
+
|
36
|
+
# @macro prop
|
37
|
+
def email
|
38
|
+
get_prop(:email)
|
39
|
+
end
|
40
|
+
|
41
|
+
# @macro prop
|
42
|
+
def address
|
43
|
+
get_prop(:address)
|
44
|
+
end
|
45
|
+
|
46
|
+
# Adds property with correct scaffolding
|
47
|
+
# @param prop [Symbol] Type Property to add, such as :name or :email
|
48
|
+
# @param val [String, Array] Value(s) to add
|
49
|
+
# @return [Array] Values for that property after the add
|
50
|
+
def add(prop, val)
|
51
|
+
# validate(prop)
|
52
|
+
prop = prop.to_sym
|
53
|
+
@properties[prop] = [] unless @properties.include? prop
|
54
|
+
|
55
|
+
if val.is_a? Array
|
56
|
+
val.each do |i|
|
57
|
+
add(prop, i)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
# don't add duplicate
|
62
|
+
if @properties[prop].select{|p| p[:value] == val}.empty?
|
63
|
+
@properties[prop] << {value: val, metadata: {}}
|
64
|
+
end
|
65
|
+
send(prop)
|
66
|
+
end
|
67
|
+
|
68
|
+
# Removes property from hash
|
69
|
+
# @param prop [Symbol] Type Property to remove, such as :name or :email
|
70
|
+
# @param val [String, Array] Value(s) to remove
|
71
|
+
# @return [Array] Values for that property after the remove
|
72
|
+
def remove(prop, val)
|
73
|
+
# validate(prop)
|
74
|
+
prop = prop.to_sym
|
75
|
+
|
76
|
+
if val.is_a? Array
|
77
|
+
val.each do |i|
|
78
|
+
remove(prop, i)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
if @properties.include? prop
|
83
|
+
@properties[prop] = @properties[prop].reject{|p| p[:value] == val}
|
84
|
+
end
|
85
|
+
send(prop)
|
86
|
+
end
|
87
|
+
|
88
|
+
# Edits an existing object based on matching email(s) or saves a new object
|
89
|
+
# @see RIQObject#save
|
90
|
+
def upsert
|
91
|
+
save({_upsert: 'email'})
|
92
|
+
end
|
93
|
+
|
94
|
+
# @param prop [Symbol] The property to fetch. One of [:name, :phone, :email, :address]
|
95
|
+
# @param val [String] The value to get info on, such as 'name@domain.com'
|
96
|
+
# @return [Hash] metadata and other info about a given property
|
97
|
+
def info(prop, val)
|
98
|
+
# validate(prop)
|
99
|
+
|
100
|
+
@properties[prop].select{|p| p[:value] == val}.first
|
101
|
+
end
|
102
|
+
|
103
|
+
private
|
104
|
+
|
105
|
+
def init(obj = nil)
|
106
|
+
unless obj.nil?
|
107
|
+
@id = obj['id']
|
108
|
+
@properties = symbolize(obj['properties'])
|
109
|
+
else
|
110
|
+
@id = nil
|
111
|
+
@properties = {}
|
112
|
+
end
|
113
|
+
self
|
114
|
+
end
|
115
|
+
|
116
|
+
# unused because we actually put all sorts of stuff in there
|
117
|
+
def validate(prop)
|
118
|
+
raise RIQError, %q(Invalid property. Use [:name | :phone | :email | :address] instead) unless [:name, :phone, :email, :address].include? prop
|
119
|
+
end
|
120
|
+
|
121
|
+
def get_prop(prop)
|
122
|
+
if @properties.include? prop
|
123
|
+
@properties[prop].map{|p| p[:value]}
|
124
|
+
else
|
125
|
+
[]
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
class << self
|
131
|
+
# Convenince method to create new Contacts
|
132
|
+
# @param id [String, nil] create a blank Contact object or
|
133
|
+
# fetch an existing one by id.
|
134
|
+
# @return [RIQ::Contact]
|
135
|
+
def contact(id = nil)
|
136
|
+
Contact.new(id)
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# Base exception class for our errors
|
2
|
+
|
3
|
+
module RIQ
|
4
|
+
class RIQError < StandardError
|
5
|
+
end
|
6
|
+
|
7
|
+
class NotImplementedError < RIQError
|
8
|
+
end
|
9
|
+
|
10
|
+
class NotFoundError < RIQError
|
11
|
+
end
|
12
|
+
|
13
|
+
class HTTPError < RIQError
|
14
|
+
attr_accessor :code
|
15
|
+
attr_accessor :message
|
16
|
+
attr_accessor :response
|
17
|
+
|
18
|
+
def initialize(resp)
|
19
|
+
# build response message
|
20
|
+
message = "\n[#{resp.code}] #{resp.message} : "
|
21
|
+
unless resp.parsed_response.nil?
|
22
|
+
begin
|
23
|
+
m = resp.parsed_response.fetch('errorMessage', 'no message')
|
24
|
+
rescue
|
25
|
+
# parse returned html
|
26
|
+
reg = resp.parsed_response.match(/<pre>(.*)<\/pre>/)
|
27
|
+
unless reg.nil?
|
28
|
+
m = reg[1].strip
|
29
|
+
else
|
30
|
+
m = 'no message'
|
31
|
+
end
|
32
|
+
end
|
33
|
+
message += "<#{m}>"
|
34
|
+
end
|
35
|
+
|
36
|
+
# pull out request info
|
37
|
+
req = resp.request
|
38
|
+
unless req.nil?
|
39
|
+
message += "\n Request: #{req.http_method} #{req.last_uri.to_s}"
|
40
|
+
unless req.raw_body.nil?
|
41
|
+
message += "\n #{req.raw_body}"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
@message = message
|
46
|
+
@response = resp
|
47
|
+
end
|
48
|
+
|
49
|
+
def to_s
|
50
|
+
@message || super
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
# require 'set'
|
2
|
+
# require 'json'
|
3
|
+
# require_relative 'riq_base'
|
4
|
+
|
5
|
+
# # Events.rb
|
6
|
+
# # Events represent interactions involving a Contact associated with a List Item.
|
7
|
+
# # Instead of appearing as new content in List columns, Events appear in a “Stream view”
|
8
|
+
# # associated with the appropriate List Item. If the same Contact is associated
|
9
|
+
# # with more than one List Item, then the Event will appear in all relevant Stream views.
|
10
|
+
# # For more info visit https://api.relateiq.com/#/ruby
|
11
|
+
|
12
|
+
# class Event < RIQBase
|
13
|
+
# # Object Attributes
|
14
|
+
# @id = nil
|
15
|
+
# @modifiedDate = nil
|
16
|
+
# @participantIds = nil
|
17
|
+
# @subject = nil
|
18
|
+
# @body = nil
|
19
|
+
|
20
|
+
# def initialize(
|
21
|
+
# _id=nil,
|
22
|
+
# subject=nil,
|
23
|
+
# body=nil,
|
24
|
+
# participantIds=nil,
|
25
|
+
# data:nil,
|
26
|
+
# hash:nil
|
27
|
+
# )
|
28
|
+
# if !data.nil?
|
29
|
+
# parse(data)
|
30
|
+
# elsif !hash.nil?
|
31
|
+
# process_hash(hash)
|
32
|
+
# elsif !id(_id).nil?
|
33
|
+
# Event::get(self)
|
34
|
+
# end
|
35
|
+
# participantIds(participantIds)
|
36
|
+
# subject(subject)
|
37
|
+
# body(body)
|
38
|
+
# end
|
39
|
+
|
40
|
+
# class << self
|
41
|
+
# def node
|
42
|
+
# 'events'
|
43
|
+
# end
|
44
|
+
|
45
|
+
# def factory(data = nil, hash = nil)
|
46
|
+
# return Event.new(data, hash)
|
47
|
+
# end
|
48
|
+
|
49
|
+
# def update(instance, options = {})
|
50
|
+
# response = Client::put(self.endpoint(), instance.payload(), options)
|
51
|
+
# return instance
|
52
|
+
# end
|
53
|
+
# end
|
54
|
+
|
55
|
+
# def parse(data)
|
56
|
+
# obj = JSON.parse(data.body)
|
57
|
+
# id(obj['id'])
|
58
|
+
# modifiedDate(obj['modifiedDate'])
|
59
|
+
# end
|
60
|
+
|
61
|
+
# def process_hash(hash)
|
62
|
+
# id(hash['id'])
|
63
|
+
# modifiedDate(hash['modifiedDate'])
|
64
|
+
# end
|
65
|
+
|
66
|
+
# # Data Payload
|
67
|
+
# def payload()
|
68
|
+
# payload = {:participantIds => @participantIds,
|
69
|
+
# :subject => subject(),
|
70
|
+
# :body => body()
|
71
|
+
# }
|
72
|
+
# if modifiedDate() then
|
73
|
+
# payload['modifiedDate'] = modifiedDate()
|
74
|
+
# end
|
75
|
+
# payload['id'] = id() if id()
|
76
|
+
# return payload
|
77
|
+
# end
|
78
|
+
|
79
|
+
# # Hybrid
|
80
|
+
# def id(value = nil)
|
81
|
+
# @id = value unless value.nil?
|
82
|
+
# end
|
83
|
+
|
84
|
+
# def modifiedDate(value = nil)
|
85
|
+
# @modifiedDate = value unless value.nil?
|
86
|
+
# end
|
87
|
+
|
88
|
+
# def subject(value = nil)
|
89
|
+
# @subject = value unless value.nil?
|
90
|
+
# end
|
91
|
+
|
92
|
+
# # value should either be a string or a list of strings
|
93
|
+
# # returns: if multiple values exist for key, a list of strings of values
|
94
|
+
# # if a single value exists, return the single string value (not in a list)
|
95
|
+
# # if no values exist, return nil
|
96
|
+
# def participantIds(value = nil)
|
97
|
+
# # set value if passed in
|
98
|
+
# @participantIds = value unless value.nil?
|
99
|
+
# end
|
100
|
+
|
101
|
+
# def body(value=nil)
|
102
|
+
# @body = value unless value.nil?
|
103
|
+
# end
|
104
|
+
# end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
# require_relative 'riq_obj'
|
2
|
+
# require_relative 'batch_manager'
|
3
|
+
|
4
|
+
module RIQ
|
5
|
+
class List < RIQObject
|
6
|
+
# can't create a list through api, so these don't need to write
|
7
|
+
attr_reader :title
|
8
|
+
attr_reader :type
|
9
|
+
attr_reader :list_items
|
10
|
+
# for consistency
|
11
|
+
alias_method :name, :title
|
12
|
+
|
13
|
+
# (see RIQObject#initialize)
|
14
|
+
def initialize(id = nil)
|
15
|
+
super
|
16
|
+
@list_items = ListItemManager.new(@id)
|
17
|
+
end
|
18
|
+
|
19
|
+
# (see RIQObject#node)
|
20
|
+
def node
|
21
|
+
self.class.node(@id)
|
22
|
+
end
|
23
|
+
|
24
|
+
# (see RIQObject#node)
|
25
|
+
def self.node(id = nil)
|
26
|
+
"lists/#{id}"
|
27
|
+
end
|
28
|
+
|
29
|
+
# (see RIQObject#data)
|
30
|
+
def data
|
31
|
+
{
|
32
|
+
id: @id,
|
33
|
+
title: @title,
|
34
|
+
type: @type,
|
35
|
+
fields: @fields
|
36
|
+
}
|
37
|
+
end
|
38
|
+
|
39
|
+
# Overwriting parent because litsts can't be saved through the API
|
40
|
+
def save
|
41
|
+
raise NotImplementedError, "Lists can't be edited through the API"
|
42
|
+
end
|
43
|
+
|
44
|
+
# Gets field if it exists
|
45
|
+
# @param id [String, Integer] field ID
|
46
|
+
# @return [Hash, nil] info on the field specified
|
47
|
+
def fields(id = nil)
|
48
|
+
unless id.nil?
|
49
|
+
@fields.select{|f| f['id'] == id.to_s}.first
|
50
|
+
else
|
51
|
+
@fields
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def list_item(oid = nil)
|
56
|
+
RIQ::ListItem.new(oid, lid: @id)
|
57
|
+
end
|
58
|
+
|
59
|
+
private
|
60
|
+
|
61
|
+
def init(obj = nil)
|
62
|
+
unless obj.nil?
|
63
|
+
@id = obj['id']
|
64
|
+
@title = obj['title']
|
65
|
+
@type = obj['listType']
|
66
|
+
@fields = obj['fields']
|
67
|
+
else
|
68
|
+
@id = nil
|
69
|
+
@title = nil
|
70
|
+
@type = nil
|
71
|
+
@fields = nil
|
72
|
+
end
|
73
|
+
self
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
class << self
|
78
|
+
# Convenince method to create new Lists
|
79
|
+
# @param id [String, nil] create a blank List object or
|
80
|
+
# fetch an existing one by id.
|
81
|
+
# @return [List]
|
82
|
+
def list(id = nil)
|
83
|
+
List.new(id)
|
84
|
+
end
|
85
|
+
# TODO: could also just have #lists that returns whatever i'm supposed to be returning for my generator
|
86
|
+
end
|
87
|
+
end
|
@@ -0,0 +1,115 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
module RIQ
|
4
|
+
class ListItem < RIQObject
|
5
|
+
attr_accessor :name
|
6
|
+
attr_accessor :field_values
|
7
|
+
attr_accessor :account_id
|
8
|
+
attr_accessor :contact_ids
|
9
|
+
attr_accessor :list_id
|
10
|
+
|
11
|
+
attr_reader :modified_date
|
12
|
+
attr_reader :created_date
|
13
|
+
|
14
|
+
def initialize(id = nil, lid: nil)
|
15
|
+
if id.is_a? Hash
|
16
|
+
super(id)
|
17
|
+
elsif id.nil? && lid.nil?
|
18
|
+
super(nil)
|
19
|
+
elsif id.nil? && !lid.nil?
|
20
|
+
super(nil)
|
21
|
+
@list_id = lid
|
22
|
+
elsif id.nil? || lid.nil?
|
23
|
+
raise RIQError, 'ObjectID and List ID are required'
|
24
|
+
else
|
25
|
+
super("#{lid}/listitems/#{id}")
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
# (see RIQObject#node)
|
30
|
+
def node
|
31
|
+
self.class.node(@list_id, @id)
|
32
|
+
end
|
33
|
+
|
34
|
+
# (see #node)
|
35
|
+
def self.node(lid = nil, oid = nil)
|
36
|
+
# weird workaround for fetching node on init
|
37
|
+
if lid.nil? && !oid.nil?
|
38
|
+
"lists/#{oid}"
|
39
|
+
else
|
40
|
+
"lists/#{lid || @list_id}/listitems/#{oid}"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
# (see RIQObject#data)
|
45
|
+
def data
|
46
|
+
{
|
47
|
+
name: @name,
|
48
|
+
account_id: @account_id,
|
49
|
+
contact_ids: @contact_ids.flatten,
|
50
|
+
id: @id,
|
51
|
+
list_id: @list_id,
|
52
|
+
field_values: @field_values,
|
53
|
+
modified_date: @modified_date
|
54
|
+
}
|
55
|
+
end
|
56
|
+
|
57
|
+
# (see RIQObject#payload)
|
58
|
+
def payload
|
59
|
+
pld = {}
|
60
|
+
data.each do |k, v|
|
61
|
+
if k == :field_values
|
62
|
+
pld['fieldValues'] = to_raw(@field_values)
|
63
|
+
elsif k['_']
|
64
|
+
pld[camel_case(k)] = v
|
65
|
+
else
|
66
|
+
pld[k] = v
|
67
|
+
end
|
68
|
+
end
|
69
|
+
pld.to_json
|
70
|
+
end
|
71
|
+
|
72
|
+
# @overload field_value(key)
|
73
|
+
# @param key [String, Integer]
|
74
|
+
# @return [Array] Value of key
|
75
|
+
# @overload field_value(key, value)
|
76
|
+
# Sets key to value
|
77
|
+
# @param key [String, Integer] Key to set
|
78
|
+
# @param value [#to_s] Sets key to value
|
79
|
+
def field_value(key, value = nil)
|
80
|
+
# TODO: double check that this works with arrays of stuff
|
81
|
+
# or, have a format function that casts ints to string on save
|
82
|
+
if value.nil?
|
83
|
+
@field_values.fetch(key.to_s, nil)
|
84
|
+
else
|
85
|
+
@field_values[key.to_s] = value.to_s
|
86
|
+
{key.to_s => value.to_s}
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
private
|
91
|
+
|
92
|
+
def init(obj = nil)
|
93
|
+
unless obj.nil?
|
94
|
+
@id = obj['id']
|
95
|
+
@list_id = obj['listId']
|
96
|
+
@name = obj['name']
|
97
|
+
@field_values = from_raw(obj['fieldValues'])
|
98
|
+
@account_id = obj['accountId']
|
99
|
+
@contact_ids = obj['contactIds']
|
100
|
+
@modified_date = obj['modifiedDate']
|
101
|
+
@created_date = obj['creaetedDate']
|
102
|
+
else
|
103
|
+
@id = nil
|
104
|
+
@list_id = nil
|
105
|
+
@name = nil
|
106
|
+
@field_values = {}
|
107
|
+
@account_id = nil
|
108
|
+
@contact_ids = []
|
109
|
+
@modified_date = nil
|
110
|
+
@created_date = nil
|
111
|
+
end
|
112
|
+
self
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|