I am working on the example Bot Authentication MS GRAPH
I have desired output in the emulator channel as on the photo below:
When user joins the channel he is presented with welcome message and Login prompt. After authentication dialog is finished I want to return to the onMessageActivity
to carry on with my code. The teams channel seems not to respond to the onMembersAdded
at all.
protected override async Task OnMembersAddedAsync(IList<ChannelAccount> membersAdded, ITurnContext<IConversationUpdateActivity> turnContext, CancellationToken cancellationToken)
{
foreach (var member in turnContext.Activity.MembersAdded)
{
if (member.Id != turnContext.Activity.Recipient.Id)
{
// First message and action that will happen when user joins the channel
await turnContext.SendActivityAsync(MessageFactory.Text("Welcome to Chat Bot. Please login."), cancellationToken);
// Call OAuthDialog
//await Dialog.RunAsync(turnContext, ConversationState.CreateProperty<DialogState>(nameof(DialogState)), cancellationToken);
// await turnContext.SendActivityAsync(MessageFactory.Text($"Welcome to Audit Bot! I am happy to help!. Type 'Login' anytime to sign-in."), cancellationToken);
}
}
}
public override async Task OnTurnAsync(ITurnContext turnContext, CancellationToken cancellationToken = default(CancellationToken))
{
if (turnContext?.Activity?.Type == ActivityTypes.Invoke && turnContext.Activity.ChannelId == "msteams")
{
await turnContext.SendActivityAsync("You are using MS Teams.");
await Dialog.RunAsync(turnContext, ConversationState.CreateProperty<DialogState>(nameof(DialogState)), cancellationToken);
}
else
{
await base.OnTurnAsync(turnContext, cancellationToken);
// Save any state changes that might have occured during the turn.
await ConversationState.SaveChangesAsync(turnContext, false, cancellationToken);
await UserState.SaveChangesAsync(turnContext, false, cancellationToken);
}
}
protected override async Task OnTokenResponseEventAsync(ITurnContext<IEventActivity> turnContext, CancellationToken cancellationToken)
{
Logger.LogInformation("Running dialog with Token Response Event Activity.");
// Run the Dialog with the new Token Response Event Activity.
// Create Token globally and assigned here
token = turnContext.Activity.Value.ToString();
//var myJsonString = "{token: {Id: \"aaakkj98898983\"}}";
//var jo = JObject.Parse(token);
// cToken = jo["token"].ToString();
// await turnContext.SendActivityAsync(cToken);
await Dialog.RunAsync(turnContext, ConversationState.CreateProperty<DialogState>(nameof(DialogState)), cancellationToken);
}
protected override async Task OnMessageActivityAsync(ITurnContext<IMessageActivity> turnContext, CancellationToken cancellationToken)
{
// Call the MainDialog to display OAuth
await Dialog.RunAsync(turnContext, ConversationState.CreateProperty<DialogState>(nameof(DialogState)), cancellationToken);
// Proceed with rest of the code
Logger.LogInformation("Running dialog with Message Activity.");
// First, we use the dispatch model to determine which cognitive service(LUIS or QnA) to use.
var recognizerResult = await _botServices.Dispatch.RecognizeAsync(turnContext, cancellationToken);
// Top intent tells us which cognitive service to use. LUIS or QnA Maker
var topIntent = recognizerResult.GetTopScoringIntent();
// Next, we call the dispatcher with the top intent.
await DispatchToTopIntentAsync(turnContext, topIntent.intent, recognizerResult, cancellationToken);
}
Dialog Class ( I want to display my Graph call only once)
AddDialog(new OAuthPrompt(
nameof(OAuthPrompt),
new OAuthPromptSettings
{
ConnectionName = "my connection", // HARD CODED
Text = "Please login",
Title = "Login",
Timeout = 300000, // User has 5 minutes to login
}));
AddDialog(new TextPrompt(nameof(TextPrompt)));
// AddDialog(new ChoicePrompt(nameof(ChoicePrompt)));
AddDialog(new WaterfallDialog(nameof(WaterfallDialog), new WaterfallStep[]
{
PromptStepAsync,
LoginStepAsync
}));
// The initial child Dialog to run.
InitialDialogId = nameof(WaterfallDialog);
}
private async Task<DialogTurnResult> PromptStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
{
var tokenResponse = (TokenResponse)stepContext.Result;
//Send token to state
// stepContext.Context.TurnState.Add("tokenResponse", tokenResponse);
if (tokenResponse != null)
{
////
await OAuthHelpers.ListMeAsync(stepContext.Context, tokenResponse);
return await stepContext.EndDialogAsync();
}
else
{
return await stepContext.BeginDialogAsync(nameof(OAuthPrompt), null, cancellationToken);
}
}
private async Task<DialogTurnResult> LoginStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
{
// Get the token from the previous step. Note that we could also have gotten the
// token directly from the prompt itself. There is an example of this in the next method.
var tokenResponse = (TokenResponse)stepContext.Result;
if (tokenResponse != null)
{
await stepContext.Context.SendActivityAsync(MessageFactory.Text("You are now logged in."), cancellationToken);
// Display my name
await OAuthHelpers.ListMeAsync(stepContext.Context, tokenResponse);
// End and return to the bot onMessageActivity
return await stepContext.EndDialogAsync();
}
await stepContext.Context.SendActivityAsync(MessageFactory.Text("Login was not successful please try again."), cancellationToken);
return await stepContext.EndDialogAsync();
}