close_encounters 0.1.2 → 0.2.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 +4 -4
- data/CHANGELOG.md +6 -17
- data/README.md +17 -0
- data/app/models/close_encounters/participant_event.rb +4 -0
- data/app/models/close_encounters/participant_service.rb +12 -9
- data/db/migrate/20250225232551_add_metadata_to_close_encounters_participant_events.rb +9 -0
- data/lib/close_encounters/engine.rb +5 -0
- data/lib/close_encounters/middleware.rb +31 -0
- data/lib/close_encounters/version.rb +1 -1
- data/lib/close_encounters.rb +33 -0
- metadata +4 -3
- data/app/views/layouts/close_encounters/application.html.erb +0 -15
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4954f6a9a487299009cb84b6af2571743e1d08d2703683edbcde73e0670a154b
|
4
|
+
data.tar.gz: d05d458352582236246c0ceab9f556f8ca3c2df9c3531db3e35123e854cb6485
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 64c3973533245763a65dd67e466c6da6b7f425853aeaebeb4712d94eb115dfc36484a49ea146a93db1e77dd5848f4c8770d1768a76c5b435d43f4acdd2f196e0
|
7
|
+
data.tar.gz: d2c569f12ce8da83cfc3d3eb8d437b0100436687212bbded9d10fee5989a74e5bd3c67d03b2f4d314c4903bdbcd90bc74990bba754cbc9ac5f9cfb5d2b612d46
|
data/CHANGELOG.md
CHANGED
@@ -5,26 +5,15 @@ All notable changes to this project will be documented in this file.
|
|
5
5
|
The format is based on [Keep a Changelog](http://keepachangelog.com/)
|
6
6
|
and this project adheres to [Semantic Versioning](http://semver.org/).
|
7
7
|
|
8
|
-
## [0.
|
8
|
+
## [0.2.0] - 2025-02-26
|
9
9
|
|
10
|
-
###
|
11
|
-
|
12
|
-
- Check if the table exits before conditionally setting up the serialize column
|
13
|
-
|
14
|
-
### Removed
|
10
|
+
### Changed
|
15
11
|
|
16
|
-
-
|
17
|
-
|
18
|
-
## [0.1.1] - 2024-07-11
|
12
|
+
- Test with Ruby 3.4
|
19
13
|
|
20
14
|
### Added
|
21
15
|
|
22
|
-
-
|
23
|
-
-
|
24
|
-
|
25
|
-
### Fixed
|
16
|
+
- Ability to use CloseEncounters::Middleware and CloseEncounters.auto_contact! to automatically track responses from third-party services.
|
17
|
+
- Add metadata to events for storing extra information about the event.
|
26
18
|
|
27
|
-
|
28
|
-
- Update ensure_service to not overwrite existing connection_info
|
29
|
-
- Allow specs to run properly locally
|
30
|
-
- Incorrect manifest paths for sprockets
|
19
|
+
## [0.1.4] - Unreleased
|
data/README.md
CHANGED
@@ -27,6 +27,23 @@ CloseEncounters.status("SomeThirdPartyService") # => 200
|
|
27
27
|
CloseEncounters.status("SomeThirdPartyService") # => 500
|
28
28
|
```
|
29
29
|
|
30
|
+
### Rack Middleware
|
31
|
+
|
32
|
+
Setup your middleware in your `config/application.rb` or `config/environments/production.rb`.
|
33
|
+
|
34
|
+
```ruby
|
35
|
+
config.middleware.use CloseEncounters::Middleware
|
36
|
+
```
|
37
|
+
|
38
|
+
This will automatically track responses from third-party services when you store a "domain" key in the
|
39
|
+
`connection_info` in the ParticipantService records.
|
40
|
+
|
41
|
+
Alternatively, you can use the `auto_contact!` method to automatically turn on the rack middleware:
|
42
|
+
|
43
|
+
```ruby
|
44
|
+
CloseEncounters.auto_contact!
|
45
|
+
```
|
46
|
+
|
30
47
|
### TODO
|
31
48
|
|
32
49
|
- [ ] Add JS to the gem to track events on the front-end.
|
@@ -6,5 +6,9 @@ module CloseEncounters
|
|
6
6
|
foreign_key: "close_encounters_participant_service_id"
|
7
7
|
|
8
8
|
scope :newest, -> { order(created_at: :desc).limit(1) }
|
9
|
+
|
10
|
+
unless ActiveRecord::Base.connection.adapter_name.downcase.include?("postgresql")
|
11
|
+
serialize :metadata, coder: JSON
|
12
|
+
end
|
9
13
|
end
|
10
14
|
end
|
@@ -6,18 +6,21 @@ module CloseEncounters
|
|
6
6
|
|
7
7
|
validates :name, presence: true
|
8
8
|
|
9
|
-
# if the table exists, then we can check the column type
|
10
|
-
if connection.table_exists?(table_name) && (
|
11
|
-
columns_hash = connection.schema_cache.columns_hash(table_name)
|
12
|
-
)
|
13
|
-
if columns_hash["connection_info"].type == :text
|
14
|
-
serialize :connection_info, coder: JSON
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
9
|
# ONLY encrypt if you have the necessary keys
|
19
10
|
if Rails.application.credentials.close_encounters_encryption_key.present?
|
20
11
|
encrypts :connection_info
|
21
12
|
end
|
13
|
+
|
14
|
+
def connection_info
|
15
|
+
if super.is_a?(String)
|
16
|
+
JSON.parse(super)
|
17
|
+
else
|
18
|
+
super
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def connection_info=(value)
|
23
|
+
super(value.to_json)
|
24
|
+
end
|
22
25
|
end
|
23
26
|
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
class AddMetadataToCloseEncountersParticipantEvents < ActiveRecord::Migration[7.1]
|
2
|
+
def change
|
3
|
+
if ActiveRecord::Base.connection.adapter_name.downcase.include?("postgresql")
|
4
|
+
add_column :close_encounters_participant_events, :metadata, :jsonb
|
5
|
+
else
|
6
|
+
add_column :close_encounters_participant_events, :metadata, :text
|
7
|
+
end
|
8
|
+
end
|
9
|
+
end
|
@@ -1,3 +1,4 @@
|
|
1
|
+
require_relative "middleware"
|
1
2
|
module CloseEncounters
|
2
3
|
class Engine < ::Rails::Engine
|
3
4
|
isolate_namespace CloseEncounters
|
@@ -6,6 +7,10 @@ module CloseEncounters
|
|
6
7
|
g.test_framework :minitest, spec: true
|
7
8
|
end
|
8
9
|
|
10
|
+
initializer "close_encounters.middleware" do |app|
|
11
|
+
app.middleware.use CloseEncounters::Middleware if CloseEncounters.auto_contact?
|
12
|
+
end
|
13
|
+
|
9
14
|
if defined?(Importmap)
|
10
15
|
initializer "close_encounters.importmap", before: "importmap" do |app|
|
11
16
|
app.config.importmap.paths << root.join("config/importmap.rb")
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module CloseEncounters
|
2
|
+
class Middleware
|
3
|
+
def initialize(app, tracker: CloseEncounters)
|
4
|
+
@app = app
|
5
|
+
@tracker = tracker
|
6
|
+
end
|
7
|
+
|
8
|
+
def call(env)
|
9
|
+
status, headers, response = @app.call(env)
|
10
|
+
|
11
|
+
record_contact(env["SERVER_NAME"], status, response)
|
12
|
+
|
13
|
+
[status, headers, response]
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def record_contact(host, status, response)
|
19
|
+
if (name = participant_services[host])
|
20
|
+
@tracker.contact(name, status:, response:)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def participant_services
|
25
|
+
@participant_services ||= CloseEncounters::ParticipantService.all
|
26
|
+
.map do |service|
|
27
|
+
[service.connection_info["domain"], service.name]
|
28
|
+
end.to_h
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
data/lib/close_encounters.rb
CHANGED
@@ -19,6 +19,39 @@ module CloseEncounters
|
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|
22
|
+
# Record a verification of a contact with a third party service where the
|
23
|
+
# verification is a callable which must also respond to to_s.
|
24
|
+
#
|
25
|
+
# For example, provide a callable which checks the JSON Schema for a response body
|
26
|
+
# and will record an event if calling the verification returns false.
|
27
|
+
#
|
28
|
+
# @param name [String] the name of the service
|
29
|
+
# @param status [Integer] the HTTP status of the contact
|
30
|
+
# @param response [String] the response object
|
31
|
+
# @param verifier [Proc] the verification callable which must also respond to to_s
|
32
|
+
def verify(name, status:, response:, verifier:)
|
33
|
+
service = ParticipantService.find_by!(name:)
|
34
|
+
unless service.events.newest.pick(:status) == status && (verified = verifier.call(response))
|
35
|
+
service.events.create!(status:, response:, metadata: {verified:, verification: verifier.to_s})
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
# Determine if contacts with third party services should be recorded automatically
|
40
|
+
# using the Rack Middleware
|
41
|
+
#
|
42
|
+
# Set the CLOSE_ENCOUNTERS_AUTO_CONTACT environment variable to enable this feature
|
43
|
+
# or call CloseEncounters.auto_contact! in an initializer
|
44
|
+
#
|
45
|
+
# @return [Boolean] whether or not to automatically record contacts
|
46
|
+
def auto_contact?
|
47
|
+
!!(ENV["CLOSE_ENCOUNTERS_AUTO_CONTACT"] || @auto_contact)
|
48
|
+
end
|
49
|
+
|
50
|
+
# Enable automatic contact recording in the Rack Middleware
|
51
|
+
def auto_contact!
|
52
|
+
@auto_contact = true
|
53
|
+
end
|
54
|
+
|
22
55
|
# Get the status of the most recent contact with a third party service
|
23
56
|
#
|
24
57
|
# @param name [String] the name of the service
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: close_encounters
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jim Gay
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2025-02-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: railties
|
@@ -112,13 +112,14 @@ files:
|
|
112
112
|
- app/models/close_encounters/application_record.rb
|
113
113
|
- app/models/close_encounters/participant_event.rb
|
114
114
|
- app/models/close_encounters/participant_service.rb
|
115
|
-
- app/views/layouts/close_encounters/application.html.erb
|
116
115
|
- config/importmap.rb
|
117
116
|
- db/migrate/20240430173723_create_close_encounters_participant_services.rb
|
118
117
|
- db/migrate/20240430173725_create_close_encounters_participant_events.rb
|
119
118
|
- db/migrate/20240508190642_add_close_ecounters_indexes.rb
|
119
|
+
- db/migrate/20250225232551_add_metadata_to_close_encounters_participant_events.rb
|
120
120
|
- lib/close_encounters.rb
|
121
121
|
- lib/close_encounters/engine.rb
|
122
|
+
- lib/close_encounters/middleware.rb
|
122
123
|
- lib/close_encounters/version.rb
|
123
124
|
- lib/tasks/close_encounters.rake
|
124
125
|
homepage: https://github.com/SOFware/close_encounters
|
@@ -1,15 +0,0 @@
|
|
1
|
-
<!DOCTYPE html>
|
2
|
-
<html>
|
3
|
-
<head>
|
4
|
-
<title>Close encounters</title>
|
5
|
-
<%= csrf_meta_tags %>
|
6
|
-
<%= csp_meta_tag %>
|
7
|
-
|
8
|
-
<%= stylesheet_link_tag "close_encounters/application", media: "all" %>
|
9
|
-
</head>
|
10
|
-
<body>
|
11
|
-
|
12
|
-
<%= yield %>
|
13
|
-
|
14
|
-
</body>
|
15
|
-
</html>
|