action_hooks 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 +7 -0
- data/CHANGELOG.md +5 -0
- data/LICENSE.txt +21 -0
- data/README.md +119 -0
- data/lib/action_hooks/configuration.rb +43 -0
- data/lib/action_hooks/engine.rb +9 -0
- data/lib/action_hooks/version.rb +5 -0
- data/lib/action_hooks/webhook_controller_behavior.rb +68 -0
- data/lib/action_hooks.rb +10 -0
- data/lib/generators/action_hooks/install/install_generator.rb +26 -0
- data/lib/generators/action_hooks/install/templates/action_hooks.rb +20 -0
- data/lib/generators/action_hooks/install/templates/create_webhook_requests.rb.erb +14 -0
- data/lib/generators/action_hooks/webhook/templates/controller.rb.erb +9 -0
- data/lib/generators/action_hooks/webhook/webhook_generator.rb +18 -0
- metadata +156 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 064ad39bd578ac07aaf40f9bbc3551a7f8134a8543666533c7346782ec38a7d2
|
|
4
|
+
data.tar.gz: f1f6e53ed1cd91f80ebbea439c765aa7a7ec9cae4a7ff315f3230b51fb92a388
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 29b792245c0630a7542e2189baaf89724090400baed65d26931e7d3fd513bf6f38092868ea9e0e7010b0940dcaa23058367ecde6387394c25c8519aa4990cb59
|
|
7
|
+
data.tar.gz: b166f6b4be57655cbab8449eba6ed16d9dfe54f8c0eb2449a6362ff24492dc4c7770391fc07da69c832b008e0d477f7b3b8475e1958daf2ebc287dfbd611a557
|
data/CHANGELOG.md
ADDED
data/LICENSE.txt
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Alexey Poimtsev
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
|
13
|
+
all copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
# ActionHooks
|
|
2
|
+
|
|
3
|
+
ActionHooks is a Ruby on Rails engine designed to securely handle incoming webhooks. It standardizes the process of receiving webhooks from various third-party services (like Stripe, GitHub, etc.) by:
|
|
4
|
+
|
|
5
|
+
1. **Persisting Webhooks:** Saving all incoming requests to the database (`webhook_requests` table) with their payload, source, and processing state before any business logic is executed.
|
|
6
|
+
2. **Security & Verification:** Verifying the authenticity of the webhook via signature validation logic and optionally restricting access by IP address.
|
|
7
|
+
3. **Asynchronous Processing:** Automatically dispatching the saved webhook to a configured background worker (`ActiveJob`) for asynchronous processing.
|
|
8
|
+
|
|
9
|
+
## Installation
|
|
10
|
+
|
|
11
|
+
Add this line to your application's Gemfile:
|
|
12
|
+
|
|
13
|
+
```ruby
|
|
14
|
+
gem "action_hooks"
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
And then execute:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
$ bundle install
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
After installing the gem, you need to run the installation generator. This will create the necessary database migration for the `webhook_requests` table and an initializer file.
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
$ rails generate action_hooks:install
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Run the database migrations:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
$ rails db:migrate
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Usage
|
|
36
|
+
|
|
37
|
+
### 1. Configuration
|
|
38
|
+
|
|
39
|
+
Configure your webhook sources in the generated initializer (`config/initializers/action_hooks.rb`). Each source represents a third-party service sending webhooks to your application.
|
|
40
|
+
|
|
41
|
+
```ruby
|
|
42
|
+
# config/initializers/action_hooks.rb
|
|
43
|
+
ActionHooks.configure do |config|
|
|
44
|
+
config.add_source(:stripe) do |source|
|
|
45
|
+
# The ActiveJob worker class that will process the webhook
|
|
46
|
+
source.worker = "StripeWebhookWorker"
|
|
47
|
+
|
|
48
|
+
# Lambda to verify the signature of the incoming request
|
|
49
|
+
source.verify_signature = ->(request) do
|
|
50
|
+
payload = request.body.read
|
|
51
|
+
sig_header = request.env['HTTP_STRIPE_SIGNATURE']
|
|
52
|
+
# Example using Stripe's library:
|
|
53
|
+
# Stripe::Webhook::Signature.verify_header(payload, sig_header, ENV['STRIPE_WEBHOOK_SECRET'])
|
|
54
|
+
true
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# Optional: Restrict incoming requests to specific IP addresses
|
|
58
|
+
# source.allowed_ips = ["127.0.0.1", "10.0.0.1"]
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### 2. Generating a Webhook Controller
|
|
64
|
+
|
|
65
|
+
To create an endpoint for a configured source, use the webhook generator. Pass the name of the source as an argument:
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
$ rails generate action_hooks:webhook stripe
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
This will:
|
|
72
|
+
1. Create a controller at `app/controllers/stripe_webhooks_controller.rb`.
|
|
73
|
+
2. Add a route to `config/routes.rb` (e.g., `post "webhooks/stripe", to: "stripe_webhooks#create"`).
|
|
74
|
+
|
|
75
|
+
The generated controller includes `ActionHooks::WebhookControllerBehavior`, which handles everything from skipping CSRF verification, verifying the IP and signature, saving the request to the database, and enqueueing your worker.
|
|
76
|
+
|
|
77
|
+
### 3. Processing the Webhook
|
|
78
|
+
|
|
79
|
+
Create the worker class that you specified in your configuration. The worker will receive the ID of the `ActionHooks::WebhookRequest` record.
|
|
80
|
+
|
|
81
|
+
```ruby
|
|
82
|
+
# app/jobs/stripe_webhook_worker.rb
|
|
83
|
+
class StripeWebhookWorker < ApplicationJob
|
|
84
|
+
queue_as :default
|
|
85
|
+
|
|
86
|
+
def perform(webhook_request_id)
|
|
87
|
+
webhook_request = ActionHooks::WebhookRequest.find(webhook_request_id)
|
|
88
|
+
|
|
89
|
+
# Access the parsed JSON payload
|
|
90
|
+
payload = webhook_request.payload
|
|
91
|
+
|
|
92
|
+
# Process the payload...
|
|
93
|
+
if payload['type'] == 'payment_intent.succeeded'
|
|
94
|
+
# Do something
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
# Update the state of the webhook request when done
|
|
98
|
+
webhook_request.processed!
|
|
99
|
+
rescue => e
|
|
100
|
+
# Mark as failed if something goes wrong
|
|
101
|
+
webhook_request.failed!
|
|
102
|
+
raise e
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
## Development
|
|
108
|
+
|
|
109
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests.
|
|
110
|
+
|
|
111
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
|
112
|
+
|
|
113
|
+
## Contributing
|
|
114
|
+
|
|
115
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/alec-c4/action_hooks.
|
|
116
|
+
|
|
117
|
+
## License
|
|
118
|
+
|
|
119
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ActionHooks
|
|
4
|
+
class SourceNotDefinedError < StandardError; end
|
|
5
|
+
|
|
6
|
+
class Source
|
|
7
|
+
attr_accessor :name, :worker, :verify_signature, :allowed_ips
|
|
8
|
+
|
|
9
|
+
def initialize(name)
|
|
10
|
+
@name = name
|
|
11
|
+
@verify_signature = ->(_request) { true }
|
|
12
|
+
@allowed_ips = []
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
class Configuration
|
|
17
|
+
def initialize
|
|
18
|
+
@sources = {}
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def add_source(name)
|
|
22
|
+
source = Source.new(name)
|
|
23
|
+
yield(source) if block_given?
|
|
24
|
+
@sources[name.to_sym] = source
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def source(name)
|
|
28
|
+
@sources.fetch(name.to_sym)
|
|
29
|
+
rescue KeyError
|
|
30
|
+
raise SourceNotDefinedError, "Source :#{name} is not defined in ActionHooks configuration"
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
class << self
|
|
35
|
+
def configuration
|
|
36
|
+
@configuration ||= Configuration.new
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def configure
|
|
40
|
+
yield(configuration)
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ActionHooks
|
|
4
|
+
module WebhookControllerBehavior
|
|
5
|
+
extend ActiveSupport::Concern
|
|
6
|
+
|
|
7
|
+
included do
|
|
8
|
+
# Skip CSRF since webhooks are typically APIs
|
|
9
|
+
skip_before_action :verify_authenticity_token, raise: false if respond_to?(:skip_before_action)
|
|
10
|
+
|
|
11
|
+
before_action :verify_webhook_ip!
|
|
12
|
+
before_action :verify_webhook_signature!
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def create
|
|
16
|
+
payload = parse_webhook_payload
|
|
17
|
+
|
|
18
|
+
webhook_request = ActionHooks::WebhookRequest.create!(
|
|
19
|
+
source: webhook_source_name.to_s,
|
|
20
|
+
payload: payload,
|
|
21
|
+
state: :pending
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
worker_class = webhook_source_config.worker
|
|
25
|
+
worker_class&.constantize&.perform_later(webhook_request.id)
|
|
26
|
+
|
|
27
|
+
head :ok
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
private
|
|
31
|
+
|
|
32
|
+
def webhook_source_name
|
|
33
|
+
# To be overridden or inferred by the controller
|
|
34
|
+
self.class.name.sub(/WebhooksController$/, "").underscore
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def webhook_source_config
|
|
38
|
+
ActionHooks.configuration.source(webhook_source_name)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def verify_webhook_ip!
|
|
42
|
+
allowed_ips = webhook_source_config.allowed_ips
|
|
43
|
+
return if allowed_ips.empty?
|
|
44
|
+
|
|
45
|
+
unless allowed_ips.include?(request.remote_ip)
|
|
46
|
+
head :forbidden
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def verify_webhook_signature!
|
|
51
|
+
unless webhook_source_config.verify_signature.call(request)
|
|
52
|
+
head :unauthorized
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def parse_webhook_payload
|
|
57
|
+
if request.content_type == "application/json"
|
|
58
|
+
JSON.parse(request.body.read).tap do
|
|
59
|
+
request.body.rewind
|
|
60
|
+
end
|
|
61
|
+
else
|
|
62
|
+
request.parameters.except(:controller, :action).to_unsafe_h
|
|
63
|
+
end
|
|
64
|
+
rescue JSON::ParserError
|
|
65
|
+
{}
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
data/lib/action_hooks.rb
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "action_hooks/version"
|
|
4
|
+
require_relative "action_hooks/configuration"
|
|
5
|
+
|
|
6
|
+
module ActionHooks
|
|
7
|
+
class Error < StandardError; end
|
|
8
|
+
end
|
|
9
|
+
require "action_hooks/engine"
|
|
10
|
+
require "action_hooks/webhook_controller_behavior"
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
require "rails/generators"
|
|
2
|
+
require "rails/generators/active_record"
|
|
3
|
+
|
|
4
|
+
module ActionHooks
|
|
5
|
+
module Generators
|
|
6
|
+
class InstallGenerator < ::Rails::Generators::Base
|
|
7
|
+
include ::Rails::Generators::Migration
|
|
8
|
+
|
|
9
|
+
source_root File.expand_path("templates", __dir__)
|
|
10
|
+
|
|
11
|
+
desc "Installs ActionHooks migration and initializer"
|
|
12
|
+
|
|
13
|
+
def self.next_migration_number(dirname)
|
|
14
|
+
::ActiveRecord::Generators::Base.next_migration_number(dirname)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def create_migration_file
|
|
18
|
+
migration_template "create_webhook_requests.rb.erb", "db/migrate/create_webhook_requests.rb"
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def create_initializer_file
|
|
22
|
+
template "action_hooks.rb", "config/initializers/action_hooks.rb"
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
ActionHooks.configure do |config|
|
|
4
|
+
# Example Configuration for Stripe
|
|
5
|
+
# config.add_source(:stripe) do |source|
|
|
6
|
+
# source.worker = "StripeWebhookWorker" # Ensure you have this ActiveJob defined
|
|
7
|
+
#
|
|
8
|
+
# # Verify signature logic (returns a boolean)
|
|
9
|
+
# source.verify_signature = ->(request) do
|
|
10
|
+
# # Example:
|
|
11
|
+
# # payload = request.body.read
|
|
12
|
+
# # sig_header = request.env['HTTP_STRIPE_SIGNATURE']
|
|
13
|
+
# # Stripe::Webhook::Signature.verify_header(payload, sig_header, 'whsec_...', tolerance: Stripe::Webhook::DEFAULT_TOLERANCE)
|
|
14
|
+
# true
|
|
15
|
+
# end
|
|
16
|
+
#
|
|
17
|
+
# # Optional: IP allowlist
|
|
18
|
+
# # source.allowed_ips = ["127.0.0.1", "10.0.0.1"]
|
|
19
|
+
# end
|
|
20
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
class CreateWebhookRequests < ActiveRecord::Migration[<%= ActiveRecord::Migration.current_version %>]
|
|
2
|
+
def change
|
|
3
|
+
create_table :webhook_requests, id: :uuid do |t|
|
|
4
|
+
t.jsonb :payload, default: {}, null: false
|
|
5
|
+
t.string :source, null: false
|
|
6
|
+
t.integer :state, null: false, default: 0
|
|
7
|
+
|
|
8
|
+
t.timestamps
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
add_index :webhook_requests, :source
|
|
12
|
+
add_index :webhook_requests, :state
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
require "rails/generators"
|
|
2
|
+
|
|
3
|
+
module ActionHooks
|
|
4
|
+
module Generators
|
|
5
|
+
class WebhookGenerator < ::Rails::Generators::NamedBase
|
|
6
|
+
source_root File.expand_path("templates", __dir__)
|
|
7
|
+
desc "Creates a webhook controller for a given source and adds its route."
|
|
8
|
+
|
|
9
|
+
def create_controller_file
|
|
10
|
+
template "controller.rb.erb", "app/controllers/#{file_name}_webhooks_controller.rb"
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def add_route
|
|
14
|
+
route %(post "webhooks/#{file_name}", to: "#{file_name}_webhooks#create")
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: action_hooks
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Alexey Poimtsev
|
|
8
|
+
bindir: exe
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
|
+
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: rails
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - ">="
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: '7.0'
|
|
19
|
+
type: :runtime
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - ">="
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: '7.0'
|
|
26
|
+
- !ruby/object:Gem::Dependency
|
|
27
|
+
name: bundler
|
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
|
29
|
+
requirements:
|
|
30
|
+
- - ">="
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: '2.0'
|
|
33
|
+
type: :development
|
|
34
|
+
prerelease: false
|
|
35
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
36
|
+
requirements:
|
|
37
|
+
- - ">="
|
|
38
|
+
- !ruby/object:Gem::Version
|
|
39
|
+
version: '2.0'
|
|
40
|
+
- !ruby/object:Gem::Dependency
|
|
41
|
+
name: rake
|
|
42
|
+
requirement: !ruby/object:Gem::Requirement
|
|
43
|
+
requirements:
|
|
44
|
+
- - "~>"
|
|
45
|
+
- !ruby/object:Gem::Version
|
|
46
|
+
version: '13.0'
|
|
47
|
+
type: :development
|
|
48
|
+
prerelease: false
|
|
49
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
50
|
+
requirements:
|
|
51
|
+
- - "~>"
|
|
52
|
+
- !ruby/object:Gem::Version
|
|
53
|
+
version: '13.0'
|
|
54
|
+
- !ruby/object:Gem::Dependency
|
|
55
|
+
name: rspec
|
|
56
|
+
requirement: !ruby/object:Gem::Requirement
|
|
57
|
+
requirements:
|
|
58
|
+
- - "~>"
|
|
59
|
+
- !ruby/object:Gem::Version
|
|
60
|
+
version: '3.0'
|
|
61
|
+
type: :development
|
|
62
|
+
prerelease: false
|
|
63
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
64
|
+
requirements:
|
|
65
|
+
- - "~>"
|
|
66
|
+
- !ruby/object:Gem::Version
|
|
67
|
+
version: '3.0'
|
|
68
|
+
- !ruby/object:Gem::Dependency
|
|
69
|
+
name: rspec-rails
|
|
70
|
+
requirement: !ruby/object:Gem::Requirement
|
|
71
|
+
requirements:
|
|
72
|
+
- - ">="
|
|
73
|
+
- !ruby/object:Gem::Version
|
|
74
|
+
version: '0'
|
|
75
|
+
type: :development
|
|
76
|
+
prerelease: false
|
|
77
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
78
|
+
requirements:
|
|
79
|
+
- - ">="
|
|
80
|
+
- !ruby/object:Gem::Version
|
|
81
|
+
version: '0'
|
|
82
|
+
- !ruby/object:Gem::Dependency
|
|
83
|
+
name: appraisal
|
|
84
|
+
requirement: !ruby/object:Gem::Requirement
|
|
85
|
+
requirements:
|
|
86
|
+
- - ">="
|
|
87
|
+
- !ruby/object:Gem::Version
|
|
88
|
+
version: '0'
|
|
89
|
+
type: :development
|
|
90
|
+
prerelease: false
|
|
91
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
92
|
+
requirements:
|
|
93
|
+
- - ">="
|
|
94
|
+
- !ruby/object:Gem::Version
|
|
95
|
+
version: '0'
|
|
96
|
+
- !ruby/object:Gem::Dependency
|
|
97
|
+
name: sqlite3
|
|
98
|
+
requirement: !ruby/object:Gem::Requirement
|
|
99
|
+
requirements:
|
|
100
|
+
- - ">="
|
|
101
|
+
- !ruby/object:Gem::Version
|
|
102
|
+
version: '0'
|
|
103
|
+
type: :development
|
|
104
|
+
prerelease: false
|
|
105
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
106
|
+
requirements:
|
|
107
|
+
- - ">="
|
|
108
|
+
- !ruby/object:Gem::Version
|
|
109
|
+
version: '0'
|
|
110
|
+
description: Save all incoming webhooks to the database, dispatch them to background
|
|
111
|
+
workers, and verify request signatures or IPs.
|
|
112
|
+
email:
|
|
113
|
+
- alexey.poimtsev@gmail.com
|
|
114
|
+
executables: []
|
|
115
|
+
extensions: []
|
|
116
|
+
extra_rdoc_files: []
|
|
117
|
+
files:
|
|
118
|
+
- CHANGELOG.md
|
|
119
|
+
- LICENSE.txt
|
|
120
|
+
- README.md
|
|
121
|
+
- lib/action_hooks.rb
|
|
122
|
+
- lib/action_hooks/configuration.rb
|
|
123
|
+
- lib/action_hooks/engine.rb
|
|
124
|
+
- lib/action_hooks/version.rb
|
|
125
|
+
- lib/action_hooks/webhook_controller_behavior.rb
|
|
126
|
+
- lib/generators/action_hooks/install/install_generator.rb
|
|
127
|
+
- lib/generators/action_hooks/install/templates/action_hooks.rb
|
|
128
|
+
- lib/generators/action_hooks/install/templates/create_webhook_requests.rb.erb
|
|
129
|
+
- lib/generators/action_hooks/webhook/templates/controller.rb.erb
|
|
130
|
+
- lib/generators/action_hooks/webhook/webhook_generator.rb
|
|
131
|
+
homepage: https://github.com/alec-c4/action_hooks
|
|
132
|
+
licenses:
|
|
133
|
+
- MIT
|
|
134
|
+
metadata:
|
|
135
|
+
homepage_uri: https://github.com/alec-c4/action_hooks
|
|
136
|
+
source_code_uri: https://github.com/alec-c4/action_hooks
|
|
137
|
+
changelog_uri: https://github.com/alec-c4/action_hooks/blob/main/CHANGELOG.md
|
|
138
|
+
rubygems_mfa_required: 'true'
|
|
139
|
+
rdoc_options: []
|
|
140
|
+
require_paths:
|
|
141
|
+
- lib
|
|
142
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
143
|
+
requirements:
|
|
144
|
+
- - ">="
|
|
145
|
+
- !ruby/object:Gem::Version
|
|
146
|
+
version: 3.2.0
|
|
147
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
148
|
+
requirements:
|
|
149
|
+
- - ">="
|
|
150
|
+
- !ruby/object:Gem::Version
|
|
151
|
+
version: '0'
|
|
152
|
+
requirements: []
|
|
153
|
+
rubygems_version: 4.0.7
|
|
154
|
+
specification_version: 4
|
|
155
|
+
summary: A Ruby gem for handling incoming webhooks securely.
|
|
156
|
+
test_files: []
|