fix(amplitude): correct wire formats and add funnels/retention analytics#5355
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
PR SummaryMedium Risk Overview Wire-format and response fixes: Identify and Group Identify now POST EU data residency: New New operations: Funnels and Retention tools and block operations are added end-to-end (registry, types, UI fields, funnel skill template). Richer query APIs: Event Segmentation gains filters (embedded in the Cosmetic: Amplitude block brand colors are updated. Reviewed by Cursor Bugbot for commit bf99662. Configure here. |
Greptile SummaryThis PR fixes several incorrect wire formats in Amplitude tools and adds new Funnels and Retention analytics operations. The Identify/Group Identify endpoints are corrected from JSON to form-urlencoded body,
Confidence Score: 5/5All four wire-format bugs are correctly patched and the two new tools are well-validated; safe to merge. The form-urlencoded body fix is confirmed correct by the executor's isPreformattedContent path. The camelCase revenue-field fix matches Amplitude's HTTP API v2 schema. EU host selection is centralised and the URL values match Amplitude's documented residency endpoints. The new Funnels and Retention tools validate their required JSON params with descriptive errors before any network call, consistent with the filters fix in event_segmentation. The dataResidency field flows through finalInputs spread in the generic handler without needing explicit case entries. No logic regressions identified. No files require special attention. Important Files Changed
Sequence Diagram%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
participant UI as Block UI
participant GH as GenericBlockHandler
participant T as ToolConfig (amplitude_*)
participant Amp as Amplitude API
UI->>GH: inputs (incl. apiKey, secretKey, dataResidency, operation-specific fields)
GH->>GH: config.params(inputs) → transformedParams
GH->>GH: "finalInputs = { ...inputs, ...transformedParams }"
alt send_event / identify / group_identify
GH->>T: executeTool(finalInputs)
T->>T: getIngestionHost(dataResidency)
Note over T: US → api2.amplitude.com / EU → api.eu.amplitude.com
T->>Amp: POST /2/httpapi (JSON, fixed camelCase productId/revenueType)
T->>Amp: POST /identify (form-urlencoded, fixed from JSON)
T->>Amp: POST /groupidentify (form-urlencoded, fixed from JSON)
else funnels / retention / segmentation / revenue / active_users
GH->>T: executeTool(finalInputs)
T->>T: getDashboardHost(dataResidency)
Note over T: US → amplitude.com / EU → analytics.eu.amplitude.com
T->>T: validate events/startEvent/returnEvent JSON
T->>Amp: "GET /api/2/funnels?e=...&start=...&end=..."
T->>Amp: "GET /api/2/retention?se=...&re=...&start=...&end=..."
Amp-->>T: "{ data: { series, ... } }"
T-->>GH: "{ success: true, output: { ... } }"
end
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
participant UI as Block UI
participant GH as GenericBlockHandler
participant T as ToolConfig (amplitude_*)
participant Amp as Amplitude API
UI->>GH: inputs (incl. apiKey, secretKey, dataResidency, operation-specific fields)
GH->>GH: config.params(inputs) → transformedParams
GH->>GH: "finalInputs = { ...inputs, ...transformedParams }"
alt send_event / identify / group_identify
GH->>T: executeTool(finalInputs)
T->>T: getIngestionHost(dataResidency)
Note over T: US → api2.amplitude.com / EU → api.eu.amplitude.com
T->>Amp: POST /2/httpapi (JSON, fixed camelCase productId/revenueType)
T->>Amp: POST /identify (form-urlencoded, fixed from JSON)
T->>Amp: POST /groupidentify (form-urlencoded, fixed from JSON)
else funnels / retention / segmentation / revenue / active_users
GH->>T: executeTool(finalInputs)
T->>T: getDashboardHost(dataResidency)
Note over T: US → amplitude.com / EU → analytics.eu.amplitude.com
T->>T: validate events/startEvent/returnEvent JSON
T->>Amp: "GET /api/2/funnels?e=...&start=...&end=..."
T->>Amp: "GET /api/2/retention?se=...&re=...&start=...&end=..."
Amp-->>T: "{ data: { series, ... } }"
T-->>GH: "{ success: true, output: { ... } }"
end
Reviews (8): Last reviewed commit: "fix(amplitude): validate retention brack..." | Re-trigger Greptile |
|
@cursor review |
|
@cursor review |
|
@cursor review |
|
@cursor review |
|
@cursor review |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit 90056e1. Configure here.
…tention - Fix Identify/Group Identify sending JSON instead of the form-urlencoded body Amplitude requires - Fix Send Event using snake_case product_id/revenue_type instead of Amplitude's camelCase productId/revenueType - Fix Get Revenue parsing a response shape that never matched the real Revenue LTV API - Add EU data residency support across all tools - Add missing filters/formula/segment params to Event Segmentation, groupBy/segment to Active Users and Revenue - Add first_used/last_used to User Activity output, non_active/flow_hidden to List Events output - Add real-time/hourly interval options to Event Segmentation - Add Funnels and Retention tools for conversion and retention analysis - Harden JSON-shape validation across funnels/segmentation/retention (fail loudly on malformed or partial input instead of silently degrading) - Expose every tool output field (user_profile, send_event, user_search) on the block so nothing is unreachable downstream - Update brand colors to current Amplitude guide
90056e1 to
15e7c14
Compare
|
@cursor review |
…dd segmentation 2nd group-by - Retention now validates retentionBrackets as a JSON array and requires it when retentionMode is "bracket", matching the block UI's requirement - Event Segmentation now throws if metric is "formula" but no formula is provided, matching the block UI's requirement - Event Segmentation now supports a documented second group-by property via groupBy2/g2 - Corrected Get Active Users' group-by copy — Amplitude's docs don't document a second-property syntax for /api/2/users the way they do for segmentation's g2, so the field no longer overpromises "max two"
|
@cursor review |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit bf99662. Configure here.
Summary
product_id/revenue_typeinstead of Amplitude's camelCaseproductId/revenueTypefilters/formula/segmentparams to Event Segmentation,groupBy/segmentto Active Users and Revenuefirst_used/last_usedto User Activity output,non_active/flow_hiddento List Events outputType of Change
Testing
Verified every fix against Amplitude's live API docs with 3 independent verification passes (wire format, response shape, block/tool alignment, backwards compatibility).
bun run lintandtsc --noEmitboth clean.Checklist