Adding a channel
Build your own channel — Slack, chatbots, web forms — by following the email channel pattern.
Ticqex is designed around composable channel and integration registries. The built-in email channel is the reference implementation; a new channel (Slack, a chat widget, a WordPress form, …) follows the same shape.
Concepts
- Channel (
server/channels/<name>/) — product behavior: how conversations work, which ticket fields apply, what the board card shows, and how inbound/outbound messages are handled. - Integration (
server/integrations/<name>/) — the external provider: declared capabilities (e.g.email.inbound,email.outbound), required env vars, transport functions, and webhook handlers. - Activation config binds an enabled channel to an enabled integration with matching capabilities.
A channel definition includes:
keyandlabelconversationbehavior (e.g. whether public replies can be sent, the label for the contact address)fields— field policies (see below)card— how tickets of this channel render on the board (badges, chips)inbound,outbound, anddeliveryEventshandlers- optional
settings.sectionscontributing panels to the admin settings UI
Steps
- Add keys — register the new channel/integration keys in
shared/ticqex-keys/and extend the config types inshared/ticqex-config/. - Implement the integration under
server/integrations/<name>/(capabilities, required env, transport, webhook verification) and register it inserver/integrations/index.ts. - Implement the channel under
server/channels/<name>/with shared client-safe metadata undershared/channels/<name>/, and register it inserver/channels/index.ts. - Wire webhooks — the generic dispatcher at
/api/webhooks/integrations/[integration]routes incoming requests to your integration's handlers; no new route needed. - Add settings UI (optional) — declare
settings.sectionson the channel and register the matching component in the settings section registry. - Update the activation config example, enable your channel, and run
pnpm config:syncto review the planned field sync. - Test — the registry test suite (
tests/unit/channels-registry.test.ts) shows the expected contract.
Field policies
Channels declare policies for ticket fields — which are required, visible, or locked for tickets of that channel. For example, email conversations require a contact address; a task ticket doesn't have one. Policies are enforced server-side so the API and MCP respect them too.
Inbound flow (email as reference)
- Provider POSTs a webhook to
/api/webhooks/integrations/<integration>. - The integration verifies the signature and normalizes the event.
- The channel's inbound handler matches or creates the contact, threads the message into an existing conversation or creates a new ticket in the default inbound status.
- Processing runs async in-process via Next.js
after()— no external job runner.
Outbound flow
When a staff member (or agent, via API/MCP) replies on a conversation ticket, the channel's outbound handler hands the message to the bound integration's transport, and delivery events (sent, bounced, …) flow back through the webhook into the thread.