forked from howdyai/botkit
-
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.
Fix for howdyai#1961: add teams helper features
- Loading branch information
Showing
6 changed files
with
239 additions
and
16 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
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,97 @@ | ||
/** | ||
* @module botkit | ||
*/ | ||
/** | ||
* Copyright (c) Microsoft Corporation. All rights reserved. | ||
* Licensed under the MIT License. | ||
*/ | ||
import { Botkit, BotkitMessage } from './core'; | ||
import { BotWorker } from './botworker'; | ||
import { TeamsInfo, MiddlewareSet, TurnContext, TaskModuleTaskInfo } from 'botbuilder'; | ||
|
||
/** | ||
* An extension of the core BotWorker class that exposes the TeamsInfo helper class for MS Teams. | ||
* This BotWorker is used with the built-in Bot Framework adapter. | ||
*/ | ||
export class TeamsBotWorker extends BotWorker { | ||
|
||
public constructor(controller: Botkit, config) { | ||
super(controller, config); | ||
} | ||
|
||
/** | ||
* Grants access to the TeamsInfo helper class | ||
* See: https://docs.microsoft.com/en-us/javascript/api/botbuilder/teamsinfo?view=botbuilder-ts-latest | ||
*/ | ||
public teams: TeamsInfo = TeamsInfo; | ||
|
||
/** | ||
* Reply to a Teams task module task/fetch or task/submit with a task module response. | ||
* See https://docs.microsoft.com/en-us/microsoftteams/platform/task-modules-and-cards/task-modules/task-modules-bots | ||
* @param message | ||
* @param taskInfo { type: 'continue|message', value: {} } | ||
*/ | ||
public async replyWithTaskInfo(message: BotkitMessage, taskInfo: any) { | ||
if (!taskInfo || taskInfo == {}) { | ||
// send a null response back | ||
taskInfo = { | ||
type: 'message', | ||
value: '', | ||
} | ||
} | ||
return new Promise((resolve, reject) => { | ||
this.controller.middleware.send.run(this, taskInfo, async (err, bot, taskInfo) => { | ||
if (err) { | ||
return reject(err); | ||
} | ||
resolve(await this.getConfig('context').sendActivity({ | ||
type: 'invokeResponse', | ||
value: { | ||
status: 200, | ||
body: { | ||
task: taskInfo | ||
} | ||
} | ||
})); | ||
}); | ||
}); | ||
} | ||
} | ||
|
||
/** | ||
* When used, causes Botkit to emit special events for teams "invokes" | ||
* Based on https://github.com/microsoft/botbuilder-js/blob/master/libraries/botbuilder/src/teamsActivityHandler.ts | ||
* This allows Botkit bots to respond directly to task/fetch or task/submit events, as an example. | ||
*/ | ||
export class TeamsInvokeMiddleware extends MiddlewareSet { | ||
/** | ||
* Not for direct use - implements the MiddlewareSet's required onTurn function used to process the event | ||
* @param context | ||
* @param next | ||
*/ | ||
public async onTurn(context: TurnContext, next: () => Promise<any>): Promise<void> { | ||
if (context.activity.type === 'invoke') { | ||
if (!context.activity.name && context.activity.channelId === 'msteams') { | ||
context.activity.channelData.botkitEventType = 'cardAction'; | ||
} else { | ||
switch (context.activity.name) { | ||
case 'fileConsent/invoke': | ||
case 'actionableMessage/executeAction': | ||
case 'composeExtension/queryLink': | ||
case 'composeExtension/query': | ||
case 'composeExtension/selectItem': | ||
case 'composeExtension/submitAction': | ||
case 'composeExtension/fetchTask': | ||
case 'composeExtension/querySettingUrl': | ||
case 'composeExtension/setting': | ||
case 'composeExtension/onCardButtonClicked': | ||
case 'task/fetch': | ||
case 'task/submit': | ||
context.activity.channelData.botkitEventType = context.activity.name; | ||
break; | ||
} | ||
} | ||
} | ||
await next(); | ||
} | ||
} |
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
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,135 @@ | ||
const request = require('request'); | ||
|
||
module.exports = function(controller) { | ||
|
||
if (!controller.adapter.name) { | ||
|
||
const adaptiveCard = { | ||
"type": "AdaptiveCard", | ||
"body": [ | ||
{ | ||
"type": "TextBlock", | ||
"text": "Here is a ninja cat:" | ||
}, | ||
{ | ||
"type": "Image", | ||
"url": "http://adaptivecards.io/content/cats/1.png", | ||
"size": "Medium" | ||
}, | ||
{ | ||
"type": "ActionSet", | ||
"actions": [ | ||
{ | ||
"type": "Action.Submit", | ||
"title": "Message Submit", | ||
"id": "begin", | ||
"data": { | ||
"command": "message" | ||
} | ||
}, | ||
{ | ||
"type": "Action.Submit", | ||
"title": "Card Submit", | ||
"id": "begin", | ||
"data": { | ||
"command": "card" | ||
} | ||
}, | ||
{ | ||
"type": "Action.Submit", | ||
"title": "Close", | ||
"id": "begin", | ||
"data": { | ||
"command": "close" | ||
} | ||
}, | ||
], | ||
"horizontalAlignment": "Center" | ||
} | ||
], | ||
"version": "1.0" | ||
} | ||
|
||
controller.hears('getTeamDetails', 'message', async(bot, message) => { | ||
try { | ||
await bot.reply(message, JSON.stringify(await bot.teams.getTeamDetails(bot.getConfig('context')))); | ||
} catch(err) { | ||
await bot.reply(message, err.message); | ||
} | ||
}); | ||
|
||
|
||
controller.hears('getMember', 'message', async(bot, message) => { | ||
try { | ||
await bot.reply(message, JSON.stringify(await bot.teams.getMember(bot.getConfig('context'), message.user))); | ||
} catch(err) { | ||
await bot.reply(message, err.message); | ||
} | ||
}); | ||
|
||
controller.hears('taskModule', 'message', async(bot, message) => { | ||
await bot.reply(message,{ | ||
attachments: [{ | ||
"contentType": "application/vnd.microsoft.card.hero", | ||
"content": { | ||
"buttons": [ | ||
{ | ||
"type": "invoke", | ||
"title": "Task Module", | ||
"value": {type: 'task/fetch'} | ||
} | ||
], | ||
"text": "Launch a task module by clicking the button.", | ||
"title": "INVOKE A TASK MODULE!" | ||
} | ||
}] | ||
}); | ||
}); | ||
|
||
controller.on('task/fetch', async(bot, message) => { | ||
await bot.replyWithTaskInfo(message,{ | ||
"type": "continue", | ||
"value": { | ||
"title": "Task module title", | ||
"height": 500, | ||
"width": "medium", | ||
card: { | ||
contentType: 'application/vnd.microsoft.card.adaptive', | ||
content: adaptiveCard, | ||
} | ||
} | ||
}) | ||
}); | ||
|
||
|
||
controller.on('task/submit', async(bot, message) => { | ||
|
||
if (message.value.data.command == 'message') { | ||
// reply with a message | ||
await bot.replyWithTaskInfo(message, { | ||
type: 'message', | ||
value: 'Submitted!', | ||
}); | ||
} else if (message.value.data.command == 'card') { | ||
// reply with another card | ||
await bot.replyWithTaskInfo(message, { | ||
"type": "continue", | ||
"value": { | ||
"title": "Task module title", | ||
"height": 500, | ||
"width": "medium", | ||
card: { | ||
contentType: 'application/vnd.microsoft.card.adaptive', | ||
content: adaptiveCard, | ||
} | ||
} | ||
}); | ||
} else { | ||
// just close the task module | ||
await bot.replyWithTaskInfo(message, null); | ||
} | ||
|
||
}); | ||
|
||
} | ||
} |