feat(webhook): align chatwoot ingress routes
This commit is contained in:
@@ -17,7 +17,7 @@ Build GoChat as a Go backend that can directly reuse the frontend from `referenc
|
||||
## Current Baseline
|
||||
|
||||
- `go test ./...` passes.
|
||||
- Route dump succeeds with `TOTAL: 793` after widget direct-upload routes were added.
|
||||
- Route dump succeeds with `TOTAL: 801` after Chatwoot webhook ingress routes were added.
|
||||
- Route parity artifacts now exist under `docs/parity/` and are generated by `cmd/route_parity`.
|
||||
- Tracked frontend-critical route audit covers 251 Chatwoot routes: 251 exact, 0 method-compatible, 0 parameter-compatible, 0 missing.
|
||||
- `/api/v1/widget` stubs are burned down and public inbox/contact/conversation/message core flows are backed by real handlers.
|
||||
@@ -60,7 +60,7 @@ This is the ordered queue for the next implementation slices. Do not skip the ro
|
||||
| Q3 | Add route boot regression coverage for wildcard conflict groups before expanding more Rails-style resources. | Phase 2 | Router tests cover nested dynamic resources that previously risked Gin conflicts. | Done |
|
||||
| Q4 | Start serializer parity fixtures for auth/session, conversations/messages, contacts/companies, inboxes, notifications, and search. | Phase 3 | Each area has at least one reference fixture and Go response test. | Doing |
|
||||
| Q5 | Review Meilisearch document shape and endpoint payloads against Chatwoot frontend consumers. | Phase 1 and Phase 3 | Search remains Meilisearch-first and payload mismatches are fixed or tracked. | Todo |
|
||||
| Q6 | Implement provider-specific webhook ingress for Chatwoot public webhook paths. | Phase 6 | Generic webhook placeholder no longer masks provider gaps; Telegram, LINE, SMS/Twilio, WhatsApp, Instagram/Twitter/TikTok routes resolve and verify like Chatwoot where supported. | Todo |
|
||||
| Q6 | Implement provider-specific webhook ingress for Chatwoot public webhook paths. | Phase 6 | Generic webhook placeholder no longer masks provider gaps; Telegram, LINE, SMS/Twilio, WhatsApp, Instagram/Twitter/TikTok routes resolve and verify like Chatwoot where supported. | Doing |
|
||||
| Q7 | Burn down enterprise gaps in this order: SLA, assignment policy and capacity, CSAT, automation/macros, Audit, CustomRole, InboxLimit, Captain/Copilot. | Phase 4 and Phase 5 | Each feature passes route, persistence, auth, side-effect, response, and test checks. | Todo |
|
||||
| Q8 | Add frontend smoke harness using the reused Chatwoot frontend once core API flows boot end-to-end. | Phase 7 | Login, inbox list, conversation list/detail, message send, contact view, and widget init run without frontend adapters. | Todo |
|
||||
|
||||
@@ -97,7 +97,7 @@ Work proceeds top-down unless a failing test or frontend blocker forces a narrow
|
||||
|
||||
| Slice | Work | Reference source | Verification | Status |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| B1 | Webhook ingress route and handler parity. | `reference/chatwoot/config/routes.rb:614-624`, `reference/chatwoot/app/controllers/webhooks/*`, `reference/chatwoot/app/controllers/api/v1/webhooks_controller.rb` | Provider lookup tests, router route dump, `go test ./...`. | Next |
|
||||
| B1 | Webhook ingress route and handler parity. | `reference/chatwoot/config/routes.rb:614-624`, `reference/chatwoot/app/controllers/webhooks/*`, `reference/chatwoot/app/controllers/api/v1/webhooks_controller.rb` | Provider lookup tests, router route dump, `go test ./...`. | Doing |
|
||||
| B2 | Auth/profile serializer fixtures. | `reference/chatwoot/app/controllers/api/v1/profile*`, frontend auth client. | Fixture tests for login/current user/profile/availability/settings. | Todo |
|
||||
| B3 | Conversation/message serializer and behavior fixtures. | Chatwoot conversation/message controllers, entities, jobs. | Fixture tests for list/show/create/update/private notes/attachments/status/assignment. | Todo |
|
||||
| B4 | Contact/company behavior fixtures. | Chatwoot contact/company controllers, merge/import/export/notes/labels. | Fixture tests for CRUD/search/merge/relation/import-export shells. | Todo |
|
||||
@@ -464,21 +464,21 @@ Tracking table:
|
||||
| P6.4 | Message APIs | `docs/ROUTE_GAP_ANALYSIS.md`, message handlers/services | Implement create/list/delete, private notes, attachments, source attribution, events. | Todo |
|
||||
| P6.5 | Inbox APIs | `docs/ROUTE_GAP_ANALYSIS.md`, inbox handlers/services | Implement CRUD, assignable agents, avatar, campaigns, channel settings, reset secret. | Todo |
|
||||
| P6.6 | Widget/public APIs | `docs/ROUTE_GAP_ANALYSIS.md`, widget/channel provider code, `chatwootParityStub` routes | Widget/public frontend-critical route behavior is handler-backed, including public inbox flow, direct uploads/attachments, and public CSAT survey submission. | Done |
|
||||
| P6.7 | Webhook ingress | `internal/router/router.go`, `internal/handler/webhook/*`, channel providers | Replace generic placeholder with provider-specific verified ingestion and dispatch. | Todo |
|
||||
| P6.7 | Webhook ingress | `internal/router/router.go`, `internal/handler/webhook/*`, channel providers | Replace generic placeholder with provider-specific verified ingestion and dispatch. | Doing |
|
||||
|
||||
Webhook ingress subtracking:
|
||||
|
||||
| ID | Provider/path | Chatwoot reference | Current Go gap | Done when | Status |
|
||||
| --- | --- | --- | --- | --- | --- |
|
||||
| P6.7a | Twitter `GET/POST /webhooks/twitter` | `api/v1/webhooks#twitter_crc`, `#twitter_events` | Go route currently exposes `/webhooks/twitter/webhook`; Chatwoot alias is missing from the public route surface. | CRC and event routes exist at Chatwoot paths and use the existing Twitter handlers/tests. | Todo |
|
||||
| P6.7b | LINE `POST /webhooks/line/:line_channel_id` | `webhooks/line#process_payload` | Router param and handler lookup are mismatched; handler reads an inbox-style param instead of line channel ID. | Handler resolves `ChannelLINE` by `channel_id`, verifies `X-Line-Signature`, and dispatches/acks like Chatwoot. | Todo |
|
||||
| P6.7c | Telegram `POST /webhooks/telegram/:bot_token` | `webhooks/telegram#process_payload` | Handler lookup is a placeholder and does not resolve the real inbox by bot token. | Handler resolves `ChannelTelegram` by `bot_token`, loads inbox, processes update, and returns provider-safe `200 OK`. | Todo |
|
||||
| P6.7d | SMS/Twilio `POST /webhooks/sms/:phone_number` | `webhooks/sms#process_payload` | Go path is `/webhooks/twilio/sms/:phone_number`; handler reads an inbox-style param. | Chatwoot path is registered, phone number resolves `ChannelTwilioSMS`, signature verification is applied where configured, and message/status events dispatch. | Todo |
|
||||
| P6.7e | WhatsApp `GET/POST /webhooks/whatsapp/:phone_number` | `webhooks/whatsapp#verify`, `#process_payload` | Param naming and verification/secret behavior need Chatwoot comparison; existing handler mostly delegates to channel package. | Verify challenge and POST event ingestion match Chatwoot path, token, response, and inbox resolution behavior. | Todo |
|
||||
| P6.7a | Twitter `GET/POST /webhooks/twitter` | `api/v1/webhooks#twitter_crc`, `#twitter_events` | Go route exposed only `/webhooks/twitter/webhook`. | CRC and event routes exist at Chatwoot paths and use the existing Twitter handlers/tests. | Done |
|
||||
| P6.7b | LINE `POST /webhooks/line/:line_channel_id` | `webhooks/line#process_payload` | Router param and handler lookup were mismatched; handler read an inbox-style param instead of line channel ID. | Handler resolves `ChannelLINE` by `channel_id`, verifies `X-Line-Signature`, and dispatches/acks like Chatwoot. | Review |
|
||||
| P6.7c | Telegram `POST /webhooks/telegram/:bot_token` | `webhooks/telegram#process_payload` | Handler lookup was a placeholder and did not resolve the real inbox by bot token. | Handler resolves `ChannelTelegram` by `bot_token`, loads inbox, processes update, and returns provider-safe `200 OK`. | Review |
|
||||
| P6.7d | SMS/Twilio `POST /webhooks/sms/:phone_number` | `webhooks/sms#process_payload` | Go path was `/webhooks/twilio/sms/:phone_number`; handler read an inbox-style param. | Chatwoot path is registered, phone number resolves `ChannelTwilioSMS`, signature verification is applied where configured, and message/status events dispatch. | Review |
|
||||
| P6.7e | WhatsApp `GET/POST /webhooks/whatsapp/:phone_number` | `webhooks/whatsapp#verify`, `#process_payload` | Param naming and verification/secret behavior need Chatwoot comparison; existing handler mostly delegates to channel package. | Verify challenge and POST event ingestion match Chatwoot path, token, response, and inbox resolution behavior. | Review |
|
||||
| P6.7f | Instagram `GET/POST /webhooks/instagram` | `webhooks/instagram#verify`, `#events` | Chatwoot no-param route is absent; Meta verification/signature behavior is not exposed separately from Facebook routes. | Verify/event routes exist at Chatwoot paths and resolve account/inbox from payload/subscription data. | Todo |
|
||||
| P6.7g | TikTok `POST /webhooks/tiktok` | `webhooks/tiktok#events` | Go route expects `:business_id`; Chatwoot route has no path param and should derive identity from payload. | Handler accepts Chatwoot path, resolves business/inbox from payload, and acks/dispatches provider events. | Todo |
|
||||
| P6.7g | TikTok `POST /webhooks/tiktok` | `webhooks/tiktok#events` | Go route expected `:business_id`; Chatwoot route has no path param and should derive identity from payload. | Handler accepts Chatwoot path, resolves business/inbox from payload, and acks/dispatches provider events. | Review |
|
||||
| P6.7h | Shopify `POST /webhooks/shopify` | `webhooks/shopify#events` | Chatwoot route exists; Go provider surface needs inventory before implementation. | Route either has a real verified handler or is explicitly tracked as unsupported without placeholder success. | Todo |
|
||||
| P6.7i | Generic fallback and auth middleware | Go `WebhookAuth`, `webhookStub` | Generic middleware reads `:channel_type/:identifier`, which breaks provider-specific routes; fallback currently returns placeholder success. | Provider routes perform provider-specific verification; fallback no longer masks missing providers with success JSON. | Todo |
|
||||
| P6.7i | Generic fallback and auth middleware | Go `WebhookAuth`, `webhookStub` | Generic middleware reads `:channel_type/:identifier`, which breaks provider-specific routes; fallback returned placeholder success. | Provider routes perform provider-specific verification; fallback no longer masks missing providers with success JSON. | Done |
|
||||
|
||||
P6.7 implementation notes:
|
||||
|
||||
@@ -563,3 +563,4 @@ Verification milestone gates:
|
||||
- 2026-06-04: Completed P6.6e widget direct upload/attachment parity for the reused Chatwoot widget frontend. `/api/v1/widget/direct_uploads` now accepts ActiveStorage metadata with `website_token` + `X-Auth-Token`, returns the raw `signed_id/direct_upload` blob shape expected by `DirectUpload`, supports the follow-up PUT body upload, and attaches `message[attachments][]` signed IDs to incoming widget messages. Message create/list payloads now include Chatwoot-style attachment fields (`data_url`, `thumb_url`, `file_type`, extension, size). Added focused handler coverage for ActiveStorage create/PUT and multipart attachment-only message send/list. Verified focused package tests and regenerated route artifacts; route dump now reports `TOTAL: 793`, while tracked parity remains `251 exact, 0 missing`. Remaining P6.6 work is deeper public CSAT behavior.
|
||||
- 2026-06-04: Completed P6.6f public CSAT deep behavior. `/public/api/v1/csat_survey/:id` now resolves the conversation UUID to the `input_csat` message and returns the Chatwoot public survey payload (`csat_survey_response`, display type, inbox avatar/name, locale, conversation/message IDs). Public CSAT submit now accepts nested `message.submitted_values`, updates the survey message content attributes, upserts a message-linked CSAT response, and enforces Chatwoot's 14-day lock with `422`. Public inbox message update now applies the same lock/response-builder path for `input_csat` messages. Added handler coverage for public CSAT show/update/lock and public inbox CSAT message update/lock. Focused package tests passed.
|
||||
- 2026-06-04: Consolidated the Hermes-era planning into this master tracker. Added the locked decision ledger, end-to-end milestone map, ordered slice backlog, enterprise work package breakdown, and detailed P6.7 provider webhook ingress checklist. Current next implementation slice is B1/P6.7 webhook ingress.
|
||||
- 2026-06-04: Started P6.7 webhook ingress parity. Added Chatwoot public webhook paths for Twitter, Telegram, LINE, SMS/Twilio, WhatsApp, Instagram, TikTok, and Shopify; removed the generic success fallback so unsupported providers no longer return placeholder success. Telegram, LINE, Twilio SMS, and TikTok handlers now resolve inboxes through provider channel records instead of inbox-id placeholders; TikTok model column naming now matches existing repository queries. Added provider lookup tests and router boot coverage. Regenerated route dump: `TOTAL: 801`; tracked route parity remains `251 exact, 0 missing`.
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
CONNECT /webhooks/:channel_type/:identifier
|
||||
DELETE /api/v1/accounts/:account_id
|
||||
DELETE /api/v1/accounts/:account_id/agent_bot_inboxes/:agent_bot_inbox_id
|
||||
DELETE /api/v1/accounts/:account_id/agent_bots/:agent_bot_id
|
||||
@@ -109,7 +108,6 @@ DELETE /platform/api/v1/apps/:id/permissibles/:permissible_id
|
||||
DELETE /platform/api/v1/banners/:id
|
||||
DELETE /platform/api/v1/installation_configs/:id
|
||||
DELETE /platform/api/v1/users/:id
|
||||
DELETE /webhooks/:channel_type/:identifier
|
||||
GET /api/v1/accounts/
|
||||
GET /api/v1/accounts/:account_id
|
||||
GET /api/v1/accounts/:account_id/agent_bot_inboxes/
|
||||
@@ -420,7 +418,11 @@ GET /public/api/v1/inboxes/:inbox_id/contacts/:contact_id
|
||||
GET /public/api/v1/inboxes/:inbox_id/contacts/:contact_id/conversations
|
||||
GET /public/api/v1/inboxes/:inbox_id/contacts/:contact_id/conversations/:conversation_id
|
||||
GET /public/api/v1/inboxes/:inbox_id/contacts/:contact_id/conversations/:conversation_id/messages
|
||||
GET /webhooks/:channel_type/:identifier
|
||||
GET /webhooks/instagram
|
||||
GET /webhooks/tiktok/:business_id
|
||||
GET /webhooks/twitter
|
||||
GET /webhooks/twitter/webhook
|
||||
GET /webhooks/whatsapp/:phone_number
|
||||
GET /widget/cable_token
|
||||
GET /widget/conversations
|
||||
GET /widget/conversations/:id/messages
|
||||
@@ -428,8 +430,6 @@ GET /widget/widget/:website_token/pre_chat_form
|
||||
GET /widget/widget/:website_token/theme_config
|
||||
GET /widget/widget/:website_token/uploads/:upload_uuid
|
||||
GET /ws
|
||||
HEAD /webhooks/:channel_type/:identifier
|
||||
OPTIONS /webhooks/:channel_type/:identifier
|
||||
PATCH /api/v1/accounts/:account_id/agent_bot_inboxes/:agent_bot_inbox_id/status
|
||||
PATCH /api/v1/accounts/:account_id/channels/facebook_channel/:fb_id
|
||||
PATCH /api/v1/accounts/:account_id/contacts/:contact_id/notes/:note_id
|
||||
@@ -465,7 +465,6 @@ PATCH /platform/api/v1/users/:id
|
||||
PATCH /public/api/v1/csat_survey/:id
|
||||
PATCH /public/api/v1/inboxes/:inbox_id/contacts/:contact_id
|
||||
PATCH /public/api/v1/inboxes/:inbox_id/contacts/:contact_id/conversations/:conversation_id/messages/:message_id
|
||||
PATCH /webhooks/:channel_type/:identifier
|
||||
PATCH /widget/contact
|
||||
POST /api/v1/accounts/
|
||||
POST /api/v1/accounts/:account_id/agent_bot_inboxes/
|
||||
@@ -710,7 +709,18 @@ POST /public/api/v1/inboxes/:inbox_id/contacts/:contact_id/conversations/:conver
|
||||
POST /public/api/v1/inboxes/:inbox_id/contacts/:contact_id/conversations/:conversation_id/toggle_status
|
||||
POST /public/api/v1/inboxes/:inbox_id/contacts/:contact_id/conversations/:conversation_id/toggle_typing
|
||||
POST /public/api/v1/inboxes/:inbox_id/contacts/:contact_id/conversations/:conversation_id/update_last_seen
|
||||
POST /webhooks/:channel_type/:identifier
|
||||
POST /webhooks/instagram
|
||||
POST /webhooks/line/:line_channel_id
|
||||
POST /webhooks/shopify
|
||||
POST /webhooks/sms/:phone_number
|
||||
POST /webhooks/telegram/:bot_token
|
||||
POST /webhooks/tiktok
|
||||
POST /webhooks/tiktok/:business_id
|
||||
POST /webhooks/twilio/sms/:phone_number
|
||||
POST /webhooks/twilio/status/:phone_number
|
||||
POST /webhooks/twitter
|
||||
POST /webhooks/twitter/webhook
|
||||
POST /webhooks/whatsapp/:phone_number
|
||||
POST /widget/conversations/:id/toggle_typing
|
||||
POST /widget/direct_uploads
|
||||
POST /widget/init
|
||||
@@ -788,7 +798,5 @@ PUT /platform/api/v1/installation_configs/:id
|
||||
PUT /public/api/v1/csat_survey/:id
|
||||
PUT /public/api/v1/inboxes/:inbox_id/contacts/:contact_id
|
||||
PUT /public/api/v1/inboxes/:inbox_id/contacts/:contact_id/conversations/:conversation_id/messages/:message_id
|
||||
PUT /webhooks/:channel_type/:identifier
|
||||
PUT /widget/direct_uploads/:upload_uuid
|
||||
TRACE /webhooks/:channel_type/:identifier
|
||||
TOTAL: 793
|
||||
TOTAL: 801
|
||||
|
||||
Reference in New Issue
Block a user