bullet_train-outgoing_webhooks 1.2.9 → 1.2.10

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 74eccc06e9bac4c34f9d57665a043f47818085eb0b0c4c53cdca3fe5cbdb49a4
4
- data.tar.gz: b6ed8bd2705b78422b4d133c97f86d3e7e3e81619d62e9893fddfe069feba977
3
+ metadata.gz: d44b251cd89a804615ec264c52649e52bbc6c79f27e292713153be356c4ba099
4
+ data.tar.gz: b045ede97a1140a494dd9e11ae3853f3ac8f106b8e73dd33392cc76636c0ed08
5
5
  SHA512:
6
- metadata.gz: d0cd98a77bc6d65bb507f3e6adad488572579ca73373fbda33d961ea540fd598d11b43259bda446de85865bedf638e4de9bd9cf529b26d8303b351903613d9f9
7
- data.tar.gz: 8318b904b4cfe110378aed89de7d98e2cebba99abf38ecb8fa60b49c7ed7c48a4577531e25efbb07a611e2c37dc213eb25cdf1b6618bee5e3291a70e8b9c71bd
6
+ metadata.gz: 6b50b117f3313cdcf7b009f1f656a9ba9593e354958c29a62c88235f497a18db35aba83587a27e8d12fb0b9ff4343fb844c5fc156dcfb0d4dd73d83474dc32ba
7
+ data.tar.gz: c857cf75207fce59abe42e84fed7c836da7d92941ee628312a31cb02f1f0dd3781714c407e2fb2ca5f8d1938bff40760ac608d44dd6e5e29708b463e822bfe53
@@ -41,6 +41,7 @@ class Api::V1::Webhooks::Outgoing::EndpointsController < Api::V1::ApplicationCon
41
41
  *permitted_fields,
42
42
  :url,
43
43
  :name,
44
+ :version,
44
45
  :scaffolding_absolutely_abstract_creative_concept_id,
45
46
  # 🚅 super scaffolding will insert new fields above this line.
46
47
  *permitted_arrays,
@@ -0,0 +1,13 @@
1
+ class Api::V1::Webhooks::Outgoing::EventsController < Api::V1::ApplicationController
2
+ account_load_and_authorize_resource :event, through: :team, through_association: :webhooks_outgoing_events
3
+
4
+ # GET /api/v1/teams/:team_id/webhooks/outgoing/events
5
+ def index
6
+ render json: @events.map(&:payload)
7
+ end
8
+
9
+ # GET /api/v1/webhooks/outgoing/events/:id
10
+ def show
11
+ render json: @event.payload
12
+ end
13
+ end
@@ -1,7 +1,8 @@
1
1
  class Webhooks::Outgoing::GenerateJob < ApplicationJob
2
2
  queue_as :default
3
3
 
4
- def perform(obj, action)
5
- obj.generate_webhook_perform(action)
4
+ # `= [1]` ensures backwards compatibility for older installations when they upgrade.
5
+ def perform(obj, action, api_versions = [1])
6
+ obj.generate_webhook_perform(action, api_versions)
6
7
  end
7
8
  end
@@ -32,6 +32,8 @@ module Webhooks::Outgoing::DeliverySupport
32
32
  end
33
33
 
34
34
  def deliver
35
+ # TODO If we ever do away with the `async: true` default for webhook generation, then I believe this needs to
36
+ # change otherwise we'd be attempting the first delivery of webhooks inline.
35
37
  if delivery_attempts.create.attempt
36
38
  touch(:delivered_at)
37
39
  else
@@ -15,10 +15,11 @@ module Webhooks::Outgoing::EndpointSupport
15
15
 
16
16
  before_validation { url&.strip! }
17
17
 
18
- validates :url, presence: true, allowed_uri: true
18
+ validates :url, presence: true, allowed_uri: BulletTrain::OutgoingWebhooks.advanced_hostname_security
19
19
 
20
20
  after_initialize do
21
21
  self.event_type_ids ||= []
22
+ self.api_version ||= I18n.t("webhooks/outgoing/endpoints.fields.api_version.options").keys.last
22
23
  end
23
24
 
24
25
  after_save :touch_parent
@@ -28,7 +28,7 @@ module Webhooks::Outgoing::EventSupport
28
28
  end
29
29
 
30
30
  def endpoints
31
- endpoints = send(BulletTrain::OutgoingWebhooks.parent_association).webhooks_outgoing_endpoints.listening_for_event_type_id(event_type_id)
31
+ endpoints = send(BulletTrain::OutgoingWebhooks.parent_association).webhooks_outgoing_endpoints.where(api_version: api_version).listening_for_event_type_id(event_type_id)
32
32
 
