Webhooks Framework - Inbound Gateway
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 | 6793 |
| Technical Name |
bwt_webhooks_inbound |
| License | LGPL-3 |
| Website | https://github.com/bitwise-hq/odoo-webhooks |
| Versions | 15.0 16.0 17.0 18.0 19.0 |
Webhooks Framework - Inbound Gateway
Bring external events into Odoo with more trust, control, and day-to-day visibility.
Secure inbound webhook intake for Odoo teams that need trustworthy validation, clear auditability, and smoother day-to-day operations.
Outcomes
Why Teams Choose It
- Helps teams accept external events with more trust and less manual risk.
- Keeps failures visible and recoverable instead of buried in custom glue.
- Turns incoming traffic into structured Odoo actions more quickly.
- Leaves room for provider-specific behavior without rebuilding the intake layer.
Audience
Who It's For
- Odoo partners connecting SaaS platforms and external systems into Odoo.
- Operations teams responsible for webhook reliability, traceability, and incident recovery.
- Integration teams that want safer intake without rebuilding the same protective layer for each project.
Capabilities
Capability Pillars
- Clear endpoint management for teams handling multiple inbound flows.
- Built-in protection against stale, duplicate, and suspicious traffic.
- Flexible routing that maps incoming events into the right Odoo work.
- Operator-friendly monitoring for review, reprocessing, and recovery.
How it works
How It Works
Inbound receives the request, verifies that it is trustworthy, filters out repeat or stale traffic, and routes the event into the right Odoo workflow with less custom plumbing around it.
Inbound request flow
Technical proof
Technical Validation
The technical section below exposes the deeper request flow, state model, and rule-processing contract so evaluators can inspect how validation, deduplication, and handler execution behave under production conditions.
Inbound processing sequence
Rollout
Rollout Path
A typical inbound rollout starts with one clearly scoped endpoint and a trust policy the team can operate with confidence.
Set Up
-
Go to
Webhooks > Inbound Endpointsand create an endpoint. - Set the path and trust settings the provider will use.
- Decide how duplicate and stale requests should be handled.
- Connect the endpoint to the handling logic you want live.
Run Day to Day
- Send provider traffic to the endpoint.
-
Review event history and status changes in
Webhooks > Inbound Events. - Reprocess or move events to dead-letter when follow-up is needed.
Looking for a faster path to live inbound integrations? Pair the framework with premium connector modules such as Stripe when you want a more turnkey rollout.
Operator Guide
This guide covers the inbound gateway: creating and configuring inbound endpoints, monitoring events, and handling failures.
Prerequisites
Install bwt_webhooks_inbound after bwt_webhooks_core and queue_job are in place. At least one handler with Direction = Inbound must exist before creating an endpoint.
Creating an Inbound Endpoint
Go to Webhooks -> Inbound -> Endpoints -> New.
Required fields:
- Name - human-readable label.
- Path - URL path suffix appended to the webhook base URL (e.g.
/webhooks/my-service). Must be unique across all endpoints. - Handler - select a handler with Direction = Inbound.
- Company - defaults to the current company.
Save the record. The endpoint is immediately active and ready to receive requests at the configured path.
Signature Verification
Under the Signature tab:
- Signature Mode - choose
None(no verification) orShared Secret HMAC(recommended for production). - When HMAC is selected, configure:
- Digest -
SHA256is recommended;SHA1andSHA512are also supported. - Encoding -
HexorBase64, depending on the upstream provider. - Primary Secret - the shared secret from the upstream provider.
- Secondary Secret - optional rotation secret; valid during key rotation.
- Signature Parts - define which header values and payload fragments are concatenated to build the signed message. Order matters and must match the upstream provider specification.
- Signature Header - the request header that carries the signature value (e.g.
X-Signature-256). - Signature Prefix - optional prefix the provider prepends to the value (e.g.
sha256=); it is stripped before comparison.
Identity and Replay Policies
Under the Identity tab:
- Delivery Identity Policy - controls deduplication on receipt (the "same request" check):
Delivery Identity- a header-carried delivery ID.Explicit Idempotency Key- a header-carried idempotency key.Raw Body SHA256- hash of the raw request body.
- Replay Identity Policy - controls business-event-level deduplication (the "same business event" check):
None- no replay protection.Business Event Identity- a field-path extracted event ID.Explicit Idempotency Key- a header-carried idempotency key.
Timestamp Validation
Enable timestamp validation under the Identity tab to reject stale or future-dated requests:
- Timestamp Header - the request header that carries the timestamp value.
- Timestamp Format -
Unix Seconds,Unix Milliseconds, orISO 8601. - Max Age (seconds) - requests older than this value are rejected.
- Max Future Skew (seconds) - requests dated this far ahead are rejected.
Monitoring Events
Go to Webhooks -> Inbound -> Events to see all received events.
Event lifecycle states:
- Received - event stored; not yet processed.
- Processing - background job is running.
- Done - processing completed successfully.
- Error - processing raised an exception; the raw traceback is stored on the event record for inspection.
- Dead Letter - handler returned a dead-letter result; manual review required.
- Rejected - signature or freshness validation failed; the event will not be retried automatically.
Use the State filter and saved views to quickly isolate failures.
Reprocessing and Dead-Letter
To reprocess an event in Error or Dead Letter state:
- Open the event record.
- Click Reset to Received to move it back to the
receivedstate. - Click Process to re-enqueue, or wait for the background runner.
Rejected events cannot be reset. Fix the endpoint configuration first (e.g. correct the signature secret), then resend the request from the upstream provider to create a fresh event.
Troubleshooting Checklist
- Signature mismatch / 401: confirm the shared secret on the endpoint matches the upstream provider exactly, including encoding (hex vs base64) and prefix stripping.
- Events arriving as Rejected with freshness error: the server clock may differ from the upstream provider; increase Max Age or sync NTP.
- Events stuck in Received: check that the
queue_jobworker is running and the job channel is not paused. - Duplicate events not deduplicated: confirm the Delivery Identity Policy is set and the upstream provider sends a consistent identity header.
- Events processed but no records created: open the event form and inspect the Matched Rule and Execution Log to see which rule fired and why the assignment did not produce the expected record.
Developer Guide
This guide covers the inbound processing pipeline, model-driven rule contract, and extension points for developers building on or customising the inbound gateway addon.
Inbound Processing Lifecycle
When a request arrives at an inbound endpoint the pipeline is:
- HTTP reception - the controller writes a
bwt.webhook.inbound.eventrecord in statereceivedand enqueues a background job. - Signature verification (if enabled) - HMAC of the configured message parts is compared against the request signature header using constant-time comparison. Failure moves the event to state
rejected. - Freshness check (if enabled) - the timestamp header is parsed and validated against the configured age and skew bounds. Failure ->
rejected. - Delivery identity - a delivery identity key is resolved and checked for duplicates. A duplicate request updates the existing event record; the new request body is not processed again.
- Handler dispatch - the event's handler is called (model-driven rules or Python callback). The return value determines the final state.
Event State Machine
Valid state transitions:
received->processing->donereceived->processing->errorreceived->processing->dead_letterreceived->rejected(signature or freshness failure; not retryable)
Operators can reset error and dead_letter events back to received for reprocessing. rejected events are closed and require a new inbound request.
Model-Driven Rule Processing
Rules are rows on bwt.webhook.inbound.handler.rule, evaluated in ascending sequence order. Each rule exposes:
condition_ids(bwt.webhook.inbound.handler.rule.condition) - each condition specifies a field path into the event payload, an operator (=,!=,in,not in,contains, ...), and a literal value.action_type- one of:
done- mark the event done; stop rule evaluation.dead_letter- move to dead-letter; stop evaluation.retry- re-enqueue afterretry_seconds; stop evaluation.create_record- create a new record ontarget_model_name.update_record- update an existing record located vialookup_ids.upsert_record- create or update; locate vialookup_ids.
assignment_ids(bwt.webhook.inbound.handler.rule.assignment) - each assignment maps a target field name to a value source:resolved_value(extracted from the event payload path),semantic_field(a named semantic binding),event_field(a field on the event record itself), orliteral(a hardcoded string or number).
Value Extraction
The framework extracts values from event payloads using dot-separated paths (e.g. data.object.id). Path resolution is handled by services/value_extraction.py:
walk_payload_path(payload, path)- navigate nested dicts and lists.extract_header(headers, name)- case-insensitive header lookup.extract_header_parameters(value)- parsekey=valuepairs from header parameter strings (e.g.Content-Type: application/json; charset=utf-8).
These helpers are available for use in custom Python callbacks.
Semantic Bindings
Semantic bindings (bwt.webhook.inbound.endpoint.semantic.binding) allow endpoints to map named semantic names (e.g. company_id, partner_id) to resolved values extracted from the request. Assignments can then reference these by semantic name, keeping rule configuration decoupled from specific payload paths.
Extending Inbound Processing
To add a computed field available as an assignment source:
- Extend
bwt.webhook.inbound.eventwith a new stored computed field. - Add a source kind entry pointing to the new field.
- Reference the field name in model-driven rule assignments via the
event_fieldsource kind.
To add a new action type, extend bwt.webhook.inbound.handler.rule and override _execute_model_driven_handler on the event model to dispatch the new type.
No core file edits are required; all extension points use standard Odoo model inheritance.
Please log in to comment on this module