support: reply by email to tickets raised outside the widget
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 39.9k
- Forks
- 3.4k
- Avg merge
- 6h 51m
- Merged PRs (30d)
- 232
Description
Is your feature request related to a problem?
Today the surface a ticket was raised from decides how the customer can be answered. A ticket created from the SDK or the API lands on the widget channel, and replies on a widget ticket are only readable inside the widget. Teams that want to own their intake UI, whether that is a contact form on a marketing site or a custom in-app help page, can create the ticket but have no way to get the answer back to the person who wrote in. Once the form is submitted, the conversation stops.
Email is the only channel with two-way delivery, and it currently arrives bundled with its own intake: the ticket is created by an inbound message and takes its identity from the sender. So teams end up choosing between an intake surface they control and a reply channel that actually reaches the customer, when what they want is both.
Describe the solution you'd like
A ticket's reply channel should be a property of the ticket rather than a consequence of how it was created. If a support request arrives with a customer email address, a team should be able to hold the whole conversation over email, whatever created the ticket. That leaves the intake surface free to be the widget, the SDK, the API, or a team's own form.
The design calls belong to whoever picks this up, in particular whether email delivery is opt in per project or per ticket, and how an address the customer has not proven control of should be treated.
Describe alternatives you've considered
- The
composeendpoint (POST /api/projects/:project_id/conversations/tickets/compose/) does create an email ticket server side, and it is the closest working path today. It is built for a team reaching out first, so a form submission routed through it reads as a message from the team rather than from the customer: the ticket does not show as unread and the new ticket notification does not fire. Its rate limit is also sized for interactive composing rather than form volume. - Relaying form submissions into a connected support address from a backend. This does not work, because inbound email takes the ticket's identity from the
Fromheader, so every relayed request is attributed to the relay instead of the person who wrote in. Sending as the customer's own domain instead is not an option for anyone with a strict DMARC policy. - Rendering the widget purely so there is somewhere to receive replies, which defeats the point for teams who chose a form deliberately.
Additional context
- #55602 asks for the same delivery leg scoped to the in-app widget: email the reply when an address was collected. This request is the general form of it, that the intake surface should not decide the reply channel. Either could subsume the other.
- #81619 is a draft that would make the relay route viable, by trusting a named relay sender and reading the requester from a header.
Debug info
- PostHog Cloud, Debug information: [please copy/paste from https://us.posthog.com/settings/project-details#variables]
- PostHog Hobby self-hosted with
docker compose, version/commit: [please provide] - PostHog self-hosted with Kubernetes (deprecated, see
Sunsetting Kubernetes support), version/commit: [please provide]
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the POST /api/projects/:project_id/conversations/tickets/compose/ endpoint and compare the related discussions in #55602 and #81619. Define how reply-channel selection and unverified customer addresses should work across widget, SDK, API, and custom-form tickets; done requires an agreed design rather than a specified file-level change.
Written by the indexing model from the issue text.
Assessment
- Domain
- api, backend
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Needs clarification
- Newbie friendliness
- 30/100