33
33
  case subject_type
34
34
  when "Scaffolding::AbsolutelyAbstract::CreativeConcept"
@@ -32,24 +32,31 @@ module Webhooks::Outgoing::IssuingModel
32
32
  # and this object has a parent where an associated outgoing webhooks endpoint could be registered.
33
33
  if event_type
34
34
  # Only generate an event record if an endpoint is actually listening for this event type.
35
- if parent.endpoints_listening_for_event_type?(event_type)
35
+ # If there are endpoints listening, make sure we know which API versions they're looking for.
36
+ if (api_versions = parent.endpoint_api_versions_listening_for_event_type(event_type)).any?
36
37
  if async
37
38
  # serialization can be heavy so run it as a job
38
- Webhooks::Outgoing::GenerateJob.perform_later(self, action)
39
+ Webhooks::Outgoing::GenerateJob.perform_later(self, action, api_versions)
39
40
  else
40
- generate_webhook_perform(action)
41
+ generate_webhook_perform(action, api_versions)
41
42
  end
42
43
  end
43
44
  end
44
45
  end
45
46
 
46
- def generate_webhook_perform(action)
47
+ def generate_webhook_perform(action, api_versions)
47
48
  event_type = Webhooks::Outgoing::EventType.find_by(id: "#{self.class.name.underscore}.#{action}")
48
- # TODO This is crazy that we generate JSON just to parse it. Can't be good for performance.
49
- # Does Jbuilder support generating a hash instead of a JSON string?
50
- data = JSON.parse(to_api_json)
51
- webhook = send(BulletTrain::OutgoingWebhooks.parent_association).webhooks_outgoing_events.create(event_type_id: event_type.id, subject: self, data: data)
52
- webhook.deliver
49
+
50
+ api_versions.each do |api_version|
51
+ webhook = send(BulletTrain::OutgoingWebhooks.parent_association).webhooks_outgoing_events.create(
52
+ event_type_id: event_type.id,
53
+ subject: self,
54
+ data: to_api_json(api_version),
55
+ api_version: api_version
56
+ )
57
+
58
+ webhook.deliver
59
+ end
53
60
  end
54
61
 
55
62
  def generate_created_webhook
@@ -12,15 +12,19 @@ module Webhooks::Outgoing::TeamSupport
12
12
  true
13
13
  end
14
14
 
15
- def endpoints_listening_for_event_type?(event_type)
15
+ def endpoint_api_versions_for_event_type(event_type)
16
+ webhooks_outgoing_endpoints.listening_for_event_type_id(event_type.id).pluck(:api_version).uniq
17
+ end
18
+
19
+ def endpoint_api_versions_listening_for_event_type(event_type)
16
20
  if should_cache_endpoints_listening_for_event_type?
17
- key = "#{cache_key_with_version}/endpoints_for_event_type/#{event_type.cache_key}"
21
+ key = "#{cache_key_with_version}/endpoints_for_event_type/#{event_type.cache_key}/api_version"
18
22
 
19
23
  Rails.cache.fetch(key, expires_in: 24.hours, race_condition_ttl: 5.seconds) do
20
- webhooks_outgoing_endpoints.listening_for_event_type_id(event_type.id).any?
24
+ endpoint_api_versions_for_event_type(event_type)
21
25
  end
22
26
  else
23
- webhooks_outgoing_endpoints.listening_for_event_type_id(event_type.id).any?
27
+ endpoint_api_versions_for_event_type(event_type)
24
28
  end
25
29
  end
26
30
 
@@ -100,6 +100,8 @@ module Webhooks::Outgoing::UriFiltering
100
100
  end
101
101
 
102
102
  def _allowed_uri?(uri)
103
+ return true unless uri.present?
104
+
103
105
  config = Rails.configuration.outgoing_webhooks
104
106
  hostname = uri.hostname.downcase
105
107
 
@@ -4,6 +4,9 @@
4
4
  <% with_field_settings form: form do %>
5
5
  <%= render 'shared/fields/text_field', method: :name, options: {autofocus: true} %>
6
6
  <%= render 'shared/fields/text_field', method: :url %>
7
+ <% unless I18n.t("webhooks/outgoing/endpoints.fields.api_version.options").keys.one? %>
8
+ <%= render 'shared/fields/super_select', method: :api_version %>
9
+ <% end %>
7
10
  <%= render 'shared/fields/super_select', method: :event_type_ids, html_options: {multiple: true},
8
11
  choices: @endpoint.valid_event_types.map { |event_type| [event_type.label_string, event_type.id] } %>
