@azure/notification-hubs 1.0.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (196) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +749 -0
  3. package/dist/index.js +2235 -0
  4. package/dist/index.js.map +1 -0
  5. package/dist-esm/src/client/cancelScheduledNotification.js +23 -0
  6. package/dist-esm/src/client/cancelScheduledNotification.js.map +1 -0
  7. package/dist-esm/src/client/createOrUpdateInstallation.js +24 -0
  8. package/dist-esm/src/client/createOrUpdateInstallation.js.map +1 -0
  9. package/dist-esm/src/client/createOrUpdateRegistration.js +17 -0
  10. package/dist-esm/src/client/createOrUpdateRegistration.js.map +1 -0
  11. package/dist-esm/src/client/createRegistration.js +24 -0
  12. package/dist-esm/src/client/createRegistration.js.map +1 -0
  13. package/dist-esm/src/client/createRegistrationId.js +26 -0
  14. package/dist-esm/src/client/createRegistrationId.js.map +1 -0
  15. package/dist-esm/src/client/deleteInstallation.js +22 -0
  16. package/dist-esm/src/client/deleteInstallation.js.map +1 -0
  17. package/dist-esm/src/client/deleteRegistration.js +25 -0
  18. package/dist-esm/src/client/deleteRegistration.js.map +1 -0
  19. package/dist-esm/src/client/getFeedbackContainerUrl.js +23 -0
  20. package/dist-esm/src/client/getFeedbackContainerUrl.js.map +1 -0
  21. package/dist-esm/src/client/getInstallation.js +23 -0
  22. package/dist-esm/src/client/getInstallation.js.map +1 -0
  23. package/dist-esm/src/client/getNotificationHubJob.js +24 -0
  24. package/dist-esm/src/client/getNotificationHubJob.js.map +1 -0
  25. package/dist-esm/src/client/getNotificationOutcomeDetails.js +24 -0
  26. package/dist-esm/src/client/getNotificationOutcomeDetails.js.map +1 -0
  27. package/dist-esm/src/client/getRegistration.js +24 -0
  28. package/dist-esm/src/client/getRegistration.js.map +1 -0
  29. package/dist-esm/src/client/index.js +44 -0
  30. package/dist-esm/src/client/index.js.map +1 -0
  31. package/dist-esm/src/client/internal/_client.js +75 -0
  32. package/dist-esm/src/client/internal/_client.js.map +1 -0
  33. package/dist-esm/src/client/internal/_createOrUpdateRegistrationDescription.js +31 -0
  34. package/dist-esm/src/client/internal/_createOrUpdateRegistrationDescription.js.map +1 -0
  35. package/dist-esm/src/client/internal/_scheduleNotificationPayload.js +37 -0
  36. package/dist-esm/src/client/internal/_scheduleNotificationPayload.js.map +1 -0
  37. package/dist-esm/src/client/internal/_sendNotificationPayload.js +51 -0
  38. package/dist-esm/src/client/internal/_sendNotificationPayload.js.map +1 -0
  39. package/dist-esm/src/client/listNotificationHubJobs.js +23 -0
  40. package/dist-esm/src/client/listNotificationHubJobs.js.map +1 -0
  41. package/dist-esm/src/client/listRegistrations.js +89 -0
  42. package/dist-esm/src/client/listRegistrations.js.map +1 -0
  43. package/dist-esm/src/client/listRegistrationsByTag.js +87 -0
  44. package/dist-esm/src/client/listRegistrationsByTag.js.map +1 -0
  45. package/dist-esm/src/client/scheduleBroadcastNotification.js +17 -0
  46. package/dist-esm/src/client/scheduleBroadcastNotification.js.map +1 -0
  47. package/dist-esm/src/client/scheduleNotification.js +18 -0
  48. package/dist-esm/src/client/scheduleNotification.js.map +1 -0
  49. package/dist-esm/src/client/sendBroadcastNotification.js +15 -0
  50. package/dist-esm/src/client/sendBroadcastNotification.js.map +1 -0
  51. package/dist-esm/src/client/sendDirectNotification.js +16 -0
  52. package/dist-esm/src/client/sendDirectNotification.js.map +1 -0
  53. package/dist-esm/src/client/sendNotification.js +16 -0
  54. package/dist-esm/src/client/sendNotification.js.map +1 -0
  55. package/dist-esm/src/client/submitNotificationHubJob.js +26 -0
  56. package/dist-esm/src/client/submitNotificationHubJob.js.map +1 -0
  57. package/dist-esm/src/client/updateInstallation.js +25 -0
  58. package/dist-esm/src/client/updateInstallation.js.map +1 -0
  59. package/dist-esm/src/client/updateRegistration.js +21 -0
  60. package/dist-esm/src/client/updateRegistration.js.map +1 -0
  61. package/dist-esm/src/index.js +12 -0
  62. package/dist-esm/src/index.js.map +1 -0
  63. package/dist-esm/src/models/installation.js +51 -0
  64. package/dist-esm/src/models/installation.js.map +1 -0
  65. package/dist-esm/src/models/notification.js +104 -0
  66. package/dist-esm/src/models/notification.js.map +1 -0
  67. package/dist-esm/src/models/notificationBuilder.js +169 -0
  68. package/dist-esm/src/models/notificationBuilder.js.map +1 -0
  69. package/dist-esm/src/models/notificationDetails.js +4 -0
  70. package/dist-esm/src/models/notificationDetails.js.map +1 -0
  71. package/dist-esm/src/models/notificationHubJob.js +4 -0
  72. package/dist-esm/src/models/notificationHubJob.js.map +1 -0
  73. package/dist-esm/src/models/options.js +4 -0
  74. package/dist-esm/src/models/options.js.map +1 -0
  75. package/dist-esm/src/models/registration.js +135 -0
  76. package/dist-esm/src/models/registration.js.map +1 -0
  77. package/dist-esm/src/models/response.js +4 -0
  78. package/dist-esm/src/models/response.js.map +1 -0
  79. package/dist-esm/src/notificationHubsClient.js +251 -0
  80. package/dist-esm/src/notificationHubsClient.js.map +1 -0
  81. package/dist-esm/src/serializers/notificationDetailsSerializer.js +58 -0
  82. package/dist-esm/src/serializers/notificationDetailsSerializer.js.map +1 -0
  83. package/dist-esm/src/serializers/notificationHubJobSerializer.js +74 -0
  84. package/dist-esm/src/serializers/notificationHubJobSerializer.js.map +1 -0
  85. package/dist-esm/src/serializers/registrationSerializer.js +375 -0
  86. package/dist-esm/src/serializers/registrationSerializer.js.map +1 -0
  87. package/dist-esm/src/utils/connectionStringUtils.js +37 -0
  88. package/dist-esm/src/utils/connectionStringUtils.js.map +1 -0
  89. package/dist-esm/src/utils/constants.js +11 -0
  90. package/dist-esm/src/utils/constants.js.map +1 -0
  91. package/dist-esm/src/utils/retryPolicy.js +144 -0
  92. package/dist-esm/src/utils/retryPolicy.js.map +1 -0
  93. package/dist-esm/src/utils/tracing.js +13 -0
  94. package/dist-esm/src/utils/tracing.js.map +1 -0
  95. package/dist-esm/src/utils/utils.js +130 -0
  96. package/dist-esm/src/utils/utils.js.map +1 -0
  97. package/dist-esm/src/utils/xmlUtils.js +101 -0
  98. package/dist-esm/src/utils/xmlUtils.js.map +1 -0
  99. package/package.json +144 -0
  100. package/types/3.1/notification-hubs.d.ts +1728 -0
  101. package/types/latest/notification-hubs.d.ts +1840 -0
  102. package/types/latest/tsdoc-metadata.json +11 -0
  103. package/types/src/client/cancelScheduledNotification.d.ts +13 -0
  104. package/types/src/client/cancelScheduledNotification.d.ts.map +1 -0
  105. package/types/src/client/createOrUpdateInstallation.d.ts +13 -0
  106. package/types/src/client/createOrUpdateInstallation.d.ts.map +1 -0
  107. package/types/src/client/createOrUpdateRegistration.d.ts +12 -0
  108. package/types/src/client/createOrUpdateRegistration.d.ts.map +1 -0
  109. package/types/src/client/createRegistration.d.ts +13 -0
  110. package/types/src/client/createRegistration.d.ts.map +1 -0
  111. package/types/src/client/createRegistrationId.d.ts +10 -0
  112. package/types/src/client/createRegistrationId.d.ts.map +1 -0
  113. package/types/src/client/deleteInstallation.d.ts +12 -0
  114. package/types/src/client/deleteInstallation.d.ts.map +1 -0
  115. package/types/src/client/deleteRegistration.d.ts +12 -0
  116. package/types/src/client/deleteRegistration.d.ts.map +1 -0
  117. package/types/src/client/getFeedbackContainerUrl.d.ts +11 -0
  118. package/types/src/client/getFeedbackContainerUrl.d.ts.map +1 -0
  119. package/types/src/client/getInstallation.d.ts +12 -0
  120. package/types/src/client/getInstallation.d.ts.map +1 -0
  121. package/types/src/client/getNotificationHubJob.d.ts +12 -0
  122. package/types/src/client/getNotificationHubJob.d.ts.map +1 -0
  123. package/types/src/client/getNotificationOutcomeDetails.d.ts +13 -0
  124. package/types/src/client/getNotificationOutcomeDetails.d.ts.map +1 -0
  125. package/types/src/client/getRegistration.d.ts +12 -0
  126. package/types/src/client/getRegistration.d.ts.map +1 -0
  127. package/types/src/client/index.d.ts +41 -0
  128. package/types/src/client/index.d.ts.map +1 -0
  129. package/types/src/client/internal/_client.d.ts +26 -0
  130. package/types/src/client/internal/_client.d.ts.map +1 -0
  131. package/types/src/client/internal/_createOrUpdateRegistrationDescription.d.ts +8 -0
  132. package/types/src/client/internal/_createOrUpdateRegistrationDescription.d.ts.map +1 -0
  133. package/types/src/client/internal/_scheduleNotificationPayload.d.ts +9 -0
  134. package/types/src/client/internal/_scheduleNotificationPayload.d.ts.map +1 -0
  135. package/types/src/client/internal/_sendNotificationPayload.d.ts +10 -0
  136. package/types/src/client/internal/_sendNotificationPayload.d.ts.map +1 -0
  137. package/types/src/client/listNotificationHubJobs.d.ts +11 -0
  138. package/types/src/client/listNotificationHubJobs.d.ts.map +1 -0
  139. package/types/src/client/listRegistrations.d.ts +12 -0
  140. package/types/src/client/listRegistrations.d.ts.map +1 -0
  141. package/types/src/client/listRegistrationsByTag.d.ts +13 -0
  142. package/types/src/client/listRegistrationsByTag.d.ts.map +1 -0
  143. package/types/src/client/scheduleBroadcastNotification.d.ts +16 -0
  144. package/types/src/client/scheduleBroadcastNotification.d.ts.map +1 -0
  145. package/types/src/client/scheduleNotification.d.ts +17 -0
  146. package/types/src/client/scheduleNotification.d.ts.map +1 -0
  147. package/types/src/client/sendBroadcastNotification.d.ts +14 -0
  148. package/types/src/client/sendBroadcastNotification.d.ts.map +1 -0
  149. package/types/src/client/sendDirectNotification.d.ts +16 -0
  150. package/types/src/client/sendDirectNotification.d.ts.map +1 -0
  151. package/types/src/client/sendNotification.d.ts +15 -0
  152. package/types/src/client/sendNotification.d.ts.map +1 -0
  153. package/types/src/client/submitNotificationHubJob.d.ts +13 -0
  154. package/types/src/client/submitNotificationHubJob.d.ts.map +1 -0
  155. package/types/src/client/updateInstallation.d.ts +14 -0
  156. package/types/src/client/updateInstallation.d.ts.map +1 -0
  157. package/types/src/client/updateRegistration.d.ts +12 -0
  158. package/types/src/client/updateRegistration.d.ts.map +1 -0
  159. package/types/src/index.d.ts +10 -0
  160. package/types/src/index.d.ts.map +1 -0
  161. package/types/src/models/installation.d.ts +200 -0
  162. package/types/src/models/installation.d.ts.map +1 -0
  163. package/types/src/models/notification.d.ts +166 -0
  164. package/types/src/models/notification.d.ts.map +1 -0
  165. package/types/src/models/notificationBuilder.d.ts +546 -0
  166. package/types/src/models/notificationBuilder.d.ts.map +1 -0
  167. package/types/src/models/notificationDetails.d.ts +87 -0
  168. package/types/src/models/notificationDetails.d.ts.map +1 -0
  169. package/types/src/models/notificationHubJob.d.ts +104 -0
  170. package/types/src/models/notificationHubJob.d.ts.map +1 -0
  171. package/types/src/models/options.d.ts +43 -0
  172. package/types/src/models/options.d.ts.map +1 -0
  173. package/types/src/models/registration.d.ts +368 -0
  174. package/types/src/models/registration.d.ts.map +1 -0
  175. package/types/src/models/response.d.ts +41 -0
  176. package/types/src/models/response.d.ts.map +1 -0
  177. package/types/src/notificationHubsClient.d.ts +190 -0
  178. package/types/src/notificationHubsClient.d.ts.map +1 -0
  179. package/types/src/serializers/notificationDetailsSerializer.d.ts +7 -0
  180. package/types/src/serializers/notificationDetailsSerializer.d.ts.map +1 -0
  181. package/types/src/serializers/notificationHubJobSerializer.d.ts +21 -0
  182. package/types/src/serializers/notificationHubJobSerializer.d.ts.map +1 -0
  183. package/types/src/serializers/registrationSerializer.d.ts +193 -0
  184. package/types/src/serializers/registrationSerializer.d.ts.map +1 -0
  185. package/types/src/utils/connectionStringUtils.d.ts +37 -0
  186. package/types/src/utils/connectionStringUtils.d.ts.map +1 -0
  187. package/types/src/utils/constants.d.ts +9 -0
  188. package/types/src/utils/constants.d.ts.map +1 -0
  189. package/types/src/utils/retryPolicy.d.ts +72 -0
  190. package/types/src/utils/retryPolicy.d.ts.map +1 -0
  191. package/types/src/utils/tracing.d.ts +6 -0
  192. package/types/src/utils/tracing.d.ts.map +1 -0
  193. package/types/src/utils/utils.d.ts +65 -0
  194. package/types/src/utils/utils.d.ts.map +1 -0
  195. package/types/src/utils/xmlUtils.d.ts +46 -0
  196. package/types/src/utils/xmlUtils.d.ts.map +1 -0
