diff --git a/Gemfile.lock b/Gemfile.lock index 5147801..7b709df 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -2,6 +2,7 @@ PATH remote: . specs: pipedrive_orbit (0.0.1) + activesupport (~> 6.1) dotenv (~> 2.7) http (~> 4.4) json (~> 2.5) @@ -12,10 +13,17 @@ PATH GEM remote: https://rubygems.org/ specs: + activesupport (6.1.3.2) + concurrent-ruby (~> 1.0, >= 1.0.2) + i18n (>= 1.6, < 2) + minitest (>= 5.1) + tzinfo (~> 2.0) + zeitwerk (~> 2.3) addressable (2.7.0) public_suffix (>= 2.0.2, < 5.0) ast (2.4.2) byebug (11.1.3) + concurrent-ruby (1.1.8) crack (0.4.5) rexml diff-lcs (1.4.4) @@ -37,7 +45,10 @@ GEM http-form_data (2.3.0) http-parser (1.2.3) ffi-compiler (>= 1.0, < 2.0) + i18n (1.8.10) + concurrent-ruby (~> 1.0) json (2.5.1) + minitest (5.14.4) orbit_activities (0.0.2) http (~> 4.4) json (~> 2.5) @@ -77,6 +88,8 @@ GEM parser (>= 3.0.1.1) ruby-progressbar (1.11.0) thor (1.1.0) + tzinfo (2.0.4) + concurrent-ruby (~> 1.0) unf (0.1.4) unf_ext unf_ext (0.0.7.7) diff --git a/README.md b/README.md index db7f730..c2c06e3 100644 --- a/README.md +++ b/README.md @@ -60,13 +60,29 @@ Once, you have an instantiated client, you can fetch Pipedrive deal notes and se ```ruby client.notes ``` +### Fetching Pipedrive Notes + +Once, you have an instantiated client, you can fetch Pipedrive activities and send them to Orbit by invoking the `#activities` instance method: + +```ruby +client.activities +``` ## CLI Usage -You can also use this package with the included CLI. To use the CLI pass in the required environment variables on the command line before invoking the CLI: +You can also use this package with the included CLI. To use the CLI pass in the required environment variables on the command line before invoking the CLI. + +To check for new deal notes: ```bash $ ORBIT_API_KEY=... ORBIT_WORKSPACE_ID=... PIPEDRIVE_API_KEY=... PIPEDRIVE_URL=... bundle exec pipedrive_orbit --check_notes ``` + +To check for new activities: + +```bash +$ ORBIT_API_KEY=... ORBIT_WORKSPACE_ID=... PIPEDRIVE_API_KEY=... PIPEDRIVE_URL=... bundle exec pipedrive_orbit --check_activities +``` + ## GitHub Actions Automation Setup ⚡ You can set up this integration in a matter of minutes using our GitHub Actions template. It will run regularly to add new activities to your Orbit workspace. All you need is a GitHub account. diff --git a/bin/pipedrive_orbit b/bin/pipedrive_orbit old mode 100644 new mode 100755 index 795eea1..dbc552f --- a/bin/pipedrive_orbit +++ b/bin/pipedrive_orbit @@ -3,6 +3,7 @@ require 'optparse' check_notes = false +check_activities = false options = {} choices = OptionParser.new do |opts| @@ -14,6 +15,9 @@ choices = OptionParser.new do |opts| opts.on("--check-notes", "Check for new Pipedrive deal notes") do check_notes = true end + opts.on("--check-check_activities", "Check for new Pipedrive activities") do + check_activities = true + end end.parse! $LOAD_PATH.unshift(File.expand_path('../lib/pipedrive_orbit', __dir__)) @@ -25,4 +29,10 @@ if check_notes puts "Checking for new Pipedrive deal notes and posting them to your Orbit workspace..." ARGV[0] = 'render' PipedriveOrbit::Scripts::CheckNotes.start(ARGV) +end + +if check_activities + puts "Checking for new Pipedrive activities and posting them to your Orbit workspace..." + ARGV[0] = 'render' + PipedriveOrbit::Scripts::CheckActivities.start(ARGV) end \ No newline at end of file diff --git a/lib/pipedrive_orbit/client.rb b/lib/pipedrive_orbit/client.rb index a99b2de..ce803a5 100644 --- a/lib/pipedrive_orbit/client.rb +++ b/lib/pipedrive_orbit/client.rb @@ -47,5 +47,14 @@ def notes orbit_workspace: @orbit_workspace ).process_notes end + + def activities + PipedriveOrbit::Pipedrive.new( + pipedrive_api_key: @pipedrive_api_key, + pipedrive_url: @pipedrive_url, + orbit_api_key: @orbit_api_key, + orbit_workspace: @orbit_workspace + ).process_activities + end end end \ No newline at end of file diff --git a/lib/pipedrive_orbit/interactions/activity.rb b/lib/pipedrive_orbit/interactions/activity.rb new file mode 100644 index 0000000..852754b --- /dev/null +++ b/lib/pipedrive_orbit/interactions/activity.rb @@ -0,0 +1,70 @@ +# frozen_string_literal: true + +require "json" + +module PipedriveOrbit + module Interactions + class Activity + def initialize(activity:, pipedrive_url:, orbit_workspace:, orbit_api_key:) + @activity = activity + @pipedrive_url = pipedrive_url + @orbit_workspace = orbit_workspace + @orbit_api_key = orbit_api_key + + after_initialize! + end + + def after_initialize! + OrbitActivities::Request.new( + api_key: @orbit_api_key, + workspace_id: @orbit_workspace, + user_agent: "community-ruby-pipedrive-orbit/#{PipedriveOrbit::VERSION}", + body: construct_body.to_json + ) + end + + def construct_member + hash = { name: @activity["person_name"] } unless @activity["person_name"].nil? + + return hash unless hash.nil? + + if !@activity["attendees"].nil? + hash = { email: @activity["attendees"][0]["email_address"] } + end + + hash + end + + def construct_body + hash = { + activity: { + activity_type: "pipedrive:activity", + tags: ["channel:pipedrive"], + title: "Added New #{@activity["type"].capitalize} Activity to Pipedrive", + description: construct_description, + occurred_at: @activity["add_time"], + key: @activity["id"], + member: {} + }, + identity: { + source: "pipedrive" + } + } + + hash[:activity][:member].merge!(construct_member) + hash[:activity][:member].merge!(company: @activity["org_name"]) unless @activity["org_name"].nil? + hash[:identity].merge!(construct_member) + + hash + end + + def construct_description + if @activity["note"] + return @activity["note"] + end + + "#{@activity["subject"]} was added by #{@activity["owner_name"]}" + end + end + end +end \ No newline at end of file diff --git a/lib/pipedrive_orbit/orbit.rb b/lib/pipedrive_orbit/orbit.rb index 43567e2..f88430f 100644 --- a/lib/pipedrive_orbit/orbit.rb +++ b/lib/pipedrive_orbit/orbit.rb @@ -11,6 +11,15 @@ def self.call(type:, data:, orbit_workspace:, orbit_api_key:) orbit_api_key: orbit_api_key ) end + + if type == "activity" + PipedriveOrbit::Interactions::Activity.new( + activity: data[:activity], + pipedrive_url: data[:pipedrive_url], + orbit_workspace: orbit_workspace, + orbit_api_key: orbit_api_key + ) + end end end end \ No newline at end of file diff --git a/lib/pipedrive_orbit/pipedrive.rb b/lib/pipedrive_orbit/pipedrive.rb index 4f0375b..a69f03f 100644 --- a/lib/pipedrive_orbit/pipedrive.rb +++ b/lib/pipedrive_orbit/pipedrive.rb @@ -1,5 +1,7 @@ # frozen_string_literal: true +require "active_support/time" + module PipedriveOrbit class Pipedrive def initialize(params = {}) @@ -26,6 +28,56 @@ def process_notes end end + def process_activities + activities = get_activities + + return get_activities["error"] if get_activities["success"] == false + return "No new activities in the past day!" if activities.nil? + + activities["data"].each do |activity| + next if no_member_info(activity) + + PipedriveOrbit::Orbit.call( + type: "activity", + data: { + activity: activity, + pipedrive_url: @pipedrive_url + }, + orbit_workspace: @orbit_workspace, + orbit_api_key: @orbit_api_key + ) + end + end + + def get_activities + url = URI("https://api.pipedrive.com/v1/activities") + url.query = "user_id=0&start_date=#{create_start_date}&end_date=#{create_end_date}&api_token=#{@pipedrive_api_key}" + https = Net::HTTP.new(url.host, url.port) + https.use_ssl = true + + request = Net::HTTP::Get.new(url) + + response = https.request(request) + + response = JSON.parse(response.body) + end + + def no_member_info(activity) + return true if activity["person_name"].nil? && activity["attendees"].nil? + + false + end + + def create_start_date + date = Date.parse(Time.now.utc.to_date.to_s)-1.day + date.strftime("%Y-%m-%d") + end + + def create_end_date + date = Date.parse(Time.now.utc.to_date.to_s) + date.strftime("%Y-%m-%d") + end + def get_notes url = URI("https://api.pipedrive.com/v1/notes") url.query = "sort=add_time DESC&api_token=#{@pipedrive_api_key}" diff --git a/lib/pipedrive_orbit/version.rb b/lib/pipedrive_orbit/version.rb index 5b8a7a8..fd17317 100644 --- a/lib/pipedrive_orbit/version.rb +++ b/lib/pipedrive_orbit/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal = true module PipedriveOrbit - VERSION = "0.0.1" + VERSION = "0.0.2" end \ No newline at end of file diff --git a/pipedrive_orbit.gemspec b/pipedrive_orbit.gemspec index f7d8f6d..fee7640 100644 --- a/pipedrive_orbit.gemspec +++ b/pipedrive_orbit.gemspec @@ -25,7 +25,8 @@ Gem::Specification.new do |spec| spec.bindir = "bin" spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) } spec.require_paths = ["lib"] - + + spec.add_dependency "activesupport", "~> 6.1" spec.add_dependency "http", "~> 4.4" spec.add_dependency "json", "~> 2.5" spec.add_dependency "zeitwerk", "~> 2.4" diff --git a/scripts/check_activities.rb b/scripts/check_activities.rb new file mode 100644 index 0000000..794ec34 --- /dev/null +++ b/scripts/check_activities.rb @@ -0,0 +1,17 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true + +require "pipedrive_orbit" +require "thor" + +module PipedriveOrbit + module Scripts + class CheckActivities < Thor + desc "render", "check for new Pipedrive activities and push them to Orbit" + def render + client = PipedriveOrbit::Client.new + client.activities + end + end + end +end \ No newline at end of file diff --git a/spec/interactions/activity_spec.rb b/spec/interactions/activity_spec.rb new file mode 100644 index 0000000..9f3e7ed --- /dev/null +++ b/spec/interactions/activity_spec.rb @@ -0,0 +1,50 @@ +# frozen_string_literal: true + +require "spec_helper" + + +RSpec.describe PipedriveOrbit::Interactions::Activity do + let(:subject) do + PipedriveOrbit::Interactions::Activity.new( + activity: { + "id" => "82", + "user_id" => "12301519", + "deal_id" => "1234", + "person_id" => "123", + "org_id" => "444", + "type" => "email", + "person_name" => "Testing Person", + "add_time" => "2021-05-18 05:11:52", + "note" => "Testing note" + }, + pipedrive_url: "https://example.com", + orbit_workspace: "1234", + orbit_api_key: "12345", + + ) + end + + describe "#call" do + context "when the type is a note" do + it "returns a Activity Object" do + stub_request(:post, "https://app.orbit.love/api/v1/1234/activities") + .with( + headers: { 'Authorization' => "Bearer 12345", 'Content-Type' => 'application/json', 'User-Agent'=>"community-ruby-pipedrive-orbit/#{PipedriveOrbit::VERSION}" }, + body: "{\"activity\":{\"activity_type\":\"pipedrive:activity\",\"tags\":[\"channel:pipedrive\"],\"title\":\"Added New Email Activity to Pipedrive\",\"description\":\"Testing note\",\"occurred_at\":\"2021-05-18 05:11:52\",\"key\":\"82\",\"member\":{\"name\":\"Testing Person\"}},\"identity\":{\"source\":\"pipedrive\",\"name\":\"Testing Person\"}}" + ) + .to_return( + status: 200, + body: { + response: { + code: 'SUCCESS' + } + }.to_json.to_s + ) + + content = subject.construct_body + + expect(content[:activity][:key]).to eql("82") + end + end + end +end \ No newline at end of file