forked from OfficeDev/Microsoft-Teams-Samples
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Meeting Extensibility]: Content Bubble JavaScript/NodeJS (OfficeDev#39)
* Content Bubble Node JS Code * Review comments Resolved Co-authored-by: Wajeed-msft <[email protected]>
- Loading branch information
1 parent
090e032
commit f6f04ae
Showing
15 changed files
with
5,361 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
MicrosoftAppId= | ||
MicrosoftAppPassword= | ||
BaseUrl= |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
/* eslint-disable */ | ||
module.exports = { | ||
"extends": "standard", | ||
"rules": { | ||
"semi": [2, "always"], | ||
"indent": [2, 4], | ||
"no-return-await": 0, | ||
"space-before-function-paren": [2, { | ||
"named": "never", | ||
"anonymous": "never", | ||
"asyncArrow": "always" | ||
}], | ||
"template-curly-spacing": [2, "always"] | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
# ContentBubble JavaScript/NodeJS | ||
This sample illustrates how to implement [Content Bubble](https://docs.microsoft.com/en-us/microsoftteams/platform/apps-in-teams-meetings/create-apps-for-teams-meetings?view=msteams-client-js-latest&tabs=dotnet#notificationsignal-api) In-Meeting Experience. | ||
|
||
## Prerequisites | ||
|
||
- [Node.js](https://nodejs.org) version 10.14 or higher | ||
|
||
```bash | ||
# determine node version | ||
node --version | ||
``` | ||
|
||
## To try this sample | ||
|
||
- Clone the repository | ||
|
||
```bash | ||
git clone https://github.com/OfficeDev/Microsoft-Teams-Samples.git | ||
``` | ||
|
||
- In a terminal, navigate to `samples\meetings-content-bubble\nodejs` | ||
|
||
```bash | ||
cd samples/meetings-content-bubble/nodejs | ||
``` | ||
|
||
- Install modules | ||
|
||
```bash | ||
npm install | ||
``` | ||
|
||
- Start the bot | ||
|
||
```bash | ||
npm start | ||
``` | ||
|
||
1) Create a new Bot by following steps mentioned in [Build a bot](https://docs.microsoft.com/en-us/microsoftteams/platform/bots/what-are-bots?view=msteams-client-js-latest#build--a-bot-for-teams-with-the-microsoft-bot-framework) documentation. | ||
2) Go to appsettings.json and add `MicrosoftAppId`, `MicrosoftAppPassword` and `BaseUrl` information. | ||
3) Update the manifest.json file with MICROSOFT-APP-ID value. | ||
4) You need to set the `externalResourceUrl` in notification payload to load the content bubble page in-meeting pop up | ||
``` | ||
notification: { | ||
alertInMeeting: true, | ||
externalResourceUrl: 'https://teams.microsoft.com/l/bubble/<<APP_ID>>?url=<<ENDPOINT_URL>>&height=270&width=300&title=ContentBubbleinTeams&completionBotId=<<APP_ID>>' | ||
} | ||
``` | ||
6) [Install the App in Teams Meeting](https://docs.microsoft.com/en-us/microsoftteams/platform/apps-in-teams-meetings/teams-apps-in-meetings?view=msteams-client-js-latest#meeting-lifecycle-scenarios) | ||
## Interacting with the app in Teams Meeting | ||
Message the Bot by @ mentioning to interact with the content bubble. | ||
1. You will see agenda items listed in an Adaptive Card. | ||
2. Select any option and click on Push Agenda button | ||
3. You can submit your feedback on either Content Bubble/Adaptive card sent in chat. |
68 changes: 68 additions & 0 deletions
68
samples/meetings-content-bubble/nodejs/bots/contentBubbleBot.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
// Copyright (c) Microsoft Corporation. All rights reserved. | ||
// Licensed under the MIT License. | ||
|
||
const {TeamsActivityHandler, MessageFactory, CardFactory } = require('botbuilder'); | ||
const{contentBubbleTitles}=require('../models/contentbubbleTitle'); | ||
const AdaptiveCard = require('../resources/adaptiveCard.json'); | ||
const templateJson = require('../resources/QuestionTemplate.json'); | ||
var ACData = require("adaptivecards-templating"); | ||
|
||
class ContentBubbleBot extends TeamsActivityHandler { | ||
constructor() { | ||
super(); | ||
this.baseUrl = process.env.BaseUrl; | ||
this.AppId = process.env.MicrosoftAppId; | ||
|
||
this.onMessage(async (context, next) => { | ||
if(context.activity.value==null){ | ||
await context.sendActivity({ attachments: [this.createAdaptiveCard()] }); | ||
} | ||
else{ | ||
var json = JSON.stringify(context.activity.value); | ||
var out=JSON.parse(json); | ||
if(out.action=='inputselector'){ | ||
contentBubbleTitles.contentQuestion=out.myReview; | ||
await this.contentBubble(context); | ||
await context.sendActivity({ attachments: [this.createQuestionAdaptiveCard(out.myReview)] }); | ||
}else { | ||
await context.sendActivity(context.activity.from.name + " : " +"**"+out.myReview+"**"+" for " + "'" + out.action + "'"); | ||
} | ||
} | ||
await next(); | ||
}); | ||
}; | ||
|
||
async handleTeamsTaskModuleSubmit(context,taskModuleRequest) { | ||
var review = JSON.stringify(taskModuleRequest.data); | ||
var reply=JSON.parse(review); | ||
await context.sendActivity(context.activity.from.name + " : " +"**"+reply.myValue+"**"+" for " + "'" + reply.title + "'") | ||
} | ||
|
||
async contentBubble(context) | ||
{ | ||
const replyActivity = MessageFactory.text("**Please provide your valuable feedback**"); | ||
replyActivity.channelData = { | ||
notification: { | ||
alertInMeeting: true, | ||
externalResourceUrl: 'https://teams.microsoft.com/l/bubble/'+this.baseUrl+'?url='+this.AppId+'&height=270&width=300&title=ContentBubbleinTeams&completionBotId='+this.AppId | ||
} | ||
}; | ||
await context.sendActivity(replyActivity); | ||
} | ||
|
||
createAdaptiveCard(){ | ||
return CardFactory.adaptiveCard(AdaptiveCard); | ||
} | ||
|
||
createQuestionAdaptiveCard(myText){ | ||
var templatePayload = templateJson; | ||
var template = new ACData.Template(templatePayload); | ||
var cardPayload = template.expand({ | ||
$root: { | ||
name: myText | ||
} | ||
}); | ||
return CardFactory.adaptiveCard(cardPayload); | ||
} | ||
} | ||
module.exports.ContentBubbleBot = ContentBubbleBot; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
// Copyright (c) Microsoft Corporation. All rights reserved. | ||
// Licensed under the MIT License. | ||
|
||
// index.js is used to setup and configure your bot | ||
|
||
// Import required pckages | ||
const path = require('path'); | ||
// const {TaskmoduleIds} =require('./models/taskmoduleids'); | ||
|
||
// console.log(TaskmoduleIds); | ||
// Read botFilePath and botFileSecret from .env file. | ||
const ENV_FILE = path.join(__dirname, '.env'); | ||
require('dotenv').config({ path: ENV_FILE }); | ||
|
||
const restify = require('restify'); | ||
|
||
// Import required bot services. | ||
// See https://aka.ms/bot-services to learn more about the different parts of a bot. | ||
const { BotFrameworkAdapter } = require('botbuilder'); | ||
const { ContentBubbleBot } = require('./bots/contentBubbleBot'); | ||
|
||
// Create adapter. | ||
// See https://aka.ms/about-bot-adapter to learn more about adapters. | ||
const adapter = new BotFrameworkAdapter({ | ||
appId: process.env.MicrosoftAppId, | ||
appPassword: process.env.MicrosoftAppPassword | ||
}); | ||
|
||
adapter.onTurnError = async (context, error) => { | ||
// This check writes out errors to console log .vs. app insights. | ||
// NOTE: In production environment, you should consider logging this to Azure | ||
// application insights. See https://aka.ms/bottelemetry for telemetry | ||
// configuration instructions. | ||
console.error(`\n [onTurnError] unhandled error: ${ error }`); | ||
|
||
// Send a trace activity, which will be displayed in Bot Framework Emulator | ||
await context.sendTraceActivity( | ||
'OnTurnError Trace', | ||
`${ error }`, | ||
'https://www.botframework.com/schemas/error', | ||
'TurnError' | ||
); | ||
|
||
// Send a message to the user | ||
await context.sendActivity('The bot encountered an error or bug.'); | ||
await context.sendActivity('To continue to run this bot, please fix the bot source code.'); | ||
}; | ||
|
||
// Create the bot that will handle incoming messages. | ||
const bot = new ContentBubbleBot(); | ||
|
||
// Create HTTP server. | ||
var server = restify.createServer(); | ||
server= require("express")(); | ||
server.listen(process.env.port || process.env.PORT || 3978, function () { | ||
console.log(`\n${ server.name } listening to ${ server.url }`); | ||
console.log('\nGet Bot Framework Emulator: https://aka.ms/botframework-emulator'); | ||
console.log('\nTo talk to your bot, open the emulator select "Open Bot"'); | ||
}); | ||
|
||
// Listen for incoming requests. | ||
server.post('/api/messages', (req, res) =>{ | ||
adapter.processActivity(req, res, async (context) =>{ | ||
await bot.run(context); | ||
}); | ||
}); | ||
|
||
const{contentBubbleTitles}=require('./models/contentbubbleTitle') | ||
var bodyParser = require("body-parser"); | ||
server.set("view engine", "ejs"); | ||
server.set("views", __dirname + "/views"); | ||
server.engine('html',require('ejs').renderFile); | ||
server.use(bodyParser.urlencoded({ extended:false})); | ||
server.get('/', (req,res)=>{res.render('index.html',{question: contentBubbleTitles.contentQuestion})}); | ||
|
7 changes: 7 additions & 0 deletions
7
samples/meetings-content-bubble/nodejs/models/contentbubbleTitle.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
// Copyright (c) Microsoft Corporation. All rights reserved. | ||
// Licensed under the MIT License. | ||
|
||
var contentBubbleTitles ={ | ||
contentQuestion:"" | ||
} | ||
module.exports.contentBubbleTitles = contentBubbleTitles; |
Oops, something went wrong.