bullet_train-outgoing_webhooks 1.0.3 → 1.0.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/config/{bullet_train_outgoing_webhooks_web_manifest.js → bullet_train_outgoing_webhooks_manifest.js} +0 -0
  3. data/app/controllers/api/v1/webhooks/outgoing/deliveries_endpoint.rb +63 -0
  4. data/app/controllers/api/v1/webhooks/outgoing/delivery_attempts_endpoint.rb +65 -0
  5. data/app/controllers/api/v1/webhooks/outgoing/endpoints_endpoint.rb +119 -0
  6. data/app/jobs/webhooks/outgoing/delivery_job.rb +7 -0
  7. data/app/models/concerns/webhooks/outgoing/issuing_model.rb +49 -0
  8. data/app/models/concerns/webhooks/outgoing/team_support.rb +15 -0
  9. data/app/models/webhooks/outgoing/delivery.rb +79 -0
  10. data/app/models/webhooks/outgoing/delivery_attempt.rb +65 -0
  11. data/app/models/webhooks/outgoing/endpoint.rb +32 -0
  12. data/app/models/webhooks/outgoing/event.rb +41 -0
  13. data/app/models/webhooks/outgoing/event_type.rb +13 -0
  14. data/app/models/webhooks/outgoing.rb +5 -0
  15. data/app/models/webhooks.rb +5 -0
  16. data/app/serializers/api/v1/webhooks/outgoing/delivery_attempt_serializer.rb +16 -0
  17. data/app/serializers/api/v1/webhooks/outgoing/delivery_serializer.rb +14 -0
  18. data/app/serializers/api/v1/webhooks/outgoing/endpoint_serializer.rb +14 -0
  19. data/db/migrate/20180420013127_create_webhooks_outgoing_endpoints.rb +10 -0
  20. data/db/migrate/20180420013505_create_webhooks_outgoing_endpoint_event_types.rb +10 -0
  21. data/db/migrate/20180420013852_create_webhooks_outgoing_event_types.rb +9 -0
  22. data/db/migrate/20180420014623_create_webhooks_outgoing_events.rb +12 -0
  23. data/db/migrate/20180420021016_create_webhooks_outgoing_deliveries.rb +11 -0
  24. data/db/migrate/20180420022027_add_team_to_webhooks_outgoing_events.rb +5 -0
  25. data/db/migrate/20180420165345_create_webhooks_outgoing_delivery_attempts.rb +11 -0
  26. data/db/migrate/20180420172112_add_error_message_to_webhooks_outgoing_delivery_attempt.rb +6 -0
  27. data/db/migrate/20181012234232_add_name_to_webhooks_outgoing_endpoints.rb +5 -0
  28. data/db/migrate/20181013030208_add_delivered_at_to_webhooks_outgoing_deliveries.rb +5 -0
  29. data/db/migrate/20181013165056_add_uuid_to_webhooks_outgoing_events.rb +5 -0
  30. data/db/migrate/20181013174539_add_payload_to_webhooks_outgoing_events.rb +5 -0
  31. data/db/migrate/20181013192951_add_attempt_number_to_webhooks_outgoing_delivery_attempts.rb +5 -0
  32. data/db/migrate/20210805060451_change_body_to_data_on_webhooks_outgoing_events.rb +5 -0
  33. data/db/migrate/20211126230846_add_event_type_ids_to_webhooks_outgoing_endpoints.rb +5 -0
  34. data/db/migrate/20211126230847_migrate_event_type_ids_on_webhooks_outgoing_endpoints.rb +8 -0
  35. data/db/migrate/20211127013539_remove_event_type_from_webhooks_outgoing_events.rb +5 -0
  36. data/db/migrate/20211127013800_add_new_event_type_id_to_webhooks_outgoing_events.rb +5 -0
  37. data/db/migrate/20211127014001_migrate_event_types_on_webhooks_outgoing_events.rb +10 -0
  38. data/db/migrate/20211127015712_drop_webhooks_outgoing_endpoint_event_types.rb +9 -0
  39. data/db/migrate/20211127015713_drop_webhooks_outgoing_event_types.rb +9 -0
  40. data/lib/bullet_train/outgoing_webhooks/engine.rb +7 -0
  41. data/lib/bullet_train/outgoing_webhooks/version.rb +1 -1
  42. metadata +44 -5
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fd1762f370294c608f481e2b2b1ad2782d550180860a2932cda6e926b6400e4a
4
- data.tar.gz: 4f8f18c48c13adbc8f1df26e7eb718572db33c3c8e2c9dd9712c77f6c8467e34
3
+ metadata.gz: e4186cf970999d91997f2410efeba593f422788cec8452978544796176d7ea47
4
+ data.tar.gz: 9700fff07690d45d249e966e29cd233f894b0f77fbffbc4cacf47a637ebb7be6
5
5
  SHA512:
