#897

Integrate tawk.to ticketing support and retire Notion support flow

OpenDanielButler1opened 3mo ago

Goal

Replace the current Notion support integration with a tawk.to-powered support/ticketing flow for AI Stats users.

Domain/brand checked: tawk.to / https://www.tawk.to/.

Research notes

  • The normal website integration is the tawk.to chat widget JavaScript snippet, copied from the tawk.to dashboard per property.
  • tawk.to ticketing can manage longer-running support cases. Tickets can be created from forwarded support emails, escalated live chats, offline messages, Knowledge Base ticket forms, and ticket forms sent inside chats.
  • The JavaScript API supports custom visitor/chat metadata through window.Tawk_API.setAttributes(attributes, callback).
    • Attribute keys must be alphanumeric or dash-only.
    • Custom attributes are limited to 50, excluding name, email, and hash.
    • Attribute values cannot be empty and must be <= 255 characters.
    • Setting verified name/email should use Secure Mode with a server-generated HMAC hash.
  • The JavaScript API also supports chat events and tags:
    • addEvent(eventName, metadata, callback) for custom chat events.
    • addTags(tags, callback) with a max of 10 tags.
  • Secure Mode requires a server-side HMAC-SHA256 hash using the visitor email and the tawk.to API key. Do not expose the API key to the client.
  • Webhooks can notify AI Stats when chats start/end, transcripts are created, or new tickets are created. Webhook payloads include an X-Tawk-Signature HMAC-SHA1 signature that should be verified with the webhook secret.
  • tawk.to REST API exists for deeper automation, including tickets/chats/properties/webhooks, but access is by request, so treat REST API work as optional/follow-up until access is approved.

Official references:

Proposed implementation

  1. Create tawk.to properties for production and staging.
  2. Add environment variables:
    • NEXT_PUBLIC_TAWK_PROPERTY_ID
    • NEXT_PUBLIC_TAWK_WIDGET_ID
    • TAWK_SECURE_MODE_API_KEY or equivalent server-only secret
    • TAWK_WEBHOOK_SECRET if webhook ingestion is enabled
    • Optional later: TAWK_REST_API_KEY if REST API access is approved
  3. Add a client-only TawkProvider / support widget loader.
    • Load the widget only when support chat is enabled and the current route should expose support.
    • Avoid loading the third-party script during SSR.
    • Confirm CSP changes if the app uses strict script-src, connect-src, frame-src, or img-src rules.
  4. For signed-in users, attach safe account context using Secure Mode + setAttributes:
    • user-id
    • email and name via Secure Mode/hash
    • org-id / workspace id, if applicable
    • plan
    • billing-status
    • credit-balance or monthly-usage-band, if safe
    • current-page
    • last-active-at
    • support-context-version
  5. Do not send secrets or sensitive raw values into tawk.to metadata.
    • Never send API keys, raw auth tokens, full payment details, or private provider keys.
    • If referencing an API key, only use a non-sensitive internal id or short display prefix where already safe.
  6. Add a signed server endpoint/action for generating the visitor hash.
    • Input: authenticated user session.
    • Output: safe visitor payload + HMAC hash.
    • The browser should never receive the tawk.to secure-mode API key.
  7. Replace Notion support UI links/forms with the tawk.to flow.
    • Dashboard support button opens/maximises the widget.
    • Public support page can either show the widget or route users to the support email/ticket flow.
    • Offline users should still be able to leave a message/ticket.
  8. Configure tawk.to ticketing operationally.
    • Set up departments such as General, Billing, Account, API/Gateway, Bug Report.
    • Forward the support inbox into tawk.to ticketing if using email-based support.
    • Configure notifications for new tickets and customer replies.
  9. Optional webhook ingestion.
    • Add /api/webhooks/tawk.
    • Verify X-Tawk-Signature against the raw request body before processing.
    • Store/log ticket ids, chat ids, transcript ids, requester email, and user/org mapping where available.
    • Use this later for Linear/GitHub issue creation or internal support analytics.
  10. Update privacy/support documentation to disclose tawk.to as the support provider and explain what account context is shared.

Acceptance criteria

  • Existing Notion support entry point is removed or clearly deprecated.
  • tawk.to widget loads on intended AI Stats routes without SSR errors.
  • Authenticated users appear in tawk.to with verified name/email using Secure Mode.
  • Safe account metadata is attached to chats/tickets and handles API errors gracefully.
  • Unauthenticated visitors can still contact support without account metadata.
  • CSP and privacy/support docs are updated.
  • Ticketing is configured for offline messages and/or support email forwarding.
  • If webhooks are included, signature verification is implemented and tested.
  • No secrets, API keys, tokens, or raw payment details are sent to tawk.to.

