├── .rspec ├── .travis.yml ├── lib └── clearbit │ ├── slack │ ├── version.rb │ ├── configuration.rb │ ├── notifier.rb │ ├── attachments │ │ ├── company.rb │ │ └── person.rb │ └── helpers.rb │ └── slack.rb ├── Gemfile ├── .gitignore ├── spec ├── clearbit │ ├── slack_spec.rb │ └── slack │ │ ├── notifier_spec.rb │ │ └── attachments │ │ ├── person_spec.rb │ │ └── company_spec.rb ├── support │ ├── helpers.rb │ └── fixtures │ │ ├── person.json │ │ └── company.json └── spec_helper.rb ├── bin └── console ├── Rakefile ├── LICENSE ├── clearbit-slack.gemspec └── README.md /.rspec: -------------------------------------------------------------------------------- 1 | --format documentation 2 | --color 3 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: ruby 2 | rvm: 3 | - 2.1.5 4 | -------------------------------------------------------------------------------- /lib/clearbit/slack/version.rb: -------------------------------------------------------------------------------- 1 | module Clearbit 2 | module Slack 3 | VERSION = '0.2.3' 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | # Specify your gem's dependencies in clearbit-slack.gemspec 4 | gemspec 5 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /.bundle/ 2 | /.yardoc 3 | /Gemfile.lock 4 | /_yardoc/ 5 | /coverage/ 6 | /doc/ 7 | /pkg/ 8 | /spec/reports/ 9 | /tmp/ 10 | *.gem 11 | -------------------------------------------------------------------------------- /spec/clearbit/slack_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe Clearbit::Slack do 4 | it 'has a version number' do 5 | expect(Clearbit::Slack::VERSION).not_to be nil 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /bin/console: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require "bundler/setup" 3 | require "clearbit/slack" 4 | 5 | # You can add fixtures and/or initialization code here to make experimenting 6 | # with your gem easier. You can also use a different console, if you like. 7 | 8 | require "irb" 9 | IRB.start 10 | -------------------------------------------------------------------------------- /spec/support/helpers.rb: -------------------------------------------------------------------------------- 1 | module Spec 2 | module Support 3 | module Helpers 4 | def parsed_fixture_data(path) 5 | JSON.parse(fixture_data(path)) 6 | end 7 | 8 | def fixture_data(path) 9 | File.open("spec/support/fixtures/#{path}", 'rb').read 10 | end 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /lib/clearbit/slack/configuration.rb: -------------------------------------------------------------------------------- 1 | module Clearbit 2 | module Slack 3 | class Configuration 4 | attr_accessor :slack_url, :slack_channel 5 | 6 | def to_hash 7 | { 8 | slack_url: slack_url, 9 | slack_channel: slack_channel 10 | } 11 | end 12 | 13 | def merge(hash) 14 | to_hash.merge(hash) 15 | end 16 | end 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /spec/spec_helper.rb: -------------------------------------------------------------------------------- 1 | $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__) 2 | 3 | require 'webmock/rspec' 4 | require 'clearbit/slack' 5 | require 'pry' 6 | 7 | Dir[File.expand_path('spec/support/**/*.rb')].each { |file| require file } 8 | 9 | Clearbit::Slack.configure do |config| 10 | config.slack_url = 'http://example' 11 | config.slack_channel = '#test' 12 | end 13 | 14 | RSpec.configure do |config| 15 | include Spec::Support::Helpers 16 | 17 | config.expect_with :rspec do |c| 18 | c.syntax = :expect 19 | end 20 | 21 | config.order = 'random' 22 | end 23 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | require 'bundler/gem_tasks' 2 | require 'clearbit' 3 | require 'clearbit/slack' 4 | 5 | desc 'Test a live lookup and ping' 6 | task :ping do 7 | Clearbit.key = ENV['CLEARBIT_KEY'] 8 | 9 | Clearbit::Slack.configure do |config| 10 | config.slack_url = ENV['SLACK_URL'] 11 | config.slack_channel = ENV['SLACK_CHANNEL'] 12 | end 13 | 14 | result = Clearbit::Enrichment.find(email: 'harlow@clearbit.com', given_name: 'Harlow', family_name: 'Ward', stream: true) 15 | result.merge!( 16 | email: 'harlow@clearbit.com', 17 | full_name: 'Harlow Ward', 18 | message: "View details in ", 19 | ) 20 | 21 | Clearbit::Slack.ping(result) 22 | end 23 | -------------------------------------------------------------------------------- /lib/clearbit/slack.rb: -------------------------------------------------------------------------------- 1 | require 'clearbit' 2 | require 'mash' 3 | require 'slack-notifier' 4 | 5 | require 'clearbit/slack/configuration' 6 | require 'clearbit/slack/helpers' 7 | require 'clearbit/slack/notifier' 8 | require 'clearbit/slack/version' 9 | require 'clearbit/slack/attachments/person' 10 | require 'clearbit/slack/attachments/company' 11 | 12 | module Clearbit 13 | module Slack 14 | def self.ping(attrs = {}, options = {}) 15 | Notifier.new(attrs, options).ping 16 | end 17 | 18 | def self.slack_url 19 | configuration.slack_url || raise('Config Error: No slack_url provided') 20 | end 21 | 22 | def self.slack_channel 23 | configuration.slack_channel || raise('Config Error: No slack_channel provided') 24 | end 25 | 26 | def self.configure 27 | yield configuration if block_given? 28 | end 29 | 30 | def self.configuration 31 | @configuration ||= Configuration.new 32 | end 33 | end 34 | end 35 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Clearbit 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 all 13 | 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 THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /clearbit-slack.gemspec: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | lib = File.expand_path('../lib', __FILE__) 3 | $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) 4 | require 'clearbit/slack/version' 5 | 6 | Gem::Specification.new do |spec| 7 | spec.name = "clearbit-slack" 8 | spec.version = Clearbit::Slack::VERSION 9 | spec.authors = ["Harlow Ward"] 10 | spec.email = ["harlow@clearbit.com"] 11 | 12 | spec.summary = %q{Clean beautiful customer data. Now in Slack.} 13 | spec.description = %q{Push rich Clearbit enrichment data in a Slack channel.} 14 | spec.homepage = "https://github.com/clearbit/clearbit-slack" 15 | 16 | spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) } 17 | spec.require_paths = ["lib"] 18 | 19 | spec.add_development_dependency 'bundler' 20 | spec.add_development_dependency 'pry', '~> 0.10', '>= 0.10.1' 21 | spec.add_development_dependency 'rake', '~> 10.0' 22 | spec.add_development_dependency 'rspec', '~> 3.5', '>= 3.5.0' 23 | spec.add_development_dependency 'webmock', '~> 2' 24 | 25 | spec.add_runtime_dependency 'clearbit', '~> 0.2', '>= 0.2.2' 26 | spec.add_runtime_dependency 'maccman-mash', '~> 0.0', '>= 0.0.2' 27 | spec.add_runtime_dependency 'slack-notifier', '~> 2.3.2', '>= 2.3.2' 28 | end 29 | -------------------------------------------------------------------------------- /spec/clearbit/slack/notifier_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe Clearbit::Slack::Notifier do 4 | 5 | let(:params) do 6 | { 7 | person: nil, 8 | full_name: 'Alex Maccaw', 9 | email: 'alex@alexmaccaw.com', 10 | message: 'message' 11 | } 12 | end 13 | 14 | context 'default values for given_name and family_name' do 15 | let(:notifier) { double(ping: true) } 16 | 17 | before do 18 | allow(Slack::Notifier).to receive(:new).and_return(notifier) 19 | end 20 | 21 | it 'returns the default values' do 22 | Clearbit::Slack::Notifier.new(params).ping 23 | 24 | expect(Slack::Notifier).to have_received(:new).with('http://example') { |&block| 25 | expect(block).to be( 26 | default( 27 | channel: '#test', 28 | icon_url: nil 29 | ) 30 | ) 31 | } 32 | 33 | expect(notifier).to have_received(:ping).with('message', attachments: [{ 34 | :fallback=>'alex@alexmaccaw.com - Alex Maccaw', 35 | :author_name=>'Alex Maccaw', 36 | :author_icon=>nil, 37 | :text=>'unknown person', 38 | :color=>"good", 39 | fields: [{ 40 | title: 'Email', 41 | value: 'alex@alexmaccaw.com - Alex Maccaw', 42 | short: true 43 | }] 44 | }]) 45 | end 46 | end 47 | 48 | context 'integration test' do 49 | it 'the default values are able to be post to slack' do 50 | stub = stub_request(:post, 'example') 51 | 52 | Clearbit::Slack::Notifier.new(params).ping 53 | 54 | expect(stub).to have_been_requested 55 | end 56 | end 57 | end 58 | -------------------------------------------------------------------------------- /lib/clearbit/slack/notifier.rb: -------------------------------------------------------------------------------- 1 | module Clearbit 2 | module Slack 3 | class Notifier 4 | attr_reader :company, :message, :person, 5 | :full_name, :email, 6 | :slack_url, :slack_channel, :slack_icon 7 | 8 | def initialize(attrs = {}, options = {}) 9 | options = Slack.configuration.merge(options) 10 | 11 | @company = attrs[:company] 12 | @message = attrs[:message] 13 | @person = attrs[:person] 14 | @full_name = attrs[:full_name] 15 | @email = attrs[:email] 16 | @slack_url = options[:slack_url] 17 | @slack_channel = options[:slack_channel] 18 | @slack_icon = options[:slack_icon] 19 | end 20 | 21 | def ping 22 | notifier.ping(message.to_s, attachments: attachments) 23 | end 24 | 25 | def notifier 26 | ::Slack::Notifier.new(slack_url) do 27 | defaults( 28 | channel: @slack_channel, 29 | icon_url: @slack_icon 30 | ) 31 | end 32 | end 33 | 34 | def attachments 35 | result = [] 36 | 37 | result << Attachments::Person.new(person).as_json 38 | 39 | if company 40 | result << Attachments::Company.new(company).as_json 41 | end 42 | 43 | result 44 | end 45 | 46 | private 47 | 48 | def person 49 | @person ||= unknown_person 50 | end 51 | 52 | def unknown_person 53 | Mash.new( 54 | email: email, 55 | bio: 'unknown person', 56 | name: { 57 | full_name: full_name, 58 | } 59 | ) 60 | end 61 | end 62 | end 63 | end 64 | -------------------------------------------------------------------------------- /spec/clearbit/slack/attachments/person_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe Clearbit::Slack::Attachments::Person, '#as_json' do 4 | it 'returns a person attachment' do 5 | person_data = parsed_fixture_data 'person.json' 6 | person = Mash.new(person_data) 7 | 8 | result = Clearbit::Slack::Attachments::Person.new(person).as_json 9 | 10 | expect(result).to eq({ 11 | :fallback => "alex@alexmaccaw.com", 12 | :color=>"good", 13 | :author_icon => "https://d1ts43dypk8bqh.cloudfront.net/v1/avatars/d54c54ad-40be-4305-8a34-0ab44710b90d", 14 | :author_name => nil, 15 | :text => "O'Reilly author, software engineer & traveller. Founder of https://clearbit.com", 16 | :fields=>[ 17 | {:title=>"Email", :value=>"alex@alexmaccaw.com", :short=>true}, 18 | {:title=>"Location", :value=>"San Francisco, CA, USA", :short=>true}, 19 | {:title=>"Employment", :value=>"Clearbit", :short=>true}, 20 | {:title=>"Title", :value=>"CEO", :short=>true}, 21 | {:title=>"LinkedIn", :value=>"", :short=>true}, 22 | {:title=>"Twitter", :value=>" (15,248 followers)", :short=>true} 23 | ] 24 | }) 25 | end 26 | 27 | it 'returns text when the bio field is null in the payload' do 28 | person_data = parsed_fixture_data 'person.json' 29 | 30 | # simluate the bio being null in the payload 31 | person_data["bio"] = nil 32 | 33 | person = Mash.new(person_data) 34 | 35 | result = Clearbit::Slack::Attachments::Person.new(person).as_json 36 | 37 | # the text value in the payload needs to not be nil 38 | expect(result).not_to include( 39 | text: a_nil_value 40 | ) 41 | end 42 | end 43 | -------------------------------------------------------------------------------- /lib/clearbit/slack/attachments/company.rb: -------------------------------------------------------------------------------- 1 | module Clearbit 2 | module Slack 3 | module Attachments 4 | class Company 5 | include Helpers 6 | attr_reader :company 7 | 8 | def initialize(company) 9 | @company = company 10 | end 11 | 12 | def as_json(options = {}) 13 | { 14 | author_name: company.name, 15 | author_icon: company.logo, 16 | text: company.description.to_s, 17 | color: color, 18 | fields: fields.compact 19 | } 20 | end 21 | 22 | private 23 | 24 | def color 25 | 'good' 26 | end 27 | 28 | def fields 29 | [ 30 | location, 31 | website, 32 | type, 33 | raised, 34 | employees, 35 | linkedin(company.linkedin), 36 | twitter(company.twitter), 37 | tags, 38 | tech 39 | ] 40 | end 41 | 42 | def location 43 | return unless company.location 44 | field 'Location', company.location, false 45 | end 46 | 47 | def website 48 | return unless company.url 49 | field 'Website', company.url 50 | end 51 | 52 | def type 53 | return unless company.type 54 | field 'Type', company.type 55 | end 56 | 57 | def employees 58 | return unless company.metrics.employees 59 | field 'Employees', format_number(company.metrics.employees) 60 | end 61 | 62 | def raised 63 | return unless company.metrics.raised 64 | field 'Raised', "$#{format_number(company.metrics.raised)}" 65 | end 66 | 67 | def tags 68 | return unless company.tags 69 | field 'Tags', company.tags.join(', '), false 70 | end 71 | 72 | def tech 73 | return unless company.tech 74 | field 'Tech', company.tech.join(', '), false 75 | end 76 | end 77 | end 78 | end 79 | end 80 | -------------------------------------------------------------------------------- /lib/clearbit/slack/attachments/person.rb: -------------------------------------------------------------------------------- 1 | module Clearbit 2 | module Slack 3 | module Attachments 4 | class Person 5 | include Helpers 6 | attr_reader :person 7 | 8 | def initialize(person) 9 | @person = person 10 | end 11 | 12 | def as_json(options = {}) 13 | { 14 | fallback: fallback, 15 | author_name: person.name.full_name, 16 | author_icon: person.avatar, 17 | text: person.bio.to_s, 18 | color: color, 19 | fields: fields.compact 20 | } 21 | end 22 | 23 | private 24 | 25 | def fallback 26 | str = person.email 27 | 28 | if name = person.name.full_name 29 | str << ' - %s' % name 30 | end 31 | 32 | str 33 | end 34 | 35 | def fields 36 | [ 37 | email, 38 | location, 39 | employment, 40 | title, 41 | role, 42 | seniority, 43 | linkedin(person.linkedin), 44 | twitter(person.twitter), 45 | ] 46 | end 47 | 48 | def email 49 | return unless person.email 50 | field 'Email', person.email 51 | end 52 | 53 | def title 54 | return unless person.employment && person.employment.title 55 | field 'Title', person.employment.title 56 | end 57 | 58 | def employment 59 | return unless person.employment && person.employment.name 60 | field 'Employment', person.employment.name 61 | end 62 | 63 | def role 64 | return unless person.employment && person.employment.role 65 | field 'Role', person.employment.role 66 | end 67 | 68 | def seniority 69 | return unless person.employment && person.employment.seniority 70 | field 'Seniority', person.employment.seniority 71 | end 72 | 73 | def location 74 | return unless person.location 75 | field 'Location', person.location 76 | end 77 | 78 | def color 79 | 'good' 80 | end 81 | end 82 | end 83 | end 84 | end 85 | -------------------------------------------------------------------------------- /lib/clearbit/slack/helpers.rb: -------------------------------------------------------------------------------- 1 | module Clearbit 2 | module Slack 3 | module Helpers 4 | def format_number(value) 5 | value.to_s.reverse.gsub(/(\d{3})(?=\d)/, '\\1,').reverse 6 | end 7 | 8 | def field(title, value, short = true) 9 | { 10 | title: title, 11 | value: value, 12 | short: short 13 | } 14 | end 15 | 16 | def link(url, title, followers = nil) 17 | if followers 18 | followers = format_number(followers) 19 | followers = " (#{followers} followers)" 20 | end 21 | 22 | "<#{url}|#{title}>#{followers}".strip 23 | end 24 | 25 | def aboutme(aboutme) 26 | return unless aboutme && aboutme.handle 27 | value = link( 28 | "https://about.me/#{aboutme.handle}", 29 | aboutme.handle 30 | ) 31 | field 'AboutMe', value 32 | end 33 | 34 | def angellist(angellist) 35 | return unless angellist && angellist.handle 36 | value = link( 37 | "https://angel.co/#{angellist.handle}", 38 | angellist.handle, 39 | angellist.followers 40 | ) 41 | field 'AngelList', value 42 | end 43 | 44 | def github(github) 45 | return unless github && github.handle 46 | value = link( 47 | "https://github.com/#{github.handle}", 48 | github.handle, 49 | github.followers 50 | ) 51 | field 'GitHub', value 52 | end 53 | 54 | def facebook(facebook) 55 | return unless facebook && facebook.handle 56 | value = link( 57 | "https://www.facebook.com/#{facebook.handle}", 58 | facebook.handle 59 | ) 60 | field 'Facebook', value 61 | end 62 | 63 | def twitter(twitter) 64 | return unless twitter && twitter.handle 65 | value = link( 66 | "http://twitter.com/#{twitter.handle}", 67 | twitter.handle, 68 | twitter.followers 69 | ) 70 | field 'Twitter', value 71 | end 72 | 73 | def linkedin(linkedin) 74 | return unless linkedin && linkedin.handle 75 | value = link( 76 | "https://www.linkedin.com/#{linkedin.handle}", 77 | linkedin.handle 78 | ) 79 | field 'LinkedIn', value 80 | end 81 | end 82 | end 83 | end 84 | -------------------------------------------------------------------------------- /spec/clearbit/slack/attachments/company_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe Clearbit::Slack::Attachments::Company, '#as_json' do 4 | let(:company_data) { parsed_fixture_data 'company.json' } 5 | let(:company) { Mash.new(company_data) } 6 | let(:result) { Clearbit::Slack::Attachments::Company.new(company).as_json } 7 | 8 | it 'returns a company attachment' do 9 | expect(result).to include( 10 | { 11 | :author_name => "Clearbit", 12 | :author_icon => "https://brandbadge.clearbit.com/a114c279-67aa-4faa-beaf-64246a856450", 13 | :text => "Clearbit provides powerful products and data APIs to help your business grow. Contact enrichment, lead generation, financial compliance, and more...", 14 | :color => "good", 15 | :fields => [ 16 | { 17 | :title => "Location", 18 | :value => "3030 16th St, San Francisco, CA 94103, USA", 19 | :short => false 20 | }, 21 | { 22 | :title => "Website", 23 | :value => "http://clearbit.com", 24 | :short => true 25 | }, 26 | { 27 | :title => "Type", 28 | :value => "private", 29 | :short => true 30 | }, 31 | { 32 | :title => "Raised", 33 | :value => "$250,000", 34 | :short => true 35 | }, 36 | { 37 | :title => "Employees", 38 | :value => "10", 39 | :short => true 40 | }, 41 | { 42 | :title => "LinkedIn", 43 | :value => "", 44 | :short => true 45 | }, 46 | { 47 | :title => "Twitter", 48 | :value => " (616 followers)", 49 | :short => true 50 | }, 51 | { 52 | :title => "Tags", 53 | :value => "Technology, Information Technology & Services", 54 | :short => false 55 | }, 56 | { 57 | :title => "Tech", 58 | :value => "google_analytics, kiss_metrics, mixpanel, adroll, olark, typekit_by_adobe, perfect_audience, customer_io, intercom, google_apps, mailgun, mixpanel, aws_route_53, aws_ec2", 59 | :short => false 60 | } 61 | ] 62 | } 63 | ) 64 | end 65 | 66 | it 'returns text when the description field is null in the payload' do 67 | # simluate the description being null in the payload 68 | company_data["description"] = nil 69 | 70 | # the text value in the payload needs to not be nil 71 | expect(result).not_to include( 72 | text: a_nil_value 73 | ) 74 | end 75 | end 76 | -------------------------------------------------------------------------------- /spec/support/fixtures/person.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "d54c54ad-40be-4305-8a34-0ab44710b90d", 3 | "name": { 4 | "fullName": "Alex MacCaw", 5 | "givenName": "Alex", 6 | "familyName": "MacCaw" 7 | }, 8 | "email": "alex@alexmaccaw.com", 9 | "gender": "male", 10 | "location": "San Francisco, CA, USA", 11 | "geo": { 12 | "city": "SF", 13 | "state": "CA", 14 | "country": "US", 15 | "lat": 37.7749295, 16 | "lng": -122.4194155 17 | }, 18 | "bio": "O'Reilly author, software engineer & traveller. Founder of https://clearbit.com", 19 | "site": "http://alexmaccaw.com", 20 | "avatar": "https://d1ts43dypk8bqh.cloudfront.net/v1/avatars/d54c54ad-40be-4305-8a34-0ab44710b90d", 21 | "employment": { 22 | "name": "Clearbit", 23 | "title": "CEO", 24 | "domain": null 25 | }, 26 | "facebook": { 27 | "handle": "amaccaw" 28 | }, 29 | "github": { 30 | "handle": "maccman", 31 | "avatar": "https://avatars.githubusercontent.com/u/2142?v=2", 32 | "company": "Clearbit", 33 | "blog": "http://alexmaccaw.com", 34 | "followers": 2932, 35 | "following": 94 36 | }, 37 | "twitter": { 38 | "handle": "maccaw", 39 | "id": "2006261", 40 | "bio": "O'Reilly author, software engineer & traveller. Founder of https://clearbit.com", 41 | "followers": 15248, 42 | "following": 1711, 43 | "location": "San Francisco", 44 | "site": "http://alexmaccaw.com", 45 | "avatar": "https://pbs.twimg.com/profile_images/1826201101/297606_10150904890650705_570400704_21211347_1883468370_n.jpeg" 46 | }, 47 | "linkedin": { 48 | "handle": "pub/alex-maccaw/78/929/ab5" 49 | }, 50 | "googleplus": { 51 | "handle": null 52 | }, 53 | "angellist": { 54 | "handle": "maccaw", 55 | "bio": "O'Reilly author, engineer & traveller. Mostly harmless.", 56 | "blog": "http://blog.alexmaccaw.com", 57 | "site": "http://alexmaccaw.com", 58 | "followers": 532, 59 | "avatar": "https://d1qb2nb5cznatu.cloudfront.net/users/403357-medium_jpg?1405661263" 60 | }, 61 | "foursquare": { 62 | "handle": null 63 | }, 64 | "aboutme": { 65 | "handle": "maccaw", 66 | "bio": "Software engineer & traveller. Walker, skier, reader, tennis player, breather, ginger beer drinker, scooterer & generally enjoying things :)", 67 | "avatar": "http://o.aolcdn.com/dims-global/dims/ABOUTME/5/803/408/80/http://d3mod6n032mdiz.cloudfront.net/thumb2/m/a/c/maccaw/maccaw-840x560.jpg" 68 | }, 69 | "gravatar": { 70 | "handle": "maccman", 71 | "urls": [ 72 | { 73 | "value": "http://alexmaccaw.com", 74 | "title": "Personal Website" 75 | } 76 | ], 77 | "avatar": "http://2.gravatar.com/avatar/994909da96d3afaf4daaf54973914b64", 78 | "avatars": [ 79 | { 80 | "url": "http://2.gravatar.com/avatar/994909da96d3afaf4daaf54973914b64", 81 | "type": "thumbnail" 82 | } 83 | ] 84 | }, 85 | "fuzzy": false 86 | } 87 | -------------------------------------------------------------------------------- /spec/support/fixtures/company.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "a114c279-67aa-4faa-beaf-64246a856450", 3 | "name": "Clearbit", 4 | "legalName": null, 5 | "domain": "clearbit.com", 6 | "domainAliases": [], 7 | "url": "http://clearbit.com", 8 | "site": { 9 | "url": "http://clearbit.com", 10 | "title": "Clearbit", 11 | "h1": "Gain insights into your customers", 12 | "metaDescription": "Clearbit provides powerful products and data APIs to help your business grow. Contact enrichment, lead generation, financial compliance, and more...", 13 | "metaAuthor": null, 14 | "phoneNumbers": [ 15 | "+1 877-223-8023" 16 | ], 17 | "emailAddresses": [ 18 | "team@clearbit.com", 19 | "sales@clearbit.com", 20 | "support@clearbit.com", 21 | "alex@clearbit.com", 22 | "harlow@clearbit.com", 23 | "jobs+engineer@clearbit.com", 24 | "jobs+sales@clearbit.com" 25 | ] 26 | }, 27 | "category": { 28 | "sector": "Information Technology", 29 | "industryGroup": "Software & Services", 30 | "industry": "Internet Software & Services", 31 | "subIndustry": "Internet Software & Services" 32 | }, 33 | "tags": [ 34 | "Technology", 35 | "Information Technology & Services" 36 | ], 37 | "description": "Clearbit provides powerful products and data APIs to help your business grow. Contact enrichment, lead generation, financial compliance, and more...", 38 | "foundedDate": null, 39 | "location": "3030 16th St, San Francisco, CA 94103, USA", 40 | "timeZone": "America/Los_Angeles", 41 | "utcOffset": -8, 42 | "geo": { 43 | "streetNumber": "3030", 44 | "streetName": "16th Street", 45 | "subPremise": null, 46 | "city": "San Francisco", 47 | "postalCode": "94103", 48 | "state": "California", 49 | "stateCode": "CA", 50 | "country": "United States", 51 | "countryCode": "US", 52 | "lat": 37.7652736, 53 | "lng": -122.4203596 54 | }, 55 | "logo": "https://brandbadge.clearbit.com/a114c279-67aa-4faa-beaf-64246a856450˝", 56 | "facebook": { 57 | "handle": null 58 | }, 59 | "linkedin": { 60 | "handle": "company/clearbit" 61 | }, 62 | "twitter": { 63 | "handle": "clearbit", 64 | "id": "2857311332", 65 | "bio": "Business Intelligence APIs", 66 | "followers": 616, 67 | "following": 26, 68 | "location": "San Francisco", 69 | "site": "https://t.co/r06mCbdPuR", 70 | "avatar": "https://pbs.twimg.com/profile_images/557204249411457024/B0Nb_vTU_normal.png" 71 | }, 72 | "crunchbase": { 73 | "handle": "organization/clearbit" 74 | }, 75 | "emailProvider": false, 76 | "type": "private", 77 | "ticker": null, 78 | "phone": null, 79 | "metrics": { 80 | "alexaUsRank": 41351, 81 | "alexaGlobalRank": 106033, 82 | "googleRank": 1, 83 | "employees": 10, 84 | "marketCap": null, 85 | "raised": 250000, 86 | "annualRevenue": null 87 | }, 88 | "tech": [ 89 | "google_analytics", 90 | "kiss_metrics", 91 | "mixpanel", 92 | "adroll", 93 | "olark", 94 | "typekit_by_adobe", 95 | "perfect_audience", 96 | "customer_io", 97 | "intercom", 98 | "google_apps", 99 | "mailgun", 100 | "mixpanel", 101 | "aws_route_53", 102 | "aws_ec2" 103 | ] 104 | } 105 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Clearbit Slack Notifier 2 | 3 | Clean beautiful customer data. Now in Slack. 4 | 5 | ![alex test](https://cloud.githubusercontent.com/assets/739782/19399022/44627600-9204-11e6-9b80-447fb5685bad.png) 6 | 7 | ## Installation 8 | 9 | Add to your application's Gemfile: 10 | 11 | ```ruby 12 | gem 'clearbit-slack' 13 | ``` 14 | 15 | ### Configuration 16 | 17 | Add Clearbit and Slack config vars: 18 | 19 | ```ruby 20 | # config/initializers/clearbit.rb 21 | Clearbit.key = ENV['CLEARBIT_KEY'] 22 | 23 | Clearbit::Slack.configure do |config| 24 | config.slack_url = ENV['SLACK_URL'] 25 | config.slack_channel = '#signups' 26 | end 27 | ``` 28 | 29 | ### Clearbit Key 30 | 31 | Sign up for a [Free Trial](https://clearbit.com/) if you don't already have a Clearbit key. 32 | 33 | ## Notifications 34 | 35 | ### Parameters 36 | 37 | | Field | Description | 38 | | ----------- | -------------------------------------------------- | 39 | | company | Company data returned from Clearbit | 40 | | person | Person data returned form Clearbit | 41 | | message | Used for deep link into an internal Admin/CRM | 42 | | email | Used to augment message data when Person not found | 43 | | full_name | Used to augment message data when Person not found | 44 | 45 | ### Streaming API 46 | 47 | Lookup email using the Clearbit streaming API and ping Slack channel: 48 | 49 | ```ruby 50 | # app/jobs/signup_notification.rb 51 | module APIHub 52 | module Jobs 53 | class SignupNotification 54 | include Sidekiq::Worker 55 | 56 | def perform(customer_id) 57 | customer = Customer.find!(customer_id) 58 | result = Clearbit::Enrichment.find(email: customer.email, given_name: customer.first_name, family_name: customer.last_name, stream: true) 59 | 60 | result.merge!( 61 | email: customer.email, 62 | full_name: "#{customer.first_name} #{customer.last_name}", 63 | message: "View details in ", 64 | ) 65 | 66 | Clearbit::Slack.ping(result) 67 | 68 | # Save Clearbit data to datastore 69 | end 70 | end 71 | end 72 | end 73 | ``` 74 | 75 | ### Webhooks 76 | 77 | Receive a webhook with Clearbit data and ping Slack channel: 78 | 79 | ```ruby 80 | # app/controllers/webhooks_controller.rb 81 | class WebhooksController < ApplicationController 82 | def clearbit 83 | webhook = Clearbit::Webhook.new(env) 84 | customer = Customer.find!(webhook.webhook_id) 85 | result = webhook.body 86 | 87 | result.merge!( 88 | email: customer.email, 89 | full_name: "#{customer.first_name} #{customer.last_name}", 90 | message: "View details in ", 91 | ) 92 | 93 | Clearbit::Slack.ping(result) 94 | 95 | # Save Clearbit data to datastore 96 | end 97 | end 98 | ``` 99 | 100 | ## Contributing 101 | 102 | 1. Fork it ( https://github.com/[my-github-username]/clearbit-slack/fork ) 103 | 2. Create your feature branch (`git checkout -b my-new-feature`) 104 | 3. Commit your changes (`git commit -am 'Add some feature'`) 105 | 4. Push to the branch (`git push origin my-new-feature`) 106 | 5. Create a new Pull Request 107 | --------------------------------------------------------------------------------