Webhooks Framework - Outbound Delivery
by Bitwise Technologies LLC https://github.com/bitwise-hq/odoo-webhooks| Availability |
Odoo Online
Odoo.sh
On Premise
|
| Odoo Apps Dependencies |
Discuss (mail)
|
| Community Apps Dependencies | Show |
| Lines of code | 6096 |
| Technical Name |
bwt_webhooks_outbound |
| License | LGPL-3 |
| Website | https://github.com/bitwise-hq/odoo-webhooks |
| Versions | 15.0 16.0 17.0 18.0 19.0 |
Webhooks Framework - Outbound Delivery
Reliable outbound delivery with templated requests, retries, and diagnostics.
Key Features
- Endpoint registry with method, body mode, and timeout controls.
- Tokenized paths plus header and payload rules for dynamic requests.
- Queue-backed delivery with retry and dead-letter handling.
- Per-attempt response logging for diagnostics and SLAs.
- Delivery context lines to map Odoo data into requests.
- Designed to plug into connector-backed integrations.
Configuration
- Go to
Webhooks > Outbound Endpointsand create an endpoint. - Set the target host/path, method, body mode, and timeout.
- Configure header and payload rules plus context lines.
- Attach a handler and outbound rule set.
Usage
- Trigger outbound rules from your business flow or connector backend.
- Monitor deliveries in
Webhooks > Outbound Deliveries. - Review attempts and retry or dead-letter as needed.
Looking for turnkey integrations? Pair this framework with premium connector addons (e.g., Stripe) to launch faster.
Operator Guide
Webhooks Outbound - Operator Guide
This guide covers the outbound delivery engine: creating and configuring outbound endpoints, triggering deliveries, monitoring attempts, and handling failures.
Prerequisites
Install bwt_webhooks_outbound after bwt_webhooks_core and queue_job are in place. At least one handler with Direction = Outbound must exist before creating an endpoint that uses a handler.
Creating an Outbound Endpoint
Go to Webhooks -> Outbound -> Endpoints -> New.
Required fields:
- Name - human-readable label.
- Code - stable, unique technical identifier used by connector addons and programmatic dispatch (lowercase slug; no spaces).
- HTTP Method -
POST(default),PUT,PATCH, orDELETE. - Request Body Mode - controls how the payload is encoded:
JSON-application/json; default for REST APIs.Form URL Encoded-application/x-www-form-urlencoded.Multipart-multipart/form-data.
- Target Path - the URL path, optionally with
{token}placeholders resolved from delivery context lines (e.g./v1/orders/{order_id}). - Company - defaults to the current company.
Target Hostname
Set Target Hostname to the absolute base URL including the scheme (e.g. https://api.example.com). Leave it blank when a connector addon resolves the hostname dynamically via _get_outbound_api_base_url.
Handler (optional)
Attach an outbound handler to intercept deliveries before the HTTP request is sent. The handler can mutate the payload, retry, cancel, or dead-letter the delivery before the HTTP call is made.
Header and Payload Rules
Use the Headers and Payload tabs to configure rules that build the outgoing request:
- Header rules - add or override request headers. Supports literal values and context-line token references.
- Payload rules - construct or override the request body using field paths and value mappings.
- Context lines - key/value pairs attached to a delivery at queue time; referenced in header and payload rules and path tokens via
{key}syntax.
Endpoint States
- Draft - endpoint configured but deliveries are not dispatched.
- Active - endpoint is live; deliveries can be queued and dispatched.
- Archived - endpoint inactive; existing delivery records remain in audit history but no new deliveries can be queued.
Monitoring Deliveries
Go to Webhooks -> Outbound -> Deliveries to see all deliveries.
Delivery lifecycle states:
- Draft - created but not yet queued.
- Queued - waiting for the background worker.
- Processing - background job is running.
- Done - HTTP request sent and accepted by the target.
- Error - an exception occurred or the target returned a non-success response code.
- Dead Letter - permanently failed after exhausting retries or explicitly dead-lettered; requires manual review.
- Canceled - cancelled before dispatch.
Click a delivery record to open its Attempts tab, which lists every HTTP request made with the response status code, headers, and body.
Retries and Dead-Letter
To retry a delivery in Error or Dead Letter state:
- Open the delivery record.
- Click Reset to Draft to move it back to the
draftstate. - Click Queue (or trigger re-queueing from your business flow) to re-enqueue the delivery.
To permanently close a failed delivery without retrying, use Action -> Dead Letter from the delivery form.
Troubleshooting Checklist
- 401 / authentication failures: ensure the connector backend is active and the API key or secret field is populated (see the connector addon docs).
- Target not reachable: verify Target Hostname is correct and the Odoo server can reach the target host on the configured port.
- Deliveries stuck in Queued: confirm the
queue_jobworker is running and the job channel is not paused or at capacity. - Payload shape wrong: open a delivery attempt and inspect the Request Body snapshot to compare the actual payload against the expected format.
- Path token not resolved: ensure the delivery's context lines contain a key matching the
{token}placeholder in Target Path.
Developer Guide
Webhooks Outbound - Developer Guide
This guide covers the outbound delivery pipeline, handler and rule contract, and extension points for developers building on or customising the outbound delivery addon.
Outbound Processing Pipeline
The diagram below shows the call chain executed for every delivery record.
Two value objects keep the data flow explicit:
OutboundRequest- immutable snapshot of the HTTP request to send (method, URL, headers, body mode, payload).HandlerOutcome- interpretation of the handler's return value:send,retry,done,dead_letter, orcancel.
Delivery State Machine
States and valid operator-driven transitions:
draft->queued(via queue action or programmatic call)queued->processing(worker picks up the job)processing->done(HTTP success)processing->error(exception or HTTP error response)processing->dead_letter(handler dead-letters)processing->canceled(handler cancels)error/dead_letter/canceled->draft(operator reset)
Model-Driven Rule Processing
Rules on bwt.webhook.outbound.handler.rule are evaluated before the HTTP request is dispatched. Supported actions:
send- allow the delivery to proceed (default when no rule matches).done- mark delivery done without sending.dead_letter- dead-letter the delivery without sending.retry- re-enqueue afterretry_seconds.mutate- modify theOutboundRequestpayload or headers via assignments before sending.
Conditions use the same field-path and operator syntax as inbound rules, evaluated against the delivery's resolved context and endpoint configuration.
Context Lines
Context lines (bwt.webhook.outbound.delivery.context_line) are key/value pairs attached to a delivery at queue time. They serve three purposes:
- Resolve
{token}placeholders in the endpoint Target Path. - Supply values referenced in header and payload rules.
- Pass business identifiers to the backend's
_get_outbound_extra_headershook (see the Connector Integration guide).
Attach context lines when queueing a delivery programmatically
endpoint = self.env["bwt.webhook.outbound.endpoint"].search(
[("code", "=", "my-endpoint")]
)
delivery = endpoint.queue_delivery(
payload={"event": "order.paid", "order_id": order.id},
context_lines={"order_id": str(order.id)},
)
Transport Layer
The service module services/transport.py translates an OutboundRequest into requests.request kwargs:
build_transport_kwargs(request)- returns a dict ready forrequests.request(**kwargs).flatten_form_data(values)- flattens nested dicts forapplication/x-www-form-urlencodedencoding usingkey[child]notation.normalize_request_files(files)- coerces file mappings into the tuples thatrequestsexpects formultipart/form-data.
These helpers can be imported and unit-tested without the ORM.
Extending Outbound Processing
To add dynamic headers (e.g. per-delivery authentication or versioning):
- Use the connector backend hook
_get_outbound_extra_headers(delivery)(see the Connector Integration guide) when the extra headers come from a connector backend. - For non-connector use cases, extend
bwt.webhook.outbound.deliveryand override_collect_extra_headersto contribute additional headers.
Headers returned by backend hooks are merged on top of endpoint header rules, so backend-level authentication always takes precedence.
To add a custom pre-dispatch check, extend bwt.webhook.outbound.delivery and override _pre_dispatch_check, returning a result dict to short-circuit or None to allow dispatch.
Please log in to comment on this module