9
12
  <%= render 'shared/fields/super_select', method: :scaffolding_absolutely_abstract_creative_concept_id,
@@ -16,6 +16,7 @@ components:
16
16
  scheme: bearer
17
17
  schemas:
18
18
  <%= automatic_components_for Webhooks::Outgoing::Endpoint %>
19
+ <%= automatic_components_for Webhooks::Outgoing::Event %>
19
20
  <%# 🚅 super scaffolding will insert new components above this line. %>
20
21
  parameters:
21
22
  id:
@@ -28,4 +29,5 @@ security:
28
29
  - BearerAuth: []
29
30
  paths:
30
31
  <%= automatic_paths_for Webhooks::Outgoing::Endpoint, Team %>
32
+ <%= automatic_paths_for Webhooks::Outgoing::Event, Team, except: %i[create update delete] %>
31
33
  <%# 🚅 super scaffolding will insert new paths above this line. %>
@@ -0,0 +1,12 @@
1
+ json.data schema: {object: OpenStruct.new, object_title: I18n.t("webhooks/outgoing/events.fields.data.heading"), object_description: I18n.t("webhooks/outgoing/events.fields.data.heading")} do
2
+ json.id schema: {type: :integer, description: I18n.t("webhooks/outgoing/events.fields.data.id.heading")}
3
+ json.name schema: {type: :string, description: I18n.t("webhooks/outgoing/events.fields.data.name.heading")}
4
+ json.description schema: {type: :string, description: I18n.t("webhooks/outgoing/events.fields.data.description.heading")}
5
+ json.created_at schema: {type: :string, format: "date-time", description: I18n.t("webhooks/outgoing/events.fields.data.created_at.heading")}
6
+ json.updated_at schema: {type: :string, format: "date-time", description: I18n.t("webhooks/outgoing/events.fields.data.updated_at.heading")}
7
+ end
8
+
9
+ json.event_id schema: {type: :string, description: I18n.t("webhooks/outgoing/events.fields.event_id.heading")}
10
+ json.event_type schema: {type: :integer, description: I18n.t("webhooks/outgoing/events.fields.event_type.heading")}
11
+ json.subject_id schema: {type: :integer, description: I18n.t("webhooks/outgoing/events.fields.subject_id.heading")}
12
+ json.subject_type schema: {type: :string, description: I18n.t("webhooks/outgoing/events.fields.subject_type.heading")}
@@ -0,0 +1 @@
1
+ json.array! @events, partial: "api/v1/webhooks/outgoing/events/event", as: :event
@@ -0,0 +1 @@
1
+ json.partial! "api/v1/webhooks/outgoing/events/event", event: @event
@@ -39,6 +39,13 @@ en:
39
39
  label: *url
40
40
  heading: *url
41
41
 
42
+ api_version:
43
+ _: &api_version API Version
44
+ label: *api_version
45
+ heading: *api_version
46
+ options:
47
+ 1: V1
48
+
42
49
  event_type_ids: &event_types
43
50
  _: &event_type_ids Event Types
44
51
  label: *event_type_ids
@@ -114,8 +121,9 @@ en:
114
121
  webhooks/outgoing/endpoint:
115
122
  name: *name
116
123
  url: *url
124
+ api_version: *api_version
117
125
  event_type_ids: *event_type_ids
126
+ scaffolding_absolutely_abstract_creative_concept_id: *scaffolding_absolutely_abstract_creative_concept_id
118
127
  # 🚅 super scaffolding will insert new activerecord attributes above this line.
119
128
  created_at: *created_at
120
- updated_at: *updated_at
121
- scaffolding_absolutely_abstract_creative_concept_id: *scaffolding_absolutely_abstract_creative_concept_id
129
+ updated_at: *updated_at
@@ -1,10 +1,72 @@
1
1
  en:
