Skip to content

Commit

Permalink
Merge pull request #1312 from OfficeDev/v-mfurquan/UserScope-WebAppli…
Browse files Browse the repository at this point in the history
…cation

User Scope web App Nodejs
  • Loading branch information
Mohammed-MSFT authored Oct 20, 2024
2 parents 2f88ee5 + d7fba4f commit 9eb7332
Show file tree
Hide file tree
Showing 38 changed files with 1,957 additions and 1 deletion.
2 changes: 1 addition & 1 deletion .github/workflows/build-complete-samples.yml
Original file line number Diff line number Diff line change
Expand Up @@ -526,7 +526,7 @@ jobs:

- project_path: 'samples/app-sso/nodejs'
name: 'app-sso'
version: '14.x'
version: '18.x'

- project_path: 'samples/app-sso/nodejs/client'
name: 'app-sso-client'
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ The [Teams Toolkit](https://marketplace.visualstudio.com/items?itemName=TeamsDev
|1|Proactive Messaging | Sample to highlight solutions to two challenges with building proactive messaging apps in Microsoft Teams. |[View][bot-proactive-msg#cs] |
|2| Sharepoint List Bot| This sample app shows the interaction between teams bot and SharePoint List, Bot saves the specified details in SharePoint List as back-end| [View][bot-sharepoint-list#cs] | | |
|3|Teams Virtual Assistant| Customized virtual assistant template to support teams capabilities. |[View][app-virtual-assistant#cs]|
|3|User Scope Web App| This sample app demonstrates posting notifications for team/channel changes using Microsoft Graph API in Node.js||[View][user-scope-web-application#js]

## [Messaging Extensions samples](https://docs.microsoft.com/microsoftteams/platform/messaging-extensions/what-are-messaging-extensions) (using the v4 SDK)
>NOTE:
Expand Down Expand Up @@ -343,6 +344,7 @@ The [Teams Toolkit](https://marketplace.visualstudio.com/items?itemName=TeamsDev
[tab-sso#cs]:samples/tab-sso/csharp

[app-virtual-assistant#cs]:samples/app-virtual-assistant/csharp
[user-scope-web-application#js]:samples/user-scope-web-application/nodejs
[identity-linking-with-sso#cs]:samples/app-identity-linking-with-sso/csharp
[bot-proactive-msg#cs]:samples/bot-proactive-messaging/csharp
[bot-proactive-msg-teamsfx#js]:samples/bot-proactive-messaging-teamsfx
Expand Down
9 changes: 9 additions & 0 deletions samples/user-scope-web-application/nodejs/.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
MicrosoftAppId = "<<MicrosoftAppId>>"
MicrosoftAppPassword = "<<MicrosoftAppPassword>>"
MicrosoftAppTenantId = "<<MicrosoftAppTenantId>>"
AllowedHosts = "*"
notificationUrl= "/api/notifications"
BaseUrl= "<<BaseUrl>>"
Base64EncodedCertificate= "<<Base64EncodedCertificate>>"
EncryptionCertificateId= "userScopeNotifications"
PRIVATE_KEY_PATH="<<PRIVATE_KEY_PATH>>"
68 changes: 68 additions & 0 deletions samples/user-scope-web-application/nodejs/Assests/sample.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
[
{
"name": "officedev-microsoft-teams-samples-user-scope-change-notification-team-channel-group-chats",
"source": "officeDev",
"title": "User Scope Graph Web App Change Notification",
"shortDescription": "This sample app demonstrates posting notifications for team/channel changes using Microsoft Graph API in Node.js.",
"url": "https://github.com/OfficeDev/Microsoft-Teams-Samples/tree/main/samples/graph-change-notification-team-channel/nodejs",
"longDescription": [
"This sample application uses Microsoft Graph API to notify users of team or channel changes, such as creation, editing, or deletion. It supports Graph API, MSAL authentication, and user-scope notifications in a Node.js web app."
],
"creationDateTime": "2024-07-02",
"updateDateTime": "2024-10-10",
"products": [
"Teams"
],
"metadata": [
{
"key": "TEAMS-SAMPLE-SOURCE",
"value": "OfficeDev"
},
{
"key": "TEAMS-SERVER-LANGUAGE",
"value": "javascript"
},
{
"key": "TEAMS-SERVER-PLATFORM",
"value": "express"
},
{
"key": "TEAMS-FEATURES",
"value": "Web-Appliaction"
}
],
"thumbnails": [
{
"type": "image",
"order": 100,
"url": "https://raw.githubusercontent.com/OfficeDev/Microsoft-Teams-Samples/main/samples/user-scope-web-application/nodejs/Images/UserScopeWebApp.gif",
"alt": "User Scope Change Notification Web App Nodejs"
}
],
"authors": [
{
"gitHubAccount": "OfficeDev",
"pictureUrl": "https://avatars.githubusercontent.com/u/6789362?s=200&v=4",
"name": "OfficeDev"
}
],
"references": [
{
"name": "Teams developer documentation",
"url": "https://aka.ms/TeamsPlatformDocs"
},
{
"name": "Teams developer questions",
"url": "https://aka.ms/TeamsPlatformFeedback"
},
{
"name": "Teams development videos from Microsoft",
"url": "https://aka.ms/sample-ref-teams-vids-from-microsoft"
},
{
"name": "Teams development videos from the community",
"url": "https://aka.ms/community/videos/m365powerplatform"
}
]
}
]
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Create and self signed pem certificate

## Generate certificate using Azure key vault.

1. Open [Azure key vault](https://docs.microsoft.com/en-us/azure/key-vault/key-vault-whatis) and navigate to `Certificates` section.
2. Click on `Generate/Import` button to create a certificate.

![Generate certificate](GenerateCertificate.png)

3. Fill the required details. Make sure `Method of Certificate Creation` is **Generate** and content type is **PEM**.

![Fill details](CreateCertificateForm.png)

4. Click on *Current version of certificate*.

![Certificate Operation](CertificateOperations.png)

5. It will open a menu, click on `Download in PFX/PEM format`

![Download certificate](PFXFormat.png)

## Install certificate.
Once the download is completed open the downloaded certificate in notepad. The downloaded certificate must be in .pem format.

The certificate will contain bot the base64 string and private key

1. Copy the content between `-----BEGIN CERTIFICATE-----` and `-----END CERTIFICATE-----`. This will be the value of `Base64EncodedCertificate` in appsettings.json file.

2. Copy the content from `-----BEGIN PRIVATE KEY-----` and `-----END PRIVATE KEY-----`. (Including the `BEGIN` and `END` strings). Inside helper folder of this project create a new .pem file and paste the copied key. The key must contain `-----BEGIN PRIVATE KEY-----` and `-----END PRIVATE KEY-----` strings.

3. The name of the file which stores the priavate key is the value of `PRIVATE_KEY_PATH`. The file must be present inside helper folder of this project.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
153 changes: 153 additions & 0 deletions samples/user-scope-web-application/nodejs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
---
page_type: sample
description: This sample app demonstrates posting notifications for team/channel changes using Microsoft Graph API in Node.js
products:
- office-teams
- office
- office-365
languages:
- Nodejs
extensions:
contentType: samples
createdDate: "02-07-2024 11:30:15 AM"
urlFragment: officedev-microsoft-teams-samples-userscope-change-notification-web-app-nodejs

---

# User Scope Change Notifications Using Microsoft Graph API In Node.js

This sample application uses Microsoft Graph API to notify users of team or channel changes, such as creation, editing, or deletion. It supports Graph API, MSAL authentication, and user-scope notifications in a Node.js web app.

## Included Features
* Graph API
* Web Application
* MSAL Authentication
* User-Scope Graph Notifications

## Interaction with Tab
![User-Scope](Images/UserScopeWebApp.gif)

## Prerequisites

- Microsoft Teams is installed and you have an account (not a guest account)
- [NodeJS](https://nodejs.org/en/)
- [dev tunnel](https://learn.microsoft.com/en-us/azure/developer/dev-tunnels/get-started?tabs=windows) or [ngrok](https://ngrok.com/download) latest version or equivalent tunneling solution
- [M365 developer account](https://docs.microsoft.com/en-us/microsoftteams/platform/concepts/build-and-test/prepare-your-o365-tenant) or access to a Teams account with the appropriate permissions to install an app.

**Note:** Please create and install self-signed certificate before running this sample using toolkit or manually.

## Setup

> Note these instructions are for running the sample on your local machine.
1) Run ngrok - point to port 3978

```bash
ngrok http 3978 --host-header="localhost:3978"
```

Alternatively, you can also use the `dev tunnels`. Please follow [Create and host a dev tunnel](https://learn.microsoft.com/en-us/azure/developer/dev-tunnels/get-started?tabs=windows) and host the tunnel with anonymous user access command as shown below:

```bash
devtunnel host -p 3978 --allow-anonymous
```

2) App Registration

### Register your application with Azure AD

1. Register a new application in the [Microsoft Entra ID - App Registrations](https://go.microsoft.com/fwlink/?linkid=2083908) portal.
2. On the overview page, copy and save the **Application (client) ID, Directory (tenant) ID**. You'll need those later when updating your Teams application manifest and in the .env file.
3. Navigate to **API Permissions**, and make sure to add the follow permissions:
- Select Add a permission
- Select Microsoft Graph -> Application permissions.
- `Chat.ReadBasic`, `Chat.Read`, `Chat.ReadWrite`
- Click on Add permissions. Please make sure to grant the admin consent for the required permissions.
4. Navigate to the **Certificates & secrets**. In the Client secrets section, click on "+ New client secret". Add a description (Name of the secret) for the secret and select "Never" for Expires. Click "Add". Once the client secret is created, copy its value, it need to be placed in the appsettings.json file.
4. Navigate to the **Authentication** . Update Authentication Section by Adding **Single-page application** Redirect URI with your baseurl/ngrok.
[Single Page Application](images/SinglePageApplication.png)
### Create and install Self-Signed certificate
To include resource data of graph notifications, this Graph API require self-signed certificate. Follow the below steps to create and manage certificate.
1. You can self-sign the certificate, since Microsoft Graph does not verify the certificate issuer, and uses the public key for only encryption.
2. Use [Azure Key Vault](https://docs.microsoft.com/en-us/azure/key-vault/key-vault-whatis) as the solution to create, rotate, and securely manage certificates. Make sure the keys satisfy the following criteria:
- The key must be of type `RSA`
- The key size must be between 2048 and 4096 bits
3. Follow this documentation for the steps - [**Create and install Self-Signed certificate**](CertificateDocumentation/README.md)
4. Clone the repository
```bash
git clone https://github.com/OfficeDev/Microsoft-Teams-Samples.git
```
A) If you are using Visual Studio Code
- Launch Visual Studio code
- File -> Open Folder
- Navigate to `samples/user-scope-web-application` folder.
- Select `nodejs` folder.
**Instruction for .env**
1. Provide Update configuration with the ```MicrosoftAppId```, ```MicrosoftAppPassword```, ```MicrosoftAppTenantId```,
```Base64EncodedCertificate```, ```EncryptionCertificateId```, ```PRIVATE_KEY_PATH``` in the .env that is created in Azure.
2. Provide the tunnel url as "BaseUrl" in appsetting on which application is running on.
3. You should be having Base64EncodedCertificate from *Create and install Self-Signed certificate* step.
4. Use Certificate "PEM" format and add the certificate name for `PRIVATE_KEY_PATH` For eg `PRIVATE_KEY_PATH`=PrivateKeyFileName.pem" in .env file. Also make sure the private key file is stored inside helper folder of this project.
**Note** : ```notificationUrl``` will be updated automatically from `teamsapp.local.yml` file when you run application by teams toolkit. And when you run locally through `npm start` then your notificationUrl will be like : `https://1234.ngrok-free.app/api/notifications` and if you are using dev tunnels, your notificationUrl will be like: `https://12345.devtunnels.ms/api/notifications`.
**Update For MicrosoftftAppId In sample code**
1. Navigate to `samples/user-scope-web-application/client/src/components/login.jsx` file and update `<<Microsoft-App-Id>>` with your MicrosoftAppID at line number 20.
2. Navigate to `samples/user-scope-web-application/client/src/components/userScopeTestApp.jsx` file and update `<<Microsoft-App-Id>>` with your MicrosoftAppID at line number 31.
- Install node modules
Inside node js folder, open your local terminal and run the below command to install node modules. You can do the same for client folder by opening the project in Visual Studio code.
```bash
npm install
```
Run your app
```bash
npm start
```
## Running the sample
You can interact with user scope web application by logging with demo tenant.
## User Scope Graph API Notifications
1. **Installation To Group Chat**
![login](Images/1.Login.png)
1. **Select Account**
![Sample](Images/2.SelectAccountForLogin.png)
1. **Successfull login**
![Sample](Images/3.LoginSuccess.png)
1. **Group chat and messages**
![Sample](Images/4.GroupChatsAndMessages.png)
## Further reading
- [Change notifications for Microsoft Teams channel](https://docs.microsoft.com/en-us/graph/teams-changenotifications-team-and-channel)
- [Create subscription permissions for supported resource](https://docs.microsoft.com/en-us/graph/api/subscription-post-subscriptions?view=graph-rest-1.0&tabs=http#team-channel-and-chat)
- [Get change notifications for chats using Microsoft Graph](https://review.learn.microsoft.com/en-us/graph/teams-changenotifications-chat?branch=main&branchFallbackFrom=pr-en-us-24192)
<img src="https://pnptelemetry.azurewebsites.net/microsoft-teams-samples/samples/user-scope-web-application-nodejs" />
37 changes: 37 additions & 0 deletions samples/user-scope-web-application/nodejs/auth.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

var request = require('request');
var Q = require('q');

// The auth module object.
var auth = {};

// Gets the application level access token.
auth.getAccessToken = function () {
var deferred = Q.defer();
var requestParams = {
grant_type: 'client_credentials',
client_id: process.env.MicrosoftAppId,
client_secret: process.env.MicrosoftAppPassword,
scope: 'https://graph.microsoft.com/.default'
};

var url = "https://login.microsoftonline.com/" + process.env.MicrosoftAppTenantId + "/oauth2/v2.0/token";
request.post({ url: url, form: requestParams }, function (err, response, body) {
var parsedBody = JSON.parse(body);

if (err) {
deferred.reject(err);
} else if (parsedBody.error) {
deferred.reject(parsedBody.error_description);
} else {
// If successful, return the access token.
deferred.resolve(parsedBody.access_token);
}
});

return deferred.promise;
};

module.exports = auth;
14 changes: 14 additions & 0 deletions samples/user-scope-web-application/nodejs/build.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
const esbuild = require('esbuild');
esbuild.build({
entryPoints: ['server.js'],
bundle: true,
platform: 'node',
outfile: 'dist/index.js'
})
.then((r) => {
console.log(`Build succeeded.`);
})
.catch((e) => {
console.log("Error building:", e.message);
process.exit(1);
});
1 change: 1 addition & 0 deletions samples/user-scope-web-application/nodejs/client/.env
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
PORT=3978
23 changes: 23 additions & 0 deletions samples/user-scope-web-application/nodejs/client/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/.pnp
.pnp.js

# testing
/coverage

# production
/build

# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local

npm-debug.log*
yarn-debug.log*
yarn-error.log*
Loading

0 comments on commit 9eb7332

Please sign in to comment.