6
- metadata.gz: 0541cf59eb0f505f0bf21ec0cce2a38bb25157f4e42fb568a1b8d9a9baf064b92fe0bb8261503546d0cab15e6a30ac81d447753f96bdc66b2591438117541643
7
- data.tar.gz: 5620e58172c9eecfb6efcf7cde46b38d28d834256bf6e4346b6369d08a23dfa90155e69ae3c3ae466c3aa7ccb85ac6bd1f078e6ec164028ae06b0b18806045b2
6
+ metadata.gz: 7b971859d534310367961541028daef0b95286d02d1bbe202ac954228ed092dacf6180277193d8b4822547838c20d3d60a7efb0eab1e56160eecf48fe7ac6606
7
+ data.tar.gz: 268648e2e285ca1398f4b526529c6a7de6a8e8efd461e73fc68003dd579fb75a335a77d3b461efd9d46b906aebc93bdd0f3fdbd6f8191dd60774deada233c491
@@ -0,0 +1,63 @@
1
+ class Api::V1::Webhooks::Outgoing::DeliveriesEndpoint < Api::V1::Root
2
+ helpers do
3
+ params :endpoint_id do
4
+ requires :endpoint_id, type: Integer, allow_blank: false, desc: "Endpoint ID"
5
+ end
6
+
7
+ params :id do
8
+ requires :id, type: Integer, allow_blank: false, desc: "Delivery ID"
9
+ end
10
+
11
+ params :delivery do
12
+ optional :event_id, type: String, desc: Api.heading(:event_id)
13
+ optional :endpoint_url, type: String, desc: Api.heading(:endpoint_url)
14
+ optional :delivered_at, type: DateTime, desc: Api.heading(:delivered_at)
15
+ # 🚅 super scaffolding will insert new fields above this line.
16
+ # 🚅 super scaffolding will insert new arrays above this line.
17
+
18
+ # 🚅 super scaffolding will insert processing for new fields above this line.
19
+ end
20
+ end
21
+
22
+ resource "webhooks/outgoing/endpoints", desc: Api.title(:collection_actions) do
23
+ after_validation do
24
+ load_and_authorize_api_resource Webhooks::Outgoing::Delivery
25
+ end
26
+
27
+ #
28
+ # INDEX
29
+ #
30
+
31
+ desc Api.title(:index), &Api.index_desc
32
+ params do
33
+ use :endpoint_id
34
+ end
35
+ oauth2
36
+ paginate per_page: 100
37
+ get "/:endpoint_id/deliveries" do
38
+ @paginated_deliveries = paginate @deliveries
39
+ render @paginated_deliveries, serializer: Api.serializer
40
+ end
41
+ end
42
+
43
+ resource "webhooks/outgoing/deliveries", desc: Api.title(:member_actions) do
44
+ after_validation do
45
+ load_and_authorize_api_resource Webhooks::Outgoing::Delivery
46
+ end
47
+
48
+ #
49
+ # SHOW
50
+ #
51
+
52
+ desc Api.title(:show), &Api.show_desc
53
+ params do
54
+ use :id
55
+ end
56
+ oauth2
57
+ route_param :id do
58
+ get do
59
+ render @delivery, serializer: Api.serializer
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,65 @@
1
+ class Api::V1::Webhooks::Outgoing::DeliveryAttemptsEndpoint < Api::V1::Root
2
+ helpers do
3
+ params :delivery_id do
4
+ requires :delivery_id, type: Integer, allow_blank: false, desc: "Delivery ID"
5
+ end
6
+
7
+ params :id do
8
+ requires :id, type: Integer, allow_blank: false, desc: "Delivery Attempt ID"
9
+ end
10
+
11
+ params :delivery_attempt do
12
+ optional :response_code, type: String, desc: Api.heading(:response_code)
13
+ optional :response_body, type: String, desc: Api.heading(:response_body)
14
+ optional :response_message, type: String, desc: Api.heading(:response_message)
15
+ optional :error_message, type: String, desc: Api.heading(:error_message)
16
+ optional :attempt_number, type: String, desc: Api.heading(:attempt_number)
17
+ # 🚅 super scaffolding will insert new fields above this line.
18
+ # 🚅 super scaffolding will insert new arrays above this line.
19
+
20
+ # 🚅 super scaffolding will insert processing for new fields above this line.
21
+ end
22
+ end
23
+
24
+ resource "webhooks/outgoing/deliveries", desc: Api.title(:collection_actions) do
25
+ after_validation do
26
+ load_and_authorize_api_resource Webhooks::Outgoing::DeliveryAttempt
27
+ end
28
+
29
+ #
30
+ # INDEX
31
+ #
32
+
33
+ desc Api.title(:index), &Api.index_desc
34
+ params do
35
+ use :delivery_id
36
+ end
37
+ oauth2
38
+ paginate per_page: 100
39
+ get "/:delivery_id/delivery_attempts" do
40
+ @paginated_delivery_attempts = paginate @delivery_attempts
41
+ render @paginated_delivery_attempts, serializer: Api.serializer
42
+ end
43
+ end
44
+
45
+ resource "webhooks/outgoing/delivery_attempts", desc: Api.title(:member_actions) do
46
+ after_validation do
47
+ load_and_authorize_api_resource Webhooks::Outgoing::DeliveryAttempt
48
+ end
49
+
50
+ #
51
+ # SHOW
52
+ #
53
+
54
+ desc Api.title(:show), &Api.show_desc
55
+ params do
56
+ use :id
57
+ end
58
+ oauth2
59
+ route_param :id do
60
+ get do
61
+ render @delivery_attempt, serializer: Api.serializer
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,119 @@
1
+ class Api::V1::Webhooks::Outgoing::EndpointsEndpoint < Api::V1::Root
2
+ helpers do
3
+ params :team_id do
4
+ requires :team_id, type: Integer, allow_blank: false, desc: "Team ID"
5
+ end
6
+
7
+ params :id do
8
+ requires :id, type: Integer, allow_blank: false, desc: "Endpoint ID"
9
+ end
10
+
11
+ params :endpoint do
12
+ optional :name, type: String, desc: Api.heading(:name)
13
+ optional :url, type: String, desc: Api.heading(:url)
14
+ # 🚅 super scaffolding will insert new fields above this line.
15
+ optional :event_type_ids, type: Array, desc: Api.heading(:event_type_ids)
16
+ # 🚅 super scaffolding will insert new arrays above this line.
17
+
18
+ # 🚅 super scaffolding will insert processing for new fields above this line.
19
+ end
20
+ end
21
+
22
+ resource "teams", desc: Api.title(:collection_actions) do
23
+ after_validation do
24
+ load_and_authorize_api_resource Webhooks::Outgoing::Endpoint
25
+ end
26
+
27
+ #
28
+ # INDEX
29
+ #
30
+
31
+ desc Api.title(:index), &Api.index_desc
32
+ params do
33
+ use :team_id
34
+ end
35
+ oauth2
36
+ paginate per_page: 100
37
+ get "/:team_id/webhooks/outgoing/endpoints" do
38
+ @paginated_endpoints = paginate @endpoints
39
+ render @paginated_endpoints, serializer: Api.serializer
40
+ end
41
+
42
+ #
43
+ # CREATE
44
+ #
45
+
46
+ desc Api.title(:create), &Api.create_desc
47
+ params do
48
+ use :team_id
49
+ use :endpoint
50
+ end
51
+ route_setting :api_resource_options, permission: :create
52
+ oauth2 "write"
53
+ post "/:team_id/webhooks/outgoing/endpoints" do
54
+ if @endpoint.save
55
+ render @endpoint, serializer: Api.serializer
56
+ else
57
+ record_not_saved @endpoint
58
+ end
59
+ end
60
+ end
61
+
62
+ resource "webhooks/outgoing/endpoints", desc: Api.title(:member_actions) do
63
+ after_validation do
64
+ load_and_authorize_api_resource Webhooks::Outgoing::Endpoint
65
+ end
66
+
67
+ #
68
+ # SHOW
69
+ #
70
+
71
+ desc Api.title(:show), &Api.show_desc
72
+ params do
73
+ use :id
74
+ end
75
+ oauth2
76
+ route_param :id do
77
+ get do
78
+ render @endpoint, serializer: Api.serializer
79
+ end
80
+ end
81
+
82
+ #
83
+ # UPDATE
84
+ #
85
+
86
+ desc Api.title(:update), &Api.update_desc
87
+ params do
88
+ use :id
89
+ use :endpoint
90
+ end
91
+ route_setting :api_resource_options, permission: :update
92
+ oauth2 "write"
93
+ route_param :id do
94
+ put do
95
+ if @endpoint.update(declared(params, include_missing: false))
96
+ render @endpoint, serializer: Api.serializer
97
+ else
98
+ record_not_saved @endpoint
99
+ end
100
+ end
101
+ end
102
+
103
+ #
104
+ # DESTROY
105
+ #
106
+
107
+ desc Api.title(:destroy), &Api.destroy_desc
108
+ params do
109
+ use :id
110
+ end
111
+ route_setting :api_resource_options, permission: :destroy
112
+ oauth2 "delete"
113
+ route_param :id do
114
+ delete do
115
+ render @endpoint.destroy, serializer: Api.serializer
116
+ end
117
+ end
118
+ end
119
+ end
@@ -0,0 +1,7 @@
1
+ class Webhooks::Outgoing::DeliveryJob < ApplicationJob
2
+ queue_as :default
3
+
4
+ def perform(delivery)
5
+ delivery.deliver
6
+ end
7
+ end
@@ -0,0 +1,49 @@
1
+ module Webhooks::Outgoing::IssuingModel
2
+ extend ActiveSupport::Concern
3
+
4
+ # define relationships.
5
+ included do
6
+ after_commit :generate_created_webhook, on: [:create]
7
+ after_commit :generate_updated_webhook, on: [:update]
8
+ after_commit :generate_deleted_webhook, on: [:destroy]
9
+ has_many :webhooks_outgoing_events, as: :subject, class_name: "Webhooks::Outgoing::Event", dependent: :nullify
10
+ end
11
+
12
+ # define class methods.
13
+ module ClassMethods
14
+ end
15
+
16
+ def generate_webhook(action)
17
+ # we can only generate webhooks for objects that return their team.
18
+ return unless respond_to? :team
19
+
20
+ # Try to find an event type definition for this action.
21
+ event_type = Webhooks::Outgoing::EventType.find_by(id: "#{self.class.name.underscore}.#{action}")
22
+
23
+ # If the event type is defined as one that people can be subscribed to,
24
+ # and this object has a team where an associated outgoing webhooks endpoint could be registered.
25
+ if event_type && team
26
+
27
+ # Only generate an event record if an endpoint is actually listening for this event type.
28
+ if team.webhooks_outgoing_endpoints.listening_for_event_type_id(event_type.id).any?
29
+ data = "Api::V1::#{self.class.name}Serializer".constantize.new(self).serializable_hash[:data]
30
+ webhook = team.webhooks_outgoing_events.create(event_type_id: event_type.id, subject: self, data: data)
31
+ webhook.deliver
32
+ end
33
+ end
34
+ end
35
+
36
+ def generate_created_webhook
37
+ generate_webhook("created")
38
+ end
39
+
40
+ def generate_updated_webhook
41
+ generate_webhook("updated")
42
+ end
43
+
44
+ def generate_deleted_webhook
45
+ return false unless respond_to?(:team)
46
+ return false if team&.being_destroyed?
47
+ generate_webhook("deleted")
48
+ end
49
+ end
@@ -0,0 +1,15 @@
1
+ module Webhooks::Outgoing::TeamSupport
2
+ extend ActiveSupport::Concern
3
+
4
+ included do
5
+ has_many :webhooks_outgoing_endpoints, class_name: "Webhooks::Outgoing::Endpoint", dependent: :destroy
6
+ has_many :webhooks_outgoing_events, class_name: "Webhooks::Outgoing::Event", dependent: :destroy
7
+
8
+ before_destroy :mark_for_destruction, prepend: true
9
+ end
10
+
11
+ def mark_for_destruction
12
+ # This allows downstream logic to check whether a team is being destroyed in order to bypass webhook issuance.
13
+ update_column(:being_destroyed, true)
14
+ end
15
+ end
@@ -0,0 +1,79 @@
1
+ class Webhooks::Outgoing::Delivery < ApplicationRecord
2
+ # 🚅 add concerns above.
3
+
4
+ belongs_to :endpoint, class_name: "Webhooks::Outgoing::Endpoint"
5
+ belongs_to :event, class_name: "Webhooks::Outgoing::Event"
6
+ has_one :team, through: :endpoint
7
+
8
+ ATTEMPT_SCHEDULE = {
9
+ 1 => 15.seconds,
10
+ 2 => 1.minute,
11
+ 3 => 5.minutes,
12
+ 4 => 15.minutes,
13
+ 5 => 1.hour,
14
+ }
15
+
16
+ # 🚅 add belongs_to associations above.
17
+
18
+ has_many :delivery_attempts, class_name: "Webhooks::Outgoing::DeliveryAttempt", dependent: :destroy, foreign_key: :delivery_id
19
+ # 🚅 add has_many associations above.
20
+
21
+ # 🚅 add has_one associations above.
22
+
23
+ # 🚅 add scopes above.
24
+
25
+ # 🚅 add validations above.
26
+
27
+ # 🚅 add callbacks above.
28
+
29
+ # 🚅 add delegations above.
30
+
31
+ def label_string
32
+ event.short_uuid
33
+ end
34
+
35
+ def next_reattempt_delay
36
+ ATTEMPT_SCHEDULE[attempt_count]
37
+ end
38
+
39
+ def deliver_async
40
+ if still_attempting?
41
+ Webhooks::Outgoing::DeliveryJob.set(wait: next_reattempt_delay).perform_later(self)
42
+ end
43
+ end
44
+
45
+ def deliver
46
+ if delivery_attempts.create.attempt
47
+ touch(:delivered_at)
48
+ else
49
+ deliver_async
50
+ end
51
+ end
52
+
53
+ def attempt_count
54
+ delivery_attempts.count
55
+ end
56
+
57
+ def delivered?
58
+ delivered_at.present?
59
+ end
60
+
61
+ def still_attempting?
62
+ return false if delivered?
63
+ attempt_count < max_attempts
64
+ end
65
+
66
+ def failed?
67
+ !(delivered? || still_attempting?)
68
+ end
69
+
70
+ def name
71
+ event.short_uuid
72
+ end
73
+
74
+ def max_attempts
75
+ ATTEMPT_SCHEDULE.keys.max
76
+ end
77
+
78
+ # 🚅 add methods above.
79
+ end
@@ -0,0 +1,65 @@
1
+ class Webhooks::Outgoing::DeliveryAttempt < ApplicationRecord
2
+ # 🚅 add concerns above.
3
+
4
+ belongs_to :delivery
5
+ has_one :team, through: :delivery
6
+ scope :successful, -> { where(response_code: 200) }
7
+
8
+ before_create do
9
+ self.attempt_number = delivery.attempt_count + 1
10
+ end
11
+
12
+ def still_attempting?
13
+ error_message.nil? && response_code.nil?
14
+ end
15
+
16
+ def successful?
17
+ [200, 201, 202, 203, 204, 205, 206, 207, 226].include?(response_code)
18
+ end
19
+
20
+ def failed?
21
+ !(successful? || still_attempting?)
22
+ end
23
+
24
+ def attempt
25
+ uri = URI.parse(delivery.endpoint_url)
26
+ http = Net::HTTP.new(uri.host, uri.port)
27
+ http.use_ssl = true if uri.scheme == "https"
28
+ request = Net::HTTP::Post.new(uri.path)
29
+ request.add_field("Content-Type", "application/json")
30
+ request.body = delivery.event.payload.to_json
31
+
32
+ begin
33
+ response = http.request(request)
34
+ self.response_message = response.message
35
+ self.response_code = response.code
36
+ self.response_body = response.body
37
+ rescue Exception => exception
38
+ self.response_code = 0
39
+ self.error_message = exception.message
40
+ end
41
+
42
+ save
43
+ successful?
44
+ end
45
+
46
+ def label_string
47
+ "#{attempt_number.ordinalize} Attempt"
48
+ end
49
+ # 🚅 add belongs_to associations above.
50
+
51
+ # 🚅 add has_many associations above.
52
+
53
+ # 🚅 add has_one associations above.
54
+
55
+ # 🚅 add scopes above.
56
+
57
+ validates :response_code, presence: true
58
+ # 🚅 add validations above.
59
+
60
+ # 🚅 add callbacks above.
61
+
62
+ # 🚅 add delegations above.
63
+
64
+ # 🚅 add methods above.
65
+ end
@@ -0,0 +1,32 @@
1
+ class Webhooks::Outgoing::Endpoint < ApplicationRecord
2
+ # 🚅 add concerns above.
3
+
4
+ belongs_to :team
5
+ # 🚅 add belongs_to associations above.
6
+
7
+ has_many :deliveries, class_name: "Webhooks::Outgoing::Delivery", dependent: :destroy, foreign_key: :endpoint_id
8
+ has_many :events, -> { distinct }, through: :deliveries
9
+ # 🚅 add has_many associations above.
10
+
11
+ # 🚅 add has_one associations above.
12
+
13
+ scope :listening_for_event_type_id, ->(event_type_id) { where("event_type_ids @> ? OR event_type_ids = '[]'::jsonb", "\"#{event_type_id}\"") }
14
+ # 🚅 add scopes above.
15
+
16
+ validates :name, presence: true
17
+ # 🚅 add validations above.
18
+
19
+ # 🚅 add callbacks above.
20
+
21
+ # 🚅 add delegations above.
22
+
23
+ def valid_event_types
24
+ Webhooks::Outgoing::EventType.all
25
+ end
26
+
27
+ def event_types
28
+ event_type_ids.map { |id| Webhooks::Outgoing::EventType.find(id) }
29
+ end
30
+
31
+ # 🚅 add methods above.
32
+ end
@@ -0,0 +1,41 @@
1
+ class Webhooks::Outgoing::Event < ApplicationRecord
2
+ include HasUuid
3
+ belongs_to :team
4
+ belongs_to :event_type, class_name: "Webhooks::Outgoing::EventType"
5
+ belongs_to :subject, polymorphic: true
6
+ has_many :deliveries, dependent: :destroy
7
+
8
+ before_create do
9
+ self.payload = generate_payload
10
+ end
11
+
12
+ def generate_payload
13
+ {
14
+ event_id: uuid,
15
+ event_type: event_type_id,
16
+ subject_id: subject_id,
17
+ subject_type: subject_type,
18
+ data: data
19
+ }
20
+ end
21
+
22
+ def event_type_name
23
+ payload.dig("event_type")
24
+ end
25
+
26
+ def endpoints
27
+ team.webhooks_outgoing_endpoints.listening_for_event_type_id(event_type_id)
28
+ end
29
+
30
+ def deliver
31
+ endpoints.each do |endpoint|
32
+ unless endpoint.deliveries.where(event: self).any?
33
+ endpoint.deliveries.create(event: self, endpoint_url: endpoint.url).deliver_async
34
+ end
35
+ end
36
+ end
37
+
38
+ def label_string
39
+ short_uuid
40
+ end
41
+ end
@@ -0,0 +1,13 @@
1
+ class Webhooks::Outgoing::EventType < ApplicationHash
2
+ self.data = YAML.load_file("config/models/webhooks/outgoing/event_types.yml").map do |topic, events|
3
+ events.map { |event| event == "crud" ? ["created", "updated", "deleted"] : event }.flatten.map { |event| {id: "#{topic}.#{event}"} }
4
+ end.flatten
5
+
6
+ def label_string
7
+ name
8
+ end
9
+
10
+ def name
11
+ id
12
+ end
13
+ end
@@ -0,0 +1,5 @@
1
+ module Webhooks::Outgoing
2
+ def self.table_name_prefix
3
+ "webhooks_outgoing_"
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ module Webhooks
2
+ def self.table_name_prefix
3
+ "webhooks_"
4
+ end
5
+ end
@@ -0,0 +1,16 @@
1
+ class Api::V1::Webhooks::Outgoing::DeliveryAttemptSerializer < Api::V1::ApplicationSerializer
2
+ set_type "webhooks/outgoing/delivery_attempt"
3
+
4
+ attributes :id,
5
+ :delivery_id,
6
+ :response_code,
7
+ :response_body,
8
+ :response_message,
9
+ :error_message,
10
+ :attempt_number,
11
+ # 🚅 super scaffolding will insert new fields above this line.
12
+ :created_at,
13
+ :updated_at
14
+
15
+ belongs_to :delivery, serializer: Api::V1::Webhooks::Outgoing::DeliverySerializer
16
+ end
@@ -0,0 +1,14 @@
1
+ class Api::V1::Webhooks::Outgoing::DeliverySerializer < Api::V1::ApplicationSerializer
2
+ set_type "webhooks/outgoing/delivery"
3
+
4
+ attributes :id,
5
+ :endpoint_id,
6
+ :event_id,
7
+ :endpoint_url,
8
+ :delivered_at,
9
+ # 🚅 super scaffolding will insert new fields above this line.
10
+ :created_at,
11
+ :updated_at
12
+
13
+ belongs_to :endpoint, serializer: Api::V1::Webhooks::Outgoing::EndpointSerializer
14
+ end
@@ -0,0 +1,14 @@
1
+ class Api::V1::Webhooks::Outgoing::EndpointSerializer < Api::V1::ApplicationSerializer
2
+ set_type "webhooks/outgoing/endpoint"
3
+
4
+ attributes :id,
5
+ :team_id,
6
+ :name,
7
+ :url,
8
+ :event_type_ids,
9
+ # 🚅 super scaffolding will insert new fields above this line.
10
+ :created_at,
11
+ :updated_at
12
+
13
+ belongs_to :team, serializer: Api::V1::TeamSerializer
14
+ end
@@ -0,0 +1,10 @@
1
+ class CreateWebhooksOutgoingEndpoints < ActiveRecord::Migration[5.2]
2
+ def change
3
+ create_table :webhooks_outgoing_endpoints do |t|
4
+ t.references :team, foreign_key: true
5
+ t.text :url
6
+
7
+ t.timestamps
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ class CreateWebhooksOutgoingEndpointEventTypes < ActiveRecord::Migration[5.2]
2
+ def change
3
+ create_table :webhooks_outgoing_endpoint_event_types do |t|
4
+ t.integer :endpoint_id
5
+ t.integer :event_type_id
6
+
7
+ t.timestamps
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,9 @@
1
+ class CreateWebhooksOutgoingEventTypes < ActiveRecord::Migration[5.2]
2
+ def change
3
+ create_table :webhooks_outgoing_event_types do |t|
4
+ t.string :name
5
+
6
+ t.timestamps
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,12 @@
1
+ class CreateWebhooksOutgoingEvents < ActiveRecord::Migration[5.2]
2
+ def change
3
+ create_table :webhooks_outgoing_events do |t|
4
+ t.integer :event_type_id
5
+ t.integer :subject_id
6
+ t.string :subject_type
7
+ t.jsonb :body
8
+
9
+ t.timestamps
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,11 @@
1
+ class CreateWebhooksOutgoingDeliveries < ActiveRecord::Migration[5.2]
2
+ def change
3
+ create_table :webhooks_outgoing_deliveries do |t|
4
+ t.integer :endpoint_id
5
+ t.integer :event_id
6
+ t.text :endpoint_url
7
+
8
+ t.timestamps
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,5 @@
1
+ class AddTeamToWebhooksOutgoingEvents < ActiveRecord::Migration[5.2]
2
+ def change
3
+ add_reference :webhooks_outgoing_events, :team, foreign_key: true
4
+ end
5
+ end
@@ -0,0 +1,11 @@
1
+ class CreateWebhooksOutgoingDeliveryAttempts < ActiveRecord::Migration[5.2]
2
+ def change
3
+ create_table :webhooks_outgoing_delivery_attempts do |t|
4
+ t.integer :delivery_id
5
+ t.integer :response_code
6
+ t.text :response_body
7
+
8
+ t.timestamps
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,6 @@
1
+ class AddErrorMessageToWebhooksOutgoingDeliveryAttempt < ActiveRecord::Migration[5.2]
2
+ def change
3
+ add_column :webhooks_outgoing_delivery_attempts, :response_message, :text
4
+ add_column :webhooks_outgoing_delivery_attempts, :error_message, :text
5
+ end
6
+ end
@@ -0,0 +1,5 @@
1
+ class AddNameToWebhooksOutgoingEndpoints < ActiveRecord::Migration[5.2]
2
+ def change
3
+ add_column :webhooks_outgoing_endpoints, :name, :string
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ class AddDeliveredAtToWebhooksOutgoingDeliveries < ActiveRecord::Migration[5.2]
2
+ def change
3
+ add_column :webhooks_outgoing_deliveries, :delivered_at, :datetime
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ class AddUuidToWebhooksOutgoingEvents < ActiveRecord::Migration[5.2]
2
+ def change
3
+ add_column :webhooks_outgoing_events, :uuid, :string
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ class AddPayloadToWebhooksOutgoingEvents < ActiveRecord::Migration[5.2]
2
+ def change
3
+ add_column :webhooks_outgoing_events, :payload, :jsonb
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ class AddAttemptNumberToWebhooksOutgoingDeliveryAttempts < ActiveRecord::Migration[5.2]
2
+ def change
3
+ add_column :webhooks_outgoing_delivery_attempts, :attempt_number, :integer
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ class ChangeBodyToDataOnWebhooksOutgoingEvents < ActiveRecord::Migration[6.1]
2
+ def change
3
+ rename_column :webhooks_outgoing_events, :body, :data
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ class AddEventTypeIdsToWebhooksOutgoingEndpoints < ActiveRecord::Migration[6.1]
2
+ def change
3
+ add_column :webhooks_outgoing_endpoints, :event_type_ids, :jsonb, default: []
4
+ end
5
+ end
@@ -0,0 +1,8 @@
1
+ class MigrateEventTypeIdsOnWebhooksOutgoingEndpoints < ActiveRecord::Migration[6.1]
2
+ def change
3
+ Webhooks::Outgoing::Endpoint.find_each do |endpoint|
4
+ event_type_ids = ActiveRecord::Base.connection.execute("SELECT * FROM webhooks_outgoing_endpoint_event_types JOIN webhooks_outgoing_event_types ON webhooks_outgoing_endpoint_event_types.event_type_id = webhooks_outgoing_event_types.id WHERE endpoint_id = #{endpoint.id}").to_a.map { |result| result.dig("name") }
5
+ endpoint.update(event_type_ids: event_type_ids)
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,5 @@
1
+ class RemoveEventTypeFromWebhooksOutgoingEvents < ActiveRecord::Migration[6.1]
2
+ def change
3
+ remove_reference :webhooks_outgoing_events, :event_type, null: false, foreign_key: false
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ class AddNewEventTypeIdToWebhooksOutgoingEvents < ActiveRecord::Migration[6.1]
2
+ def change
3
+ add_column :webhooks_outgoing_events, :event_type_id, :string
4
+ end
5
+ end
@@ -0,0 +1,10 @@
1
+ class MigrateEventTypesOnWebhooksOutgoingEvents < ActiveRecord::Migration[6.1]
2
+ def up
3
+ Webhooks::Outgoing::Event.find_each do |event|
4
+ event.update_column(:event_type_id, event.payload.dig("event_type"))
5
+ end
6
+ end
7
+
8
+ def down
9
+ end
10
+ end
@@ -0,0 +1,9 @@
1
+ class DropWebhooksOutgoingEndpointEventTypes < ActiveRecord::Migration[6.1]
2
+ def up
3
+ drop_table :webhooks_outgoing_endpoint_event_types
4
+ end
5
+
6
+ def down
7
+ raise ActiveRecord::IrreversibleMigration
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ class DropWebhooksOutgoingEventTypes < ActiveRecord::Migration[6.1]
2
+ def up
3
+ drop_table :webhooks_outgoing_event_types
4
+ end
5
+
6
+ def down
7
+ raise ActiveRecord::IrreversibleMigration
8
+ end
9
+ end
@@ -1,6 +1,13 @@
1
1
  module BulletTrain
