Skip to content

Commit c6473e3

Browse files
authored
Merge pull request #101032 from metanMSFT/metan/multiple-resources
[Cog Svcs] Add multiple resources tutorial
2 parents 1d831f6 + 8ba95a9 commit c6473e3

File tree

3 files changed

+267
-0
lines changed

3 files changed

+267
-0
lines changed

articles/cognitive-services/immersive-reader/index.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ landingContent:
3939
links:
4040
- text: Python
4141
url: tutorial-python.md
42+
- text: Use multiple Immersive Reader resources
43+
url: tutorial-multiple-resources.md
4244

4345
- title: Explore Immersive Reader
4446
linkLists:

articles/cognitive-services/immersive-reader/toc.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
items:
1818
- name: Launch the Immersive Reader (Python)
1919
href: tutorial-python.md
20+
- name: Use multiple Immersive Reader resources
21+
href: tutorial-multiple-resources.md
2022
- name: How-To
2123
items:
2224
- name: Create Immersive Reader resource
Lines changed: 263 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,263 @@
1+
---
2+
title: "Tutorial: Integrate multiple Immersive Reader resources"
3+
titleSuffix: Azure Cognitive Services
4+
description: In this tutorial, you'll create a Node.js application that launches the Immersive Reader using multiple Immersive Reader resources.
5+
author: skamal
6+
manager: nitinme
7+
8+
ms.service: cognitive-services
9+
ms.subservice: immersive-reader
10+
ms.topic: tutorial
11+
ms.date: 01/14/2020
12+
ms.author: skamal
13+
#Customer intent: As a developer, I want to learn more about the Immersive Reader SDK so that I can fully utilize all that the SDK has to offer.
14+
---
15+
16+
# Tutorial: Integrate multiple Immersive Reader resources
17+
18+
In the [overview](./overview.md), you learned about what the Immersive Reader is and how it implements proven techniques to improve reading comprehension for language learners, emerging readers, and students with learning differences. In the [Node.js quickstart](./quickstart-nodejs.md), you learned how to use Immersive Reader with a single resource. This tutorial covers how to integrate multiple Immersive Reader resources in the same application. In this tutorial, you learn how to:
19+
20+
> [!div class="checklist"]
21+
> * Create multiple Immersive Reader resource under an existing resource group
22+
> * Launch the Immersive Reader using multiple resources
23+
24+
If you don't have an Azure subscription, create a [free account](https://azure.microsoft.com/free/?WT.mc_id=A261C142F) before you begin.
25+
26+
## Prerequisites
27+
28+
* Follow the [quickstart](./quickstart-nodejs.md) to create a web app that launches the Immersive Reader with NodeJS. In that quickstart, you configure a single Immersive Reader resource. We will build on top of that in this tutorial.
29+
30+
## Create the Immersive Reader resources
31+
32+
Follow [these instructions](./how-to-create-immersive-reader.md) to create each Immersive Reader resource. The **Create-ImmersiveReaderResource** script has `ResourceName`, `ResourceSubdomain`, and `ResourceLocation` as parameters. These should be unique for each resource being created. The remaining parameters should be the same as what you used when setting up your first Immersive Reader resource. This way, each resource can be linked to the same Azure resource group and Azure AD application.
33+
34+
The example below shows how to create two resources, one in WestUS, and another in EastUS. Notice the unique values for `ResourceName`, `ResourceSubdomain`, and `ResourceLocation`.
35+
36+
```azurepowershell-interactive
37+
Create-ImmersiveReaderResource
38+
-SubscriptionName <SUBSCRIPTION_NAME> `
39+
-ResourceName Resource_name_wus `
40+
-ResourceSubdomain resource-subdomain-wus `
41+
-ResourceSKU <RESOURCE_SKU> `
42+
-ResourceLocation westus `
43+
-ResourceGroupName <RESOURCE_GROUP_NAME> `
44+
-ResourceGroupLocation <RESOURCE_GROUP_LOCATION> `
45+
-AADAppDisplayName <AAD_APP_DISPLAY_NAME> `
46+
-AADAppIdentifierUri <AAD_APP_IDENTIFIER_URI> `
47+
-AADAppClientSecret <AAD_APP_CLIENT_SECRET>
48+
49+
Create-ImmersiveReaderResource
50+
-SubscriptionName <SUBSCRIPTION_NAME> `
51+
-ResourceName Resource_name_eus `
52+
-ResourceSubdomain resource-subdomain-eus `
53+
-ResourceSKU <RESOURCE_SKU> `
54+
-ResourceLocation eastus `
55+
-ResourceGroupName <RESOURCE_GROUP_NAME> `
56+
-ResourceGroupLocation <RESOURCE_GROUP_LOCATION> `
57+
-AADAppDisplayName <AAD_APP_DISPLAY_NAME> `
58+
-AADAppIdentifierUri <AAD_APP_IDENTIFIER_URI> `
59+
-AADAppClientSecret <AAD_APP_CLIENT_SECRET>
60+
```
61+
62+
## Add resources to environment configuration
63+
64+
In the quickstart, you created an environment configuration file that contains the `TenantId`, `ClientId`, `ClientSecret`, and `Subdomain` parameters. Since all of your resources use the same Azure AD application, we can use the same values for the `TenantId`, `ClientId`, and `ClientSecret`. The only change that needs to be made is to list each subdomain for each resource.
65+
66+
Your new __.env__ file should now look something like the following:
67+
68+
```text
69+
TENANT_ID={YOUR_TENANT_ID}
70+
CLIENT_ID={YOUR_CLIENT_ID}
71+
CLIENT_SECRET={YOUR_CLIENT_SECRET}
72+
SUBDOMAIN_WUS={YOUR_WESTUS_SUBDOMAIN}
73+
SUBDOMAIN_EUS={YOUR_EASTUS_SUBDOMAIN}
74+
```
75+
76+
Be sure not to commit this file into source control, as it contains secrets that should not be made public.
77+
78+
Next, we're going to modify the _routes\index.js_ file that we created to support our multiple resources. Replace its content with the following code.
79+
80+
As before, this code creates an API endpoint that acquires an Azure AD authentication token using your service principal password. This time, it allows the user to specify a resource location and pass it in as a query parameter. It then returns an object containing the token and the corresponding subdomain.
81+
82+
```javascript
83+
var express = require('express');
84+
var router = express.Router();
85+
var request = require('request');
86+
87+
/* GET home page. */
88+
router.get('/', function(req, res, next) {
89+
res.render('index', { title: 'Express' });
90+
});
91+
92+
router.get('/GetTokenAndSubdomain', function(req, res) {
93+
try {
94+
request.post({
95+
headers: {
96+
'content-type': 'application/x-www-form-urlencoded'
97+
},
98+
url: `https://login.windows.net/${process.env.TENANT_ID}/oauth2/token`,
99+
form: {
100+
grant_type: 'client_credentials',
101+
client_id: process.env.CLIENT_ID,
102+
client_secret: process.env.CLIENT_SECRET,
103+
resource: 'https://cognitiveservices.azure.com/'
104+
}
105+
},
106+
function(err, resp, tokenResult) {
107+
if (err) {
108+
console.log(err);
109+
return res.status(500).send('CogSvcs IssueToken error');
110+
}
111+
112+
var tokenResultParsed = JSON.parse(tokenResult);
113+
114+
if (tokenResultParsed.error) {
115+
console.log(tokenResult);
116+
return res.send({error : "Unable to acquire Azure AD token. Check the debugger for more information."})
117+
}
118+
119+
var token = tokenResultParsed.access_token;
120+
121+
var subdomain = "";
122+
var region = req.query && req.query.region;
123+
switch (region) {
124+
case "eus":
125+
subdomain = process.env.SUBDOMAIN_EUS
126+
break;
127+
case "wus":
128+
default:
129+
subdomain = process.env.SUBDOMAIN_WUS
130+
}
131+
132+
return res.send({token, subdomain});
133+
});
134+
} catch (err) {
135+
console.log(err);
136+
return res.status(500).send('CogSvcs IssueToken error');
137+
}
138+
});
139+
140+
module.exports = router;
141+
```
142+
143+
The **getimmersivereaderlaunchparams** API endpoint should be secured behind some form of authentication (for example, [OAuth](https://oauth.net/2/)) to prevent unauthorized users from obtaining tokens to use against your Immersive Reader service and billing; that work is beyond the scope of this tutorial.
144+
145+
## Launch the Immersive Reader with sample content
146+
147+
1. Open _views\index.pug_, and replace its content with the following code. This code populates the page with some sample content, and adds two buttons that launches the Immersive Reader. One for launching Immersive Reader for the EastUS resource, and another for the WestUS resource.
148+
149+
```pug
150+
doctype html
151+
html
152+
head
153+
title Immersive Reader Quickstart Node.js
154+
155+
link(rel='stylesheet', href='https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css')
156+
157+
// A polyfill for Promise is needed for IE11 support.
158+
script(src='https://cdn.jsdelivr.net/npm/promise-polyfill@8/dist/polyfill.min.js')
159+
160+
script(src='https://contentstorage.onenote.office.net/onenoteltir/immersivereadersdk/immersive-reader-sdk.1.0.0.js')
161+
script(src='https://code.jquery.com/jquery-3.3.1.min.js')
162+
163+
style(type="text/css").
164+
.immersive-reader-button {
165+
background-color: white;
166+
margin-top: 5px;
167+
border: 1px solid black;
168+
float: right;
169+
}
170+
body
171+
div(class="container")
172+
button(class="immersive-reader-button" data-button-style="icon" data-locale="en" onclick='handleLaunchImmersiveReader("wus")') WestUS Immersive Reader
173+
button(class="immersive-reader-button" data-button-style="icon" data-locale="en" onclick='handleLaunchImmersiveReader("eus")') EastUS Immersive Reader
174+
175+
h1(id="ir-title") About Immersive Reader
176+
div(id="ir-content" lang="en-us")
177+
p Immersive Reader is a tool that implements proven techniques to improve reading comprehension for emerging readers, language learners, and people with learning differences. The Immersive Reader is designed to make reading more accessible for everyone. The Immersive Reader
178+
179+
ul
180+
li Shows content in a minimal reading view
181+
li Displays pictures of commonly used words
182+
li Highlights nouns, verbs, adjectives, and adverbs
183+
li Reads your content out loud to you
184+
li Translates your content into another language
185+
li Breaks down words into syllables
186+
187+
h3 The Immersive Reader is available in many languages.
188+
189+
p(lang="es-es") El Lector inmersivo está disponible en varios idiomas.
190+
p(lang="zh-cn") 沉浸式阅读器支持许多语言
191+
p(lang="de-de") Der plastische Reader ist in vielen Sprachen verfügbar.
192+
p(lang="ar-eg" dir="rtl" style="text-align:right") يتوفر \"القارئ الشامل\" في العديد من اللغات.
193+
194+
script(type="text/javascript").
195+
function getTokenAndSubdomainAsync(region) {
196+
return new Promise(function (resolve, reject) {
197+
$.ajax({
198+
url: "/GetTokenAndSubdomain",
199+
type: "GET",
200+
data: {
201+
region: region
202+
},
203+
success: function (data) {
204+
if (data.error) {
205+
reject(data.error);
206+
} else {
207+
resolve(data);
208+
}
209+
},
210+
error: function (err) {
211+
reject(err);
212+
}
213+
});
214+
});
215+
}
216+
217+
function handleLaunchImmersiveReader(region) {
218+
getTokenAndSubdomainAsync(region)
219+
.then(function (response) {
220+
const token = response["token"];
221+
const subdomain = response["subdomain"];
222+
// Learn more about chunk usage and supported MIME types https://docs.microsoft.com/azure/cognitive-services/immersive-reader/reference#chunk
223+
const data = {
224+
title: $("#ir-title").text(),
225+
chunks: [{
226+
content: $("#ir-content").html(),
227+
mimeType: "text/html"
228+
}]
229+
};
230+
// Learn more about options https://docs.microsoft.com/azure/cognitive-services/immersive-reader/reference#options
231+
const options = {
232+
"onExit": exitCallback,
233+
"uiZIndex": 2000
234+
};
235+
ImmersiveReader.launchAsync(token, subdomain, data, options)
236+
.catch(function (error) {
237+
alert("Error in launching the Immersive Reader. Check the console.");
238+
console.log(error);
239+
});
240+
})
241+
.catch(function (error) {
242+
alert("Error in getting the Immersive Reader token and subdomain. Check the console.");
243+
console.log(error);
244+
});
245+
}
246+
247+
function exitCallback() {
248+
console.log("This is the callback function. It is executed when the Immersive Reader closes.");
249+
}
250+
```
251+
252+
3. Our web app is now ready. Start the app by running:
253+
254+
```bash
255+
npm start
256+
```
257+
258+
4. Open your browser and navigate to [http://localhost:3000](http://localhost:3000). You should see the above content on the page. Click on either the **EastUS Immersive Reader** button or the **WestUS Immersive Reader** button to launch the Immersive Reader using those respective resources.
259+
260+
## Next steps
261+
262+
* Explore the [Immersive Reader SDK](https://github.com/microsoft/immersive-reader-sdk) and the [Immersive Reader SDK Reference](./reference.md)
263+
* View code samples on [GitHub](https://github.com/microsoft/immersive-reader-sdk/tree/master/js/samples/advanced-csharp)

0 commit comments

Comments
 (0)