riq 1.0.1 → 1.0.2

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.
@@ -0,0 +1,158 @@
1
+ require_relative 'riq_obj'
2
+ using RIQExtensions
3
+
4
+ module RIQ
5
+ # Contacts represent people in an Organization’s address book.
6
+ class Contact < RIQObject
7
+ attr_accessor :properties
8
+
9
+ # (see RIQObject#node)
10
+ def node
11
+ self.class.node(@id)
12
+ end
13
+
14
+ # (see RIQObject.node)
15
+ def self.node(id = nil)
16
+ "contacts/#{id}"
17
+ end
18
+
19
+ # (see RIQObject#data)
20
+ def data
21
+ {
22
+ id: @id,
23
+ properties: @properties
24
+ # modified_date: @modified_date
25
+ }
26
+ end
27
+
28
+ # @!macro [new] prop
29
+ # @return [Array] all of the values for $0
30
+ def name
31
+ get_prop(:name)
32
+ end
33
+
34
+ # @macro prop
35
+ def phone
36
+ get_prop(:phone)
37
+ end
38
+
39
+ # @macro prop
40
+ def email
41
+ get_prop(:email)
42
+ end
43
+
44
+ # @macro prop
45
+ def address
46
+ get_prop(:address)
47
+ end
48
+
49
+ # Adds property with correct scaffolding
50
+ # @param prop [Symbol] Type Property to add, such as :name or :email
51
+ # @param val [String, Array] Value(s) to add
52
+ # @return [Array] Values for that property after the add
53
+ def add(prop, val)
54
+ # validate(prop)
55
+ prop = prop.to_sym
56
+ @properties[prop] = [] unless @properties.include? prop
57
+
58
+ if val.is_a? Array
59
+ val.each do |i|
60
+ add(prop, i)
61
+ end
62
+ return
63
+ end
64
+
65
+ raise RIQError, 'Values must be strings' unless val.is_a? String
66
+
67
+ # don't add duplicate
68
+ if @properties[prop].select{|p| p[:value] == val}.empty?
69
+ @properties[prop] << {value: val, metadata: {}}
70
+ end
71
+ send(prop)
72
+ end
73
+
74
+ # Removes property from hash
75
+ # @param prop [Symbol] Type Property to remove, such as :name or :email
76
+ # @param val [String, Array] Value(s) to remove
77
+ # @return [Array] Values for that property after the remove
78
+ def remove(prop, val)
79
+ # validate(prop)
80
+ prop = prop.to_sym
81
+
82
+ if val.is_a? Array
83
+ val.each do |i|
84
+ remove(prop, i)
85
+ end
86
+ end
87
+
88
+ if @properties.include? prop
89
+ @properties[prop] = @properties[prop].reject{|p| p[:value] == val}
90
+ end
91
+ send(prop)
92
+ end
93
+
94
+ # Edits an existing object based on matching email(s) or saves a new object
95
+ # @see RIQObject#save
96
+ def upsert
97
+ save({_upsert: 'email'})
98
+ end
99
+
100
+ # @param prop [Symbol] The property to fetch. One of [:name, :phone, :email, :address]
101
+ # @param val [String] The value to get info on, such as 'name@domain.com'
102
+ # @return [Hash] metadata and other info about a given property
103
+ def info(prop, val)
104
+ # validate(prop)
105
+
106
+ @properties[prop].select{|p| p[:value] == val}.first
107
+ end
108
+
109
+ private
110
+
111
+ def init(obj = nil)
112
+ unless obj.nil?
113
+ @id = obj[:id]
114
+ @modified_date = obj[:modified_date].cut_milis if obj[:modified_date]
115
+ @properties = {}
116
+ obj[:properties].each do |k,v|
117
+ raise RIQError, "Properties must be arrays, #{k} wasn't" if !v.is_a?(Array)
118
+
119
+ v.each do |i|
120
+ unless i.is_a?(Hash)
121
+ add(k, i)
122
+ else
123
+ @properties[k] = [] unless @properties.include?(k)
124
+ @properties[k] << i
125
+ end
126
+ end
127
+ end
128
+ else
129
+ @id = nil
130
+ @properties = {}
131
+ end
132
+ self
133
+ end
134
+
135
+ # unused because we actually put all sorts of stuff in there
136
+ def validate(prop)
137
+ raise RIQError, %q(Invalid property. Use [:name | :phone | :email | :address] instead) unless [:name, :phone, :email, :address].include? prop
138
+ end
139
+
140
+ def get_prop(prop)
141
+ if @properties.include? prop
142
+ @properties[prop].map{|p| p[:value]}
143
+ else
144
+ []
145
+ end
146
+ end
147
+ end
148
+
149
+ class << self
150
+ # Convenience method to create new Contacts
151
+ # @param id [String, nil] create a blank Contact object or
152
+ # fetch an existing one by id.
153
+ # @return [Contact]
154
+ def contact(id = nil)
155
+ Contact.new(id)
156
+ end
157
+ end
158
+ end
@@ -0,0 +1,56 @@
1
+ module RIQ
2
+ # Base exception class for our errors.
3
+ class RIQError < StandardError
4
+ end
5
+
6
+ # Hasn't been implemented yet. Doesn't get used often.
7
+ class NotImplementedError < RIQError
8
+ end
9
+
10
+ # Raised when an ObjectId fetch doesn't return anything.
11
+ class NotFoundError < RIQError
12
+ end
13
+
14
+ # Main error that includes info about the request and what went wrong.
15
+ class HTTPError < RIQError
16
+ attr_accessor :code
17
+ attr_accessor :message
18
+ attr_accessor :response
19
+
20
+ def initialize(resp)
21
+ # build response message
22
+ message = "\n[#{resp.code}] #{resp.message} : "
23
+ unless resp.parsed_response.nil?
24
+ begin
25
+ m = resp.parsed_response.fetch('errorMessage', 'no message')
26
+ rescue
27
+ # parse returned HTML
28
+ reg = resp.parsed_response.match(/<pre>(.*)<\/pre>/)
29
+ unless reg.nil?
30
+ m = reg[1].strip
31
+ else
32
+ m = 'no message'
33
+ end
34
+ end
35
+ message += "<#{m}>"
36
+ end
37
+
38
+ # pull out request info
39
+ req = resp.request
40
+ unless req.nil?
41
+ message += "\n Request: #{req.http_method} #{req.last_uri.to_s}"
42
+ unless req.raw_body.nil?
43
+ message += "\n #{req.raw_body}"
44
+ end
45
+ end
46
+
47
+ @message = message
48
+ @response = resp
49
+ end
50
+
51
+ # used to print the error nicely
52
+ def to_s
53
+ @message || super
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,73 @@
1
+ require_relative 'riq_obj'
2
+ using RIQExtensions
3
+
4
+ module RIQ
5
+ # Events represent interactions involving a Contact associated with a List Item.
6
+ class Event < RIQObject
7
+ attr_accessor :subject
8
+ attr_accessor :body
9
+ # attr_reader :participant_ids
10
+
11
+ # (see RIQObject#node)
12
+ def node
13
+ self.class.node
14
+ end
15
+
16
+ # (see RIQObject#node)
17
+ def self.node
18
+ "events"
19
+ end
20
+
21
+ # (see RIQObject#data)
22
+ def data
23
+ {
24
+ subject: @subject,
25
+ body: @body,
26
+ participant_ids: @participant_ids
27
+ }
28
+ end
29
+
30
+ # @param type [Symbol] One of :email or :phone
31
+ # @param value [String] An email or phone number for the contact
32
+ def add_participant(type, value)
33
+ raise RIQError, 'Type must be :email or :phone' unless [:email, :phone].include?(type)
34
+ @participant_ids << {type: type, value: value}
35
+ end
36
+
37
+ # @return [Array] Immutable copy of participant_ids
38
+ def participant_ids
39
+ @participant_ids.dup
40
+ end
41
+
42
+ # @return [Hash] Success message, if successful.
43
+ def save
44
+ # there are no options to pass for event save
45
+ @client.put(node, payload, options: nil)
46
+ {status: 204, message: 'No Content'}
47
+ end
48
+
49
+ private
50
+ def init(obj = nil)
51
+ unless obj.nil?
52
+ @subject = obj[:subject]
53
+ @body = obj[:body]
54
+ @participant_ids = []
55
+ obj[:participant_ids].each{|o| add_participant(o[:type], o[:value])}
56
+ else
57
+ @subject = nil
58
+ @body = nil
59
+ @participant_ids = []
60
+ end
61
+ self
62
+ end
63
+ end
64
+
65
+ class << self
66
+ # Convenience method to create new Events
67
+ # @param obj [Hash] Info to parse into event
68
+ # @return [Event]
69
+ def event(obj = nil)
70
+ Event.new(obj)
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,89 @@
1
+ require_relative 'riq_obj'
2
+
3
+ module RIQ
4
+ # A List is an object that can be created and customized by a User to represent
5
+ # Accounts (companies) or Contacts (people) in a process (such as a sales pipeline).
6
+ class List < RIQObject
7
+ # can't create a list through API, so these don't need to write
8
+ attr_reader :title
9
+ attr_reader :type
10
+ attr_reader :list_items
11
+ # for consistency
12
+ alias_method :name, :title
13
+
14
+ # (see RIQObject#initialize)
15
+ def initialize(id = nil)
16
+ super
17
+ @list_items = ListItemManager.new(@id)
18
+ end
19
+
20
+ # (see RIQObject#node)
21
+ def node
22
+ self.class.node(@id)
23
+ end
24
+
25
+ # (see RIQObject.node)
26
+ def self.node(id = nil)
27
+ "lists/#{id}"
28
+ end
29
+
30
+ # (see RIQObject#data)
31
+ def data
32
+ {
33
+ id: @id,
34
+ title: @title,
35
+ type: @type,
36
+ fields: @fields
37
+ }
38
+ end
39
+
40
+ # Overwriting parent because lists can't be saved through the API
41
+ def save
42
+ raise NotImplementedError, "Lists can't be edited through the API"
43
+ end
44
+
45
+ # Gets field if it exists
46
+ # @param id [String, Integer] field ID
47
+ # @return [Hash, nil] info on the field specified
48
+ def fields(id = nil)
49
+ unless id.nil?
50
+ @fields.select{|f| f['id'] == id.to_s}.first
51
+ else
52
+ @fields
53
+ end
54
+ end
55
+
56
+ # Convenience method for fetching or creating a listitem from the given list
57
+ # @param oid [String, nil] ObjectId
58
+ def list_item(oid = nil)
59
+ RIQ::ListItem.new(oid, lid: @id)
60
+ end
61
+
62
+ private
63
+
64
+ def init(obj = nil)
65
+ unless obj.nil?
66
+ @id = obj[:id]
67
+ @title = obj[:title]
68
+ @type = obj[:listType]
69
+ @fields = obj[:fields]
70
+ else
71
+ @id = nil
72
+ @title = nil
73
+ @type = nil
74
+ @fields = nil
75
+ end
76
+ self
77
+ end
78
+ end
79
+
80
+ class << self
81
+ # Convenience method to create new Lists
82
+ # @param id [String, nil] create a blank List object or
83
+ # fetch an existing one by id.
84
+ # @return [List]
85
+ def list(id = nil)
86
+ List.new(id)
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,119 @@
1
+ require_relative 'riq_obj'
2
+ using RIQExtensions
3
+
4
+ module RIQ
5
+ # A List Item is a row in a List.
6
+ class ListItem < RIQObject
7
+ attr_accessor :name
8
+ attr_accessor :field_values
9
+ attr_accessor :account_id
10
+ attr_accessor :contact_ids
11
+ attr_accessor :list_id
12
+
13
+ attr_reader :modified_date
14
+ attr_reader :created_date
15
+
16
+ def initialize(id = nil, lid: nil)
17
+ if id.is_a? Hash
18
+ super(id)
19
+ elsif id.nil? && lid.nil?
20
+ super(nil)
21
+ elsif id.nil? && !lid.nil?
22
+ super(nil)
23
+ @list_id = lid
24
+ elsif id.nil? || lid.nil?
25
+ raise RIQError, 'ObjectID and List ID are required'
26
+ else
27
+ super("#{lid}/listitems/#{id}")
28
+ end
29
+ end
30
+
31
+ # (see RIQObject#node)
32
+ def node
33
+ self.class.node(@list_id, @id)
34
+ end
35
+
36
+ # @note this is the only object for which you have to include two params
37
+ # @param lid [String] ListId that the lit item belongs to
38
+ # @param oid [String] ObjectId for the object
39
+ def self.node(lid = nil, oid = nil)
40
+ # weird workaround for fetching node on init
41
+ if lid.nil? && !oid.nil?
42
+ "lists/#{oid}"
43
+ else
44
+ "lists/#{lid || @list_id}/listitems/#{oid}"
45
+ end
46
+ end
47
+
48
+ # (see RIQObject#data)
49
+ def data
50
+ {
51
+ name: @name,
52
+ account_id: @account_id,
53
+ contact_ids: @contact_ids.flatten,
54
+ id: @id,
55
+ list_id: @list_id,
56
+ field_values: @field_values,
57
+ modified_date: @modified_date
58
+ }
59
+ end
60
+
61
+ # (see RIQObject#payload)
62
+ def payload
63
+ pld = {}
64
+ data.each do |k, v|
65
+ if k == :field_values
66
+ pld['fieldValues'] = @field_values.to_raw
67
+ elsif k['_']
68
+ pld[k.to_cam] = v
69
+ else
70
+ pld[k] = v
71
+ end
72
+ end
73
+ pld.to_json
74
+ end
75
+
76
+ # @overload field_value(key)
77
+ # @param key [String, Integer]
78
+ # @return [Array] Value of key
79
+ # @overload field_value(key, value)
80
+ # Sets key to value
81
+ # @param key [String, Integer] Key to set
82
+ # @param value [#to_s] Sets key to value
83
+ def field_value(key, value = nil)
84
+ # TODO: double check that this works with arrays of stuff
85
+ # or, have a format function that casts ints to string on save
86
+ if value.nil?
87
+ @field_values.fetch(key.to_sym, nil)
88
+ else
89
+ @field_values[key.to_sym] = value.to_s
90
+ {key.to_sym => value.to_s}
91
+ end
92
+ end
93
+
94
+ private
95
+
96
+ def init(obj = nil)
97
+ unless obj.nil?
98
+ @id = obj[:id]
99
+ @list_id = obj[:list_id]
100
+ @name = obj[:name]
101
+ @field_values = obj[:field_values] ? obj[:field_values].from_raw : {}
102
+ @account_id = obj[:account_id]
103
+ @contact_ids = obj[:contact_ids] || []
104
+ @modified_date = obj[:modified_date].cut_milis if obj[:modified_date]
105
+ @created_date = obj[:creaeted_date].cut_milis if obj[:creaeted_date]
106
+ else
107
+ @id = nil
108
+ @list_id = nil
109
+ @name = nil
110
+ @field_values = {}
111
+ @account_id = nil
112
+ @contact_ids = []
113
+ @modified_date = nil
114
+ @created_date = nil
115
+ end
116
+ self
117
+ end
118
+ end
119
+ end