2
2
  module OutgoingWebhooks
3
3
  class Engine < ::Rails::Engine
4
+ initializer "bullet_train.outgoing_webhooks.register_api_endpoints" do |app|
5
+ if BulletTrain::Api
6
+ BulletTrain::Api.endpoints << "Api::V1::Webhooks::Outgoing::EndpointsEndpoint"
7
+ BulletTrain::Api.endpoints << "Api::V1::Webhooks::Outgoing::DeliveriesEndpoint"
8
+ BulletTrain::Api.endpoints << "Api::V1::Webhooks::Outgoing::DeliveryAttemptsEndpoint"
9
+ end
10
+ end
4
11
  end
5
12
  end
6
13
  end
@@ -1,5 +1,5 @@
1
1
  module BulletTrain
2
2
  module OutgoingWebhooks
3
- VERSION = "1.0.3"
3
+ VERSION = "1.0.4"
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.0.3
4
+ version: 1.0.4
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-01-23 00:00:00.000000000 Z
11
+ date: 2022-02-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -24,7 +24,8 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: 7.0.0
27
- description: Bullet Train Outgoing Webhooks
27
+ description: Allow users of your Rails application to subscribe and receive webhooks
28
+ when activity takes place in your application.
28
29
  email:
29
30
  - andrew.culver@gmail.com
