From 935b79cbc53df2de0c944bf41674fbeaf3e5425a Mon Sep 17 00:00:00 2001
From: activitysmith-bot
Date: Fri, 10 Jul 2026 11:58:37 +0000
Subject: [PATCH 01/11] chore: regenerate SDK
---
generated/apis/AppIconBadgesApi.ts | 81 +++++++++++++++++++++++
generated/apis/index.ts | 1 +
generated/models/index.ts | 103 +++++++++++++++++++----------
3 files changed, 150 insertions(+), 35 deletions(-)
create mode 100644 generated/apis/AppIconBadgesApi.ts
diff --git a/generated/apis/AppIconBadgesApi.ts b/generated/apis/AppIconBadgesApi.ts
new file mode 100644
index 0000000..f78cbe1
--- /dev/null
+++ b/generated/apis/AppIconBadgesApi.ts
@@ -0,0 +1,81 @@
+/* tslint:disable */
+/* eslint-disable */
+/**
+ * ActivitySmith API
+ * Send push notifications and Live Activities to your own devices via a single API key.
+ *
+ * The version of the OpenAPI document: 1.0.0
+ *
+ *
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
+ * https://openapi-generator.tech
+ * Do not edit the class manually.
+ */
+
+
+import * as runtime from '../runtime';
+import type {
+ AppIconBadgeCountUpdateRequest,
+ AppIconBadgeCountUpdateResponse,
+ BadRequestError,
+ ForbiddenError,
+ NoRecipientsError,
+ RateLimitError,
+} from '../models/index';
+
+export interface UpdateAppIconBadgeCountRequest {
+ appIconBadgeCountUpdateRequest: AppIconBadgeCountUpdateRequest;
+}
+
+/**
+ *
+ */
+export class AppIconBadgesApi extends runtime.BaseAPI {
+
+ /**
+ * Updates the App Icon Badge Count on devices matched by API key scope and optional target channels. Send `badge: 0` to clear the count. Badge updates are independent of push notifications and do not create a push notification history item.
+ * Update App Icon Badge Count
+ */
+ async updateAppIconBadgeCountRaw(requestParameters: UpdateAppIconBadgeCountRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> {
+ if (requestParameters['appIconBadgeCountUpdateRequest'] == null) {
+ throw new runtime.RequiredError(
+ 'appIconBadgeCountUpdateRequest',
+ 'Required parameter "appIconBadgeCountUpdateRequest" was null or undefined when calling updateAppIconBadgeCount().'
+ );
+ }
+
+ const queryParameters: any = {};
+
+ const headerParameters: runtime.HTTPHeaders = {};
+
+ headerParameters['Content-Type'] = 'application/json';
+
+ if (this.configuration && this.configuration.accessToken) {
+ const token = this.configuration.accessToken;
+ const tokenString = await token("apiKeyAuth", []);
+
+ if (tokenString) {
+ headerParameters["Authorization"] = `Bearer ${tokenString}`;
+ }
+ }
+ const response = await this.request({
+ path: `/badge`,
+ method: 'POST',
+ headers: headerParameters,
+ query: queryParameters,
+ body: requestParameters['appIconBadgeCountUpdateRequest'],
+ }, initOverrides);
+
+ return new runtime.JSONApiResponse(response);
+ }
+
+ /**
+ * Updates the App Icon Badge Count on devices matched by API key scope and optional target channels. Send `badge: 0` to clear the count. Badge updates are independent of push notifications and do not create a push notification history item.
+ * Update App Icon Badge Count
+ */
+ async updateAppIconBadgeCount(requestParameters: UpdateAppIconBadgeCountRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise {
+ const response = await this.updateAppIconBadgeCountRaw(requestParameters, initOverrides);
+ return await response.value();
+ }
+
+}
diff --git a/generated/apis/index.ts b/generated/apis/index.ts
index f269477..ecb06b5 100644
--- a/generated/apis/index.ts
+++ b/generated/apis/index.ts
@@ -1,5 +1,6 @@
/* tslint:disable */
/* eslint-disable */
+export * from './AppIconBadgesApi';
export * from './LiveActivitiesApi';
export * from './MetricsApi';
export * from './PushNotificationsApi';
diff --git a/generated/models/index.ts b/generated/models/index.ts
index 69b9e93..3d12627 100644
--- a/generated/models/index.ts
+++ b/generated/models/index.ts
@@ -6,7 +6,6 @@
* @interface ActivityMetric
*/
export interface ActivityMetric {
- [key: string]: any | any;
/**
*
* @type {string}
@@ -63,7 +62,6 @@ export type ActivityMetricValue = number | string;
* @interface AlertPayload
*/
export interface AlertPayload {
- [key: string]: any | any;
/**
*
* @type {string}
@@ -77,13 +75,74 @@ export interface AlertPayload {
*/
body?: string;
}
+/**
+ * App Icon Badge Count update. Send badge 0 to clear the count.
+ * @export
+ * @interface AppIconBadgeCountUpdateRequest
+ */
+export interface AppIconBadgeCountUpdateRequest {
+ /**
+ * The count to show on the ActivitySmith app icon. Send 0 to clear it.
+ * @type {number}
+ * @memberof AppIconBadgeCountUpdateRequest
+ */
+ badge: number;
+ /**
+ *
+ * @type {ChannelTarget}
+ * @memberof AppIconBadgeCountUpdateRequest
+ */
+ target?: ChannelTarget;
+}
+/**
+ *
+ * @export
+ * @interface AppIconBadgeCountUpdateResponse
+ */
+export interface AppIconBadgeCountUpdateResponse {
+ /**
+ *
+ * @type {boolean}
+ * @memberof AppIconBadgeCountUpdateResponse
+ */
+ success: boolean;
+ /**
+ *
+ * @type {number}
+ * @memberof AppIconBadgeCountUpdateResponse
+ */
+ badge: number;
+ /**
+ *
+ * @type {number}
+ * @memberof AppIconBadgeCountUpdateResponse
+ */
+ devices_notified: number;
+ /**
+ *
+ * @type {number}
+ * @memberof AppIconBadgeCountUpdateResponse
+ */
+ users_notified: number;
+ /**
+ *
+ * @type {Array}
+ * @memberof AppIconBadgeCountUpdateResponse
+ */
+ effective_channel_slugs: Array;
+ /**
+ *
+ * @type {string}
+ * @memberof AppIconBadgeCountUpdateResponse
+ */
+ timestamp: string;
+}
/**
*
* @export
* @interface BadRequestError
*/
export interface BadRequestError {
- [key: string]: any | any;
/**
*
* @type {string}
@@ -103,7 +162,6 @@ export interface BadRequestError {
* @interface ChannelTarget
*/
export interface ChannelTarget {
- [key: string]: any | any;
/**
* Channel slugs. When omitted, API key scope determines recipients.
* @type {Array}
@@ -117,7 +175,6 @@ export interface ChannelTarget {
* @interface ContentStateEnd
*/
export interface ContentStateEnd {
- [key: string]: any | any;
/**
*
* @type {string}
@@ -305,7 +362,6 @@ export type ContentStateEndStepColorsEnum = typeof ContentStateEndStepColorsEnum
* @interface ContentStateStart
*/
export interface ContentStateStart {
- [key: string]: any | any;
/**
*
* @type {string}
@@ -487,7 +543,6 @@ export type ContentStateStartStepColorsEnum = typeof ContentStateStartStepColors
* @interface ContentStateUpdate
*/
export interface ContentStateUpdate {
- [key: string]: any | any;
/**
*
* @type {string}
@@ -669,7 +724,6 @@ export type ContentStateUpdateStepColorsEnum = typeof ContentStateUpdateStepColo
* @interface ForbiddenError
*/
export interface ForbiddenError {
- [key: string]: any | any;
/**
*
* @type {string}
@@ -716,10 +770,10 @@ export interface LiveActivityAction {
method?: LiveActivityWebhookMethod;
/**
* Optional webhook payload body. Used only when type=webhook.
- * @type {{ [key: string]: any; }}
+ * @type {object}
* @memberof LiveActivityAction
*/
- body?: { [key: string]: any; };
+ body?: object;
}
/**
@@ -738,7 +792,6 @@ export type LiveActivityActionType = typeof LiveActivityActionType[keyof typeof
* @interface LiveActivityAlertBadge
*/
export interface LiveActivityAlertBadge {
- [key: string]: any | any;
/**
*
* @type {string}
@@ -758,7 +811,6 @@ export interface LiveActivityAlertBadge {
* @interface LiveActivityAlertIcon
*/
export interface LiveActivityAlertIcon {
- [key: string]: any | any;
/**
* Apple SF Symbol name.
* @type {string}
@@ -797,7 +849,6 @@ export type LiveActivityColor = typeof LiveActivityColor[keyof typeof LiveActivi
* @interface LiveActivityEndRequest
*/
export interface LiveActivityEndRequest {
- [key: string]: any | any;
/**
*
* @type {string}
@@ -829,7 +880,6 @@ export interface LiveActivityEndRequest {
* @interface LiveActivityEndResponse
*/
export interface LiveActivityEndResponse {
- [key: string]: any | any;
/**
*
* @type {boolean}
@@ -867,7 +917,6 @@ export interface LiveActivityEndResponse {
* @interface LiveActivityLimitError
*/
export interface LiveActivityLimitError {
- [key: string]: any | any;
/**
*
* @type {string}
@@ -899,7 +948,6 @@ export interface LiveActivityLimitError {
* @interface LiveActivityStartRequest
*/
export interface LiveActivityStartRequest {
- [key: string]: any | any;
/**
*
* @type {ContentStateStart}
@@ -937,7 +985,6 @@ export interface LiveActivityStartRequest {
* @interface LiveActivityStartResponse
*/
export interface LiveActivityStartResponse {
- [key: string]: any | any;
/**
*
* @type {boolean}
@@ -981,7 +1028,6 @@ export interface LiveActivityStartResponse {
* @interface LiveActivityStreamDeleteRequest
*/
export interface LiveActivityStreamDeleteRequest {
- [key: string]: any | any;
/**
*
* @type {StreamContentState}
@@ -1013,7 +1059,6 @@ export interface LiveActivityStreamDeleteRequest {
* @interface LiveActivityStreamDeleteResponse
*/
export interface LiveActivityStreamDeleteResponse {
- [key: string]: any | any;
/**
*
* @type {boolean}
@@ -1073,7 +1118,6 @@ export type LiveActivityStreamDeleteResponseOperationEnum = typeof LiveActivityS
* @interface LiveActivityStreamPutResponse
*/
export interface LiveActivityStreamPutResponse {
- [key: string]: any | any;
/**
*
* @type {boolean}
@@ -1155,7 +1199,6 @@ export type LiveActivityStreamPutResponseOperationEnum = typeof LiveActivityStre
* @interface LiveActivityStreamRequest
*/
export interface LiveActivityStreamRequest {
- [key: string]: any | any;
/**
*
* @type {StreamContentState}
@@ -1199,7 +1242,6 @@ export interface LiveActivityStreamRequest {
* @interface LiveActivityUpdateRequest
*/
export interface LiveActivityUpdateRequest {
- [key: string]: any | any;
/**
*
* @type {string}
@@ -1231,7 +1273,6 @@ export interface LiveActivityUpdateRequest {
* @interface LiveActivityUpdateResponse
*/
export interface LiveActivityUpdateResponse {
- [key: string]: any | any;
/**
*
* @type {boolean}
@@ -1280,7 +1321,6 @@ export type LiveActivityWebhookMethod = typeof LiveActivityWebhookMethod[keyof t
* @interface MetricError
*/
export interface MetricError {
- [key: string]: any | any;
/**
*
* @type {string}
@@ -1300,7 +1340,6 @@ export interface MetricError {
* @interface MetricValueUpdateRequest
*/
export interface MetricValueUpdateRequest {
- [key: string]: any | any;
/**
*
* @type {MetricValueUpdateRequestValue}
@@ -1326,7 +1365,6 @@ export type MetricValueUpdateRequestValue = number | string;
* @interface MetricValueUpdateResponse
*/
export interface MetricValueUpdateResponse {
- [key: string]: any | any;
/**
*
* @type {boolean}
@@ -1340,7 +1378,6 @@ export interface MetricValueUpdateResponse {
* @interface NoRecipientsError
*/
export interface NoRecipientsError {
- [key: string]: any | any;
/**
*
* @type {string}
@@ -1366,7 +1403,6 @@ export interface NoRecipientsError {
* @interface NotFoundError
*/
export interface NotFoundError {
- [key: string]: any | any;
/**
*
* @type {string}
@@ -1413,10 +1449,10 @@ export interface PushNotificationAction {
method?: PushNotificationWebhookMethod;
/**
* Optional webhook payload body. Used only when type=webhook.
- * @type {{ [key: string]: any; }}
+ * @type {object}
* @memberof PushNotificationAction
*/
- body?: { [key: string]: any; };
+ body?: object;
}
/**
@@ -1474,10 +1510,10 @@ export interface PushNotificationRequest {
actions?: Array;
/**
*
- * @type {{ [key: string]: any; }}
+ * @type {object}
* @memberof PushNotificationRequest
*/
- payload?: { [key: string]: any; };
+ payload?: object;
/**
*
* @type {number}
@@ -1503,7 +1539,6 @@ export interface PushNotificationRequest {
* @interface PushNotificationResponse
*/
export interface PushNotificationResponse {
- [key: string]: any | any;
/**
*
* @type {boolean}
@@ -1552,7 +1587,6 @@ export type PushNotificationWebhookMethod = typeof PushNotificationWebhookMethod
* @interface RateLimitError
*/
export interface RateLimitError {
- [key: string]: any | any;
/**
*
* @type {string}
@@ -1578,7 +1612,6 @@ export type SendPushNotification429Response = LiveActivityLimitError | RateLimit
* @interface StreamContentState
*/
export interface StreamContentState {
- [key: string]: any | any;
/**
*
* @type {string}
From 5a57b90e5818ab5e0d9417a66a1ccab0c8f38992 Mon Sep 17 00:00:00 2001
From: bardonadam
Date: Fri, 10 Jul 2026 19:02:44 +0700
Subject: [PATCH 02/11] feat: add app icon badge resource
---
README.md | 26 ++++++++++++++++++++
src/ActivitySmith.ts | 54 ++++++++++++++++++++++++++++++++++++++++-
tests/resources.test.js | 40 ++++++++++++++++++++++++++++++
3 files changed, 119 insertions(+), 1 deletion(-)
diff --git a/README.md b/README.md
index bf604c2..3e72d1b 100644
--- a/README.md
+++ b/README.md
@@ -14,6 +14,8 @@ See [API reference](https://activitysmith.com/docs/api-reference/introduction)
- [Send a Push Notification](#send-a-push-notification)
- [Rich Push Notifications with Media](#rich-push-notifications-with-media)
- [Actionable Push Notifications](#actionable-push-notifications)
+- [App Icon Badge Count](#app-icon-badge-count)
+ - [Update App Icon Badge Count](#update-app-icon-badge-count)
- [Live Activities](#live-activities)
- [Start & Update Live Activity](#start--update-live-activity)
- [End Live Activity](#end-live-activity)
@@ -131,6 +133,30 @@ await activitysmith.notifications.send({
});
```
+## App Icon Badge Count
+
+Set the number shown on the ActivitySmith app icon across devices in your API key's account scope. This is separate from push notifications.
+
+### Update App Icon Badge Count
+
+```ts
+await activitysmith.appIconBadge.update(12);
+```
+
+Pass `0` to clear the count:
+
+```ts
+await activitysmith.appIconBadge.update(0);
+```
+
+Use `channels` to update only devices in selected channels:
+
+```ts
+await activitysmith.appIconBadge.update(3, {
+ channels: ["sales", "customer-success"],
+});
+```
+
## Live Activities
There are six types of Live Activities:
diff --git a/src/ActivitySmith.ts b/src/ActivitySmith.ts
index f2aaffe..dac93e5 100644
--- a/src/ActivitySmith.ts
+++ b/src/ActivitySmith.ts
@@ -1,4 +1,10 @@
-import { Configuration, PushNotificationsApi, LiveActivitiesApi, MetricsApi } from "../generated/index";
+import {
+ AppIconBadgesApi,
+ Configuration,
+ LiveActivitiesApi,
+ MetricsApi,
+ PushNotificationsApi,
+} from "../generated/index";
const SDK_VERSION = "1.8.0";
const SDK_HEADER_NAME = "X-ActivitySmith-SDK";
@@ -26,6 +32,11 @@ type MetricUpdateRequestBody = MetricUpdateParameters["metricValueUpdateRequest"
type MetricValue = MetricUpdateRequestBody["value"];
type MetricUpdateOptions = Omit;
type MetricInitOverrides = Parameters[1];
+type AppIconBadgeUpdateParameters = Parameters[0];
+type AppIconBadgeRawParameters = Parameters[0];
+type AppIconBadgeRequestBody = AppIconBadgeUpdateParameters["appIconBadgeCountUpdateRequest"];
+type AppIconBadgeUpdateOptions = Omit & { channels?: string[] };
+type AppIconBadgeInitOverrides = Parameters[1];
type ChannelTargetInput = { channels?: string[] };
type PushSendRequest = PushRequestBody & { channels?: string[] };
@@ -346,6 +357,45 @@ export class MetricsResource {
}
}
+export class AppIconBadgeResource {
+ private readonly api: AppIconBadgesApi;
+
+ constructor(api: AppIconBadgesApi) {
+ this.api = api;
+ }
+
+ update(
+ badge: number,
+ options: AppIconBadgeUpdateOptions = {},
+ initOverrides?: AppIconBadgeInitOverrides,
+ ) {
+ return this.api.updateAppIconBadgeCount(
+ {
+ appIconBadgeCountUpdateRequest: withTargetChannels({
+ badge,
+ ...options,
+ }) as AppIconBadgeRequestBody,
+ },
+ initOverrides,
+ );
+ }
+
+ // Backward-compatible generated-style aliases.
+ updateAppIconBadgeCount(
+ requestParameters: AppIconBadgeUpdateParameters,
+ initOverrides?: AppIconBadgeInitOverrides,
+ ) {
+ return this.api.updateAppIconBadgeCount(requestParameters, initOverrides);
+ }
+
+ updateAppIconBadgeCountRaw(
+ requestParameters: AppIconBadgeRawParameters,
+ initOverrides?: AppIconBadgeInitOverrides,
+ ) {
+ return this.api.updateAppIconBadgeCountRaw(requestParameters, initOverrides);
+ }
+}
+
export class ActivitySmith {
public static readonly liveActivityTypes = LiveActivityTypes;
public static readonly contentState = contentState;
@@ -355,6 +405,7 @@ export class ActivitySmith {
public readonly notifications: NotificationsResource;
public readonly liveActivities: LiveActivitiesResource;
public readonly metrics: MetricsResource;
+ public readonly appIconBadge: AppIconBadgeResource;
constructor(opts: ActivitySmithOptions) {
if (!opts?.apiKey) {
@@ -372,5 +423,6 @@ export class ActivitySmith {
this.notifications = new NotificationsResource(new PushNotificationsApi(config));
this.liveActivities = new LiveActivitiesResource(new LiveActivitiesApi(config));
this.metrics = new MetricsResource(new MetricsApi(config));
+ this.appIconBadge = new AppIconBadgeResource(new AppIconBadgesApi(config));
}
}
diff --git a/tests/resources.test.js b/tests/resources.test.js
index 4d88e81..f53a76c 100644
--- a/tests/resources.test.js
+++ b/tests/resources.test.js
@@ -158,6 +158,46 @@ describe("resource wrappers", () => {
).toThrow("ActivitySmith: media cannot be combined with actions");
});
+ it("passes zero through to clear the app icon badge count", async () => {
+ const ActivitySmith = require("../dist/src/index.js");
+ const generated = require("../dist/generated/index.js");
+
+ const updateSpy = vi
+ .spyOn(generated.AppIconBadgesApi.prototype, "updateAppIconBadgeCount")
+ .mockResolvedValue({ success: true, badge: 0 });
+
+ const client = new ActivitySmith({ apiKey: "test" });
+ const result = await client.appIconBadge.update(0);
+
+ expect(result).toEqual({ success: true, badge: 0 });
+ expect(updateSpy).toHaveBeenCalledWith(
+ { appIconBadgeCountUpdateRequest: { badge: 0 } },
+ undefined,
+ );
+ });
+
+ it("maps top-level channels to target.channels for appIconBadge.update", async () => {
+ const ActivitySmith = require("../dist/src/index.js");
+ const generated = require("../dist/generated/index.js");
+
+ const updateSpy = vi
+ .spyOn(generated.AppIconBadgesApi.prototype, "updateAppIconBadgeCount")
+ .mockResolvedValue({ success: true, badge: 3 });
+
+ const client = new ActivitySmith({ apiKey: "test" });
+ await client.appIconBadge.update(3, { channels: ["sales", "customer-success"] });
+
+ expect(updateSpy).toHaveBeenCalledWith(
+ {
+ appIconBadgeCountUpdateRequest: {
+ badge: 3,
+ target: { channels: ["sales", "customer-success"] },
+ },
+ },
+ undefined,
+ );
+ });
+
it("wraps live activity payloads for short methods", async () => {
const ActivitySmith = require("../dist/src/index.js");
const generated = require("../dist/generated/index.js");
From 661f434ae13d277ca92f1eae04b561ef69dc7149 Mon Sep 17 00:00:00 2001
From: bardonadam
Date: Fri, 10 Jul 2026 20:36:16 +0700
Subject: [PATCH 03/11] feat: simplify badge count setter
---
README.md | 53 +++++++++++++++----------------
src/ActivitySmith.ts | 69 ++++++++++++++---------------------------
tests/resources.test.js | 6 ++--
3 files changed, 54 insertions(+), 74 deletions(-)
diff --git a/README.md b/README.md
index 3e72d1b..128071b 100644
--- a/README.md
+++ b/README.md
@@ -14,8 +14,6 @@ See [API reference](https://activitysmith.com/docs/api-reference/introduction)
- [Send a Push Notification](#send-a-push-notification)
- [Rich Push Notifications with Media](#rich-push-notifications-with-media)
- [Actionable Push Notifications](#actionable-push-notifications)
-- [App Icon Badge Count](#app-icon-badge-count)
- - [Update App Icon Badge Count](#update-app-icon-badge-count)
- [Live Activities](#live-activities)
- [Start & Update Live Activity](#start--update-live-activity)
- [End Live Activity](#end-live-activity)
@@ -24,6 +22,7 @@ See [API reference](https://activitysmith.com/docs/api-reference/introduction)
- [Live Activity Colors](#live-activity-colors)
- [Channels](#channels)
- [Widgets](#widgets)
+- [App Icon Badge Count](#app-icon-badge-count)
## Installation
@@ -133,30 +132,6 @@ await activitysmith.notifications.send({
});
```
-## App Icon Badge Count
-
-Set the number shown on the ActivitySmith app icon across devices in your API key's account scope. This is separate from push notifications.
-
-### Update App Icon Badge Count
-
-```ts
-await activitysmith.appIconBadge.update(12);
-```
-
-Pass `0` to clear the count:
-
-```ts
-await activitysmith.appIconBadge.update(0);
-```
-
-Use `channels` to update only devices in selected channels:
-
-```ts
-await activitysmith.appIconBadge.update(3, {
- channels: ["sales", "customer-success"],
-});
-```
-
## Live Activities
There are six types of Live Activities:
@@ -530,6 +505,32 @@ String metric values work too.
await activitysmith.metrics.update("prod.status", "healthy");
```
+## App Icon Badge Count
+
+
+
+
+
+Keep the numbers you care about on your ActivitySmith app icon. Show MRR, a customer count, a stock price, or any other value you want to keep in view.
+
+```ts
+await activitysmith.badgeCount(12);
+```
+
+Pass `0` to clear the badge.
+
+```ts
+await activitysmith.badgeCount(0);
+```
+
+To target specific devices, pass their channel slugs in `channels`.
+
+```ts
+await activitysmith.badgeCount(3, {
+ channels: ["sales", "customer-success"],
+});
+```
+
## Error Handling
```ts
diff --git a/src/ActivitySmith.ts b/src/ActivitySmith.ts
index dac93e5..adcd1c1 100644
--- a/src/ActivitySmith.ts
+++ b/src/ActivitySmith.ts
@@ -32,14 +32,16 @@ type MetricUpdateRequestBody = MetricUpdateParameters["metricValueUpdateRequest"
type MetricValue = MetricUpdateRequestBody["value"];
type MetricUpdateOptions = Omit;
type MetricInitOverrides = Parameters[1];
-type AppIconBadgeUpdateParameters = Parameters[0];
-type AppIconBadgeRawParameters = Parameters[0];
-type AppIconBadgeRequestBody = AppIconBadgeUpdateParameters["appIconBadgeCountUpdateRequest"];
-type AppIconBadgeUpdateOptions = Omit & { channels?: string[] };
+type AppIconBadgeRequestBody =
+ Parameters[0]["appIconBadgeCountUpdateRequest"];
type AppIconBadgeInitOverrides = Parameters[1];
type ChannelTargetInput = { channels?: string[] };
type PushSendRequest = PushRequestBody & { channels?: string[] };
+export type BadgeCountOptions = {
+ channels?: string[];
+};
+
const LiveActivityTypes = {
segmentedProgress: "segmented_progress",
progress: "progress",
@@ -357,45 +359,6 @@ export class MetricsResource {
}
}
-export class AppIconBadgeResource {
- private readonly api: AppIconBadgesApi;
-
- constructor(api: AppIconBadgesApi) {
- this.api = api;
- }
-
- update(
- badge: number,
- options: AppIconBadgeUpdateOptions = {},
- initOverrides?: AppIconBadgeInitOverrides,
- ) {
- return this.api.updateAppIconBadgeCount(
- {
- appIconBadgeCountUpdateRequest: withTargetChannels({
- badge,
- ...options,
- }) as AppIconBadgeRequestBody,
- },
- initOverrides,
- );
- }
-
- // Backward-compatible generated-style aliases.
- updateAppIconBadgeCount(
- requestParameters: AppIconBadgeUpdateParameters,
- initOverrides?: AppIconBadgeInitOverrides,
- ) {
- return this.api.updateAppIconBadgeCount(requestParameters, initOverrides);
- }
-
- updateAppIconBadgeCountRaw(
- requestParameters: AppIconBadgeRawParameters,
- initOverrides?: AppIconBadgeInitOverrides,
- ) {
- return this.api.updateAppIconBadgeCountRaw(requestParameters, initOverrides);
- }
-}
-
export class ActivitySmith {
public static readonly liveActivityTypes = LiveActivityTypes;
public static readonly contentState = contentState;
@@ -405,7 +368,7 @@ export class ActivitySmith {
public readonly notifications: NotificationsResource;
public readonly liveActivities: LiveActivitiesResource;
public readonly metrics: MetricsResource;
- public readonly appIconBadge: AppIconBadgeResource;
+ private readonly appIconBadgesApi: AppIconBadgesApi;
constructor(opts: ActivitySmithOptions) {
if (!opts?.apiKey) {
@@ -423,6 +386,22 @@ export class ActivitySmith {
this.notifications = new NotificationsResource(new PushNotificationsApi(config));
this.liveActivities = new LiveActivitiesResource(new LiveActivitiesApi(config));
this.metrics = new MetricsResource(new MetricsApi(config));
- this.appIconBadge = new AppIconBadgeResource(new AppIconBadgesApi(config));
+ this.appIconBadgesApi = new AppIconBadgesApi(config);
+ }
+
+ badgeCount(
+ badge: number,
+ options: BadgeCountOptions = {},
+ initOverrides?: AppIconBadgeInitOverrides,
+ ) {
+ return this.appIconBadgesApi.updateAppIconBadgeCount(
+ {
+ appIconBadgeCountUpdateRequest: withTargetChannels({
+ badge,
+ ...options,
+ }) as AppIconBadgeRequestBody,
+ },
+ initOverrides,
+ );
}
}
diff --git a/tests/resources.test.js b/tests/resources.test.js
index f53a76c..87f1499 100644
--- a/tests/resources.test.js
+++ b/tests/resources.test.js
@@ -167,7 +167,7 @@ describe("resource wrappers", () => {
.mockResolvedValue({ success: true, badge: 0 });
const client = new ActivitySmith({ apiKey: "test" });
- const result = await client.appIconBadge.update(0);
+ const result = await client.badgeCount(0);
expect(result).toEqual({ success: true, badge: 0 });
expect(updateSpy).toHaveBeenCalledWith(
@@ -176,7 +176,7 @@ describe("resource wrappers", () => {
);
});
- it("maps top-level channels to target.channels for appIconBadge.update", async () => {
+ it("maps channels to target.channels for badgeCount", async () => {
const ActivitySmith = require("../dist/src/index.js");
const generated = require("../dist/generated/index.js");
@@ -185,7 +185,7 @@ describe("resource wrappers", () => {
.mockResolvedValue({ success: true, badge: 3 });
const client = new ActivitySmith({ apiKey: "test" });
- await client.appIconBadge.update(3, { channels: ["sales", "customer-success"] });
+ await client.badgeCount(3, { channels: ["sales", "customer-success"] });
expect(updateSpy).toHaveBeenCalledWith(
{
From 5ec54c0b64119eba40c581dbe09944e965401a0f Mon Sep 17 00:00:00 2001
From: bardonadam
Date: Fri, 10 Jul 2026 20:43:02 +0700
Subject: [PATCH 04/11] docs: refine badge count copy
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index 128071b..bfc3440 100644
--- a/README.md
+++ b/README.md
@@ -511,7 +511,7 @@ await activitysmith.metrics.update("prod.status", "healthy");
-Keep the numbers you care about on your ActivitySmith app icon. Show MRR, a customer count, a stock price, or any other value you want to keep in view.
+Show the number you care about on your ActivitySmith app icon. Track MRR, a customer count, a stock price, or any other value you want to keep in view.
```ts
await activitysmith.badgeCount(12);
From 0cba4aada430cdc1e5a2c65be55d981c3d74eee5 Mon Sep 17 00:00:00 2001
From: bardonadam
Date: Fri, 10 Jul 2026 20:46:24 +0700
Subject: [PATCH 05/11] docs: simplify badge count examples
---
README.md | 8 --------
1 file changed, 8 deletions(-)
diff --git a/README.md b/README.md
index bfc3440..dcb1459 100644
--- a/README.md
+++ b/README.md
@@ -523,14 +523,6 @@ Pass `0` to clear the badge.
await activitysmith.badgeCount(0);
```
-To target specific devices, pass their channel slugs in `channels`.
-
-```ts
-await activitysmith.badgeCount(3, {
- channels: ["sales", "customer-success"],
-});
-```
-
## Error Handling
```ts
From 131bce34a330bfa97723c950acc19bb6aaefd676 Mon Sep 17 00:00:00 2001
From: bardonadam
Date: Fri, 10 Jul 2026 20:50:26 +0700
Subject: [PATCH 06/11] docs: clarify channel targeting
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index dcb1459..8faeab0 100644
--- a/README.md
+++ b/README.md
@@ -471,7 +471,7 @@ Choose from these colors for the Live Activity accent, including progress bars a
## Channels
-Channels are used to target specific team members or devices. Can be used for both push notifications and live activities.
+Use `channels` to target specific team members or devices.
```ts
await activitysmith.notifications.send({
From dec88fb54de3de9400c902ace36eea23da351246 Mon Sep 17 00:00:00 2001
From: bardonadam
Date: Fri, 10 Jul 2026 20:56:47 +0700
Subject: [PATCH 07/11] docs: restore badge channel example
---
README.md | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/README.md b/README.md
index 8faeab0..1b413a9 100644
--- a/README.md
+++ b/README.md
@@ -523,6 +523,14 @@ Pass `0` to clear the badge.
await activitysmith.badgeCount(0);
```
+Use `channels` to target specific team members or devices.
+
+```ts
+await activitysmith.badgeCount(3, {
+ channels: ["sales", "customer-success"],
+});
+```
+
## Error Handling
```ts
From 1f1410685abdbe2d4ea3366aab27a31e2d90d256 Mon Sep 17 00:00:00 2001
From: bardonadam
Date: Fri, 10 Jul 2026 20:58:50 +0700
Subject: [PATCH 08/11] docs: refine channel targeting copy
---
README.md | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/README.md b/README.md
index 1b413a9..c8c6331 100644
--- a/README.md
+++ b/README.md
@@ -471,7 +471,7 @@ Choose from these colors for the Live Activity accent, including progress bars a
## Channels
-Use `channels` to target specific team members or devices.
+Use `channels` to target specific team members or devices
```ts
await activitysmith.notifications.send({
@@ -523,7 +523,7 @@ Pass `0` to clear the badge.
await activitysmith.badgeCount(0);
```
-Use `channels` to target specific team members or devices.
+Use `channels` to target specific team members or devices
```ts
await activitysmith.badgeCount(3, {
From e1e97efc62789e62826754dab1eb35fa04c3f8ff Mon Sep 17 00:00:00 2001
From: bardonadam
Date: Fri, 10 Jul 2026 21:11:25 +0700
Subject: [PATCH 09/11] docs: use badge count example
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index c8c6331..dfeac02 100644
--- a/README.md
+++ b/README.md
@@ -514,7 +514,7 @@ await activitysmith.metrics.update("prod.status", "healthy");
Show the number you care about on your ActivitySmith app icon. Track MRR, a customer count, a stock price, or any other value you want to keep in view.
```ts
-await activitysmith.badgeCount(12);
+await activitysmith.badgeCount(8333);
```
Pass `0` to clear the badge.
From e7bab3912221257877ab0c01c5514bf6aac01054 Mon Sep 17 00:00:00 2001
From: bardonadam
Date: Sat, 11 Jul 2026 14:47:55 +0700
Subject: [PATCH 10/11] docs: align Node README with SDK landing page
Why:\n- Keep the Node README consistent with the approved SDK landing-page structure.\n\nHow:\n- Move Channels below App Icon Badge Count.\n- Add channel examples for Push Notifications, Live Activities, and badges.\n- Update badge clearing guidance.\n\nVerification:\n- git diff --cached --check\n\nInitiated-by: user\nImplemented-by: codex
---
README.md | 46 ++++++++++++++++++++++++++++++++--------------
1 file changed, 32 insertions(+), 14 deletions(-)
diff --git a/README.md b/README.md
index dfeac02..7dc1631 100644
--- a/README.md
+++ b/README.md
@@ -20,9 +20,9 @@ See [API reference](https://activitysmith.com/docs/api-reference/introduction)
- [Live Activity Action](#live-activity-action)
- [Icons and Badges](#icons-and-badges)
- [Live Activity Colors](#live-activity-colors)
-- [Channels](#channels)
- [Widgets](#widgets)
- [App Icon Badge Count](#app-icon-badge-count)
+- [Channels](#channels)
## Installation
@@ -469,18 +469,6 @@ Choose from these colors for the Live Activity accent, including progress bars a
`lime`, `green`, `cyan`, `blue`, `purple`, `magenta`, `red`, `orange`, `yellow`, `gray`
-## Channels
-
-Use `channels` to target specific team members or devices
-
-```ts
-await activitysmith.notifications.send({
- title: "New subscription 💸",
- message: "Customer upgraded to Pro plan",
- channels: ["sales", "customer-success"], // Optional
-});
-```
-
## Widgets
@@ -513,18 +501,48 @@ await activitysmith.metrics.update("prod.status", "healthy");
Show the number you care about on your ActivitySmith app icon. Track MRR, a customer count, a stock price, or any other value you want to keep in view.
+Set or update the badge value.
+
```ts
await activitysmith.badgeCount(8333);
```
-Pass `0` to clear the badge.
+To clear the badge, set its value to 0.
```ts
await activitysmith.badgeCount(0);
```
+## Channels
+
Use `channels` to target specific team members or devices
+### Push Notifications
+
+```ts
+await activitysmith.notifications.send({
+ title: "New subscription 💸",
+ message: "Customer upgraded to Pro plan",
+ channels: ["sales", "customer-success"],
+});
+```
+
+### Live Activities
+
+```ts
+await activitysmith.liveActivities.start({
+ content_state: {
+ title: "Nightly Database Backup",
+ subtitle: "verify restore",
+ type: "progress",
+ percentage: 62,
+ },
+ channels: ["sales", "customer-success"],
+});
+```
+
+### App Icon Badge Count
+
```ts
await activitysmith.badgeCount(3, {
channels: ["sales", "customer-success"],
From a61f976f4d1fce0aaf5106d0528fffecf3e9a5e6 Mon Sep 17 00:00:00 2001
From: bardonadam
Date: Sat, 11 Jul 2026 15:08:10 +0700
Subject: [PATCH 11/11] chore: release 1.9.0
Why:\n- Prepare the Node SDK release for the new App Icon Badge Count feature.\n\nHow:\n- Bump package and SDK header versions from 1.8.0 to 1.9.0.\n- Add the focused 1.9.0 changelog entry.\n\nVerification:\n- npm test\n- 25 tests passed\n\nInitiated-by: user\nImplemented-by: codex
---
CHANGELOG.md | 5 +++++
package-lock.json | 4 ++--
package.json | 2 +-
src/ActivitySmith.ts | 2 +-
4 files changed, 9 insertions(+), 4 deletions(-)
create mode 100644 CHANGELOG.md
diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 0000000..9485214
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,5 @@
+## 1.9.0
+
+### New Features
+
+- **New Feature: App Icon Badge Count** - Show MRR, user counts, stock prices, and more on your ActivitySmith app icon.
diff --git a/package-lock.json b/package-lock.json
index 518baed..713333d 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "activitysmith",
- "version": "1.8.0",
+ "version": "1.9.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "activitysmith",
- "version": "1.8.0",
+ "version": "1.9.0",
"license": "MIT",
"devDependencies": {
"typescript": "^5.3.3",
diff --git a/package.json b/package.json
index ea282fc..9a1241e 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "activitysmith",
- "version": "1.8.0",
+ "version": "1.9.0",
"description": "Official ActivitySmith Node.js SDK",
"keywords": [
"activitysmith",
diff --git a/src/ActivitySmith.ts b/src/ActivitySmith.ts
index adcd1c1..1222797 100644
--- a/src/ActivitySmith.ts
+++ b/src/ActivitySmith.ts
@@ -6,7 +6,7 @@ import {
PushNotificationsApi,
} from "../generated/index";
-const SDK_VERSION = "1.8.0";
+const SDK_VERSION = "1.9.0";
const SDK_HEADER_NAME = "X-ActivitySmith-SDK";
const SDK_HEADER_VALUE = `node-v${SDK_VERSION}`;