├── .gitignore ├── Gemfile ├── lib ├── closeio │ ├── task.rb │ ├── version.rb │ ├── contact.rb │ ├── report.rb │ ├── organization.rb │ ├── email_template.rb │ ├── opportunity.rb │ ├── lead_status.rb │ ├── saved_search.rb │ ├── email_activity.rb │ ├── note_activity.rb │ ├── opportunity_status.rb │ ├── lead.rb │ ├── paginated_list.rb │ └── base.rb └── closeio.rb ├── closeio-0.0.3.gem ├── .document ├── Rakefile ├── Gemfile.lock ├── LICENSE ├── closeio.gemspec └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | closeio-*.gem 2 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | gem 'rake' 4 | gemspec 5 | -------------------------------------------------------------------------------- /lib/closeio/task.rb: -------------------------------------------------------------------------------- 1 | module Closeio 2 | class Task < Base; end 3 | end -------------------------------------------------------------------------------- /lib/closeio/version.rb: -------------------------------------------------------------------------------- 1 | module Closeio 2 | VERSION = "0.0.9" 3 | end 4 | -------------------------------------------------------------------------------- /lib/closeio/contact.rb: -------------------------------------------------------------------------------- 1 | module Closeio 2 | class Contact < Base; end 3 | end -------------------------------------------------------------------------------- /lib/closeio/report.rb: -------------------------------------------------------------------------------- 1 | module Closeio 2 | class Report < Base; end 3 | end -------------------------------------------------------------------------------- /closeio-0.0.3.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/preact/closeio/master/closeio-0.0.3.gem -------------------------------------------------------------------------------- /lib/closeio/organization.rb: -------------------------------------------------------------------------------- 1 | module Closeio 2 | class Organization < Base; end 3 | end -------------------------------------------------------------------------------- /.document: -------------------------------------------------------------------------------- 1 | README.rdoc 2 | lib/**/*.rb 3 | bin/* 4 | features/**/*.feature 5 | LICENSE 6 | -------------------------------------------------------------------------------- /lib/closeio/email_template.rb: -------------------------------------------------------------------------------- 1 | module Closeio 2 | class EmailTemplate < Base; end 3 | end -------------------------------------------------------------------------------- /lib/closeio/opportunity.rb: -------------------------------------------------------------------------------- 1 | module Closeio 2 | class Opportunity < Base 3 | end 4 | end -------------------------------------------------------------------------------- /lib/closeio/lead_status.rb: -------------------------------------------------------------------------------- 1 | module Closeio 2 | class LeadStatus < Base 3 | def self.resource_path 4 | return "/status/lead/" 5 | end 6 | end 7 | end -------------------------------------------------------------------------------- /lib/closeio/saved_search.rb: -------------------------------------------------------------------------------- 1 | module Closeio 2 | class SavedSearch < Base 3 | def leads 4 | Closeio::Lead.where query: self.query 5 | end 6 | end 7 | end -------------------------------------------------------------------------------- /lib/closeio/email_activity.rb: -------------------------------------------------------------------------------- 1 | module Closeio 2 | class EmailActivity < Base 3 | 4 | def self.resource_path 5 | return "/activity/email/" 6 | end 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /lib/closeio/note_activity.rb: -------------------------------------------------------------------------------- 1 | module Closeio 2 | class NoteActivity < Base 3 | 4 | def self.resource_path 5 | return "/activity/note/" 6 | end 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /lib/closeio/opportunity_status.rb: -------------------------------------------------------------------------------- 1 | module Closeio 2 | class OpportunityStatus < Base 3 | def self.resource_path 4 | return "/status/opportunity/" 5 | end 6 | end 7 | end -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | require "bundler/gem_tasks" 2 | 3 | require 'rdoc/task' 4 | Rake::RDocTask.new do |rdoc| 5 | version = File.exist?('VERSION') ? File.read('VERSION') : "" 6 | 7 | rdoc.rdoc_dir = 'rdoc' 8 | rdoc.title = "closeio #{version}" 9 | rdoc.rdoc_files.include('README*') 10 | rdoc.rdoc_files.include('lib/**/*.rb') 11 | end 12 | -------------------------------------------------------------------------------- /lib/closeio.rb: -------------------------------------------------------------------------------- 1 | require 'httparty' 2 | require 'ostruct' 3 | require 'forwardable' 4 | 5 | require 'closeio/base' 6 | require 'closeio/contact' 7 | require 'closeio/email_activity' 8 | require 'closeio/email_template' 9 | require 'closeio/lead' 10 | require 'closeio/lead_status' 11 | require 'closeio/note_activity' 12 | require 'closeio/organization' 13 | require 'closeio/opportunity' 14 | require 'closeio/opportunity_status' 15 | require 'closeio/paginated_list' 16 | require 'closeio/report' 17 | require 'closeio/saved_search' 18 | require 'closeio/task' 19 | require 'closeio/version' -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | PATH 2 | remote: . 3 | specs: 4 | closeio (0.0.1) 5 | crack (>= 0.1.8) 6 | httparty (>= 0.11.0) 7 | 8 | GEM 9 | remote: https://rubygems.org/ 10 | specs: 11 | crack (0.4.1) 12 | safe_yaml (~> 0.9.0) 13 | httparty (0.11.0) 14 | multi_json (~> 1.0) 15 | multi_xml (>= 0.5.2) 16 | multi_json (1.7.9) 17 | multi_xml (0.5.5) 18 | rake (10.1.0) 19 | safe_yaml (0.9.5) 20 | test-unit (2.5.5) 21 | 22 | PLATFORMS 23 | ruby 24 | 25 | DEPENDENCIES 26 | bundler (~> 1.3) 27 | closeio! 28 | rake 29 | test-unit 30 | -------------------------------------------------------------------------------- /lib/closeio/lead.rb: -------------------------------------------------------------------------------- 1 | module Closeio 2 | class Lead < Base 3 | # 4 | # Options: '_limit' => 1000, 'query' => 'custom.status:2' 5 | # 6 | def self.where opts={} 7 | res = get(resource_path, query: opts) 8 | 9 | if res.success? 10 | res['data'].nil? ? [] : res['data'].map{|obj| new(obj)} 11 | else 12 | bad_response res 13 | end 14 | end 15 | 16 | def emails 17 | Closeio::EmailActivity.where lead_id: self.id 18 | end 19 | 20 | def notes 21 | Closeio::NoteActivity.where lead_id: self.id 22 | end 23 | 24 | def contact 25 | self.contacts.first 26 | end 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /lib/closeio/paginated_list.rb: -------------------------------------------------------------------------------- 1 | module Closeio 2 | class PaginatedList < ::Array 3 | attr_reader :total, :pages, :per_page, :page 4 | def initialize(results) 5 | @total = results['total'] 6 | @pages = results['pages'] 7 | @per_page = results['per_page'] 8 | @page = results['page'] 9 | 10 | result_key, result_class = 11 | if results.has_key?('shots') 12 | ['shots', Closeio::Shot] 13 | elsif results.has_key?('lead') 14 | ['leads', Closeio::Lead] 15 | else 16 | ['comments', Closeio::Comment] 17 | end 18 | 19 | super((results[result_key] || []).map { |attrs| result_class.new attrs }) 20 | end 21 | 22 | def inspect 23 | ivar_str = instance_variables.map {|iv| "#{iv}=#{instance_variable_get(iv).inspect}"}.join(", ") 24 | "#<#{self.class.inspect} #{ivar_str}, @contents=#{super}>" 25 | end 26 | end 27 | end 28 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013 Taylor Brooks 2 | 3 | MIT License 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining 6 | a copy of this software and associated documentation files (the 7 | "Software"), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, 9 | distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so, subject to 11 | the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be 14 | included in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 20 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 22 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /closeio.gemspec: -------------------------------------------------------------------------------- 1 | # -*- encoding: utf-8 -*- 2 | $:.push File.expand_path("../lib", __FILE__) 3 | require "closeio/version" 4 | require "base64" 5 | 6 | Gem::Specification.new do |s| 7 | s.name = "closeio" 8 | s.version = Closeio::VERSION 9 | s.authors = ["Taylor Brooks"] 10 | s.email = ["dGJyb29rc0BnbWFpbC5jb20="].map{ |e| Base64.decode64(e) } 11 | s.homepage = "https://github.com/taylorbrooks/closeio" 12 | s.summary = %q{A Ruby wrapper for the CloseIO API} 13 | s.description = %q{A Ruby wrapper for the CloseIO API -- a sales CRM built by salespeople, for salespeople.} 14 | s.license = "MIT" 15 | 16 | s.files = `git ls-files`.split($/) 17 | s.executables = s.files.grep(%r{^bin/}).map{ |f| File.basename(f) } 18 | s.test_files = s.files.grep(%r{^(test|spec|features)/}) 19 | 20 | s.require_paths = ["lib"] 21 | 22 | s.add_runtime_dependency(%q, [">= 0.1.8"]) 23 | s.add_runtime_dependency(%q, ["0.11.0"]) 24 | 25 | s.add_development_dependency "bundler", "~> 1.3" 26 | s.add_development_dependency "rake" 27 | s.add_development_dependency "test-unit" 28 | end -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ### A Ruby wrapper for the Close.IO API 2 | 3 | Learn about the Closeio API at http://developer.close.io. 4 | 5 | ### Installation 6 | Add this line to your application's Gemfile: 7 | ````ruby 8 | # in your Gemfile 9 | gem 'closeio' 10 | 11 | # then... 12 | bundle install 13 | 14 | # Add your Close.io api key as an ENV variable 15 | ENV['CLOSEIO_API_KEY']='xxxxxxxx' 16 | ```` 17 | 18 | ### Usage 19 | ````ruby 20 | # Find a specific lead 21 | lead = Closeio::Lead.find 'lead_xxxxxxxxxxxx' 22 | 23 | # See some data about the lead 24 | lead.addresses 25 | lead.contacts 26 | lead.opportunities 27 | 28 | # Find leads that match fields 29 | Closeio::Lead.where query: 'custom.current_system:[Simple Donation]' 30 | 31 | # Create a lead 32 | Closeio::Lead.create name: "Bluth Company", contacts: [{name: "Buster Bluth", emails: [{email: "cartographer@bluthcompany.com"}]}] 33 | 34 | # Saved Search (SmartView) 35 | saved_search = Closeio::SavedSearch.all.first 36 | saved_search.leads 37 | ```` 38 | 39 | ### Contributing 40 | 41 | 1. Fork it 42 | 2. Create your feature branch (`git checkout -b my-new-feature`) 43 | 3. Commit your changes (`git commit -am 'Add some feature'`) 44 | 4. Push to the branch (`git push origin my-new-feature`) 45 | 5. Create new Pull Request 46 | 47 | 48 | ### Copyright 49 | Copyright (c) 2013 Taylor Brooks. See LICENSE for details. -------------------------------------------------------------------------------- /lib/closeio/base.rb: -------------------------------------------------------------------------------- 1 | module Closeio 2 | class Base < OpenStruct 3 | 4 | include HTTParty 5 | base_uri 'https://app.close.io/api/v1' 6 | basic_auth ENV['CLOSEIO_API_KEY'], '' 7 | headers 'Content-Type' => 'application/json' 8 | debug_output $stdout 9 | format :json 10 | 11 | extend Forwardable 12 | def_delegators 'self.class', :delete, :get, :post, :put, :resource_path, :bad_response 13 | 14 | attr_reader :data 15 | 16 | def initialize attrs={} 17 | if attrs['data'] 18 | super attrs['data'] 19 | else 20 | super Hash[attrs] 21 | end 22 | end 23 | 24 | def save 25 | put "#{resource_path}#{self.id}/", body: self.to_h.to_json 26 | end 27 | 28 | class << self 29 | def bad_response response 30 | if response.class == HTTParty::Response 31 | raise HTTParty::ResponseError, response 32 | end 33 | raise StandardError, 'Unknown error' 34 | end 35 | 36 | def all response = nil, opts={} 37 | res = response || get(resource_path, opts) 38 | 39 | if res.success? 40 | res['data'].nil? ? [] : res['data'].map{|obj| new(obj)} 41 | else 42 | bad_response res 43 | end 44 | end 45 | 46 | # Closeio::Lead.create name: "Bluth Company", contacts: [{name: "Buster Bluth", emails: [{email: "cartographer@bluthcompany.com"}]}] 47 | def create opts={} 48 | res = post resource_path, body: opts.to_json 49 | res.success? ? new(res) : bad_response(res) 50 | end 51 | 52 | # 53 | # Closeio::Lead.update '39292', name: "Bluth Company", contacts: [{name: "Buster Bluth", emails: [{email: "cartographer@bluthcompany.com"}]}] 54 | # 55 | def update id, opts={} 56 | put "#{resource_path}#{id}/", body: opts.to_json 57 | end 58 | 59 | def destroy id 60 | if res['data'].is_a? Array 61 | raise "Yo I'm an array" 62 | else 63 | delete "#{resource_path}#{id}/" 64 | end 65 | end 66 | 67 | def find id 68 | res = get "#{resource_path}#{id}/" 69 | res.ok? ? new(res) : bad_response(res) 70 | end 71 | 72 | def where opts={} 73 | res = get(resource_path, query: opts) 74 | 75 | if res.success? 76 | res['data'].nil? ? [] : res['data'].map{|obj| new(obj)} 77 | else 78 | bad_response res 79 | end 80 | end 81 | 82 | def resource_path 83 | klass = name.split('::').last.gsub(/([a-z\d])([A-Z])/,'\1_\2').downcase 84 | return "/#{klass}/" 85 | end 86 | end 87 | end 88 | end 89 | --------------------------------------------------------------------------------