30
31
  executables: []
@@ -34,10 +35,26 @@ files:
34
35
  - MIT-LICENSE
35
36
  - README.md
36
37
  - Rakefile
37
- - app/assets/config/bullet_train_outgoing_webhooks_web_manifest.js
38
+ - app/assets/config/bullet_train_outgoing_webhooks_manifest.js
38
39
  - app/controllers/account/webhooks/outgoing/deliveries_controller.rb
39
40
  - app/controllers/account/webhooks/outgoing/delivery_attempts_controller.rb
40
41
  - app/controllers/account/webhooks/outgoing/endpoints_controller.rb
42
+ - app/controllers/api/v1/webhooks/outgoing/deliveries_endpoint.rb
43
+ - app/controllers/api/v1/webhooks/outgoing/delivery_attempts_endpoint.rb
44
+ - app/controllers/api/v1/webhooks/outgoing/endpoints_endpoint.rb
45
+ - app/jobs/webhooks/outgoing/delivery_job.rb
46
+ - app/models/concerns/webhooks/outgoing/issuing_model.rb
47
+ - app/models/concerns/webhooks/outgoing/team_support.rb
48
+ - app/models/webhooks.rb
49
+ - app/models/webhooks/outgoing.rb
50
+ - app/models/webhooks/outgoing/delivery.rb
51
+ - app/models/webhooks/outgoing/delivery_attempt.rb
52
+ - app/models/webhooks/outgoing/endpoint.rb
53
+ - app/models/webhooks/outgoing/event.rb
54
+ - app/models/webhooks/outgoing/event_type.rb
55
+ - app/serializers/api/v1/webhooks/outgoing/delivery_attempt_serializer.rb
56
+ - app/serializers/api/v1/webhooks/outgoing/delivery_serializer.rb
57
+ - app/serializers/api/v1/webhooks/outgoing/endpoint_serializer.rb
41
58
  - app/views/account/webhooks/outgoing/deliveries/_breadcrumbs.html.erb
