Repository navigation
Add App API newsletter core methods - #235
Conversation
Batch 6 of the App API backfill. Adds fourteen newsletter methods to APIClient: - listNewsletters / createNewsletter / getNewsletter / deleteNewsletter - getNewsletterContents / getNewsletterContent / updateNewsletterContent - getNewsletterContentMetrics / getNewsletterContentMetricsLinks - getNewsletterMetrics / getNewsletterMetricsLinks / getNewsletterMessages - sendNewsletter / scheduleNewsletter Reuses buildQueryString, LinkMetricsOptions, and the private resourceBase() helper (widened to include 'newsletters'). Adds newsletter-specific option types (ListNewslettersOptions, NewsletterMetricType, NewsletterMetricsOptions, NewsletterMessagesOptions) since newsletters use a different channel set (inbox; no whatsapp/slack). Includes unit tests (100% coverage), live integration coverage (reads gated on the existing CIO_TEST_NEWSLETTER_ID; send/schedule/create left to unit tests), and docs in docs/app.md. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
| getNewsletterContentMetricsLinks( | ||
| newsletterId: string | number, | ||
| contentId: string | number, | ||
| options: NewsletterMetricsOptions = {}, | ||
| ) { | ||
| if (isEmpty(newsletterId)) { | ||
| throw new MissingParamError('newsletterId'); | ||
| } | ||
|
|
||
| if (isEmpty(contentId)) { | ||
| throw new MissingParamError('contentId'); | ||
| } | ||
|
|
||
| const query = buildQueryString({ period: options.period, steps: options.steps, type: options.type }); | ||
|
|
||
| return this.request.get( | ||
| `${this.resourceBase('newsletters', newsletterId)}/contents/${encodeURIComponent(contentId)}/metrics/links${query}`, | ||
| ); | ||
| } |
There was a problem hiding this comment.
Codex is flagging that the current backend link metrics handler reads unique for content link metrics. So this should use LinkMetricsOptions and serialize { period, steps, unique }
| export type NewsletterMetricsOptions = { | ||
| period?: MetricsPeriod; | ||
| steps?: number; | ||
| /** Scope the report to a single channel. */ | ||
| type?: NewsletterMetricType; | ||
| }; |
There was a problem hiding this comment.
Another issue flagged by codex:
NewsletterMetricsOptions advertises type, and getNewsletterContentMetrics / getNewsletterMetrics forward it, but current services origin/main newsletter metrics always use channeltype.All. So getNewsletterMetrics(id, { type: "email" }) silently returns all-channel metrics. Either remove type from the SDK/docs/tests for newsletter metrics or land backend support first.
| /** Options for {@link APIClient.getNewsletterMessages}. */ | ||
| export type NewsletterMessagesOptions = PaginationOptions & { | ||
| /** Filter to deliveries with this metric (e.g. `delivered`, `opened`, `bounced`). */ | ||
| metric?: string; | ||
| /** Only include deliveries after this Unix timestamp (seconds). */ | ||
| start_ts?: number; | ||
| /** Only include deliveries before this Unix timestamp (seconds). */ | ||
| end_ts?: number; | ||
| /** When `true`, include tracked responses on each delivery. */ | ||
| get_tracked_responses?: boolean; | ||
| }; |
There was a problem hiding this comment.
Should this expose type? The shared deliveries handler supports it, and the campaign/broadcast message methods already include it.
mattander
left a comment
There was a problem hiding this comment.
A few issues then this should be fine.
…ples (CDP-6270 review) Verified against the backend (ext_api/newsletters + ext_api/deliveries): - Newsletter metrics are always aggregated across all channels (metrics.go uses channeltype.All); the API ignores a channel `type` filter. Removed `type` from getNewsletterMetrics / getNewsletterContentMetrics. - Content link metrics read `unique`, not `type` (link_metrics.go). Switched getNewsletterContentMetricsLinks to LinkMetricsOptions. - Newsletter messages DO support a channel `type` filter (shared deliveries.Index / parse.go), so added `type` to getNewsletterMessages. - createNewsletter requires `recipients`; scheduleNewsletter uses `scheduled_at` + `timezone` (not `timestamp`). Fixed docs/examples/tests. Renamed NewsletterMetricType -> NewsletterChannelType (now used for the messages channel filter). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
A new set of the App API backfill which adds the core newsletter endpoints (CRUD, contents, metrics, send/schedule). Localization + test groups are added in #236
New methods (14)
listNewsletters,createNewsletter,getNewsletter,deleteNewsletter,getNewsletterContents,getNewsletterContent,updateNewsletterContent,getNewsletterContentMetrics,getNewsletterContentMetricsLinks,getNewsletterMetrics,getNewsletterMetricsLinks,getNewsletterMessages,sendNewsletter,scheduleNewsletter.Assisted by AI 🤖
Note
Medium Risk
Adds
sendNewsletterandscheduleNewsletter, which can trigger real customer messaging; otherwise additive SDK wrappers with validation consistent with existing broadcast methods.Overview
Extends
APIClientwith Customer.io App API newsletter support, reusing the existing campaign/broadcast pattern via an updatedresourceBase('newsletters', …)helper.Core surface: list/create/get/delete newsletters; content variants (list/get/update); newsletter- and content-level metrics and link metrics; messages listing with channel filters;
sendNewsletterandscheduleNewsletter.Also in this diff: language CRUD on newsletters and on test groups (list/create test groups plus per-group language endpoints). New option types include
ListNewslettersOptions,NewsletterMetricsOptions(no per-channeltypeon metrics),NewsletterChannelType, andNewsletterMessagesOptions.Docs in
docs/app.mddocument every new method. Tests stub HTTP paths and query strings intest/api.ts;test/integration/live.tsadds read-only checks forlistNewslettersand optionalCIO_TEST_NEWSLETTER_IDlookups (mutating/send paths stay unit-tested only).Reviewed by Cursor Bugbot for commit edf85ee. Bugbot is set up for automated code reviews on this repo. Configure here.