You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/handler_plugins.md
+59-9Lines changed: 59 additions & 9 deletions
Original file line number
Diff line number
Diff line change
@@ -4,26 +4,33 @@ This document provides in-depth information about handler plugins and how you ca
4
4
5
5
## Writing a Handler Plugin
6
6
7
-
Handler plugins are Ruby classes that extend the `Hooks::Plugins::Handlers::Base` class. They are used to process webhook payloads and can do anything you want. They follow a very simple interface that allows you to define a `call` method that takes three parameters: `payload`, `headers`, and `config`. The `call` method should return a hash with the response data. The hash that this method returns will be sent back to the webhook sender as a JSON response.
7
+
Handler plugins are Ruby classes that extend the `Hooks::Plugins::Handlers::Base` class. They are used to process webhook payloads and can do anything you want. They follow a very simple interface that allows you to define a `call` method that takes four parameters: `payload`, `headers`, `env`, and `config`.
8
+
9
+
**Important:** The `call` method should return a hash by default. Since the server now defaults to JSON format, any hash returned by the handler will be automatically converted to JSON with the correct `Content-Type: application/json` headers set by Grape. This ensures consistent API responses and proper JSON serialization.
8
10
9
11
-`payload`: The webhook payload, which can be a Hash or a String. This is the data that the webhook sender sends to your endpoint.
10
12
-`headers`: A Hash of HTTP headers that were sent with the webhook request.
11
13
-`env`: A modified Rack environment that contains a lot of context about the request. This includes information about the request method, path, query parameters, and more. See [`rack_env_builder.rb`](../lib/hooks/app/rack_env_builder.rb) for the complete list of available keys.
12
14
-`config`: A Hash containing the endpoint configuration. This can include any additional settings or parameters that you want to use in your handler. Most of the time, this won't be used but sometimes endpoint configs add `opts` that can be useful for the handler.
13
15
16
+
The method should return a **hash** that will be automatically serialized to JSON format with appropriate headers. The server defaults to JSON format for both input and output processing.
17
+
14
18
```ruby
15
19
# example file path: plugins/handlers/example.rb
16
20
classExample < Hooks::Plugins::Handlers::Base
17
21
# Process a webhook payload
18
22
#
19
23
#@parampayload[Hash, String] webhook payload (pure JSON with string keys)
**Best Practice**: Always return a hash from your handler's `call` method. The hash will be automatically serialized to JSON and sent to the webhook sender with proper headers. This ensures consistent API responses and proper JSON formatting.
62
+
63
+
Example response format:
64
+
65
+
```json
66
+
{
67
+
"status": "success",
68
+
"message": "webhook processed successfully",
69
+
"data": {
70
+
"processed_at": "2023-10-01T12:34:56Z",
71
+
"items_processed": 5
72
+
}
73
+
}
74
+
```
75
+
76
+
> **Note**: The JSON format behavior can be configured using the `default_format` option in your global configuration. See the [Configuration documentation](./configuration.md) for more details.
77
+
46
78
### `payload` Parameter
47
79
48
80
The `payload` parameter can be a Hash or a String. If the payload is a String, it will be parsed as JSON. If it is a Hash, it will be passed directly to the handler. The payload can contain any data that the webhook sender wants to send.
@@ -159,6 +191,8 @@ The `log.debug`, `log.info`, `log.warn`, and `log.error` methods are available i
159
191
160
192
All handler plugins have access to the `error!` method, which is used to raise an error with a specific message and HTTP status code. This is useful for returning error responses to the webhook sender.
161
193
194
+
When using `error!` with the default JSON format, both hash and string responses are handled appropriately:
195
+
162
196
```ruby
163
197
class Example < Hooks::Plugins::Handlers::Base
164
198
# Example webhook handler
@@ -167,11 +201,12 @@ class Example < Hooks::Plugins::Handlers::Base
# @param env [Hash] A modified Rack environment that contains a lot of context about the request
169
203
# @param config [Hash] Endpoint configuration
170
-
# @return [Hash] Response data
204
+
# @return [Hash] Response data (automatically converted to JSON)
171
205
def call(payload:, headers:, env:, config:)
172
206
173
207
if payload.nil? || payload.empty?
174
208
log.error("Payload is empty or nil")
209
+
# String errors are JSON-encoded with default format
175
210
error!("Payload cannot be empty or nil", 400)
176
211
end
177
212
@@ -182,21 +217,22 @@ class Example < Hooks::Plugins::Handlers::Base
182
217
end
183
218
```
184
219
185
-
You can also use the `error!` method to return a JSON response as well:
220
+
**Recommended approach**: Use hash-based error responses for consistent JSON structure:
186
221
187
222
```ruby
188
223
class Example < Hooks::Plugins::Handlers::Base
189
224
def call(payload:, headers:, env:, config:)
190
225
191
226
if payload.nil? || payload.empty?
192
227
log.error("Payload is empty or nil")
228
+
# Hash errors are automatically converted to JSON
193
229
error!({
194
230
error: "payload_empty",
195
231
message: "the payload cannot be empty or nil",
196
232
success: false,
197
233
custom_value: "some_custom_value",
198
234
request_id: env["hooks.request_id"]
199
-
}, 500)
235
+
}, 400)
200
236
end
201
237
202
238
return {
@@ -206,6 +242,18 @@ class Example < Hooks::Plugins::Handlers::Base
206
242
end
207
243
```
208
244
245
+
This will return a properly formatted JSON error response:
246
+
247
+
```json
248
+
{
249
+
"error": "payload_empty",
250
+
"message": "the payload cannot be empty or nil",
251
+
"success": false,
252
+
"custom_value": "some_custom_value",
253
+
"request_id": "uuid-here"
254
+
}
255
+
```
256
+
209
257
### `#Retryable.with_context(:default)`
210
258
211
259
This method uses a default `Retryable` context to handle retries. It is used to wrap the execution of a block of code that may need to be retried in case of failure.
@@ -220,7 +268,7 @@ class Example < Hooks::Plugins::Handlers::Base
0 commit comments