protected override Task <MessagingExtensionActionResponse> OnTeamsMessagingExtensionFetchTaskAsync(ITurnContext <IInvokeActivity> turnContext, MessagingExtensionAction action, CancellationToken cancellationToken) { switch (action.CommandId) { // These commandIds are defined in the Teams App Manifest. case TeamsCommands.TakeQuickNote: var quickNoteCard = NoteCardFactory.GetAdaptiveCard("NewNoteTemplate.json", new Note()); return(CreateActionResponse("Create quick note", quickNoteCard)); case TeamsCommands.NoteFromMessage: var converter = new Converter(); var newNote = new Note { Title = FixString(new string(HtmlUtilities.ConvertToPlainText(action.MessagePayload.Body.Content).Take(42).ToArray())), NoteBody = FixString(converter.Convert(action.MessagePayload.Body.Content)), }; var newNoteCard = NoteCardFactory.GetAdaptiveCard("NewNoteTemplate.json", newNote); return(CreateActionResponse("Create note from message", newNoteCard)); default: throw new NotImplementedException($"Invalid Fetch CommandId: {action.CommandId}"); } }
private async Task <bool> InterruptDialogAsync(DialogContext innerDc, CancellationToken cancellationToken) { var interrupted = false; var activity = innerDc.Context.Activity; var userProfile = await _userProfileState.GetAsync(innerDc.Context, () => new UserProfileState(), cancellationToken); var dialog = innerDc.ActiveDialog?.Id != null?innerDc.FindDialog(innerDc.ActiveDialog?.Id) : null; if (activity.Type == ActivityTypes.Message && !string.IsNullOrEmpty(activity.Text)) { // Check if the active dialog is a skill for conditional interruption. var isSkill = dialog is SkillDialog; // Get Dispatch LUIS result from turn state. var dispatchResult = innerDc.Context.TurnState.Get <DispatchLuis>(StateProperties.DispatchResult); (var dispatchIntent, var dispatchScore) = dispatchResult.TopIntent(); // Check if we need to switch skills. if (isSkill && IsSkillIntent(dispatchIntent) && dispatchIntent.ToString() != dialog.Id && dispatchScore > 0.9) { if (_skillsConfig.Skills.TryGetValue(dispatchIntent.ToString(), out var identifiedSkill)) { var prompt = _templateManager.GenerateActivityForLocale("SkillSwitchPrompt", new { Skill = identifiedSkill.Name }); await innerDc.BeginDialogAsync(_switchSkillDialog.Id, new SwitchSkillDialogOptions(prompt, identifiedSkill), cancellationToken); interrupted = true; } else { throw new ArgumentException($"{dispatchIntent.ToString()} is not in the skills configuration"); } } if (dispatchIntent == DispatchLuis.Intent.l_General) { // Get connected LUIS result from turn state. var generalResult = innerDc.Context.TurnState.Get <GeneralLuis>(StateProperties.GeneralResult); (var generalIntent, var generalScore) = generalResult.TopIntent(); if (generalScore > 0.5) { switch (generalIntent) { case GeneralLuis.Intent.Cancel: { await innerDc.Context.SendActivityAsync(_templateManager.GenerateActivityForLocale("CancelledMessage", userProfile), cancellationToken); await innerDc.CancelAllDialogsAsync(cancellationToken); await innerDc.BeginDialogAsync(InitialDialogId, cancellationToken : cancellationToken); interrupted = true; break; } case GeneralLuis.Intent.Escalate: { await innerDc.Context.SendActivityAsync(_templateManager.GenerateActivityForLocale("EscalateMessage", userProfile), cancellationToken); await innerDc.RepromptDialogAsync(cancellationToken); interrupted = true; break; } case GeneralLuis.Intent.Help: { if (!isSkill) { // If current dialog is a skill, allow it to handle its own help intent. await innerDc.Context.SendActivityAsync(_templateManager.GenerateActivityForLocale("HelpCard", userProfile), cancellationToken); await innerDc.RepromptDialogAsync(cancellationToken); interrupted = true; } break; } case GeneralLuis.Intent.Logout: { // Log user out of all accounts. await LogUserOutAsync(innerDc, cancellationToken); await innerDc.Context.SendActivityAsync(_templateManager.GenerateActivityForLocale("LogoutMessage", userProfile), cancellationToken); await innerDc.CancelAllDialogsAsync(cancellationToken); await innerDc.BeginDialogAsync(InitialDialogId, cancellationToken : cancellationToken); interrupted = true; break; } case GeneralLuis.Intent.Repeat: { // Sends the activities since the last user message again. var previousResponse = await _previousResponseAccessor.GetAsync(innerDc.Context, () => new List <Activity>(), cancellationToken); foreach (var response in previousResponse) { // Reset id of original activity so it can be processed by the channel. response.Id = string.Empty; await innerDc.Context.SendActivityAsync(response, cancellationToken); } interrupted = true; break; } case GeneralLuis.Intent.StartOver: { await innerDc.Context.SendActivityAsync(_templateManager.GenerateActivityForLocale("StartOverMessage", userProfile), cancellationToken); // Cancel all dialogs on the stack. await innerDc.CancelAllDialogsAsync(cancellationToken); await innerDc.BeginDialogAsync(InitialDialogId, cancellationToken : cancellationToken); interrupted = true; break; } case GeneralLuis.Intent.Stop: { // Use this intent to send an event to your device that can turn off the microphone in speech scenarios. break; } case GeneralLuis.Intent.ShowNotes: { var notesService = new MockNoteService(); var notes = await notesService.FindAsync("*"); var adaptiveCardAttachment = NoteCardFactory.CreateNoteListAttachment(notes); await innerDc.Context.SendActivityAsync(MessageFactory.Attachment(adaptiveCardAttachment), cancellationToken); await innerDc.RepromptDialogAsync(cancellationToken); interrupted = true; break; } } } } } return(interrupted); }
protected override async Task <MessagingExtensionResponse> OnTeamsMessagingExtensionSelectItemAsync(ITurnContext <IInvokeActivity> turnContext, JObject query, CancellationToken cancellationToken) { // The Preview card's Tap should have a Value property assigned, this will be returned to the bot in this event. var selectedNote = query.ToObject <Note>(); if (selectedNote == null) { throw new Exception("Unable to create a note from the selected item."); } var card = NoteCardFactory.GetAdaptiveCard("NoteTemplate.json", selectedNote); var fromMessage = (AdaptiveTextBlock)card.Body.Find(ae => ae.Id == "FromMessage"); fromMessage.Text = $"{turnContext.Activity.From.Name} shared a note with you."; if (string.IsNullOrWhiteSpace(selectedNote.MessageLinkUrl)) { // strip the action card.Actions.RemoveAt(0); } var imageElement = card.Body.FindAll(element => element.Id == "IconUrl").FirstOrDefault(); var attachment = new Attachment { Content = card, ContentType = AdaptiveCard.ContentType, }; var messageActivity = MessageFactory.Attachment(attachment).ApplyConversationReference(turnContext.Activity.GetConversationReference()); await turnContext.SendActivityAsync(messageActivity, cancellationToken); // TODO maybe do this? https://stackoverflow.com/questions/57116935/how-to-use-adaptive-cards-on-teams-messaging-extension return(new MessagingExtensionResponse()); // We take every row of the results and wrap them in cards wrapped in in MessagingExtensionAttachment objects. // The Preview is optional, if it includes a Tap, that will trigger the OnTeamsMessagingExtensionSelectItemAsync event back on this bot. //var card = new ThumbnailCard //{ // //Title = selectedNote.Title, // Images = new List<CardImage> { new CardImage(GetNoteIconUrl(selectedNote), "Icon") }, // //Subtitle = $"On {selectedNote.MessageActionsPayload.CreatedDateTime}, created by {selectedNote.MessageActionsPayload.From.Application.DisplayName}", // Text = selectedNote.NoteBody, // Buttons = string.IsNullOrWhiteSpace(selectedNote.MessageLinkUrl) // ? null // : new List<CardAction> // { // new CardAction // { // Type = ActionTypes.OpenUrl, // Title = "Go to conversation", // Value = selectedNote.MessageLinkUrl // }, // } //}; //var attachment = new MessagingExtensionAttachment //{ // ContentType = ThumbnailCard.ContentType, // Content = card, //}; //return new MessagingExtensionResponse //{ // ComposeExtension = new MessagingExtensionResult // { // Type = "result", // AttachmentLayout = "list", // Attachments = new List<MessagingExtensionAttachment> { attachment } // } //}; }