feat: create Intercom customer requests#720
Conversation
- intercomSigningSecret: drop AUTH_INTERCOM_SECRET fallback; return ""
when INTERCOM_SIGNING_SECRET is absent so the 503 path fires correctly
instead of accepting requests signed with the OAuth client secret
- IntercomIssueUnlink: check RowsAffected() and return 404 when no row
matched, consistent with IntercomIssueLink behaviour
- intercomIssueDescriptionHTML: guard Permalink with HasPrefix("https://")
to block javascript: URI injection before building the <a href>
- IntercomConnect 412 path: replace problem.JSON map with problem.Write
for RFC 7807 consistency
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…com-create-link-issues-fro
|
Controller disposition for current head Evidence:
Required path:
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 2cd79518b8
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| Name string `json:"name"` | ||
| Email string `json:"email"` | ||
| App struct { | ||
| ID string `json:"id"` |
There was a problem hiding this comment.
Decode Intercom id_code before completing OAuth
Intercom's /me response puts the workspace/app identifier under app.id_code (the OAuth token response does not provide app_id), but this struct only decodes app.id. As a result appID := firstNonEmpty(me.App.ID, me.AppID, token.AppID) remains empty after a successful OAuth exchange, and every Intercom install fails with “did not include an access token and app id.” Add an id_code field and use it when saving the integration.
Useful? React with 👍 / 👎.
| problem.Write(w, http.StatusBadRequest, "Intercom action body could not be read", err.Error()) | ||
| return intercomConversationAction{}, false | ||
| } | ||
| if !verifyIntercomSignature(secret, r.Header.Get("X-Hub-Signature"), r.Header.Get("X-Intercom-Signature"), body) { |
There was a problem hiding this comment.
Accept Canvas Kit X-Body-Signature callbacks
These issue action endpoints are intended for Intercom Canvas Kit POST callbacks, which are signed with X-Body-Signature using HMAC-SHA256, not the webhook-only X-Hub-Signature. In that context, legitimate search/link/create/status requests that only include X-Body-Signature will be rejected with 401 before any issue work runs. Verify that header here as well.
Useful? React with 👍 / 👎.
| authorizationUrl: { type: string, format: uri } | ||
| state: { type: string } | ||
| workspaceSlug: { type: string } | ||
| IntercomConnectResponse: |
There was a problem hiding this comment.
Define the Intercom connect response schema
IntercomConnectResponse is declared with no schema, so the new /integrations/intercom/connect 200 response $ref resolves to null and the generated SDK exposes IntercomConnectResponse as never. Type-safe clients therefore cannot read the authorizationUrl needed to redirect users even though the handler returns it. Give this component the same shape as the other OAuth connect responses.
Useful? React with 👍 / 👎.
| {Provider: "jira", Name: "Jira", Description: "Sync issue status, ownership, and cross-links with Jira projects."}, | ||
| {Provider: "discord", Name: "Discord", Description: "Create, search, and share issues from Discord slash commands."}, | ||
| {Provider: "microsoft_teams", Name: "Microsoft Teams", Description: "Create issues and projects from Teams conversations and post project updates."}, | ||
| {Provider: "intercom", Name: "Intercom", Description: "Create and link issues from support conversations and sync customer feedback status."}, |
There was a problem hiding this comment.
Add intercom to the integration provider contract
This new catalog entry makes GET /integrations return provider: "intercom", but the OpenAPI Integration.provider enum and generated SDK union still omit that value. Any SDK consumer using the documented list response gets an impossible provider value and cannot handle the new integration type without casting. Add intercom to the enum alongside this catalog change.
Useful? React with 👍 / 👎.
Summary
customerwhen creating or linking an issue.customer_requestrows for Intercom conversations with provider metadata, source URL, and linked issue.Verification
docker run --rm -v "$PWD":/work -w /work/apps/api golang:1.25 go test ./internal/integrations -run Intercompassed.pnpm lintpassed.make checkcurrently blocks inpnpm typecheckon pre-existing web Better Auth/Drizzle missing modules (apps/web/src/lib/auth*.ts,apps/web/src/lib/db/*.ts).docker run --rm -v "$PWD":/work -w /work/apps/api golang:1.25 go test ./...currently blocks on existingTestZendeskSetupRequirementAndSubdomainexpectation mismatch.Closes #576