package/README.md ADDED
@@ -0,0 +1,749 @@
1
+ # Azure Notification Hubs SDK for JavaScript
2
+
3
+ Azure Notification Hubs provide a scaled-out push engine that enables you to send notifications to any platform (Apple, Amazon Kindle, Android, Baidu, Web, Windows, etc.) from any back-end (cloud or on-premises). Notification Hubs works well for both enterprise and consumer scenarios. Here are a few example scenarios:
4
+
5
+ - Send breaking news notifications to millions with low latency.
6
+ - Send location-based coupons to interested user segments.
7
+ - Send event-related notifications to users or groups for media/sports/finance/gaming applications.
8
+ - Push promotional contents to applications to engage and market to customers.
9
+ - Notify users of enterprise events such as new messages and work items.
10
+ - Send codes for multi-factor authentication.
11
+
12
+ [Source code](https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/notificationhubs/notification-hubs/) |
13
+ [Product documentation](https://docs.microsoft.com/azure/notification-hubs/)
14
+
15
+ ## Getting started
16
+
17
+ ### Currently supported environments
18
+
19
+ - [LTS versions of Node.js](https://nodejs.org/about/releases/)
20
+ - Latest versions of Safari, Chrome, Edge, and Firefox.
21
+
22
+ See our [support policy](https://github.com/Azure/azure-sdk-for-js/blob/main/SUPPORT.md) for more details.
23
+
24
+ ### Install the package
25
+
26
+ ```bash
27
+ npm install @azure/notification-hubs
28
+ ```
29
+
30
+ ### Prerequisites
31
+
32
+ - An [Azure Subscription](https://azure.microsoft.com)
33
+ - An [App Notification Hubs](https://docs.microsoft.com/azure/notification-hubs/) resource.
34
+
35
+ ### Create an Azure Notification Hubs resource
36
+
37
+ An Azure Notification Hub can be created using the following methods:
38
+
39
+ 1. [Azure Portal](https://docs.microsoft.com/azure/notification-hubs/create-notification-hub-portal)
40
+ 2. [Azure CLI](https://docs.microsoft.com/azure/notification-hubs/create-notification-hub-azure-cli)
41
+ 3. [Bicep](https://docs.microsoft.com/azure/notification-hubs/create-notification-hub-bicep)
42
+ 4. [ARM Template](https://docs.microsoft.com/azure/notification-hubs/create-notification-hub-template)
43
+
44
+ Once created, the Notification Hub can be configured using the [Azure Portal or Azure CLI](https://docs.microsoft.com/azure/notification-hubs/configure-notification-hub-portal-pns-settings?tabs=azure-portal).
45
+
46
+ ### Importing the Client
47
+
48
+ This SDK for JavaScript offers two ways of interacting with Azure Notification Hubs, either through the class-based approach, or with a modular design approach. The class-based approach is consistent across all packages to create a client and then interact with the methods on the client.
49
+
50
+ ```typescript
51
+ import {
52
+ NotificationHubsServiceClient
53
+ createAppleInstallation
54
+ } from "@azure/notification-hubs";
55
+
56
+ const client = new NotificationHubServiceClient("<connection string>", "<hub name>");
57
+
58
+ const installation = createAppleInstallation({
59
+ installationId: "<installation-id>",
60
+ pushChannel: "<push-channel>",
61
+ tags: ["likes_javascript"],
62
+ });
63
+
64
+ const result = await client.createOrUpdateInstallation(installation);
65
+ ```
66
+
67
+ The modular approach allows the developer to pick and choose which functions to import as each method is exposed individually. This approach uses subpath-exports with ES-Modules to expose the methods via direct imports. With the individual exports, this creates a better tree-shaking experience and smaller bundle sizes that the developer can take advantage of.
68
+
69
+ Note that creating a client is exposed through the `"@azure/notification-hubs/client"` subpath and all client methods are exposed through the `"@azure/notification-hubs/client"` subpath. Each function exported takes the `client` as the first parameter and the rest of the parameters remain unchanged.
70
+
71
+ The following subpaths are exposed:
72
+
73
+ - `@azure/notification-hubs/client` - The main entry point for the client via `createClientContext`
74
+ - `@azure/notification-hubs/client/*` - The client methods such as `getInstallation` or `sendNotification`
75
+ - `@azure/notification-hubs/models/installation` - The installation models and factory methods.
76
+ - `@azure/notification-hubs/models/notification` - The notification models and factory methods.
77
+ - `@azure/notification-hubs/models/notificationBuilder` - The notification builder models and factory methods.
78
+ - `@azure/notification-hubs/models/options` - The method options such as `SendOperationOptions`.
79
+ - `@azure/notification-hubs/models/registration` - The registration models and factory methods.
80
+
81
+ The above code snippet then becomes the following:
82
+
83
+ ```typescript
84
+ import { createClientContext } from "@azure/notification-hubs/client";
85
+ import { createAppleInstallation } from "@azure/notification-hubs/models/installation";
86
+ import { createOrUpdateInstallation } from "@azure/notification-hubs/client/createOrUpdateInstallation";
87
+
88
+ const context = createClientContext("<connection string>", "<hub name>");
89
+
90
+ const installation = createAppleInstallation({
91
+ installationId: "<installation-id>",
92
+ pushChannel: "<push-channel>",
93
+ tags: ["likes_javascript"],
94
+ });
95
+
96
+ const result = await createOrUpdateInstallation(context, installation);
97
+ ```
98
+
99
+ ### Authenticate the client
100
+
101
+ Interaction with an Azure Notification Hub starts with the `NotificationHubServiceClient` which supports [Shared Access Signature connection strings](https://docs.microsoft.com/azure/notification-hubs/notification-hubs-push-notification-security). This includes the following permission levels: **Listen**, **Manage**, **Send**.
102
+
103
+ Listen allows for a client to register itself via the Registration and Installations API. Send allows for the client to send notifications to devices using the send APIs. Finally, Manage allows the user to do Registration and Installation management, such as queries.
104
+
105
+ A new `NotificationHubServiceClient` client can be created using the constructor with the connection string and Notification Hub name.
106
+
107
+ ```typescript
108
+ import { NotificationHubServiceClient } from "@azure/notification-hubs";
109
+
110
+ const client = new NotificationHubServiceClient("<connection string>", "<hub name>");
111
+ ```
112
+
113
+ Using the modular approach, the `createClientContext` can be imported via the `"@azure/notification-hubs/client"` subpath.
114
+
115
+ ```typescript
116
+ import { createClientContext } from "@azure/notification-hubs/client";
117
+
118
+ const context = createClientContext("<connection string>", "<hub name>");
119
+ ```
120
+
121
+ ## Key concepts
122
+
123
+ Once the `NotificationHubClient` has been initialized, the following concepts can be explored.
124
+
125
+ - Device Management via Installations and RegistrationDescriptions
126
+ - Send Notifications to Devices
127
+
128
+ ### Device Management
129
+
130
+ Device management is a core concept to Notification Hubs to be able to store the unique identifier from the native Platform Notification Service (PNS) such as APNs or Firebase, and associated metadata such as tags used for sending push notifications to audiences. This is done with two APIs, the Installation API which is the newer and preferred mechanism, and Registrations.
131
+
132
+ #### Installations API
133
+
134
+ Installations are a newer and native JSON approach to device management that contains additional properties such as an installation ID and user ID which can be used for sending to audiences. The installations API has a few advantages over the existing Registration APIs in the following ways:
135
+
136
+ - Fully idempotent API so calling create on the installation, so an operation can be retried without worries about duplications.
137
+ - Support for `userId` and `installationId` properties which can be then used in tag expressions such as `$InstallationId:myInstallId` and `$UserId:bob@contoso.com`.
138
+ - Templates are now part of the installation instead of a separate registration and can be reference by name as a tag for sending.
139
+ - Partial updates are supported through the [JSON Patch Standard](https://tools.ietf.org/html/rfc6902), which allows to add tags and change other data without having to first query the installation.
140
+
141
+ Installations can be created through the `createOrUpdateInstallation` method such as the following:
142
+
143
+ ```typescript
144
+ import { NotificationHubServiceClient, createAppleInstallation } from "@azure/notification-hubs";
145
+ import { v4 as uuid } from "uuid";
146
+
147
+ const client = new NotificationHubServiceClient("<connection string>", "<hub name>");
148
+
149
+ // Create an installation for APNs
150
+ let installation = createAppleInstallation({
151
+ installationId: uuid(), // Must be unique
152
+ pushChannel: "00fc13adff785122b4ad28809a3420982341241421348097878e577c991de8f0", // PNS specific handle
153
+ tags: ["likes_hockey", "likes_football"],
154
+ });
155
+
156
+ installation = await client.createOrUpdateInstallation(installation);
157
+ ```
158
+
159
+ Using the modular approach, the code would be as follows:
160
+
161
+ ```typescript
162
+ import { createClientContext } from "@azure/notification-hubs/client";
163
+ import { createAppleInstallation } from "@azure/notification-hubs/models/installation";
164
+ import { createOrUpdateInstallation } from "@azure/notification-hubs/client/createOrUpdateInstallation";
165
+ import { v4 as uuid } from "uuid";
166
+
167
+ const context = createClientContext("<connection string>", "<hub name>");
168
+
169
+ // Create an installation for APNs
170
+ let installation = createAppleInstallation({
171
+ installationId: uuid(), // Must be unique
172
+ pushChannel: "00fc13adff785122b4ad28809a3420982341241421348097878e577c991de8f0", // PNS specific handle
173
+ tags: ["likes_hockey", "likes_football"],
174
+ });
175
+
176
+ installation = await createOrUpdateInstallation(context, installation);
177
+ ```
178
+
179
+ An update to an installation can be made through the JSON Patch schema such as adding a tag and a user ID using the `updateInstallation` method.
180
+
181
+ ```typescript
182
+ import { NotificationHubServiceClient, JsonPatch } from "@azure/notification-hubs";
183
+
184
+ const client = new NotificationHubServiceClient("<connection string>", "<hub name>");
185
+
186
+ const installationId = "<unique installation ID>";
187
+
188
+ const updates: JsonPatch[] = [
189
+ { op: "add", path: "/tags", value: "likes_baseball" },
190
+ { op: "add", path: "/userId", value: "bob@contoso.com" },
191
+ ];
192
+
193
+ const installation = await client.updateInstallation(installationId, updates);
194
+ ```
195
+
196
+ Using the modular approach, the code would be as follows:
197
+
198
+ ```typescript
199
+ import { createClientContext } from "@azure/notification-hubs/client";
200
+ import { JsonPatch, createAppleInstallation } from "@azure/notification-hubs/models/installation";
201
+ import { updateInstallation } from "@azure/notification-hubs/client/updateInstallation";
202
+
203
+ const context = createClientContext("<connection string>", "<hub name>");
204
+
205
+ const installationId = "<unique installation ID>";
206
+
207
+ const updates: JsonPatch[] = [
208
+ { op: "add", path: "/tags", value: "likes_baseball" },
209
+ { op: "add", path: "/userId", value: "bob@contoso.com" },
210
+ ];
211
+
212
+ const installation = await updateInstallation(context, installationId, updates);
213
+ ```
214
+
215
+ To retrieve an existing installation, use the `getInstallation` method with your existing unique installation ID.
216
+
217
+ ```typescript
218
+ import { NotificationHubServiceClient } from "@azure/notification-hubs";
219
+
220
+ const client = new NotificationHubServiceClient("<connection string>", "<hub name>");
221
+
222
+ const installationId = "<unique installation ID>";
223
+
224
+ const installation = client.getInstallation(installationId);
225
+ ```
226
+
227
+ Using the modular approach, the code would be as follows:
228
+
229
+ ```typescript
230
+ import { createClientContext } from "@azure/notification-hubs/client";
231
+ import { getInstallation } from "@azure/notification-hubs/client/getInstallation";
232
+
233
+ const context = createClientContext("<connection string>", "<hub name>");
234
+
235
+ const installationId = "<unique installation ID>";
236
+
237
+ const installation = getInstallation(context, installationId);
238
+ ```
239
+
240
+ #### Registrations API
241
+
242
+ A registration is associated with a PNS just as the installation above, with the unique device identifier from the PNS, and associated tags. Templates registrations are a way of creating pre-defined body templates which can then be customized at send time with properties to fill in for the message. For more information about templates, see [Templates documentation](https://docs.microsoft.com/azure/notification-hubs/notification-hubs-templates-cross-platform-push-messages).
243
+
244
+ An installation may be created in one of two ways, first by getting a registration ID from the server using `getInstallationId` and then `createOrUpdateRegistration` or via the `createRegistration` method.
245
+
246
+ ```typescript
247
+ import {
248
+ NotificationHubServiceClient,
249
+ createAppleRegistrationDescription,
250
+ } from "@azure/notification-hubs";
251
+
252
+ const client = new NotificationHubServiceClient("<connection string>", "<hub name>");
253
+
254
+ let registration = createAppleRegistrationDescription({
255
+ deviceToken: "00fc13adff785122b4ad28809a3420982341241421348097878e577c991de8f0",
256
+ tags: ["likes_hockey", "likes_football"],
257
+ });
258
+
259
+ registration = await client.createRegistration(registration);
260
+
261
+ console.log(`New Registration ID: ${registration.registrationId}`);
262
+ ```
263
+
264
+ Using the modular approach, the code would be as follows:
265
+
266
+ ```typescript
267
+ import { createClientContext } from "@azure/notification-hubs/client";
268
+ import { createAppleRegistrationDescription } from "@azure/notification-hubs/models/registration";
269
+ import { createRegistration } from "@azure/notification-hubs/client/createRegistration";
270
+
271
+ const context = createClientContext("<connection string>", "<hub name>");
272
+
273
+ let registration = createAppleRegistrationDescription({
274
+ deviceToken: "00fc13adff785122b4ad28809a3420982341241421348097878e577c991de8f0",
275
+ tags: ["likes_hockey", "likes_football"],
276
+ });
277
+
278
+ registration = await createRegistration(context, registration);
279
+
280
+ console.log(`New Registration ID: ${registration.registrationId}`);
281
+ ```
282
+
283
+ Updates can be done via the `updateRegistration` method but unlike installations, does not support incremental updates. Querying for an existing registration can be done with the `getRegistration` method.
284
+
285
+ ```typescript
286
+ import { NotificationHubServiceClient } from "@azure/notification-hubs";
287
+
288
+ const client = new NotificationHubServiceClient("<connection string>", "<hub name>");
289
+
290
+ const registrationId = "<unique Registration ID>";
291
+
292
+ let registration = await client.getRegistration(registrationId);
293
+
294
+ registration.tags.push("likes_sports");
295
+
296
+ registration = await client.updateRegistration(registration);
297
+ ```
298
+
299
+ Using the modular approach, the code would be as follows:
300
+
301
+ ```typescript
302
+ import { createClientContext } from "@azure/notification-hubs/client";
303
+ import { getRegistration } from "@azure/notification-hubs/client/getRegistration";
304
+ import { updateRegistration } from "@azure/notification-hubs/client/updateRegistration";
305
+
306
+ const context = createClientContext("<connection string>", "<hub name>");
307
+
308
+ const registrationId = "<unique Registration ID>";
309
+
310
+ let registration = await getRegistration(context, registrationId);
311
+
312
+ registration.tags.push("likes_sports");
313
+
314
+ registration = await updateRegistration(context, registration);
315
+ ```
316
+
317
+ Registrations, unlike installations, can be queried to get all registrations, matching registrations to a condition, or by tags. Registrations can be queried using the `listRegistrations` and `listRegistrationsByTag` method. Both methods support limiting via the `top` option and support asynchronous paging.
318
+
319
+ ```typescript
320
+ import { NotificationHubServiceClient } from "@azure/notification-hubs/client";
321
+
322
+ const client = new NotificationHubServiceClient("<connection string>", "<hub name>");
323
+
324
+ const registrations = await client.listRegistrationsByTag("likes_hockey");
325
+
326
+ let page = 0;
327
+ for await (const pages of registrations.byPage()) {
328
+ console.log(`Page number ${page++}`);
329
+ for (const item of pages) {
330
+ console.log(JSON.stringify(item, null, 2));
331
+ }
332
+ }
333
+ ```
334
+
335
+ Using the modular approach, the code would be as follows:
336
+
337
+ ```typescript
338
+ import { createClientContext } from "@azure/notification-hubs/client";
339
+ import { listRegistrationsByTag } from "@azure/notification-hubs/client/listRegistrationsByTag";
340
+
341
+ const context = createClientContext("<connection string>", "<hub name>");
342
+
343
+ const registrations = await listRegistrationsByTag(context, "likes_hockey");
344
+
345
+ let page = 0;
346
+ for await (const pages of registrations.byPage()) {
347
+ console.log(`Page number ${page++}`);
348
+ for (const item of pages) {
349
+ console.log(JSON.stringify(item, null, 2));
350
+ }
351
+ }
352
+ ```
353
+
354
+ ### Send Operations
355
+
356
+ Notification Hubs supports sending notifications to devices either directly using the unique PNS provided identifier, using tags for audience send, or a general broadcast to all devices. Using the Standard SKU and above, [scheduled send](https://docs.microsoft.com/azure/notification-hubs/notification-hubs-send-push-notifications-scheduled) allows the user to schedule notifications up to seven days in advance. All send operations return a Tracking ID and Correlation ID which can be used for Notification Hubs support cases. With the Standard SKU and above, a Notification ID is also returned which can be used to get notification telemetry via the `getNotificationOutcomeDetails` method.
357
+
358
+ For debugging purposes, the `enableTestSend` options can be set to `true` which gets immediate feedback from the PNS on the `send*` methods, however, is not supported in production scenarios. This is not supported on the scheduled send methods.
359
+
360
+ Raw JSON or XML strings can be sent to the send or scheduled send methods, or the notification builders can be used which helps construct messages per PNS such as APNs, Firebase, Baidu, ADM and WNS. These builders will build the native message format and fill in associated HTTP headers so there is no guessing about which fields are available for each PNS.
361
+
362
+ ```typescript
363
+ // Using the class-based approach
364
+ import { buildAppleNativeMessage } from "@azure/notification-hubs";
365
+
366
+ // Using the modular approach
367
+ import { buildAppleNativeMessage } from "@azure/notification-hubs/models/notificationBuilder";
368
+
369
+ const apnsMessage = buildAppleNativeMessage({
370
+ alert: {
371
+ title: "Notification Title",
372
+ subtitle: "Notification Subtitle",
373
+ body: "Notification body goes here",
374
+ },
375
+ sound: "default",
376
+ interruptionLevel: "time-sensitive",
377
+ });
378
+
379
+ // Send the message using the modular approach
380
+ const result = await sendBroadcastNotification(context, apnsMessage);
381
+ ```
382
+
383
+ #### Broadcast Send
384
+
385
+ Notification Hubs can be used to send notifications to all registered devices per platform using broadcast send through the `sendBroadcastNotification` method.
386
+
387
+ ```typescript
388
+ import {
389
+ NotificationHubServiceClient,
390
+ SendOperationOptions,
391
+ createAppleNotification,
392
+ } from "@azure/notification-hubs/client";
393
+
394
+ const context = createClientContext(connectionString, hubName);
395
+
396
+ const messageBody = `{ "aps" : { "alert" : "Hello" } }`;
397
+
398
+ const message = createAppleNotification({
399
+ body: messageBody,
400
+ headers: {
401
+ "apns-priority": "10",
402
+ "apns-push-type": "alert",
403
+ },
404
+ });
405
+
406
+ // Not required but can set test send to true for debugging purposes.
407
+ const sendOptions: SendOperationOptions = { enableTestSend: false };
408
+ const result = await client.sendBroadcastNotification(message, sendOptions);
409
+
410
+ console.log(`Tracking ID: ${result.trackingId}`);
411
+ console.log(`Correlation ID: ${result.correlationId}`);
412
+
413
+ // Only available in Standard SKU and above
414
+ if (result.notificationId) {
415
+ console.log(`Notification ID: ${result.notificationId}`);
416
+ }
417
+ ```
418
+
419
+ Using the modular approach, the code would be as follows:
420
+
421
+ ```typescript
422
+ import { SendOperationOptions } from "@azure/notification-hubs/models/options";
423
+ import { createClientContext } from "@azure/notification-hubs/client";
424
+ import { createAppleNotification } from "@azure/notification-hubs/models/notification";
425
+ import { sendBroadcastNotification } from "@azure/notification-hubs/client/sendBroadcastNotification";
426
+
427
+ const context = createClientContext(connectionString, hubName);
428
+
429
+ const messageBody = `{ "aps" : { "alert" : "Hello" } }`;
430
+
431
+ const message = createAppleNotification({
432
+ body: messageBody,
433
+ headers: {
434
+ "apns-priority": "10",
435
+ "apns-push-type": "alert",
436
+ },
437
+ });
438
+
439
+ // Not required but can set test send to true for debugging purposes.
440
+ const sendOptions: SendOperationOptions = { enableTestSend: false };
441
+ const result = await sendBroadcastNotification(context, message, sendOptions);
442
+
443
+ console.log(`Tracking ID: ${result.trackingId}`);
444
+ console.log(`Correlation ID: ${result.correlationId}`);
445
+
446
+ // Only available in Standard SKU and above
447
+ if (result.notificationId) {
448
+ console.log(`Notification ID: ${result.notificationId}`);
449
+ }
450
+ ```
451
+
452
+ #### Direct Send
453
+
454
+ To send directly a device, the user can send using the platform provided unique identifier such as APNs device token by calling the `sendDirectNotification` method.
455
+
456
+ ```typescript
457
+ import {
458
+ NotificationHubServiceClient,
459
+ SendOperationOptions,
460
+ createAppleNotification,
461
+ } from "@azure/notification-hubs";
462
+
463
+ const client = new NotificationHubServiceClient(connectionString, hubName);
464
+
465
+ const deviceToken = "00fc13adff785122b4ad28809a3420982341241421348097878e577c991de8f0";
466
+ const messageBody = `{ "aps" : { "alert" : "Hello" } }`;
467
+
468
+ const message = createAppleNotification({
469
+ body: messageBody,
470
+ headers: {
471
+ "apns-priority": "10",
472
+ "apns-push-type": "alert",
473
+ },
474
+ });
475
+
476
+ // Not required but can set test send to true for debugging purposes.
477
+ const sendOptions: SendOperationOptions = { enableTestSend: false };
478
+ const result = await client.sendDirectNotification(devicetoken, message, sendOptions);
479
+
480
+ console.log(`Tracking ID: ${result.trackingId}`);
481
+ console.log(`Correlation ID: ${result.correlationId}`);
482
+
483
+ // Only available in Standard SKU and above
484
+ if (result.notificationId) {
485
+ console.log(`Notification ID: ${result.notificationId}`);
486
+ }
487
+ ```
488
+
489
+ Using the modular approach, the code would be as follows:
490
+
491
+ ```typescript
492
+ import { SendOperationOptions } from "@azure/notification-hubs/models/options";
493
+ import { createClientContext } from "@azure/notification-hubs/client";
494
+ import { createAppleNotification } from "@azure/notification-hubs/models/notification";
495
+ import { sendDirectNotification } from "@azure/notification-hubs/client/sendDirectNotification";
496
+
497
+ const context = createClientContext(connectionString, hubName);
498
+
499
+ const deviceToken = "00fc13adff785122b4ad28809a3420982341241421348097878e577c991de8f0";
500
+ const messageBody = `{ "aps" : { "alert" : "Hello" } }`;
501
+
502
+ const message = createAppleNotification({
503
+ body: messageBody,
504
+ headers: {
505
+ "apns-priority": "10",
506
+ "apns-push-type": "alert",
507
+ },
508
+ });
509
+
510
+ // Not required but can set test send to true for debugging purposes.
511
+ const sendOptions: SendOperationOptions = { enableTestSend: false };
512
+ const result = await sendDirectNotification(context, devicetoken, message, sendOptions);
513
+
514
+ console.log(`Tracking ID: ${result.trackingId}`);
515
+ console.log(`Correlation ID: ${result.correlationId}`);
516
+
517
+ // Only available in Standard SKU and above
518
+ if (result.notificationId) {
519
+ console.log(`Notification ID: ${result.notificationId}`);
520
+ }
521
+ ```
522
+
523
+ #### Audience Send
524
+
525
+ In addition to targeting a single device, a user can target multiple devices using tags. These tags can be supplied as a list of tags, which then creates a tag expression to match registered devices, or via a tag expression which can then use Boolean logic to target the right audience. For more information about tags and tags expressions, see [Routing and Tag Expressions](https://docs.microsoft.com/azure/notification-hubs/notification-hubs-tags-segment-push-message).
526
+
527
+ ```typescript
528
+ import {
529
+ NotificationHubServiceClient,
530
+ SendOperationOptions,
531
+ createAppleMessage,
532
+ } from "@azure/notification-hubs";
533
+
534
+ const client = new NotificationHubServiceClient("<connection string>", "<hub name>");
535
+
536
+ const tagExpression = "likes_hockey && likes_football";
537
+ const messageBody = `{ "aps" : { "alert" : "Hello" } }`;
538
+
539
+ const message = createAppleMessage({
540
+ body: messageBody,
541
+ headers: {
542
+ "apns-priority": "10",
543
+ "apns-push-type": "alert",
544
+ },
545
+ });
546
+
547
+
548
+ // Not required but can set test send to true for debugging purposes.
549
+ const sendOptions: SendOperationOptions = { enableTestSend: false };
550
+ const result = await client.sendNotification(tagExpression, message, sendOptions);
551
+
552
+ console.log(`Tracking ID: ${result.trackingId}`);
553
+ console.log(`Correlation ID: ${result.correlationId}`);
554
+
555
+ // Only available in Standard SKU and above
556
+ if (result.notificationId) {
557
+ console.log(`Notification ID: ${result.notificationId}`);
558
+ }
559
+ ```
560
+
561
+ Using the modular approach, the code would be as follows:
562
+
563
+ ```typescript
564
+ import { SendOperationOptions } from "@azure/notification-hubs/models/options";
565
+ import { createClientContext } from "@azure/notification-hubs/client";
566
+ import { createAppleNotification } from "@azure/notification-hubs/models/notification";
567
+ import { sendNotification } from "@azure/notification-hubs/client/sendNotification";
568
+
569
+ const context = createClientContext("<connection string>", "<hub name>");
570
+
571
+ const tagExpression = "likes_hockey && likes_football";
572
+ const messageBody = `{ "aps" : { "alert" : "Hello" } }`;
573
+
574
+ const message = createAppleMessage({
575
+ body: messageBody,
576
+ headers: {
577
+ "apns-priority": "10",
578
+ "apns-push-type": "alert",
579
+ },
580
+ });
581
+
582
+
583
+ // Not required but can set test send to true for debugging purposes.
584
+ const sendOptions: SendOperationOptions = { enableTestSend: false };
585
+ const result = await sendNotification(context, tagExpression, message, sendOptions);
586
+
587
+ console.log(`Tracking ID: ${result.trackingId}`);
588
+ console.log(`Correlation ID: ${result.correlationId}`);
589
+
590
+ // Only available in Standard SKU and above
591
+ if (result.notificationId) {
592
+ console.log(`Notification ID: ${result.notificationId}`);
593
+ }
594
+ ```
595
+
596
+ #### Scheduled Send
597
+
598
+ Push notifications can be scheduled up to seven days in advance with Standard SKU namespaces and above using the `scheduleBroadcastNotification` method to send to devices with tags or a general broadcast with the `scheduleBroadcastNotification`. This returns a notification ID which can be then used to cancel if necessary via the `cancelScheduledNotification` method.
599
+
600
+ ```typescript
601
+ import {
602
+ NotificationHubServiceClient,
603
+ SendOperationOptions,
604
+ createAppleNotification,
605
+ } from "@azure/notification-hubs";
606
+
607
+ const client = new NotificationHubServiceClient("<connection string>", "<hub name>");
608
+
609
+ const tagExpression = "likes_hockey && likes_football";
610
+ const messageBody = `{ "aps" : { "alert" : "Hello" } }`;
611
+
612
+ // Schedule 8 hours from nows
613
+ const scheduledTime = new Date(Date.now() + (8 * 60 * 60 * 1000));
614
+
615
+ const message = createAppleNotification({
616
+ body: messageBody,
617
+ headers: {
618
+ "apns-priority": "10",
619
+ "apns-push-type": "alert",
620
+ },
621
+ });
622
+
623
+ // Not required but can set test send to true for debugging purposes.
624
+ const sendOptions: SendOperationOptions = { enableTestSend: false };
625
+ const result = await client.scheduleNotification(scheduledTime, tagExpression, message, sendOptions);
626
+
627
+ console.log(`Tracking ID: ${result.trackingId}`);
628
+ console.log(`Correlation ID: ${result.correlationId}`);
629
+
630
+ // Can be used to cancel via the cancelScheduledSend method
631
+ console.log(`Notification ID: ${result.notificationId}`);
632
+ ```
633
+
634
+ Using the modular approach, the code would be as follows:
635
+
636
+ ```typescript
637
+ import { SendOperationOptions } from "@azure/notification-hubs/models/options";
638
+ import { createClientContext } from "@azure/notification-hubs/client";
639
+ import { createAppleNotification } from "@azure/notification-hubs/models/notification";
640
+ import { scheduleNotification } from "@azure/notification-hubs/client/scheduleNotification";
641
+
642
+ const context = createClientContext("<connection string>", "<hub name>");
643
+
644
+ const tagExpression = "likes_hockey && likes_football";
645
+ const messageBody = `{ "aps" : { "alert" : "Hello" } }`;
646
+
647
+ // Schedule 8 hours from nows
648
+ const scheduledTime = new Date(Date.now() + (8 * 60 * 60 * 1000));
649
+
650
+ const message = createAppleNotification({
651
+ body: messageBody,
652
+ headers: {
653
+ "apns-priority": "10",
654
+ "apns-push-type": "alert",
655
+ },
656
+ });
657
+
658
+ // Not required but can set test send to true for debugging purposes.
659
+ const sendOptions: SendOperationOptions = { enableTestSend: false };
660
+ const result = await scheduleNotification(context, scheduledTime, tagExpression, message, sendOptions);
661
+
662
+ console.log(`Tracking ID: ${result.trackingId}`);
663
+ console.log(`Correlation ID: ${result.correlationId}`);
664
+
665
+ // Can be used to cancel via the cancelScheduledSend method
666
+ console.log(`Notification ID: ${result.notificationId}`);
667
+ ```
668
+
669
+ ## Troubleshooting
670
+
671
+ ### Diagnose Dropped Notifications
672
+
673
+ Azure Notification Hubs has a complete guide to troubleshooting problems with dropped notifications in the [Diagnose dropped notifications in Azure Notification Hubs Guide](https://docs.microsoft.com/azure/notification-hubs/notification-hubs-push-notification-fixer).
674
+
675
+ [Test send](https://docs.microsoft.com/azure/notification-hubs/notification-hubs-push-notification-fixer#enabletestsend-property) is supported supported in the send methods with the `enableTestSend` option:
676
+
677
+ ```typescript
678
+ const sendOptions: SendOperationOptions = { enableTestSend: true };
679
+ const result = await client.sendDirectNotification(devicetoken, message, sendOptions);
680
+ ```
681
+
682
+ ### Logging
683
+
684
+ Enabling logging may help uncover useful information about failures. In order to see a log of HTTP requests and responses, set the `AZURE_LOG_LEVEL` environment variable to `info`. Alternatively, logging can be enabled at runtime by calling `setLogLevel` in the `@azure/logger`:
685
+
686
+ ```javascript
687
+ const { setLogLevel } = require("@azure/logger");
688
+
689
+ setLogLevel("info");
690
+ ```
691
+
692
+ For more detailed instructions on how to enable logs, you can look at the [@azure/logger package docs](https://github.com/Azure/azure-sdk-for-js/tree/main/sdk/core/logger).
693
+
694
+ ## Next steps
695
+
696
+ The following samples show you the various ways you can interact with Azure Notification Hubs:
697
+
698
+ **Device Management:**
699
+
700
+ - Installations API
701
+ - [Create Or Update Installation](https://github.com/Azure/azure-sdk-for-js/tree/main/sdk/notificationhubs/notification-hubs/samples-dev/createInstallation.ts)
702
+ - [Update Installation](https://github.com/Azure/azure-sdk-for-js/tree/main/sdk/notificationhubs/notification-hubs/samples-dev/updateInstallation.ts)
703
+ - Registration API
704
+ - [Create Registration](https://github.com/Azure/azure-sdk-for-js/tree/main/sdk/notificationhubs/notification-hubs/samples-dev/createRegistration.ts)s
705
+ - [Create Or Update Registration](https://github.com/Azure/azure-sdk-for-js/tree/main/sdk/notificationhubs/notification-hubs/samples-dev/createOrUpdateRegistration.ts)
706
+ - [Update Registration](https://github.com/Azure/azure-sdk-for-js/tree/main/sdk/notificationhubs/notification-hubs/samples-dev/updateRegistration.ts)
707
+ - [List Registrations](https://github.com/Azure/azure-sdk-for-js/tree/main/sdk/notificationhubs/notification-hubs/samples-dev/listRegistrations.ts)
708
+ - [List Registration By Tag](https://github.com/Azure/azure-sdk-for-js/tree/main/sdk/notificationhubs/notification-hubs/samples-dev/listRegistrationsByTag.ts)
709
+
710
+ **Send Operations:**
711
+
712
+ - [Broadcast Send](https://github.com/Azure/azure-sdk-for-js/tree/main/sdk/notificationhubs/notification-hubs/samples-dev/sendBroadcastNotification.ts)
713
+ - [Direct Send](https://github.com/Azure/azure-sdk-for-js/tree/main/sdk/notificationhubs/notification-hubs/samples-dev/sendDirectNotification.ts)
714
+ - [Audience Send With Tags List](https://github.com/Azure/azure-sdk-for-js/tree/main/sdk/notificationhubs/notification-hubs/samples-dev/sendTagsList.ts)
715
+ - [Audience Send With Tag Expression](https://github.com/Azure/azure-sdk-for-js/tree/main/sdk/notificationhubs/notification-hubs/samples-dev/sendTagExpression.ts)
716
+ - [Scheduled Broadcast Send](https://github.com/Azure/azure-sdk-for-js/tree/main/sdk/notificationhubs/notification-hubs/samples-dev/scheduledSendBroadcastNotification.ts)
717
+ - [Scheduled Send](https://github.com/Azure/azure-sdk-for-js/tree/main/sdk/notificationhubs/notification-hubs/samples-dev/scheduledSendNotification.ts)
718
+
719
+ **Management Operations:**
720
+
721
+ - [Export Registrations](https://github.com/Azure/azure-sdk-for-js/tree/main/sdk/notificationhubs/notification-hubs/samples-dev/exportRegistrationsJob.ts)
722
+ - [Import Registrations](https://github.com/Azure/azure-sdk-for-js/tree/main/sdk/notificationhubs/notification-hubs/samples-dev/importRegistrationsJob.ts)
723
+
724
+ ## Contributing
725
+
726
+ If you'd like to contribute to this library, please read the [contributing guide](https://github.com/Azure/azure-sdk-for-js/blob/main/CONTRIBUTING.md) to learn more about how to build and test the code.
727
+
728
+ This module's tests are a mixture of live and unit tests, which require you to have an Azure Notification Hubs instance. To execute the tests you'll need to run:
729
+
730
+ 1. `rush update`
731
+ 2. `rush build -t @azure/notification-hubs`
732
+ 3. Create a .env file with these contents in the `sdk\notificationhubs\notification-hubs` folder:
733
+ `NOTIFICATIONHUBS_CONNECTION_STRING=connection string for your Notification Hubs instance`
734
+ `NOTIFICATION_HUB_NAME=Notification Hub name`
735
+ 4. `cd sdk\notificationhubs\notification-hubs`
736
+ 5. `npm run test`.
737
+
738
+ View our [tests](https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/notificationhubs/notification-hubs/test)
739
+ folder for more details.
740
+
741
+ ## Related projects
742
+
743
+ - [Microsoft Azure SDK for JavaScript](https://github.com/Azure/azure-sdk-for-js)
744
+ - [Azure Notification Hubs](https://docs.microsoft.com/azure/notification-hubs/notification-hubs-push-notification-overview)
745
+
746
+ ![Impressions](https://azure-sdk-impressions.azurewebsites.net/api/impressions/azure-sdk-for-js%2Fsdk%notificationhubs%2Fnotification-hubs%2FREADME.png)
747
+
748
+ [azure_cli]: https://docs.microsoft.com/cli/azure
749
+ [azure_sub]: https://azure.microsoft.com/free/