Use Immersive Reader to increase Reading Comprehension using Azure  Function and Cognitive Services
Tags: node, azurefunctions, cognitiveservices, serverless
Published: 2020-04-10 21:01:35

---
title: Use Immersive Reader to increase Reading Comprehension using Azure  Function and Cognitive Services
published: true
date: 2020-04-10 18:38:17 UTC
tags: nodejs,azure-functions,cognitive-services,serverless
canonical_url: https://blog.heyayush.live/Immersive-Functions
---

### Use Immersive Reader to increase Reading Comprehension using Azure Function and Cognitive Services

![](https://cdn-images-1.medium.com/max/1024/1*7Ups_-s3DO2EEaMHrXwZbA.png)

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

- Shows content in a minimal reading view
- Displays pictures of commonly used words
- Highlights nouns, verbs, adjectives, and adverbs
- Reads your content out loud to you
- Translates your content into another language
- Breaks down words into syllables

Azure Functions is a solution for easily running small pieces of code, or “functions,” in the cloud. It’s a serverless offering from Microsoft Azure.

[https://github.com/heyAyushh/ImmersiveFunction/raw/master/demo.gif](https://github.com/heyAyushh/ImmersiveFunction/raw/master/demo.gif)

try the Demo [here](https://immersivefn.now.sh/)

In this blog post we will see how to enable Immersive reader for your frontend.

- Learn how \*\*[Azure Functions\*\*](http://functions.azure.com/) can access token from Azure portal on your web client’s behalf.
- Add immersive reader to any website.
- Enable images pls.
- Working code sample is [available here](https://github.com/heyAyushh/ImmersiveFunction) -

### Prerequisites 🥚 -

- [NodeJS < 10+](http://nodejs.org/) & [npm](http://npmjs.com/)
- [Azure](http://portal.azure.com/) Account — Get it Free, [for Students](https://blog.heyayush.live/get-100dollar-Azure-credits-for-Students-without-Credit-card), [for Professionals](https://azure.microsoft.com/en-us/free/)
- [VSCode](https://code.visualstudio.com/) with [Azure Functions Extension installed](https://marketplace.visualstudio.com/items?itemName=ms-azuretools.vscode-azurefunctions)

### Go get your secrets first 🍕

1. Go [this page](https://docs.microsoft.com/en-us/azure/cognitive-services/immersive-reader/how-to-create-immersive-reader) and Execute a powershell script
2. Save the **output** as those are the secrets.

![](https://cdn-images-1.medium.com/max/1024/1*ITtPw8LcbJicztWFvmPbUw.gif)<figcaption><em>(Alt-text: Getting credentials for the project)</em></figcaption>

It actually executes a powershell script which deploys immersive reader cognitive service, sets up azure active directory for your app and returns essential secrets.

### Let’s Get Going 🍳

1. Our first step will be installing Azure function core tools in local system so that we can test it.  
To do that we need to instruct npm to install and enable it for us.

![](https://cdn-images-1.medium.com/max/1024/1*puxk4NUbm-ioGfw5SoTbKA.gif)<figcaption><em>(Alt-text: Just open terminal and install azure function core tools.)</em></figcaption>

```
npm install -g azure-functions-core-tools@3
```

2. Initialise a function App. This will be a folder where azure functions will be created and stored.

![](https://cdn-images-1.medium.com/max/1024/1*Q4F93Z7-0uT6vgNL9iPblw.gif)<figcaption>(<em>Alt-text: Just open terminal and install azure function core tools.)</em></figcaption>

_Execute_

```
func init APPNAME
```

and choose node and JavaScript worker. You’ll see a folder generated with your APPNAME and consists host.json file. We will call this location as root of the directory.

3. Let’s create a “HTTP Trigger” function now. This will be a serverless function endpoint which authenticates and passes us the token required to access immersive reader resource. “HTTP Trigger” here means the function to be triggered (Start execution) by HTTP requests.

![](https://cdn-images-1.medium.com/max/1024/1*qGqH6pQ6F5rj8TMs8xjwZA.gif)<figcaption>(<em>Alt-text: Create a “HTTP Trigger” Azure function for our App)</em></figcaption>

```
func new --name GetTokenAndSubdomain --template “HTTP trigger”
```

Meanwhile you will see a sub-folder generated after this execution with files index.js and function.json.

4. Install Dependencies to be used in our app.

![](https://cdn-images-1.medium.com/max/1024/1*DYj6oZMILahhl7Qqv4WWhw.png)<figcaption>(<em>Alt-text: Installed axios dependency using npm)</em></figcaption>

```
npm i -s axios dotenv
```

axios here is a js library that will help us with requesting the immersive service AD for token and dotenv will be used to load tokens and Secrets from .env file.

5. Create .env file to add secrets that can be accessed by our function. We have to load our secrets which we obtained earlier by the powershell script.

```
TENANT\_ID={YOUR\_TENANT\_ID} 
CLIENT\_ID={YOUR\_CLIENT\_ID} 
CLIENT\_SECRET={YOUR\_CLIENT\_SECRET} 
SUBDOMAIN={YOUR\_SUBDOMAIN}
```

6. Copy the code below and paste it into index.js of our created function in step 3.

![](https://cdn-images-1.medium.com/max/1024/1*gePn7rmk7aC733LB4_IuQw.gif)<figcaption>(<em>Alt-text: Paste the code below in Index.js of /GetTokenAndSubdomain function)</em></figcaption>

```
require('dotenv').config();
const axios = require('axios').default;

module.exports = async function(context, req) {
try {
const tokenResponse = await axios.post(
`https://login.windows.net/${process.env.TENANT_ID}/oauth2/token`,
new URLSearchParams({
grant\_type: 'client\_credentials',
client\_id: process.env.CLIENT\_ID,
client\_secret: process.env.CLIENT\_SECRET,
resource: 'https://cognitiveservices.azure.com/'
}).toString(),
{
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
}
);
var tokenResultParsed = tokenResponse.data;
context.res = {
status: 200,
body: { token: tokenResultParsed.access\_token, subdomain: process.env.SUBDOMAIN }
};
} catch (err) {
console.log(err);
context.res = {
status: 500,
error: 'Unable to acquire Azure AD token. Check the debugger for more information.'
};
}
};
```

This code is a simple Client Credentials OAuth2 handler for our function to grab token from Azure, It submits a post request to our Active Directory with our Client\_ID and Client\_Secret.

Line 1, Loads all the variables from .env file to actual processing environment. We are using them in our code with prefix process.env.

Line 6 starts the post request execution and it saves the data to tokenResponse . The token is extracted from the data JSON object using tokenResponse.data and stored into tokenResultParsed . context.res now returns the token to the frontend client or whoever hitting our endpoint.

You can go to root directory of the Function App and type

```
func host start
```

which will start a local development server on port 7071.

Try accessing [localhost:7071/api/GetTokenAndSubdomain](http://localhost:7071/api/GetTokenAndSubdomain)in your browser and you'll see a token render on page. If you do get a token, "Congrats! you've followed the blog correctly". If not, Please go back and check for some points that you might have missed.

7. Let’s Deploy our Function app with VSCode and azure function extension. Moreover we also need to copy the azure function url with authorization code in order to have it accessed by client.

![](https://cdn-images-1.medium.com/max/900/1*_WIAoZLi5qbabi7wu3Co_g.gif)<figcaption>(<em>Alt-text: Deploy Azure function from VSCode and copy the function url in Azure portal)</em></figcaption>

8 . Now it’s time to embed Immersive reader js sdk in your HTML . Developing whole frontend is again out of the scope for this blog, however I'll describe how to get your sample html up and running. Grab the sample HTML site from [here](https://github.com/heyAyushh/ImmersiveFunction/blob/master/web/index.html).

line no. 10. loads the immersive reader Javascript sdk

```
<script
    src="https://contentstorage.onenote.office.net/onenoteltir/immersivereadersdk/immersive-reader-sdk.1.0.0.js">
</script>
```

line 25 has a button with class immersive-reader-button Which on click handles function on line 75. handleLaunchImmersiveReader() Handles the authentication by executing the function getTokenAndSubdomainAsync() on line 55.

getTokenAndSubdomainAsync() sends a get request to our function with url on line 58. we need to paste URL obtained in step 7 here so that our client can access it. line 82 and 83 extracts token and subdomain which is passed in ImmersiveReader.launchAsync() .

line 87 has the extracts title from #ir-title class used in 26, Similarly content data which also needs to be passed in ImmersiveReader.launchAsync() is passed from #ir-content html class on line 27. Notice how the lang="en-us" is used to specify the language and dir="rtl"is used to specify rtl languages.

ImmersiveReader.launchAsync() Launches a iframe with beautiful immersive reader.  
You can deploy the sample anywhere you like, ex. GitHub pages (in a private repo) or [zeit.co](http://zeit.co/)  
learn how to deploy site in 15s with zeit [here](http://bit.ly/15secZEIT).

_Point 🎯: The GetTokenAndSubdomain 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 quickstart._

You can access the [JS SDK Refrence here](https://docs.microsoft.com/en-us/azure/cognitive-services/immersive-reader/reference).

9. Oops, we have a problem after deployment of frontend. Probably that’s a CORS issue.

![](https://cdn-images-1.medium.com/max/1024/1*SBlvNv5nSmtRGMNjVYJqPQ.jpeg)<figcaption>(<em>Alt-text:Cross Origin Resource sharing issue)</em></figcaption>

This is why the frontend can’t access our function because Azure has some security enabled by default. Cross Origin Resource Sharing is a technique that permits resource sharing between scripts running on a browser client and resources from a different origin.

Let’s disable CORS just for our frontend so that it can have access to our function.

![](https://cdn-images-1.medium.com/max/900/1*_WIAoZLi5qbabi7wu3Co_g.gif)<figcaption>(<em>Alt-text: Solving Cross Origin Resource sharing issue from Azure portal)</em></figcaption>

10 . Stay at Home

<iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fgiphy.com%2Fembed%2FKCvzHXd3nz2Oh3LkNn%2Ftwitter%2Fiframe&amp;display_name=Giphy&amp;url=https%3A%2F%2Fmedia.giphy.com%2Fmedia%2FKCvzHXd3nz2Oh3LkNn%2Fgiphy.gif&amp;image=https%3A%2F%2Fi.giphy.com%2Fmedia%2FKCvzHXd3nz2Oh3LkNn%2Fgiphy.gif&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=giphy" width="435" height="435" frameborder="0" scrolling="no"><a href="https://medium.com/media/b664fc6fad92dabe727aa7af8b6bccbe/href">https://medium.com/media/b664fc6fad92dabe727aa7af8b6bccbe/href</a></iframe>
### Thanks for reading
<iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fgiphy.com%2Fembed%2Fl2SpLcDp9iQDWRS8w%2Ftwitter%2Fiframe&amp;display_name=Giphy&amp;url=https%3A%2F%2Fmedia.giphy.com%2Fmedia%2Fl2SpLcDp9iQDWRS8w%2Fgiphy.gif&amp;image=https%3A%2F%2Fi.giphy.com%2Fmedia%2Fl2SpLcDp9iQDWRS8w%2Fgiphy.gif&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=giphy" width="435" height="305" frameborder="0" scrolling="no"><a href="https://medium.com/media/718ceaa86f20588648c8eb4f867151a7/href">https://medium.com/media/718ceaa86f20588648c8eb4f867151a7/href</a></iframe>

Let me know the feedback.  
Follow / Subscribe for more awesome azure content.

* * *