blueshift_crm 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: ae6f2541ddf0c9a5d3e7b02294463398a46e5d0074d0b225a4b3fb29d3449bc8
4
+ data.tar.gz: 115e3c4bb73537869701e98f6f19aaabd8c6487300abb444aff7573a9381529c
5
+ SHA512:
6
+ metadata.gz: 8b6cad6ea2db23d2133cf62db0cc8d0ca7bf85a14bb5c015217a265cb46d95d62ae9811cf4132058443db63a8747f52f85d8da925d610cde670d66e2d1db1812
7
+ data.tar.gz: 62a3c0092d724d0d1ccd2f670820181adeea26392da6ae11455f8ca42238276d27800e47a85d9471731de077b70e6426d02a04bd8b2c8e83c80d75332b63de88
data/README.md ADDED
@@ -0,0 +1,60 @@
1
+ # Blueshift CRM (Ruby)
2
+
3
+ A lightweight Ruby client for the Blueshift CRM API.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ bundle add blueshift_crm
9
+ ```
10
+
11
+ ### Add ENV variables for API keys:
12
+
13
+ ```bash
14
+ export BLUESHIFT_SITE_ID=""
15
+ export BLUESHIFT_EVENT_API_KEY=""
16
+ export BLUESHIFT_USER_API_KEY=""
17
+ export BLUESHIFT_API_PASSWORD=""
18
+ ```
19
+
20
+ ### Optional:
21
+
22
+ ```bash
23
+ export BLUESHIFT_REGION=""
24
+ ```
25
+
26
+ ## Usage:
27
+
28
+ ```bash
29
+ # create a client instance:
30
+ client = BlueshiftCRM::Client.new
31
+ ```
32
+ #### Adapters:
33
+ ```bash
34
+ client.adapters.list
35
+ ```
36
+
37
+ #### Campaigns:
38
+ ```bash
39
+ client.campaigns.list
40
+ ```
41
+
42
+ #### Custom User Lists:
43
+ ```bash
44
+ client.custom_user_lists.seed_lists
45
+ ```
46
+
47
+ #### Customers:
48
+ ```bash
49
+ client.customers.get(uuid: "")
50
+ ```
51
+
52
+ #### Events:
53
+ ```bash
54
+ client.events.history(event: "")
55
+ ```
56
+
57
+ #### Segments:
58
+ ```bash
59
+ client.campaigns.list
60
+ ```
@@ -0,0 +1,96 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BlueshiftCRM
4
+ class Client
5
+ DEFAULT_TIMEOUT = 30
6
+ READONLY_GETS = %w[GET].freeze
7
+
8
+ attr_reader :base_url, :site_id
9
+
10
+ # region: "eu" or nil
11
+ # user_api_key: required for most endpoints (you called this blueshift_api_password; both envs supported)
12
+ # event_api_key: required for POST /api/v1/event
13
+ def initialize(
14
+ region: ENV["BLUESHIFT_REGION"],
15
+ user_api_key: ENV["BLUESHIFT_USER_API_KEY"] || ENV["blueshift_api_password"],
16
+ event_api_key: ENV["BLUESHIFT_EVENT_API_KEY"] || ENV["event_api_key"],
17
+ site_id: ENV["BLUESHIFT_SITE_ID"] || ENV["site_id"],
18
+ timeout: DEFAULT_TIMEOUT
19
+ )
20
+ @base_url = region.to_s.downcase == "eu" ? "https://api.eu.getblueshift.com" : "https://api.getblueshift.com"
21
+ @user_api_key = user_api_key
22
+ @event_api_key = event_api_key
23
+ @site_id = site_id
24
+ @timeout = timeout
25
+
26
+ raise ArgumentError, "Missing user_api_key (BLUESHIFT_USER_API_KEY)" unless @user_api_key
27
+ raise ArgumentError, "Missing event_api_key (BLUESHIFT_EVENT_API_KEY or event_api_key)" unless @event_api_key
28
+ raise ArgumentError, "Missing site_id (BLUESHIFT_SITE_ID or site_id)" unless @site_id
29
+
30
+ @conn_user = build_conn(auth_key: @user_api_key)
31
+ @conn_event = build_conn(auth_key: @event_api_key)
32
+ end
33
+
34
+ # ---- Public resource accessors ----
35
+ def campaigns = @campaigns ||= Resources::Campaigns.new(self)
36
+ def events = @events ||= Resources::Events.new(self)
37
+ def customers = @customers ||= Resources::Customers.new(self)
38
+ def segments = @segments ||= Resources::Segments.new(self)
39
+ def adapters = @adapters ||= Resources::Adapters.new(self)
40
+ def custom_user_lists = @custom_user_lists ||= Resources::CustomUserLists.new(self)
41
+
42
+ # ---- Core HTTP helpers ----
43
+ def get(path, params: {}, user_api: true)
44
+ request(:get, path, params: with_site_id(params), user_api: user_api)
45
+ end
46
+
47
+ def post(path, body: {}, params: {}, user_api: true)
48
+ request(:post, path, body: body, params: with_site_id(params), user_api: user_api)
49
+ end
50
+
51
+ def put(path, body: {}, params: {}, user_api: true)
52
+ request(:put, path, body: body, params: with_site_id(params), user_api: user_api)
53
+ end
54
+
55
+ def request(method, path, body: nil, params: {}, user_api: true)
56
+ conn = user_api ? @conn_user : @conn_event
57
+ resp = conn.public_send(method, path) do |req|
58
+ req.params.update(params.compact)
59
+ req.headers["Content-Type"] = "application/json" unless READONLY_GETS.include?(method.to_s.upcase)
60
+ req.body = JSON.dump(body) if body && !READONLY_GETS.include?(method.to_s.upcase)
61
+ end
62
+
63
+ parse_response(resp)
64
+ rescue Faraday::ClientError => e
65
+ status = e.response&.dig(:status)
66
+ body = e.response&.dig(:body)
67
+ raise Error.new("HTTP #{status || 'error'}: #{e.message}", status: status, body: body)
68
+ rescue Faraday::Error => e
69
+ raise Error.new("HTTP error: #{e.message}")
70
+ end
71
+
72
+ private
73
+
74
+ def with_site_id(params)
75
+ { site_id: @site_id }.merge(params || {})
76
+ end
77
+
78
+ def build_conn(auth_key:)
79
+ Faraday.new(url: @base_url) do |f|
80
+ f.request :retry, max: 2, interval: 0.25, backoff_factor: 2, methods: %i[get put post delete]
81
+ f.options.timeout = @timeout
82
+ # HTTP Basic with API key as username and blank password
83
+ f.request :authorization, :basic, auth_key, ""
84
+ f.adapter Faraday.default_adapter
85
+ end
86
+ end
87
+
88
+ def parse_response(resp)
89
+ return nil if resp.body.to_s.strip.empty?
90
+ JSON.parse(resp.body)
91
+ rescue JSON::ParserError
92
+ resp.body
93
+ end
94
+ end
95
+ end
96
+
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BlueshiftCRM
4
+ class Error < StandardError
5
+ attr_reader :status, :body
6
+
7
+ def initialize(message, status: nil, body: nil)
8
+ super(message)
9
+ @status = status
10
+ @body = body
11
+ end
12
+ end
13
+ end
14
+
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BlueshiftCRM
4
+ module Resources
5
+ class Adapters < Base
6
+ # GET /api/v1/account_adapters?channel_name=...&adapter_name=...
7
+ def list(channel_name: nil, adapter_name: nil)
8
+ client.get("/api/v1/account_adapters", params: { channel_name:, adapter_name: })
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BlueshiftCRM
4
+ module Resources
5
+ class Base
6
+ def initialize(client)
7
+ @client = client
8
+ end
9
+
10
+ private
11
+
12
+ attr_reader :client
13
+ end
14
+ end
15
+ end
16
+
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BlueshiftCRM
4
+ module Resources
5
+ class Campaigns < Base
6
+ # GET /api/v2/campaigns.json
7
+ def list(page: nil, per_page: nil, updated_after: nil)
8
+ client.get("/api/v2/campaigns.json", params: { page:, per_page:, updated_after: })
9
+ end
10
+
11
+ # GET /api/v1/campaigns.json
12
+ def performance(start_date:, end_date:, timezone: nil)
13
+ client.get("/api/v1/campaigns.json", params: { start_date:, end_date:, timezone: })
14
+ end
15
+
16
+ # GET /api/v1/campaigns/{uuid}/detail.json
17
+ def detail(uuid:)
18
+ client.get("/api/v1/campaigns/#{uuid}/detail.json")
19
+ end
20
+
21
+ # Optional: POST /api/v1/campaigns/{type}
22
+ def create(campaign_type:, payload:)
23
+ client.post("/api/v1/campaigns/#{campaign_type}", body: payload)
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BlueshiftCRM
4
+ module Resources
5
+ class CustomUserLists < Base
6
+ # GET /api/v1/custom_user_lists/seed_lists
7
+ def seed_lists
8
+ client.get("/api/v1/custom_user_lists/seed_lists")
9
+ end
10
+
11
+ # GET /api/v1/custom_user_lists/id/{custom_user_list_id}
12
+ def details(list_id:)
13
+ client.get("/api/v1/custom_user_lists/id/#{list_id}")
14
+ end
15
+
16
+ # Optional helpers if you plan to create/manage lists:
17
+ def create(name:, description: nil)
18
+ client.post("/api/v1/custom_user_lists/create", body: { name:, description: })
19
+ end
20
+
21
+ def add_user(list_id:, identifier:)
22
+ client.put("/api/v1/custom_user_lists/add_user_to_list/#{list_id}", body: identifier)
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BlueshiftCRM
4
+ module Resources
5
+ class Customers < Base
6
+ # GET /api/v1/customers/{uuid}
7
+ def get(uuid:)
8
+ client.get("/api/v1/customers/#{uuid}")
9
+ end
10
+
11
+ # GET /api/v1/customers?email=... or customer_id=...
12
+ def search(email: nil, customer_id: nil)
13
+ client.get("/api/v1/customers", params: { email:, customer_id: })
14
+ end
15
+
16
+ # POST /api/v1/customers (create or update)
17
+ def upsert(payload:)
18
+ client.post("/api/v1/customers", body: payload)
19
+ end
20
+
21
+ # GET /api/v1/customer_search/show_events?uuid=...
22
+ def events(uuid:, limit: nil)
23
+ client.get("/api/v1/customer_search/show_events", params: { uuid:, limit: })
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BlueshiftCRM
4
+ module Resources
5
+ class Events < Base
6
+ # POST /api/v1/event (requires Event API key)
7
+ def send_event(event:)
8
+ client.request(:post, "/api/v1/event", body: event, user_api: false)
9
+ end
10
+
11
+ # GET /api/v1/event/debug
12
+ def latest_debug
13
+ client.get("/api/v1/event/debug")
14
+ end
15
+
16
+ # GET /api/v1/event/history
17
+ def history(event: nil, limit: nil)
18
+ client.get("/api/v1/event/history", params: { event:, limit: })
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BlueshiftCRM
4
+ module Resources
5
+ class Segments < Base
6
+ # GET /api/v1/segments/list
7
+ def list
8
+ client.get("/api/v1/segments/list")
9
+ end
10
+
11
+ # GET /api/v1/segments/{segment_uuid}/matching_users.json
12
+ def matching_users_count(segment_uuid:)
13
+ client.get("/api/v1/segments/#{segment_uuid}/matching_users.json")
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+ module BlueshiftCRM
3
+ VERSION = "0.1.0"
4
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "json"
4
+ require "faraday"
5
+
6
+ require_relative "blueshift_crm/version"
7
+ require_relative "blueshift_crm/error"
8
+ require_relative "blueshift_crm/client"
9
+
10
+ # resources
11
+ require_relative "blueshift_crm/resources/base"
12
+ require_relative "blueshift_crm/resources/campaigns"
13
+ require_relative "blueshift_crm/resources/events"
14
+ require_relative "blueshift_crm/resources/customers"
15
+ require_relative "blueshift_crm/resources/segments"
16
+ require_relative "blueshift_crm/resources/adapters"
17
+ require_relative "blueshift_crm/resources/custom_user_lists"
18
+
19
+ module BlueshiftCRM
20
+ # Entry module namespace
21
+ end
22
+
metadata ADDED
@@ -0,0 +1,90 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: blueshift_crm
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - JD Warren
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2025-11-05 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: faraday
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '2.9'
20
+ - - "<"
21
+ - !ruby/object:Gem::Version
22
+ version: '3.0'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ version: '2.9'
30
+ - - "<"
31
+ - !ruby/object:Gem::Version
32
+ version: '3.0'
33
+ - !ruby/object:Gem::Dependency
34
+ name: rspec
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '3.0'
40
+ type: :development
41
+ prerelease: false
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: '3.0'
47
+ description: A lightweight, Faraday-based Ruby client for Blueshift CRM covering campaigns,
48
+ events, customers, segments, adapters, and custom user lists.
49
+ email:
50
+ - johndavid400@gmail.com
51
+ executables: []
52
+ extensions: []
53
+ extra_rdoc_files: []
54
+ files:
55
+ - README.md
56
+ - lib/blueshift_crm.rb
57
+ - lib/blueshift_crm/client.rb
58
+ - lib/blueshift_crm/error.rb
59
+ - lib/blueshift_crm/resources/adapters.rb
60
+ - lib/blueshift_crm/resources/base.rb
61
+ - lib/blueshift_crm/resources/campaigns.rb
62
+ - lib/blueshift_crm/resources/custom_user_lists.rb
63
+ - lib/blueshift_crm/resources/customers.rb
64
+ - lib/blueshift_crm/resources/events.rb
65
+ - lib/blueshift_crm/resources/segments.rb
66
+ - lib/blueshift_crm/version.rb
67
+ homepage: https://github.com/johndavid400/blueshift_crm
68
+ licenses:
69
+ - MIT
70
+ metadata: {}
71
+ post_install_message:
72
+ rdoc_options: []
73
+ require_paths:
74
+ - lib
75
+ required_ruby_version: !ruby/object:Gem::Requirement
76
+ requirements:
77
+ - - ">="
78
+ - !ruby/object:Gem::Version
79
+ version: '3.0'
80
+ required_rubygems_version: !ruby/object:Gem::Requirement
81
+ requirements:
82
+ - - ">="
83
+ - !ruby/object:Gem::Version
84
+ version: '0'
85
+ requirements: []
86
+ rubygems_version: 3.4.19
87
+ signing_key:
88
+ specification_version: 4
89
+ summary: Ruby client for Blueshift CRM API
90
+ test_files: []