Open arundhathiMenon opened 1 week ago
As long as you configured the Entra app registration as multi-tenant, it should work. Please share the error message if you meet any issues.
index.ts File:
import * as restify from "restify"; require('dotenv').config(); import { CloudAdapter, ConfigurationServiceClientCredentialFactory, ConfigurationBotFrameworkAuthentication, TurnContext, MemoryStorage, ConversationState, UserState, } from "botbuilder"; import { TeamsBot } from "./teamsBot"; import config from "./config";
const credentialsFactory = new ConfigurationServiceClientCredentialFactory({ MicrosoftAppId: config.botId, MicrosoftAppPassword: config.botPassword, MicrosoftAppType: "MultiTenant", });
const botFrameworkAuthentication = new ConfigurationBotFrameworkAuthentication( {}, credentialsFactory );
const adapter = new CloudAdapter(botFrameworkAuthentication);
const onTurnErrorHandler = async (context: TurnContext, error: Error) => {
console.error(\n [onTurnError] unhandled error: ${error}
);
if (context.activity.type === "message") {
await context.sendTraceActivity(
"OnTurnError Trace",
${error}
,
"https://www.botframework.com/schemas/error",
"TurnError"
);
await context.sendActivity(The bot encountered unhandled error:\n ${error.message}
);
await context.sendActivity("To continue to run this bot, please fix the bot source code.");
}
};
adapter.onTurnError = onTurnErrorHandler;
const memoryStorage = new MemoryStorage();
const conversationState = new ConversationState(memoryStorage); const userState = new UserState(memoryStorage);
const bot = new TeamsBot(conversationState, userState);
const server = restify.createServer();
server.use(restify.plugins.bodyParser());
server.listen(process.env.port || process.env.PORT || 3978, () => {
console.log(\nBot Started, ${server.name} listening to ${server.url}
);
});
server.post("/api/messages", async (req, res) => { await adapter.process(req, res, async (context) => { await bot.run(context); }); });
..................................... teamsBot.ts File
import { TeamsActivityHandler, CardFactory, MessageFactory, UserTokenClient, ConversationState, UserState, TurnContext, } from "botbuilder"; import OnedriveLinkInputAdaptiveCard from "./adaptiveCards/cd_one_drive_input.json"; import HelpAdaptiveCard from "./adaptiveCards/cd_help_user.json"; import GreetAdaptiveCard from "./adaptiveCards/cd_greet_user.json"; import { DialogSet, DialogTurnStatus, OAuthPrompt, WaterfallDialog, WaterfallStepContext, } from "botbuilder-dialogs"; import { CloudAdapter } from "botbuilder"; const OAUTH_PROMPT_ID = "oauthPrompt"; const MAIN_DIALOG = "mainDialog"; import config from "./config";
export class TeamsBot extends TeamsActivityHandler { private oneDriveLink: string | null; private pdfContents: string[];
private conversationState: ConversationState; private dialogState: any; private dialogs: DialogSet;
constructor(conversationState: ConversationState, userState: UserState) { super(); this.oneDriveLink = null; this.pdfContents = [];
this.conversationState = conversationState;
this.dialogState = this.conversationState.createProperty("dialogState");
this.dialogs = new DialogSet(this.dialogState);
this.dialogs.add(
new OAuthPrompt(OAUTH_PROMPT_ID, {
connectionName: config.ConnectionName, // Replace with your connection name
text: "Please sign in to continue.",
title: "Sign in",
timeout: 300000,
})
);
this.dialogs.add(
new WaterfallDialog(MAIN_DIALOG, [
this.promptForLoginStep.bind(this),
this.processLoginResultStep.bind(this),
])
);
this.onMessage(async (context, next) => {
console.log("Messages from teams channel: ", context.activity);
const dialogContext = await this.dialogs.createContext(context);
const results = await dialogContext.continueDialog();
if (results.status === DialogTurnStatus.empty) {
await dialogContext.beginDialog(MAIN_DIALOG);
}
await this.conversationState.saveChanges(context, false);
await next();
});
this.onMembersAdded(async (context, next) => {
const welcomeText =
"Hello and welcome by tune's intelligent AI assistant";
await context.sendActivity(MessageFactory.text(welcomeText));
await next();
});
}
private async promptForLoginStep(step: WaterfallStepContext) { const userTokenClient: UserTokenClient = step.context.turnState.get( step.context.adapter.UserTokenClientKey ) as UserTokenClient;
const tokenResponse = await userTokenClient.getUserToken(
step.context,
config.ConnectionName,
null
);
console.log("tokenResponse..", tokenResponse);
if (!tokenResponse) {
return await step.prompt(OAUTH_PROMPT_ID, {});
} else {
return await step.next(tokenResponse);
}
}
private async processLoginResultStep(step: WaterfallStepContext) { const tokenResponse = step.result;
if (tokenResponse && tokenResponse.token) {
const accessToken = tokenResponse.token;
console.log("accessToken..", accessToken);
await step.context.sendActivity("Login successful!");
} else {
await step.context.sendActivity("Login failed. Please try again.");
}
return await step.endDialog();
}
} ............................................ I am currently testing a Teams bot application using the BOTID and BOTPASSWORD provided by the bot service. I have configured the Azure setup according to the documentation.
I’m facing an issue with the package I am using. It keeps returning errors indicating that certain functionality is not present in the package. I believe the botbuilder package might have been updated, and I am looking for the correct package that supports Single Sign-On (SSO) and allows retrieval of an access token with user context.
Could you please provide guidance on the latest package version I should use to enable SSO and obtain an access token with the user's context in a Teams bot application?
You could refer this sample for implementation details: https://github.com/OfficeDev/Microsoft-Teams-Samples/tree/main/samples/bot-conversation-sso-quickstart/js
i am refering to https://github.com/OfficeDev/Microsoft-Teams-Samples/blob/main/samples/bot-sso-adaptivecard/nodejs/bots/botSSOAdaptiveCard.js, here i am getting error : [onTurnError] unhandled error: TypeError: context.adapter.getSignInLink is not a function
Don't we have getSignInLink method on the adapter object in the current version?
@arundhathiMenon To get better support, could you please create an issue in the Microsoft-Teams-Samples repo asking them to update the sample code? You could also create an issue in the botbuilder package's repo for help: https://github.com/microsoft/botbuilder-js.
can you please guide me on this,
I have two accounts: arundhathi@one.ai and arundhathi@two.ai. On Azure, I have a subscription under the one.ai tenant, where I’ve registered both an app and a bot. However, I have a SharePoint license and a Microsoft Teams account associated with the arundhathi@two.ai account.
Currently, I’m implementing SSO (Single Sign-On) to authorize users when they log in to Microsoft Teams, but I am using the app registration credentials (client ID, secret, etc.) from the arundhathi@one.ai tenant.
Will this setup work, or is there a requirement to have a subscription under the two.ai tenant as well for proper SSO functionality? Would having the app and bot registered under two.ai be necessary for this scenario?