From b4a149a5f321be5c19503e158d2a83e9a010dda8 Mon Sep 17 00:00:00 2001 From: Mike Hillyer Date: Tue, 14 Nov 2023 18:18:42 -0500 Subject: [PATCH] Add samples for webhooks to the example config, update webhooks docs page with helper info. --- docs/userguide/configuration/example.md | 11 ++++ docs/userguide/operation/webhooks.md | 82 +++++++++++++++++++++++++ 2 files changed, 93 insertions(+) diff --git a/docs/userguide/configuration/example.md b/docs/userguide/configuration/example.md index f6e3b50b..f6ad0dd6 100644 --- a/docs/userguide/configuration/example.md +++ b/docs/userguide/configuration/example.md @@ -32,6 +32,7 @@ local queue_module = require 'policy-extras.queue' local listener_domains = require 'policy-extras.listener_domains' local sources = require 'policy-extras.sources' local dkim_sign = require 'policy-extras.dkim_sign' +local log_hooks = require 'policy-extras.log_hooks' -- Load TSA shaper tools local shaping_config = '/opt/kumomta/etc/policy/shaping.toml' @@ -123,6 +124,16 @@ kumo.on('init', function() -- kumo.configure_redis_throttles { node = 'redis://127.0.0.1/' } end) -- END OF THE INIT EVENT +-- Send a JSON webhook to a local network host. +-- See https://docs.kumomta.com/userguide/operation/webhooks/ +log_hooks:new_json { + name = "webhook", + url = "http://10.0.0.1:4242/log", + log_parameters = { + headers = { 'Subject', 'X-Customer-ID' }, + }, +} + -- Configure listener domains for relay, oob bounces, and FBLs using the -- listener_domains.lua policy helper. -- WARNING: THIS WILL NOT LOAD WITHOUT THE listener_domains.toml FILE IN PLACE diff --git a/docs/userguide/operation/webhooks.md b/docs/userguide/operation/webhooks.md index d077b043..cfe82ddd 100644 --- a/docs/userguide/operation/webhooks.md +++ b/docs/userguide/operation/webhooks.md @@ -19,6 +19,88 @@ enter the Ready Queue they are set to deliver via an arbitrary Lua event rather than SMTP, with the Lua script configured to issue an HTTP request to the destination server. +## Using the log_hooks.lua Helper + +While the methods documented below can be used to implement advanced webhook delivery scenarios, most users will benefit from using the *log_hooks.lua* helper. + +To implement the helper, add the following to your init.lua: + +```lua +local log_hooks = require 'policy-extras.log_hooks' +log_hooks:new_json { + name = "webhook", + -- log_parameters are combined with the name and + -- passed through to kumo.configure_log_hook + log_parameters = { + headers = { 'Subject', 'X-Customer-ID' }, + }, + -- queue config are passed to kumo.make_queue_config. + -- You can use these to override the retry parameters + -- if you wish. + -- The defaults are shown below. + queue_config = { + retry_interval = "1m", + max_retry_interval = "20m", + }, + -- The URL to POST the JSON to + url = "http://10.0.0.1:4242/log", +} +``` + +More advanced usage is possible by implementing the full call to the log_hooks.lua helper, in the following format: + +```lua +local log_hooks = require 'policy-extras.log_hooks' +log_hooks:new { + name = "webhook", + -- log_parameters are combined with the name and + -- passed through to kumo.configure_log_hook + log_parameters = { + headers = { 'Subject', 'X-Customer-ID' }, + }, + -- queue config are passed to kumo.make_queue_config. + -- You can use these to override the retry parameters + -- if you wish. + -- The defaults are shown below. + queue_config = { + retry_interval = "1m", + max_retry_interval = "20m", + }, + constructor = function(domain, tenant, campaign) + local connection = {} + local client = kumo.http.build_client {} + function connection:send(message) + local response = client + :post('http://10.0.0.1:4242/log') + :header('Content-Type', 'application/json') + :body(message:get_data()) + :send() + + local disposition = string.format( + '%d %s: %s', + response:status_code(), + response:status_reason(), + response:text() + ) + + if response:status_is_success() then + return disposition + end + + -- Signal that the webhook request failed. + -- In this case the 500 status prevents us from retrying + -- the webhook call again, but you could be more sophisticated + -- and analyze the disposition to determine if retrying it + -- would be useful and generate a 400 status instead. + -- In that case, the message we be retryed later, until + -- it reached it expiration. + kumo.reject(500, disposition) + end + return connection + end, +} +``` + ## Configuring a Log Hook The first step in setting up Webhooks is to turn on the log hook. This adds a