2
- webhooks/outgoing/events:
3
- fields:
4
- uuid: &uuid
5
- heading: Event UUID
6
- short_uuid: *uuid
7
- event_type_name:
8
- heading: Event Type
2
+ webhooks/outgoing/events: &events
3
+ label: &label Webhooks Events
4
+ fields: &fields
5
+ data:
6
+ _: &data Event Data
7
+ label: *data
8
+ heading: *data
9
+
10
+ id:
11
+ _: &id Event ID
12
+ label: *id
13
+ heading: *id
14
+
15
+ name:
16
+ _: &name Event Name
17
+ label: *name
18
+ heading: *name
19
+
20
+ description:
21
+ _: &description Event Description
22
+ label: *description
23
+ heading: *description
24
+
25
+ created_at:
26
+ _: &created_at DateTime Event was added
27
+ label: *created_at
28
+ heading: *created_at
29
+ updated_at:
30
+ _: &updated_at DateTime Event was updated
31
+ label: *updated_at
32
+ heading: *updated_at
33
+
34
+ event_id:
35
+ _: &event_id Event UUID
36
+ label: *event_id
37
+ heading: *event_id
38
+
39
+ event_type:
40
+ _: &event_type Event Type
41
+ label: *event_type
42
+ heading: *event_type
43
+
44
+ subject_id:
45
+ _: &subject_id Subject ID
46
+ label: *subject_id
47
+ heading: *subject_id
48
+
49
+ subject_type:
50
+ _: &subject_type Subject Type
51
+ label: *subject_type
52
+ heading: *subject_type
53
+
9
54
  payload:
10
- heading: JSON Payload
55
+ _: &payload Payload
56
+ label: *payload
57
+ heading: *payload
58
+
59
+ uuid:
60
+ _: &uuid UUID
61
+ label: *uuid
62
+ heading: *uuid
63
+
64
+ short_uuid:
65
+ _: &short_uuid Short UUID
66
+ label: *short_uuid
67
+ heading: *short_uuid
68
+
69
+ event_type_name:
70
+ _: &event_type_name Event Type Name
71
+ label: *event_type_name
72
+ heading: *event_type_name
data/config/routes.rb CHANGED
@@ -6,10 +6,9 @@ Rails.application.routes.draw do
6
6
  resources BulletTrain::OutgoingWebhooks.parent_resource do
7
7
  namespace :webhooks do
8
8
  namespace :outgoing do
9
- resources :events
10
9
  resources :endpoints do
11
- resources :deliveries, only: [:index, :show] do
12
- resources :delivery_attempts, only: [:index, :show]
10
+ resources :deliveries, only: %i[index show] do
11
+ resources :delivery_attempts, only: %i[index show]
13
12
  end
14
13
  end
15
14
  end
@@ -25,6 +24,7 @@ Rails.application.routes.draw do
25
24
  namespace :webhooks do
26
25
  namespace :outgoing do
27
26
  resources :endpoints, defaults: {format: :json}
27
+ resources :events, only: %i[index show], defaults: {format: :json}
28
28
  end
29
29
  end
30
30
  end
@@ -1,5 +1,5 @@
1
1
  module BulletTrain
2
2
  module OutgoingWebhooks
3
- VERSION = "1.2.9"
3
+ VERSION = "1.2.10"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bullet_train-outgoing_webhooks
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.9
4
+ version: 1.2.10
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Culver
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-12-28 00:00:00.000000000 Z
11
+ date: 2022-12-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: standard
@@ -71,6 +71,7 @@ files:
71
71
  - app/controllers/api/v1/webhooks.rb
72
72
  - app/controllers/api/v1/webhooks/outgoing.rb
73
73
  - app/controllers/api/v1/webhooks/outgoing/endpoints_controller.rb
74
+ - app/controllers/api/v1/webhooks/outgoing/events_controller.rb
74
75
  - app/jobs/webhooks/outgoing/delivery_job.rb
75
76
  - app/jobs/webhooks/outgoing/generate_job.rb
76
77
  - app/models/concerns/webhooks/outgoing/delivery_attempt_support.rb
@@ -126,6 +127,9 @@ files:
126
127
  - app/views/api/v1/webhooks/outgoing/endpoints/_endpoint.json.jbuilder
127
128
  - app/views/api/v1/webhooks/outgoing/endpoints/index.json.jbuilder
128
129
  - app/views/api/v1/webhooks/outgoing/endpoints/show.json.jbuilder
130
+ - app/views/api/v1/webhooks/outgoing/events/_event.json.jbuilder
131
+ - app/views/api/v1/webhooks/outgoing/events/index.json.jbuilder
132
+ - app/views/api/v1/webhooks/outgoing/events/show.json.jbuilder
129
133
  - config/locales/en/webhooks/outgoing/deliveries.en.yml
130
134
  - config/locales/en/webhooks/outgoing/delivery_attempts.en.yml
131
135
  - config/locales/en/webhooks/outgoing/endpoints.en.yml
@@ -178,7 +182,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
178
182
  - !ruby/object:Gem::Version
179
183
  version: '0'
180
184
  requirements: []
181
- rubygems_version: 3.3.7
185
+ rubygems_version: 3.4.1
182
186
  signing_key:
183
187
  specification_version: 4
184
188
  summary: Allow users of your Rails application to subscribe and receive webhooks when