Skip to content

Commit 18c7fcb

Browse files
sarthak688claude
andcommitted
feat(subscriptions): add Subscriptions service foundation + read methods [internal]
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 parent 8a069eb commit 18c7fcb

12 files changed

Lines changed: 872 additions & 6 deletions

File tree

src/models/notification/index.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
/**
2-
* Notification models barrel export.
2+
* Notification & Subscription models barrel export.
33
*/
44

55
export * from './notifications.types';
66
export * from './notifications.models';
7+
export * from './subscriptions.types';
8+
export * from './subscriptions.models';

src/models/notification/notifications.types.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,23 @@ export enum NotificationCategory {
3131
Fatal = 'Fatal',
3232
}
3333

34+
/**
35+
* Notification delivery channel.
36+
*
37+
* `InApp` is always implicitly enabled (it is not returned by `getSupportedChannels()`);
38+
* the others must be checked via `Subscriptions.getSupportedChannels()`.
39+
*/
40+
export enum NotificationMode {
41+
/** Real-time in-app push. Always available. */
42+
InApp = 'InApp',
43+
/** Email delivery. */
44+
Email = 'Email',
45+
/** Slack delivery. */
46+
Slack = 'Slack',
47+
/** Microsoft Teams delivery. */
48+
Teams = 'Teams',
49+
}
50+
3451
/**
3552
* Notification entry as returned by `GET /odata/v1/NotificationEntry`.
3653
*
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
/**
2+
* Subscription service model — public response shapes and the ServiceModel interface
3+
* that drives generated API documentation.
4+
*/
5+
6+
import type {
7+
SubscriptionGetAllOptions,
8+
SubscriptionGetPublishersOptions,
9+
SubscriptionGetPublishersResponse,
10+
SubscriptionGetResponse,
11+
SubscriptionGetSupportedChannelsResponse,
12+
} from './subscriptions.types';
13+
14+
/**
15+
* Public surface of the Subscriptions service. JSDoc on this interface drives
16+
* the generated API reference documentation.
17+
*
18+
* Every method takes the tenant GUID as the first argument, which the SDK
19+
* forwards to the subscription API on each call.
20+
*/
21+
export interface SubscriptionServiceModel {
22+
/**
23+
* Gets the current user's subscription preferences, optionally filtered to a set of
24+
* publisher names.
25+
*
26+
* Returns the full list of publishers (their topics, channels, and current subscription
27+
* state) the user has access to. Use {@link SubscriptionGetAllOptions.publishers} to
28+
* narrow to specific publishers.
29+
*
30+
* @param tenantId - Tenant GUID
31+
* @param options - Optional publisher-name filter
32+
* @returns Full subscription state for the matched publishers
33+
* {@link SubscriptionGetResponse}
34+
*
35+
* @example Basic usage
36+
* ```typescript
37+
* import { Subscriptions } from '@uipath/uipath-typescript/notifications';
38+
*
39+
* const subscriptions = new Subscriptions(sdk);
40+
* const { publishers } = await subscriptions.getAll('<tenantId>');
41+
* ```
42+
*
43+
* @example Filter to specific publishers
44+
* ```typescript
45+
* const { publishers } = await subscriptions.getAll('<tenantId>', {
46+
* publishers: ['Orchestrator', 'Actions'],
47+
* });
48+
* ```
49+
* @internal
50+
*/
51+
getAll(tenantId: string, options?: SubscriptionGetAllOptions): Promise<SubscriptionGetResponse>;
52+
53+
/**
54+
* Lists available publishers and their topics, regardless of the user's current subscription.
55+
*
56+
* Used for discovery — pair with {@link getAll} to inspect what's subscribable.
57+
*
58+
* Note: the response from this endpoint carries only identity/discovery fields on
59+
* publishers and topics (no subscription state). Use {@link getAll} to inspect state.
60+
*
61+
* @param tenantId - Tenant GUID
62+
* @param options - Optional publisher-name filter
63+
* @returns Publishers and their full topic catalogue (discovery fields only)
64+
* {@link SubscriptionGetPublishersResponse}
65+
*
66+
* @example Basic usage
67+
* ```typescript
68+
* const { publishers } = await subscriptions.getPublishers('<tenantId>');
69+
* ```
70+
*
71+
* @example Filter to a single publisher
72+
* ```typescript
73+
* const { publishers } = await subscriptions.getPublishers('<tenantId>', { name: 'Orchestrator' });
74+
* ```
75+
* @internal
76+
*/
77+
getPublishers(tenantId: string, options?: SubscriptionGetPublishersOptions): Promise<SubscriptionGetPublishersResponse>;
78+
79+
/**
80+
* Gets the notification channels supported in the current tenant.
81+
*
82+
* Check the `isEnabled` field on each {@link SupportedChannel} before attempting to subscribe to a
83+
* channel — disabled channels will be rejected by the server.
84+
*
85+
* Note: `InApp` is always available and is not included in the response.
86+
*
87+
* @param tenantId - Tenant GUID
88+
* @returns Supported channels with enabled status
89+
* {@link SubscriptionGetSupportedChannelsResponse}
90+
*
91+
* @example
92+
* ```typescript
93+
* import { NotificationMode } from '@uipath/uipath-typescript/notifications';
94+
*
95+
* const { channels } = await subscriptions.getSupportedChannels('<tenantId>');
96+
* const slack = channels.find(c => c.name === NotificationMode.Slack);
97+
* if (slack?.isEnabled) {
98+
* // safe to subscribe to Slack
99+
* }
100+
* ```
101+
* @internal
102+
*/
103+
getSupportedChannels(tenantId: string): Promise<SubscriptionGetSupportedChannelsResponse>;
104+
}
Lines changed: 241 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,241 @@
1+
/**
2+
* Subscription service types — request/response shapes for user subscription preferences.
3+
*/
4+
5+
import { NotificationCategory, NotificationMode } from './notifications.types';
6+
7+
/**
8+
* Status of a notification mode (channel) for a publisher — whether the user has
9+
* activated this channel.
10+
*/
11+
export interface AllowedMode {
12+
/** Notification channel. */
13+
name: NotificationMode;
14+
/** Whether the user has activated this channel for the publisher. */
15+
isActive: boolean;
16+
}
17+
18+
/**
19+
* Per-mode subscription state for a topic.
20+
*/
21+
export interface SubscriptionMode {
22+
/** Notification channel. */
23+
name: NotificationMode;
24+
/** Whether the user is subscribed to this topic via this channel. */
25+
isSubscribed: boolean;
26+
/** Whether the topic is subscribed by default via this channel. */
27+
isSubscribedByDefault: boolean;
28+
}
29+
30+
/**
31+
* Base topic shape — identity/discovery fields only, with no subscription state.
32+
*/
33+
export interface SubscriptionTopicBase {
34+
/** Topic GUID. */
35+
id: string;
36+
/** Stable topic identifier (e.g. `Process.JobExecution.Faulted`). */
37+
name: string;
38+
/** Human-readable topic name. */
39+
displayName: string | null;
40+
/** Topic description. */
41+
description: string | null;
42+
/** Topic group name. */
43+
group: string | null;
44+
}
45+
46+
/**
47+
* A topic that the user can subscribe to, with full subscription state — as returned by `getAll()`.
48+
*/
49+
export interface SubscriptionTopic extends SubscriptionTopicBase {
50+
/** Severity category. */
51+
category: NotificationCategory;
52+
/** Parent topic group name. Often `null`. */
53+
parentGroup: string | null;
54+
/** Whether the user is currently subscribed to this topic. */
55+
isSubscribed: boolean;
56+
/** Whether the topic is mandatory — cannot be unsubscribed. */
57+
isMandatory: boolean;
58+
/** Whether the topic should be visible in the user-facing subscription UI. */
59+
isVisible: boolean;
60+
/** Whether the topic is subscribed by default for new users. */
61+
isDefault: boolean;
62+
/** Whether notifications for this topic can be batched. */
63+
isAllowedToBeDispatchedInBatch: boolean;
64+
/** Whether the topic is marked as infrequent (lower-priority delivery). */
65+
isInfrequent: boolean;
66+
/** Number of days notifications for this topic are retained. */
67+
retentionDays: number;
68+
/** Display ordering hint. */
69+
orderingSequence: number;
70+
/** Per-channel subscription state. */
71+
modes: SubscriptionMode[];
72+
}
73+
74+
/**
75+
* An entity reference used in publisher / topic-group subscription requests.
76+
*/
77+
export interface SubscriptionEntity {
78+
/** Entity GUID. */
79+
id: string;
80+
/** Entity name. */
81+
name: string | null;
82+
/** Entity type. */
83+
type: string | null;
84+
/** Parent name (e.g. folder name for a sub-folder). */
85+
parentName: string | null;
86+
/** Whether the user is subscribed to notifications for this entity. */
87+
isSubscribed: boolean;
88+
}
89+
90+
/**
91+
* Group of entities that belong to a topic group.
92+
*/
93+
export interface TopicGroupEntity {
94+
/** Topic group name. */
95+
name: string | null;
96+
/** Entities belonging to this group. */
97+
entities: SubscriptionEntity[] | null;
98+
}
99+
100+
/**
101+
* Entity-sync operation an event maps to.
102+
*/
103+
export enum EntitySyncOperation {
104+
Add = 'Add',
105+
Delete = 'Delete',
106+
}
107+
108+
/**
109+
* Event mapping that triggers entity synchronization for an entity type.
110+
*/
111+
export interface EntitySyncEvent {
112+
/** Source event name. */
113+
eventName: string | null;
114+
/** Sync operation the event maps to. */
115+
operation: EntitySyncOperation;
116+
}
117+
118+
/**
119+
* Entity-type metadata declared by a publisher (e.g. folder entity registration).
120+
*/
121+
export interface SubscriptionEntityType {
122+
/** Entity type name. */
123+
type: string | null;
124+
/** URL template for resolving entity links. */
125+
urlTemplate: string | null;
126+
/** Property used to project the entity in publications. */
127+
projectionProperty: string | null;
128+
/** Publication payload property carrying the entity reference. */
129+
publicationPayloadProperty: string | null;
130+
/** Request type used for entity sync. */
131+
requestType: string | null;
132+
/** Payload template for entity sync requests. */
133+
payload: string | null;
134+
/** Events that trigger entity synchronization. */
135+
entitySyncEvents: EntitySyncEvent[] | null;
136+
}
137+
138+
/**
139+
* Entity types supported by a topic group.
140+
*/
141+
export interface TopicGroupEntityType {
142+
/** Topic group name. */
143+
name: string | null;
144+
/** Entity type names. */
145+
entityTypes: string[] | null;
146+
}
147+
148+
/**
149+
* Base publisher shape — identity/discovery fields and the topic catalogue, with no subscription state.
150+
*/
151+
export interface SubscriptionPublisherBase {
152+
/** Publisher GUID. */
153+
id: string;
154+
/** Stable publisher name (e.g. `Orchestrator`, `Actions`). */
155+
name: string;
156+
/** Human-readable publisher name. */
157+
displayName: string | null;
158+
/** Topics published under this publisher. */
159+
topics: SubscriptionTopicBase[];
160+
}
161+
162+
/**
163+
* A publisher with its topics, channels, and subscription state — as returned by `getAll()`.
164+
*/
165+
export interface SubscriptionPublisher extends SubscriptionPublisherBase {
166+
/** Topics published under this publisher, with full per-topic subscription state. */
167+
topics: SubscriptionTopic[];
168+
/** URL to navigate to when a publisher notification is clicked. */
169+
redirectionUrl: string | null;
170+
/** Number of days notifications from this publisher are retained. */
171+
retentionDays: number;
172+
/** Whether notifications from this publisher are included in summary digests. */
173+
addToSummary: boolean;
174+
/** Whether the user has opted in to receive notifications from this publisher. */
175+
isUserOptin: boolean;
176+
/** Channels available for this publisher and their activation state. */
177+
modes: AllowedMode[];
178+
/** Entities (e.g. folders) the user has entity-level subscriptions for. */
179+
entities: SubscriptionEntity[] | null;
180+
/** Entity types the publisher exposes. */
181+
entityTypes: SubscriptionEntityType[] | null;
182+
/** Topic-group entity sets the user has entity-level subscriptions for. */
183+
topicGroupEntities: TopicGroupEntity[];
184+
/** Topic-group entity types. */
185+
topicGroupEntityTypes: TopicGroupEntityType[] | null;
186+
}
187+
188+
/**
189+
* Channel availability returned by `getSupportedChannels()`.
190+
*
191+
* Note: `InApp` is never returned — it is always implicitly available.
192+
*/
193+
export interface SupportedChannel {
194+
/** Notification channel. */
195+
name: NotificationMode;
196+
/** Whether the channel is enabled for the current tenant. */
197+
isEnabled: boolean;
198+
}
199+
200+
/**
201+
* Options for `Subscriptions.getAll()`.
202+
*/
203+
export interface SubscriptionGetAllOptions {
204+
/** Filter to specific publisher names. When omitted, all publishers are returned. */
205+
publishers?: string[];
206+
}
207+
208+
/**
209+
* Options for `Subscriptions.getPublishers()`.
210+
*/
211+
export interface SubscriptionGetPublishersOptions {
212+
/** Filter to a specific publisher name. When omitted, all publishers are returned. */
213+
name?: string;
214+
}
215+
216+
/**
217+
* Response from `getAll()` — publishers with their topics, channels, and full subscription state.
218+
*/
219+
export interface SubscriptionGetResponse {
220+
/** Publishers with their topics and subscription state. */
221+
publishers: SubscriptionPublisher[];
222+
}
223+
224+
/**
225+
* Response from `getPublishers()` — the publisher/topic discovery catalogue.
226+
*
227+
* Publishers and topics carry only identity/discovery fields (no subscription state);
228+
* use `getAll()` to inspect subscription state.
229+
*/
230+
export interface SubscriptionGetPublishersResponse {
231+
/** Publishers with their topic catalogue. */
232+
publishers: SubscriptionPublisherBase[];
233+
}
234+
235+
/**
236+
* Response from `getSupportedChannels()`.
237+
*/
238+
export interface SubscriptionGetSupportedChannelsResponse {
239+
/** Notification channels supported in the current tenant. `InApp` is not listed — it is always available. */
240+
channels: SupportedChannel[];
241+
}

0 commit comments

Comments
 (0)