Open questions

  • Should tawk.to be loaded everywhere, only in the dashboard, or only after the user clicks Help/Support?
  • Should support metadata include billing/credit context by default, or should that only be added when a user opens support from a billing page?
  • Do we want webhook ingestion in the first pass, or should it be a follow-up after the widget/ticketing replacement is live?
  • Should ticket ids be mirrored into Linear/GitHub later, or should tawk.to remain the source of truth for support cases?

Activity

7
linear-code[bot]3mo ago
opencode-agent[bot]3mo ago
Issue understanding This feature request asks to rip out the existing Notion-based support ticket system (contact form → Notion database → ticket comments via Notion API) and replace it with a tawk.to chat widget + ticketing flow. The Notion support code is substantial — a ~386-line Notion client (`apps/web/src/lib/support/notion.ts`), API routes at `/api/contact` and `/api/internal/support/tickets/[...]`, a contact page, a Support card in the quickstart section, and a support schedule module. There is already an empty `chat-widget.tsx` stub that returns null. No CSP exists yet (no middleware.ts). The key work is: tawk.to client widget (similar to the GA `CookieConsentManager` pattern using `next/script`), Secure Mode HMAC endpoint, env vars in turbo.json `globalEnv`, a server action for visitor hash generation, and cleaning up the Notion support code paths.

AI Agent Prompt (Copy/Paste)

Replace the existing Notion-based support system with a tawk.to chat/ticketing integration.

Code to inspect first:
- `apps/web/src/lib/support/notion.ts` — current Notion API client
- `apps/web/src/lib/support/schedule.ts` — support availability logic
- `apps/web/src/app/api/contact/route.ts` — public contact endpoint
- `apps/web/src/app/api/internal/support/tickets/` — ticket CRUD routes
- `apps/web/src/components/contact/ContactClient.tsx` — contact form
- `apps/web/src/components/(data)/model/quickstart/Support.tsx` — support card
- `apps/web/src/components/chat-widget.tsx` — stub returning null
- `apps/web/src/app/(dashboard)/contact/page.tsx` — contact page
- `apps/web/src/components/analytics/CookieConsentManager.tsx` — pattern for next/script third-party loading
- `apps/web/src/lib/analytics.ts` — pattern for env-var config modules
- `turbo.json` `globalEnv` for where to add new env vars
- `apps/web/src/app/layout.tsx` — root layout for provider placement

Work required:
1. Remove Notion support code: delete `lib/support/notion.ts`, `lib/support/schedule.ts`, `app/api/contact/route.ts`, `app/api/internal/support/tickets/` directory, `components/contact/` directory, and clean up `components/(data)/model/quickstart/Support.tsx` to remove Notion-specific logic (keep Discord/email/docs links). Update the contact page to point to the new flow.
2. Create `apps/web/src/lib/support/tawk.ts` config module exporting env vars: `NEXT_PUBLIC_TAWK_PROPERTY_ID`, `NEXT_PUBLIC_TAWK_WIDGET_ID`, and server-only `TAWK_SECURE_MODE_API_KEY`. Add these to `turbo.json` `globalEnv`.
3. Create `apps/web/src/components/support/TawkProvider.tsx` — client component that loads the tawk.to widget script via `next/script` (like CookieConsentManager does for GA). Use `strategy="lazyOnload"`. Only load on routes that should show support (dashboard routes). For signed-in users, call `window.Tawk_API.setAttributes()` with safe account metadata (user-id, email via Secure Mode hash, plan, org-id, current-page). For Secure Mode, add a server action or API route at `app/api/internal/support/tawk-hash/route.ts` that takes the authenticated user session and returns `{ visitorPayload, hash }`.
4. Rewrite `components/chat-widget.tsx` to render `TawkProvider` conditionally (or integrate `TawkProvider` into root layout).
5. Add `app/api/webhooks/tawk/route.ts` for optional webhook ingestion — verify `X-Tawk-Signature` HMAC-SHA1 against the raw body using `TAWK_WEBHOOK_SECRET`.
6. Ensure no secrets/API keys/payment details are sent to tawk.to. Never expose `TAWK_SECURE_MODE_API_KEY` to the client.
7. Update privacy/support docs if they reference Notion.

For CSP: the app currently has no CSP. If adding one is in scope, add a `middleware.ts` with `script-src 'self' https://*.tawk.to https://*.tawk.com; connect-src 'self' https://*.tawk.to https://*.tawk.com; frame-src https://*.tawk.to; img-src 'self' data: https://*.tawk.to`. Otherwise, note that CSP is absent and tag as a follow-up.

Run `pnpm lint`, `pnpm typecheck`, and check `apps/web` builds cleanly after changes.

opencode session  |  github run

admin assigned danielbutler12mo ago
admin added status/stalestatus/stalestatus/stalestatus/stale labels2mo ago