agilecrm-wrapper 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 926e3d0e0645d675a68fdec939471f5e3693b2f6
4
+ data.tar.gz: e295958f5c71c25e047de65096a77ce2d1c0f128
5
+ SHA512:
6
+ metadata.gz: 405466b4f3e9e937ef85c714da1615d1283ff213ad69bb471c2496082747f7509a5208eeeeb2ff3d7d4b1e4b0749119dd74ef53f5ffa15d63ad34b7a8216d353
7
+ data.tar.gz: 904226678f44055def597b3f0684e49500b7473367944cd577b1c30d587a00d144b44018bcc7bd3dfd862fdb47fcbf56851717f293fe9f38caeafd3f6961d7b7
@@ -0,0 +1,20 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ coverage
6
+ InstalledFiles
7
+ lib/bundler/man
8
+ pkg
9
+ rdoc
10
+ spec/reports
11
+ test/tmp
12
+ test/version_tmp
13
+ tmp
14
+
15
+ # YARD artifacts
16
+ .yardoc
17
+ _yardoc
18
+ doc/
19
+ todo.txt
20
+ agile.js
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --require spec_helper
@@ -0,0 +1,9 @@
1
+ Style/Documentation:
2
+ Enabled: false
3
+
4
+ Style/RaiseArgs:
5
+ Enabled: false
6
+
7
+ Metrics/MethodLength:
8
+ CountComments: false
9
+ Max: 15
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in agilecrm-ruby-api.gemspec
4
+ gemspec
@@ -0,0 +1,89 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ agilecrm-wrapper (1.0.0)
5
+ faraday
6
+ faraday_middleware
7
+ hashie
8
+ json
9
+
10
+ GEM
11
+ remote: https://rubygems.org/
12
+ specs:
13
+ addressable (2.3.6)
14
+ ast (2.0.0)
15
+ astrolabe (1.3.0)
16
+ parser (>= 2.2.0.pre.3, < 3.0)
17
+ awesome_print (1.2.0)
18
+ coderay (1.1.0)
19
+ crack (0.4.2)
20
+ safe_yaml (~> 1.0.0)
21
+ diff-lcs (1.2.5)
22
+ faraday (0.9.0)
23
+ multipart-post (>= 1.2, < 3)
24
+ faraday_middleware (0.9.1)
25
+ faraday (>= 0.7.4, < 0.10)
26
+ hashie (3.3.1)
27
+ json (1.8.1)
28
+ method_source (0.8.2)
29
+ multipart-post (2.0.0)
30
+ parser (2.2.0.pre.5)
31
+ ast (>= 1.1, < 3.0)
32
+ slop (~> 3.4, >= 3.4.5)
33
+ powerpack (0.0.9)
34
+ pry (0.10.1)
35
+ coderay (~> 1.1.0)
36
+ method_source (~> 0.8.1)
37
+ slop (~> 3.4)
38
+ rack (1.5.2)
39
+ rack-protection (1.5.3)
40
+ rack
41
+ rainbow (2.0.0)
42
+ rake (10.3.2)
43
+ rspec (3.1.0)
44
+ rspec-core (~> 3.1.0)
45
+ rspec-expectations (~> 3.1.0)
46
+ rspec-mocks (~> 3.1.0)
47
+ rspec-core (3.1.5)
48
+ rspec-support (~> 3.1.0)
49
+ rspec-expectations (3.1.2)
50
+ diff-lcs (>= 1.2.0, < 2.0)
51
+ rspec-support (~> 3.1.0)
52
+ rspec-its (1.0.1)
53
+ rspec-core (>= 2.99.0.beta1)
54
+ rspec-expectations (>= 2.99.0.beta1)
55
+ rspec-mocks (3.1.2)
56
+ rspec-support (~> 3.1.0)
57
+ rspec-support (3.1.1)
58
+ rubocop (0.26.1)
59
+ astrolabe (~> 1.3)
60
+ parser (>= 2.2.0.pre.4, < 3.0)
61
+ powerpack (~> 0.0.6)
62
+ rainbow (>= 1.99.1, < 3.0)
63
+ ruby-progressbar (~> 1.4)
64
+ ruby-progressbar (1.6.0)
65
+ safe_yaml (1.0.4)
66
+ sinatra (1.4.5)
67
+ rack (~> 1.4)
68
+ rack-protection (~> 1.4)
69
+ tilt (~> 1.3, >= 1.3.4)
70
+ slop (3.6.0)
71
+ tilt (1.4.1)
72
+ webmock (1.19.0)
73
+ addressable (>= 2.3.6)
74
+ crack (>= 0.3.2)
75
+
76
+ PLATFORMS
77
+ ruby
78
+
79
+ DEPENDENCIES
80
+ agilecrm-wrapper!
81
+ awesome_print
82
+ bundler (~> 1.6)
83
+ pry
84
+ rake
85
+ rspec
86
+ rspec-its
87
+ rubocop
88
+ sinatra
89
+ webmock
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2014 Cogmation Robotics Inc.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,119 @@
1
+ AgileCRMWrapper
2
+ =================
3
+
4
+ This project is a ruby client that wraps the [AgileCRM REST API](https://www.agilecrm.com/api/rest). **Note: This is not an official project, you're welcome to use it but don't expect the AgileCRM team to support it.**
5
+
6
+ At present, only operations related to the **contact** and **note** resources are supported. Need something added? Make a feature request in the issues tab. Pull requests are always welcome.
7
+
8
+ ## Installation
9
+
10
+ Add this line to your application's Gemfile:
11
+
12
+ gem 'agilecrm-wrapper'
13
+
14
+ And then execute:
15
+
16
+ $ bundle
17
+
18
+ # Usage
19
+
20
+ To begin using this gem, Initialize the library using a configuration block including your agile **API key**, **email**, and **domain**, like this:
21
+
22
+ ```ruby
23
+ AgileCRMWrapper.configure do |config|
24
+ config.api_key = 'XXXXXXXXXXX'
25
+ config.domain = 'my-agile-domain'
26
+ config.email = 'myemail@example.com'
27
+ end
28
+ ```
29
+
30
+ ### 1. Working with Contacts
31
+
32
+ **GET** operations return one or more `AgileCRMWrapper::Contact` objects. These are just `Hashie::Mash` objects with a few utility methods sprinkled on. You can access any of the Contact fields returned by AgileCRM's REST API, see [here](https://www.agilecrm.com/api/rest#contact-fields) for what that entails. Example:
33
+ ```ruby
34
+ contact = AgileCRMWrapper::Contact.find(123)
35
+ contact.tags #=> ["tag", "your", "it"]
36
+ contact.id #=> 123
37
+ contact.properties #=> [{ type: 'SYSTEM', name: "email", value: "blah@mail.com" }]
38
+ ```
39
+
40
+ ###### To retrieve a list of contacts
41
+ ```ruby
42
+ AgileCRMWrapper::Contact.all
43
+ ```
44
+
45
+ ###### To get an individual contact by ID
46
+ ```ruby
47
+ AgileCRMWrapper::Contact.find(123)
48
+ ```
49
+
50
+ ###### To find contacts by email
51
+ ```ruby
52
+ contact = AgileCRMWrapper::Contact.search_by_email("foo@example.com")
53
+ # or pass multiple emails as seperate arguments or an array
54
+ contacts = AgileCRMWrapper::Contact.search_by_email(
55
+ "foo@example.com", "bar@example.com"
56
+ )
57
+ ```
58
+
59
+ ###### To create a new contact
60
+ ```ruby
61
+ AgileCRMWrapper::Contact.create(
62
+ tags: ["tag", "your", "it"],
63
+ first_name: "Justin",
64
+ last_name: "Case",
65
+ email: "blah@mail.com",
66
+ my_custom_field: "im a custom field!"
67
+ )
68
+ ```
69
+
70
+ ###### To update a single contact
71
+ ```ruby
72
+ contact.update(first_name: "Foo", last_name: "Bar", tags: ["new_tag"])
73
+ ```
74
+
75
+ Note, tags specified in `update` will simply be added to the existing list of tags.
76
+
77
+ ###### To delete a single contact
78
+ ```ruby
79
+ # perform operation directly
80
+ AgileCRMWrapper::Contact.delete(123)
81
+ # or
82
+ AgileCRMWrapper::Contact.find(123).destroy
83
+ ```
84
+
85
+ ###### Convenient access to properties hash values
86
+ ```ruby
87
+ contact.get_property("email") #=> "blah@mail.com"
88
+ contact.get_propety("my_custom_field") #=> "im a custom field!"
89
+ contact.get_property("unkown_attribute") #=> nil
90
+ ```
91
+
92
+ ### 2. Working with Notes
93
+
94
+ ###### To create a new note
95
+ ```ruby
96
+ AgileCRMWrapper::Note.create(
97
+ subject: "My Note",
98
+ description: "My notes's description.",
99
+ contact_ids: ["123"]
100
+ )
101
+ ```
102
+
103
+ ###### To add a Note to a Contact using Email-ID
104
+ ```ruby
105
+ AgileCRMWrapper::Note.add_by_email(
106
+ email: "blah@mail.com",
107
+ subject: "My Note",
108
+ description: "My notes's description."
109
+ )
110
+ ```
111
+
112
+
113
+ ## Contributing
114
+
115
+ 1. Fork it ( https://github.com/nozpheratu/agilecrm-wrapper/fork )
116
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
117
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
118
+ 4. Push to the branch (`git push origin my-new-feature`)
119
+ 5. Create a new Pull Request
@@ -0,0 +1,10 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task default: :spec
7
+
8
+ task :console do
9
+ exec 'pry -r agilecrm-wrapper -I ./lib'
10
+ end
@@ -0,0 +1,35 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'agilecrm-wrapper/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'agilecrm-wrapper'
8
+ spec.version = AgileCRMWrapper::VERSION
9
+ spec.authors = ['Cyle']
10
+ spec.email = ['cylehunter33@gmail.com']
11
+ spec.summary = 'Ruby wrapper for Agile CRM API.'
12
+ spec.description = 'Ruby wrapper for Agile CRM API.'
13
+ spec.homepage = 'https://github.com/nozpheratu/agilecrm-wrapper'
14
+ spec.license = 'MIT'
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(/^bin/) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(/^(test|spec|features)/)
19
+ spec.require_paths = ['lib']
20
+
21
+ spec.add_dependency 'faraday'
22
+ spec.add_dependency 'faraday_middleware'
23
+ spec.add_dependency 'hashie'
24
+ spec.add_dependency 'json'
25
+
26
+ spec.add_development_dependency 'rubocop'
27
+ spec.add_development_dependency 'bundler', '~> 1.6'
28
+ spec.add_development_dependency 'rake'
29
+ spec.add_development_dependency 'rspec'
30
+ spec.add_development_dependency 'pry'
31
+ spec.add_development_dependency 'webmock'
32
+ spec.add_development_dependency 'rspec-its'
33
+ spec.add_development_dependency 'awesome_print'
34
+ spec.add_development_dependency 'sinatra'
35
+ end
@@ -0,0 +1,47 @@
1
+ require 'faraday'
2
+ require 'faraday_middleware'
3
+ require 'json'
4
+ require 'agilecrm-wrapper/version'
5
+ require 'agilecrm-wrapper/configuration'
6
+ require 'agilecrm-wrapper/contact'
7
+ require 'agilecrm-wrapper/note'
8
+ require 'agilecrm-wrapper/response/raise_error'
9
+
10
+ module AgileCRMWrapper
11
+ class << self
12
+ attr_accessor :configuration
13
+
14
+ def configuration
15
+ @configuration ||= Configuration.new
16
+ end
17
+
18
+ def reset
19
+ @configuration = Configuration.new
20
+ end
21
+
22
+ def configure
23
+ yield(configuration)
24
+ end
25
+
26
+ def endpoint
27
+ "https://#{configuration.domain}.agilecrm.com/dev/api"
28
+ end
29
+
30
+ def connection
31
+ @connection ||= default_connection
32
+ end
33
+
34
+ def default_connection
35
+ options = {
36
+ headers: { 'Accept' => 'application/json' }
37
+ }
38
+ Faraday.new(endpoint, options) do |conn|
39
+ conn.request(:json)
40
+ conn.request(:basic_auth, configuration.email, configuration.api_key)
41
+ conn.response(:json, content_type: /\bjson$/)
42
+ conn.response(:agilecrm_error)
43
+ conn.adapter(Faraday.default_adapter)
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,11 @@
1
+ module AgileCRMWrapper
2
+ class Configuration
3
+ attr_accessor :domain, :api_key, :email
4
+
5
+ def initialize
6
+ @domain = ''
7
+ @api_key = ''
8
+ @email = ''
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,119 @@
1
+ require 'agilecrm-wrapper/error'
2
+ require 'hashie'
3
+
4
+ module AgileCRMWrapper
5
+ class Contact < Hashie::Mash
6
+ SYSTEM_PROPERTIES = %w(first_name last_name company title email)
7
+ CONTACT_FIELDS = %w(id type tags lead_score star_value)
8
+
9
+ class << self
10
+ def all
11
+ response = AgileCRMWrapper.connection.get('contacts')
12
+ if response.status == 200
13
+ return response.body.map { |body| new body }
14
+ else
15
+ return response
16
+ end
17
+ end
18
+
19
+ def find(id)
20
+ response = AgileCRMWrapper.connection.get("contacts/#{id}")
21
+ if response.status == 200
22
+ new(response.body)
23
+ elsif response.status == 204
24
+ fail(AgileCRMWrapper::NotFound.new(response))
25
+ end
26
+ end
27
+
28
+ def search_by_email(*emails)
29
+ emails = emails.flatten.compact.uniq
30
+ response = AgileCRMWrapper.connection.post(
31
+ 'contacts/search/email', "email_ids=#{emails}",
32
+ 'content-type' => 'application/x-www-form-urlencoded'
33
+ )
34
+ if response.body.size > 1
35
+ response.body.reject(&:nil?).map { |body| new body }
36
+ else
37
+ res = new(response.body.first)
38
+ res.empty? ? nil : res
39
+ end
40
+ end
41
+
42
+ def create(options = {})
43
+ payload = parse_contact_fields(options)
44
+ AgileCRMWrapper.connection.post('contacts', payload)
45
+ end
46
+
47
+ def delete(arg)
48
+ AgileCRMWrapper.connection.delete("contacts/#{arg}")
49
+ end
50
+
51
+ def parse_contact_fields(options)
52
+ payload = { 'properties' => [] }
53
+ options.each do |key, value|
54
+ if contact_field?(key)
55
+ payload[key.to_s] = value
56
+ else
57
+ payload['properties'] << parse_property(key, value)
58
+ end
59
+ end
60
+ payload
61
+ end
62
+
63
+ private
64
+
65
+ def parse_property(key, value)
66
+ if system_propety?(key)
67
+ { 'type' => 'SYSTEM', 'name' => key.to_s, 'value' => value }
68
+ else
69
+ { 'type' => 'CUSTOM', 'name' => key.to_s, 'value' => value }
70
+ end
71
+ end
72
+
73
+ def system_propety?(key)
74
+ SYSTEM_PROPERTIES.include?(key.to_s)
75
+ end
76
+
77
+ def contact_field?(key)
78
+ CONTACT_FIELDS.include?(key.to_s)
79
+ end
80
+ end
81
+
82
+ def destroy
83
+ self.class.delete(id)
84
+ end
85
+
86
+ def notes
87
+ response = AgileCRMWrapper.connection.get("contacts/#{id}/notes")
88
+ response.body.map { |note| AgileCRMWrapper::Note.new(note) }
89
+ end
90
+
91
+ def update(options = {})
92
+ payload = self.class.parse_contact_fields(options)
93
+ payload['properties'] = merge_properties(payload['properties'])
94
+ merge!(payload)
95
+ response = AgileCRMWrapper.connection.put('contacts', self)
96
+ merge!(response.body)
97
+ end
98
+
99
+ def get_property(property_name)
100
+ return unless respond_to?(:properties)
101
+ prop = properties.select { |a| a['name'] == property_name.to_s }
102
+ OpenStruct.new(*prop).value
103
+ end
104
+
105
+ private
106
+
107
+ def merge_properties(new_properties)
108
+ properties.map do |h|
109
+ new_properties.delete_if do |h2|
110
+ if h['name'] == h2['name']
111
+ h['value'] = h2['value']
112
+ true
113
+ end
114
+ end
115
+ h
116
+ end + new_properties
117
+ end
118
+ end
119
+ end