contactually-ruby 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE.txt +22 -0
- data/README.md +80 -0
- data/Rakefile +7 -0
- data/lib/contactually-ruby.rb +38 -0
- data/lib/contactually/accounts.rb +22 -0
- data/lib/contactually/api.rb +87 -0
- data/lib/contactually/buckets.rb +49 -0
- data/lib/contactually/contact_groupings.rb +16 -0
- data/lib/contactually/contacts.rb +54 -0
- data/lib/contactually/contents.rb +30 -0
- data/lib/contactually/errors.rb +21 -0
- data/lib/contactually/groupings.rb +36 -0
- data/lib/contactually/middleware/error_detector.rb +31 -0
- data/lib/contactually/notes.rb +31 -0
- data/lib/contactually/representer/account_representer.rb +15 -0
- data/lib/contactually/representer/bucket_representer.rb +16 -0
- data/lib/contactually/representer/contact_representer.rb +48 -0
- data/lib/contactually/representer/content_representer.rb +18 -0
- data/lib/contactually/representer/grouping_representer.rb +30 -0
- data/lib/contactually/representer/grouping_statistic_representer.rb +14 -0
- data/lib/contactually/representer/note_representer.rb +15 -0
- data/lib/contactually/representer/task_representer.rb +21 -0
- data/lib/contactually/tasks.rb +49 -0
- data/lib/contactually/utils.rb +44 -0
- data/lib/contactually/version.rb +3 -0
- data/spec/accounts_spec.rb +58 -0
- data/spec/api_spec.rb +125 -0
- data/spec/buckets_spec.rb +97 -0
- data/spec/contact_groupings_spec.rb +44 -0
- data/spec/contacts_spec.rb +133 -0
- data/spec/contents_spec.rb +80 -0
- data/spec/error_detector_spec.rb +24 -0
- data/spec/fixtures/account.json +10 -0
- data/spec/fixtures/accounts_index.json +19 -0
- data/spec/fixtures/bucket.json +8 -0
- data/spec/fixtures/buckets_index.json +41 -0
- data/spec/fixtures/contact.json +38 -0
- data/spec/fixtures/contacts_index.json +172 -0
- data/spec/fixtures/content.json +10 -0
- data/spec/fixtures/contents_index.json +29 -0
- data/spec/fixtures/grouping.json +19 -0
- data/spec/fixtures/groupings_index.json +28 -0
- data/spec/fixtures/note.json +7 -0
- data/spec/fixtures/note_destroy.json +4 -0
- data/spec/fixtures/notes_index.json +30 -0
- data/spec/fixtures/task.json +27 -0
- data/spec/fixtures/tasks_index.json +41 -0
- data/spec/groupings_spec.rb +85 -0
- data/spec/notes_spec.rb +85 -0
- data/spec/spec_helper.rb +14 -0
- data/spec/tasks_spec.rb +127 -0
- metadata +205 -0
@@ -0,0 +1,36 @@
|
|
1
|
+
module Contactually
|
2
|
+
class Groupings
|
3
|
+
def initialize(master)
|
4
|
+
@master = master
|
5
|
+
end
|
6
|
+
|
7
|
+
def create(params = {})
|
8
|
+
hash = @master.call('groupings.json', :post, params)
|
9
|
+
Contactually::Utils.build_grouping(hash)
|
10
|
+
end
|
11
|
+
|
12
|
+
def index(params = {})
|
13
|
+
hash = @master.call('groupings.json', :get, params)
|
14
|
+
Contactually::Utils.groupings_hash_to_objects(hash)
|
15
|
+
end
|
16
|
+
|
17
|
+
def minimal_index(params = {})
|
18
|
+
hash = @master.call('groupings/minimal_index.json', :get, params)
|
19
|
+
Contactually::Utils.build_grouping(hash)
|
20
|
+
end
|
21
|
+
|
22
|
+
def destroy(id, params = {})
|
23
|
+
@master.call("groupings/#{id}.json", :delete, params)
|
24
|
+
end
|
25
|
+
|
26
|
+
def show(id, params = {})
|
27
|
+
hash = @master.call("groupings/#{id}.json", :get, params)
|
28
|
+
Contactually::Utils.build_grouping(hash)
|
29
|
+
end
|
30
|
+
|
31
|
+
def update(id, params = {})
|
32
|
+
hash = @master.call("groupings/#{id}.json", :put, params)
|
33
|
+
Contactually::Utils.build_grouping(hash)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Contactually
|
2
|
+
module Middleware
|
3
|
+
class ErrorDetector < Faraday::Middleware
|
4
|
+
|
5
|
+
def call(env)
|
6
|
+
@app.call(env).on_complete do |env|
|
7
|
+
unless (200..299).include? env[:status]
|
8
|
+
cast_error(env[:body])
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def cast_error(body)
|
16
|
+
case JSON.parse(body)['error']
|
17
|
+
when /^Invalid parameters/ then
|
18
|
+
raise InvalidParametersError, body
|
19
|
+
when /^We already have/ then
|
20
|
+
raise DuplicatedContactError, body
|
21
|
+
when /^You need to sign in/ then
|
22
|
+
raise AuthenticationError, body
|
23
|
+
else
|
24
|
+
raise APIError, body
|
25
|
+
end
|
26
|
+
rescue JSON::ParserError
|
27
|
+
raise APIError, body
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Contactually
|
2
|
+
class Notes
|
3
|
+
def initialize(master)
|
4
|
+
@master = master
|
5
|
+
end
|
6
|
+
|
7
|
+
def index(params = {})
|
8
|
+
hash = @master.call('notes.json', :get, params)
|
9
|
+
Contactually::Utils.notes_hash_to_objects(hash)
|
10
|
+
end
|
11
|
+
|
12
|
+
def show(id, params = {})
|
13
|
+
hash = @master.call("notes/#{id}.json", :get, params)
|
14
|
+
Contactually::Utils.build_note(hash)
|
15
|
+
end
|
16
|
+
|
17
|
+
def create(params = {})
|
18
|
+
hash = @master.call('notes.json', :post, params)
|
19
|
+
Contactually::Utils.build_note(hash)
|
20
|
+
end
|
21
|
+
|
22
|
+
def destroy(id, params = {})
|
23
|
+
@master.call("notes/#{id}.json", :delete, params)
|
24
|
+
end
|
25
|
+
|
26
|
+
def update(id, params = {})
|
27
|
+
hash = @master.call("notes/#{id}.json", :put, params)
|
28
|
+
Contactually::Utils.build_note(hash)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Contactually
|
2
|
+
class Account < OpenStruct
|
3
|
+
end
|
4
|
+
|
5
|
+
module Representer
|
6
|
+
class AccountRepresenter < Roar::Decorator
|
7
|
+
include Roar::Representer::JSON
|
8
|
+
property :id
|
9
|
+
property :username
|
10
|
+
property :remote_id
|
11
|
+
property :type
|
12
|
+
property :disabled_at
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Contactually
|
2
|
+
class Bucket < OpenStruct
|
3
|
+
end
|
4
|
+
|
5
|
+
module Representer
|
6
|
+
class BucketRepresenter < Roar::Decorator
|
7
|
+
include Roar::Representer::JSON
|
8
|
+
property :id
|
9
|
+
property :name
|
10
|
+
property :goal
|
11
|
+
property :reminder_interval
|
12
|
+
property :created_at
|
13
|
+
property :updated_at
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module Contactually
|
2
|
+
class Contact < OpenStruct
|
3
|
+
end
|
4
|
+
|
5
|
+
module Representer
|
6
|
+
class ContactRepresenter < Roar::Decorator
|
7
|
+
include Roar::Representer::JSON
|
8
|
+
property :id
|
9
|
+
property :user_id
|
10
|
+
property :first_name
|
11
|
+
property :last_name
|
12
|
+
property :full_name
|
13
|
+
property :initials
|
14
|
+
property :title
|
15
|
+
property :company
|
16
|
+
property :email
|
17
|
+
property :avatar
|
18
|
+
property :avatar_url
|
19
|
+
property :last_contacted
|
20
|
+
property :visible
|
21
|
+
property :twitter
|
22
|
+
property :facebook_url
|
23
|
+
property :linkedin_url
|
24
|
+
property :first_contacted
|
25
|
+
property :created_at
|
26
|
+
property :updated_at
|
27
|
+
property :hits
|
28
|
+
property :team_parent_id
|
29
|
+
property :snoozed_at
|
30
|
+
property :snooze_days
|
31
|
+
property :email_addresses
|
32
|
+
property :tags
|
33
|
+
property :contact_status
|
34
|
+
property :team_last_contacted
|
35
|
+
property :team_last_contacted_by
|
36
|
+
property :phone_numbers
|
37
|
+
property :addresses
|
38
|
+
property :social_profiles
|
39
|
+
property :websites
|
40
|
+
property :custom_fields
|
41
|
+
property :sent
|
42
|
+
property :received
|
43
|
+
property :link
|
44
|
+
property :content
|
45
|
+
collection :groupings, extend: GroupingRepresenter, class: Grouping
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Contactually
|
2
|
+
class Content < OpenStruct
|
3
|
+
end
|
4
|
+
|
5
|
+
module Representer
|
6
|
+
class ContentRepresenter < Roar::Decorator
|
7
|
+
include Roar::Representer::JSON
|
8
|
+
property :id
|
9
|
+
property :user_id
|
10
|
+
property :url
|
11
|
+
property :title
|
12
|
+
property :description
|
13
|
+
property :article
|
14
|
+
property :original_content_id
|
15
|
+
collection :groupings, extend: GroupingRepresenter, class: Grouping
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Contactually
|
2
|
+
class Grouping < OpenStruct
|
3
|
+
end
|
4
|
+
|
5
|
+
module Representer
|
6
|
+
class GroupingRepresenter < Roar::Decorator
|
7
|
+
include Roar::Representer::JSON
|
8
|
+
property :id
|
9
|
+
property :type
|
10
|
+
property :name
|
11
|
+
property :stub
|
12
|
+
property :user_id
|
13
|
+
property :domain_id
|
14
|
+
property :editable
|
15
|
+
property :conversable
|
16
|
+
property :locked
|
17
|
+
property :derived_from_id
|
18
|
+
property :created_at
|
19
|
+
property :updated_at
|
20
|
+
property :has_followups
|
21
|
+
property :num_days_to_followup
|
22
|
+
property :program_id
|
23
|
+
property :objective
|
24
|
+
property :sort_order
|
25
|
+
property :accounts
|
26
|
+
property :number_of_contacts
|
27
|
+
property :goal
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Contactually
|
2
|
+
class GroupingStatistic < OpenStruct
|
3
|
+
end
|
4
|
+
|
5
|
+
module Representer
|
6
|
+
class GroupingStatisticRepresenter < Roar::Decorator
|
7
|
+
include Roar::Representer::JSON
|
8
|
+
property :messages_sent
|
9
|
+
property :messages_received
|
10
|
+
property :status
|
11
|
+
collection :contacts, extend: ContactRepresenter, class: Contact
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Contactually
|
2
|
+
class Note < OpenStruct
|
3
|
+
end
|
4
|
+
|
5
|
+
module Representer
|
6
|
+
class NoteRepresenter < Roar::Decorator
|
7
|
+
include Roar::Representer::JSON
|
8
|
+
property :id
|
9
|
+
property :body
|
10
|
+
property :contact_id
|
11
|
+
property :timestamp
|
12
|
+
property :user_id
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Contactually
|
2
|
+
class Task < OpenStruct
|
3
|
+
end
|
4
|
+
|
5
|
+
module Representer
|
6
|
+
class TaskRepresenter < Roar::Decorator
|
7
|
+
include Roar::Representer::JSON
|
8
|
+
property :id
|
9
|
+
property :title
|
10
|
+
property :due_date
|
11
|
+
property :completed_at
|
12
|
+
property :deleted_at
|
13
|
+
property :is_follow_up
|
14
|
+
property :last_contacted
|
15
|
+
property :contact_id
|
16
|
+
property :ignored
|
17
|
+
property :completed_via
|
18
|
+
property :approval_data
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module Contactually
|
2
|
+
class Tasks
|
3
|
+
def initialize(master)
|
4
|
+
@master = master
|
5
|
+
end
|
6
|
+
|
7
|
+
def show(id, params = {})
|
8
|
+
hash = @master.call("tasks/#{id}.json", :get, params)
|
9
|
+
Contactually::Utils.build_task(hash)
|
10
|
+
end
|
11
|
+
|
12
|
+
def complete(id, params = {})
|
13
|
+
hash = @master.call("tasks/#{id}/complete.json", :post, params)
|
14
|
+
Contactually::Utils.build_task(hash)
|
15
|
+
end
|
16
|
+
|
17
|
+
def create(params = {})
|
18
|
+
hash = @master.call('tasks.json', :post, params)
|
19
|
+
Contactually::Utils.build_task(hash)
|
20
|
+
end
|
21
|
+
|
22
|
+
def destroy(id, params = {})
|
23
|
+
@master.call("tasks/#{id}.json", :delete, params)
|
24
|
+
end
|
25
|
+
|
26
|
+
def generate_followups(params = {})
|
27
|
+
@master.call('tasks/generate_followups.json', :post, params)
|
28
|
+
end
|
29
|
+
|
30
|
+
def ignore(id, params = {})
|
31
|
+
hash = @master.call("tasks/#{id}/ignore.json", :post, params)
|
32
|
+
Contactually::Utils.build_task(hash)
|
33
|
+
end
|
34
|
+
|
35
|
+
def index(params = {})
|
36
|
+
hash = @master.call('tasks.json', :get, params)
|
37
|
+
Contactually::Utils.tasks_hash_to_objects(hash)
|
38
|
+
end
|
39
|
+
|
40
|
+
def snooze(id, params = {})
|
41
|
+
@master.call("tasks/#{id}/snooze.json", :post, params)
|
42
|
+
end
|
43
|
+
|
44
|
+
def update(id, params = {})
|
45
|
+
hash = @master.call("tasks/#{id}.json", :put, params)
|
46
|
+
Contactually::Utils.build_task(hash)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module Contactually
|
2
|
+
class Utils
|
3
|
+
|
4
|
+
class << self
|
5
|
+
def method_missing(m, *args)
|
6
|
+
case m
|
7
|
+
when /^(\w*)_hash_to_objects/ then
|
8
|
+
hash_to_objects($1, *args)
|
9
|
+
when /^build_(\w*)/ then
|
10
|
+
build_object($1, *args)
|
11
|
+
else
|
12
|
+
super(m, *args)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def respond_to?(m, *args)
|
17
|
+
case m
|
18
|
+
when /^(\w*)_hash_to_objects/ then
|
19
|
+
true
|
20
|
+
when /^build_(\w*)/ then
|
21
|
+
true
|
22
|
+
else
|
23
|
+
super(m, *args)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def hash_to_objects(type, hash)
|
30
|
+
representer_class = "Contactually::Representer::#{type.classify}Representer".constantize
|
31
|
+
object_class = "Contactually::#{type.classify}".constantize
|
32
|
+
hash['data'].inject([]) do |arr, obj|
|
33
|
+
arr << representer_class.new(object_class.new).from_hash(obj)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def build_object(type, hash)
|
38
|
+
representer_class = "Contactually::Representer::#{type.classify}Representer".constantize
|
39
|
+
object_class = "Contactually::#{type.classify}".constantize
|
40
|
+
representer_class.new(object_class.new).from_hash(hash)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Contactually::Accounts do
|
4
|
+
|
5
|
+
let(:account_json) { File.read(File.join(File.dirname(__FILE__),"fixtures/account.json")) }
|
6
|
+
let(:accounts_index_json) { File.read(File.join(File.dirname(__FILE__),"fixtures/accounts_index.json")) }
|
7
|
+
|
8
|
+
before(:all) do
|
9
|
+
Contactually.configure { |c| c.access_token = 'VALID_ACCESS_TOKEN' }
|
10
|
+
@master = Contactually::API.new
|
11
|
+
end
|
12
|
+
|
13
|
+
subject { described_class.new @master }
|
14
|
+
describe '#initialize' do
|
15
|
+
specify do
|
16
|
+
expect(subject).to be_kind_of Contactually::Accounts
|
17
|
+
end
|
18
|
+
|
19
|
+
specify do
|
20
|
+
expect(subject.instance_variable_get(:@master)).to be_kind_of Contactually::API
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe '#index' do
|
25
|
+
it 'calls the api with correct params' do
|
26
|
+
allow(@master).to receive(:call).with('accounts.json', :get, { foo: :bar }).and_return({ 'data' => [] })
|
27
|
+
subject.index({ foo: :bar })
|
28
|
+
expect(@master).to have_received(:call)
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'returns accounts from json response' do
|
32
|
+
allow(@master).to receive(:call).with('accounts.json', :get, {}).and_return(JSON.load(accounts_index_json))
|
33
|
+
expect(subject.index({})).to be_kind_of Array
|
34
|
+
expect(subject.index({})[0]).to be_kind_of Contactually::Account
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
describe '#show' do
|
39
|
+
it 'calls the api with correct params' do
|
40
|
+
allow(@master).to receive(:call).with('accounts/1.json', :get, { foo: :bar }).and_return({ id: 1 })
|
41
|
+
subject.show(1, { foo: :bar })
|
42
|
+
expect(@master).to have_received(:call)
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'returns an account' do
|
46
|
+
allow(@master).to receive(:call).with('accounts/1.json', :get, { foo: :bar }).and_return(JSON.load(account_json))
|
47
|
+
expect(subject.show(1, { foo: :bar })).to be_kind_of Contactually::Account
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
describe '#destroy' do
|
52
|
+
it 'calls the api with correct params' do
|
53
|
+
allow(@master).to receive(:call).with('accounts/1.json', :delete, {})
|
54
|
+
subject.destroy(1)
|
55
|
+
expect(@master).to have_received(:call)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|