42
59
  - app/views/account/webhooks/outgoing/deliveries/_delivery.json.jbuilder
43
60
  - app/views/account/webhooks/outgoing/deliveries/_form.html.erb
@@ -78,6 +95,27 @@ files:
78
95
  - config/locales/en/webhooks/outgoing/endpoints.en.yml
79
96
  - config/locales/en/webhooks/outgoing/events.en.yml
80
97
  - config/routes.rb
98
+ - db/migrate/20180420013127_create_webhooks_outgoing_endpoints.rb
99
+ - db/migrate/20180420013505_create_webhooks_outgoing_endpoint_event_types.rb
100
+ - db/migrate/20180420013852_create_webhooks_outgoing_event_types.rb
101
+ - db/migrate/20180420014623_create_webhooks_outgoing_events.rb
102
+ - db/migrate/20180420021016_create_webhooks_outgoing_deliveries.rb
103
+ - db/migrate/20180420022027_add_team_to_webhooks_outgoing_events.rb
104
+ - db/migrate/20180420165345_create_webhooks_outgoing_delivery_attempts.rb
105
+ - db/migrate/20180420172112_add_error_message_to_webhooks_outgoing_delivery_attempt.rb
106
+ - db/migrate/20181012234232_add_name_to_webhooks_outgoing_endpoints.rb
107
+ - db/migrate/20181013030208_add_delivered_at_to_webhooks_outgoing_deliveries.rb
108
+ - db/migrate/20181013165056_add_uuid_to_webhooks_outgoing_events.rb
109
+ - db/migrate/20181013174539_add_payload_to_webhooks_outgoing_events.rb
110
+ - db/migrate/20181013192951_add_attempt_number_to_webhooks_outgoing_delivery_attempts.rb
111
+ - db/migrate/20210805060451_change_body_to_data_on_webhooks_outgoing_events.rb
112
+ - db/migrate/20211126230846_add_event_type_ids_to_webhooks_outgoing_endpoints.rb
113
+ - db/migrate/20211126230847_migrate_event_type_ids_on_webhooks_outgoing_endpoints.rb
114
+ - db/migrate/20211127013539_remove_event_type_from_webhooks_outgoing_events.rb
115
+ - db/migrate/20211127013800_add_new_event_type_id_to_webhooks_outgoing_events.rb
116
+ - db/migrate/20211127014001_migrate_event_types_on_webhooks_outgoing_events.rb
117
+ - db/migrate/20211127015712_drop_webhooks_outgoing_endpoint_event_types.rb
118
+ - db/migrate/20211127015713_drop_webhooks_outgoing_event_types.rb
81
119
  - lib/bullet_train/outgoing_webhooks.rb
82
120
  - lib/bullet_train/outgoing_webhooks/engine.rb
83
121
  - lib/bullet_train/outgoing_webhooks/version.rb
@@ -106,5 +144,6 @@ requirements: []
106
144
  rubygems_version: 3.2.22
107
145
  signing_key:
108
146
  specification_version: 4
109
- summary: Bullet Train Outgoing Webhooks
147
+ summary: Allow users of your Rails application to subscribe and receive webhooks when
148
+ activity takes place in your application.
110
149
  test_files: []