private async Task AskAboutFeaturePhonesAsync(IDialogContext context) { Activity activity = (Activity)context.Activity; var reply = activity.CreateReply("Are you looking for a classic phone or a smart phone?"); SuggestedActions buttons; // turn on flag askingAboutFeaturePhones = true; buttons = new SuggestedActions() { Actions = new List <CardAction>() { new CardAction() { Title = "Classic Phone", Type = ActionTypes.ImBack, Value = "I'm looking for a classic phone" }, new CardAction() { Title = "SmartPhone", Type = ActionTypes.ImBack, Value = "I'm looking for a smart phone" }, new CardAction() { Title = "It doesn't really matter to me", Type = ActionTypes.ImBack, Value = "It doesn't matter" } } }; reply.SuggestedActions = buttons; await Miscellany.InsertDelayAsync(context); await context.PostAsync(reply); }
public static SuggestedActions GetSuggestedActionsForGenres(List <Segment> segments) { List <CardAction> actions = new List <CardAction>() { new CardAction() { Title = "None", Type = ActionTypes.ImBack, Value = "None" } }; foreach (var segment in segments) { actions.Add(new CardAction() { Title = segment.Name, Type = ActionTypes.ImBack, Value = segment.Name }); } SuggestedActions suggestedActions = new SuggestedActions() { Actions = actions }; return(suggestedActions); }
/// <summary> /// Text message is created and added to the message collection. /// </summary> /// <param name="text">new message text.</param> /// <param name="suggestedActions">suggestion value for message</param> private void AddTextMessage(string text, SuggestedActions suggestedActions = null) { TextMessage message = new TextMessage(); message.Text = text; message.Author = this.ViewModel.Bot; if (suggestedActions != null) { ChatSuggestions suggestions = new ChatSuggestions(); var suggestionItems = new ObservableCollection <ISuggestion>(); foreach (CardAction action in suggestedActions.Actions) { var suggestion = new Suggestion(); suggestion.Text = action.Title; if (!string.IsNullOrEmpty(action.Image)) { suggestion.Image = action.Image; } suggestionItems.Add(suggestion); } suggestions.Items = suggestionItems; message.Suggestions = suggestions; } ViewModel.Messages.Add(message); }
private async Task AskToConfirmAsync(IDialogContext context, string msg) { Activity activity = (Activity)context.Activity; var reply = activity.CreateReply(msg); SuggestedActions buttons = new SuggestedActions() { Actions = new List <CardAction>() { new CardAction() { Title = "Yes", Type = ActionTypes.ImBack, Value = "Yes" }, new CardAction() { Title = "No", Type = ActionTypes.ImBack, Value = "No" } } }; reply.SuggestedActions = buttons; await context.PostAsync(reply); context.Wait(ConfirmationReceivedAsync); }
public void SuggestedActionsInitsWithNoArgs() { var suggestedAction = new SuggestedActions(); Assert.NotNull(suggestedAction); Assert.IsType <SuggestedActions>(suggestedAction); }
private async Task SendReply(ITurnContext turnContext, string message, SuggestedActions suggestedActions = null) { var reply = turnContext.Activity.CreateReply(message); reply.Type = ActivityTypes.Message; reply.TextFormat = TextFormatTypes.Plain; reply.SuggestedActions = suggestedActions; await turnContext.SendActivityAsync(reply); }
public void SuggestedActionsInitsWithIEnumerables() { var to = new SuggestedActionEnumerableTo(); var actions = new SuggestedActionEnumerableActions(); var suggestedActions = new SuggestedActions(to, actions); Assert.NotNull(suggestedActions); Assert.IsType <SuggestedActions>(suggestedActions); }
/// <summary> /// Append actions for the suggestion item. /// </summary> /// <param name="action"></param> /// <param name="cardActions"></param> /// <returns></returns> public static SuggestedActions AppendActions(this SuggestedActions action, List <CardAction> cardActions) { if (action.Actions == null) { action.Actions = new List <CardAction>(); } cardActions.ForEach(item => action.Actions.Add(item)); return(action); }
private static SuggestedActions GetSuggestions(JToken value) { var actions = NormalizedToList(value); var suggestedActions = new SuggestedActions() { Actions = GetCardActions(actions) }; return(suggestedActions); }
private async Task DoubleCheck(IDialogContext context, string mostLikelyIntent, string secondMostLikely) { string friendly1 = humanFriendlyIntent[mostLikelyIntent].Item1; string friendly2; string textForUser = string.Concat("I'm not sure I followed that\r\n", "I think you meant you ", friendly1); Activity reply, lastMessage = (Activity)context.Activity; Attachment imageAttachment = new Attachment() { ContentUrl = "http://madcalm.com/wp-content/uploads/2018/06/MADCALM-CONFUSED.png", ContentType = "image/png", Name = "Bender_Rodriguez.png" }; SuggestedActions suggestedActions = new SuggestedActions() { Actions = new List <CardAction>() { new CardAction() { Title = "Yes", Type = ActionTypes.ImBack, Value = "Yes" /*, Image = "https://emojipedia-us.s3.amazonaws.com/thumbs/120/emoji-one/104/thumbs-up-sign_1f44d.png"*/ }, new CardAction() { Title = "No", Type = ActionTypes.ImBack, Value = "No", /*Image = "https://emojipedia-us.s3.amazonaws.com/thumbs/120/apple/129/thumbs-down-sign_1f44e.png"*/ } } }; if (secondMostLikely != null) { friendly2 = humanFriendlyIntent[secondMostLikely].Item1; textForUser += string.Concat("\r\n but maybe you'd rather ", friendly2, "\r\n, could you please select the correct one?"); suggestedActions.Actions[0].Title += ",I " + friendly1; suggestedActions.Actions[1].Title += ",I " + friendly2; suggestedActions.Actions[0].Value = mostLikelyIntent; suggestedActions.Actions[1].Value = secondMostLikely; suggestedActions.Actions.Add(new CardAction() { Title = "Neither", Type = ActionTypes.ImBack, Value = "Neither" }); } else { textForUser += ", is that right?"; suggestedActions.Actions[0].Value = mostLikelyIntent; } reply = lastMessage.CreateReply(textForUser); reply.SuggestedActions = suggestedActions; reply.Attachments.Add(imageAttachment); reply.AttachmentLayout = "carousel"; await context.PostAsync(reply); context.Wait(CheckUserAnswerAsync); }
/// <summary> /// Get suggestion from Hint property. /// </summary> /// <param name="curLink"></param> /// <param name="appendCommonActions"></param> /// <returns></returns> public static SuggestedActions GetHintSuggestionActions(this NeuralLinkModel curLink, bool appendCommonActions = true) { var result = new SuggestedActions() { Actions = ParseActionsFromColonFormatString(curLink.NeuralExp.Hint) }; if (appendCommonActions) { result.AppendActions(ParseActionsFromColonFormatString(CommonActionOptions)); } return(result); }
private async Task <bool> EvaluateExpression(ITurnContext turnContext, RequestState requestState) { var res = false; var curLink = requestState.CurrentLink; if (curLink?.NeuralExp != null) { if (curLink.NeuralExp.SkipEvaluation) { await EvaluateExpressionInput(turnContext, requestState);//Default expression } else { foreach (var note in curLink.Notes) { await turnContext.SendActivityAsync(curLink.ApplyFormat(note)); } var title = curLink.NeuralExp.QuestionTitle; SuggestedActions suggestedActions = null; if (curLink.NeuralExp.Hint != null && curLink.NeuralExp.Hint.Contains(":")) { suggestedActions = curLink.GetHintSuggestionActions(); } if (curLink.NeuralExp is LinkExpression) { var card = new HeroCard { Text = title, Buttons = (curLink.NeuralExp as LinkExpression).ActionItems.Select(action => new CardAction(ActionTypes.PostBack, title: action.Title, value: action.Value)).ToList() }; var reply = MessageFactory.Attachment(card.ToAttachment()); reply.SuggestedActions = suggestedActions; await turnContext.SendActivityAsync(reply); } else { await SendReply(turnContext, curLink.ApplyFormat(title), suggestedActions); } requestState.CurrentState = ChatStateType.ExpInput; } res = true; } return(res); }
public static SuggestedActions GetSuggestedQnAActions(string[] result) { var k = new SuggestedActions() { Actions = new List <CardAction>() }; foreach (var r in result) { k.Actions.Add(new CardAction() { Title = r, Type = ActionTypes.PostBack, Value = $"{r}" }); } return(k); }
private SuggestedActions GetAccountSuggestions() { var suggestedActions = new SuggestedActions { Actions = new List <CardAction>() }; foreach (var account in _accounts) { suggestedActions.Actions.Add(new CardAction { Title = account.Name, Type = ActionTypes.ImBack, Value = account.Name }); } return(suggestedActions); }
private Action <IActivity> SuggestedActionsValidator(string expectedText, SuggestedActions expectedSuggestedActions) { return(activity => { Assert.IsInstanceOfType(activity, typeof(IMessageActivity)); var msg = (IMessageActivity)activity; Assert.AreEqual(expectedText, msg.Text); Assert.AreEqual(expectedSuggestedActions.Actions.Count, msg.SuggestedActions.Actions.Count); for (var i = 0; i < expectedSuggestedActions.Actions.Count; i++) { Assert.AreEqual(expectedSuggestedActions.Actions[i].Type, msg.SuggestedActions.Actions[i].Type); Assert.AreEqual(expectedSuggestedActions.Actions[i].Value, msg.SuggestedActions.Actions[i].Value); Assert.AreEqual(expectedSuggestedActions.Actions[i].Title, msg.SuggestedActions.Actions[i].Title); } }); }
public static SuggestedActions GetSuggestedQnAActions(QnAResult qnAResult) { var k = new SuggestedActions() { Actions = new List <CardAction>() }; foreach (var r in qnAResult.Answers) { k.Actions.Add(new CardAction() { Title = r.AnswerAnswer, Type = ActionTypes.PostBack, Value = $"{r.AnswerAnswer}" }); } return(k); }
private static SuggestedActions GetSuggestions(JToken value) { var suggestionActions = new SuggestedActions() { Actions = new List <CardAction>() }; var actions = NormalizedToList(value); foreach (var action in actions) { if (action is JValue jValue && jValue.Type == JTokenType.String) { var actionStr = jValue.ToObject <string>().Trim(); suggestionActions.Actions.Add(new CardAction(type: ActionTypes.MessageBack, title: actionStr, displayText: actionStr, text: actionStr)); }
private Action <IActivity> SuggestedActionsValidator(string expectedText, SuggestedActions expectedSuggestedActions) { return(activity => { Assert.IsAssignableFrom <IMessageActivity>(activity); var msg = (IMessageActivity)activity; Assert.Equal(expectedText, msg.Text); Assert.Equal(expectedSuggestedActions.Actions.Count, msg.SuggestedActions.Actions.Count); for (var i = 0; i < expectedSuggestedActions.Actions.Count; i++) { Assert.Equal(expectedSuggestedActions.Actions[i].Type, msg.SuggestedActions.Actions[i].Type); Assert.Equal(expectedSuggestedActions.Actions[i].Value, msg.SuggestedActions.Actions[i].Value); Assert.Equal(expectedSuggestedActions.Actions[i].Title, msg.SuggestedActions.Actions[i].Title); } }); }
public static SuggestedActions CreateSuggestedAction(List <string> values) { List <CardAction> actions = new List <CardAction>(); foreach (var value in values) { actions.Add(new CardAction() { Title = value, Type = ActionTypes.ImBack, Value = value }); } SuggestedActions suggestedAction = new SuggestedActions() { Actions = actions }; return(suggestedAction); }
public void SuggestedActionsInits() { var to = new List <string>() { "recipient1" }; var actions = new List <CardAction>() { new CardAction() }; var suggestedAction = new SuggestedActions(to, actions); Assert.NotNull(suggestedAction); Assert.IsType <SuggestedActions>(suggestedAction); Assert.Equal(to, suggestedAction.To); Assert.Equal(actions, suggestedAction.Actions); }
public static List <CardAction> ToMessageBackActions(this SuggestedActions suggestedActions) { var actionsList = new List <CardAction>(); foreach (var cardAction in suggestedActions.Actions) { switch (cardAction.Type) { case ActionTypes.ImBack: { var newCardAction = new CardAction() { Type = ActionTypes.MessageBack, Title = cardAction.Title, Text = cardAction.Value.ToString(), DisplayText = cardAction.Value.ToString(), Value = new JObject { { Constants.AddedBy, Constants.SuggestedActionsMiddleware }, { "type", ActionTypes.ImBack } } }; actionsList.Add(newCardAction); } break; case ActionTypes.MessageBack: { var newValue = new JObject { { "Value", cardAction.Value.ToString() }, { Constants.AddedBy, Constants.SuggestedActionsMiddleware }, { "type", ActionTypes.MessageBack } }; cardAction.Value = newValue; actionsList.Add(cardAction); } break; default: throw new InvalidOperationException($"{cardAction.Type} suggestion action is not supported"); } } return(actionsList); }
private void RenderSuggestedActionItems(IRenderContext context, SuggestedActions suggestedActions) { if (suggestedActionsContent == null) { return; } foreach (var suggestedAction in suggestedActions.Actions) { var template = Instantiate(context.Theme.Button); template.transform.SetParent(suggestedActionsContent.transform); var button = template.GetComponent <Button>(); context.RenderToTarget(button.gameObject, suggestedAction.Title); button.onClick.AddListener(() => { context.InvokeCardAction(suggestedAction); ClearSuggestedActions(); }); } }
/// <summary> /// Get children nodes suggestion based on ranking. /// </summary> /// <param name="curLink"></param> /// <param name="appendCommonActions"></param> /// <returns></returns> public static SuggestedActions GetChildSuggestionActions(this NeuralLinkModel curLink, bool appendCommonActions = true) { curLink.CildrenRank.Sort((x, y) => y.Value.CompareTo(x.Value)); var result = new SuggestedActions() { Actions = curLink.CildrenRank.Select(id => { var name = DbLinkCollection.GetFieldValue(id.Key, x => x.Name).Result; return(new CardAction { Title = name, Value = id.Key, Type = ActionTypes.PostBack }); }).ToList() }; if (appendCommonActions) { result.AppendActions(ParseActionsFromColonFormatString(CommonActionOptions)); } return(result); }
public override async Task StartAsync(IDialogContext context) { List <string> brandsWanted, modelsWanted; string flowType; Activity reply, lastMsg = (Activity)context.Activity; SuggestedActions suggestedActions = new SuggestedActions { Actions = new List <CardAction>() { new CardAction() { Title = "Yes, I know what I want", Type = ActionTypes.ImBack, Value = "Yes" }, new CardAction() { Title = "No, I haven't made up my mind", Type = ActionTypes.ImBack, Value = "No" } } }; try { if (IndicatedModelsAndOrBrands(out brandsWanted, out modelsWanted)) { await Miscellany.InsertDelayAsync(context); await context.PostAsync("Yes, I can help you with that."); await ProcessSelectedBrandsAndModels(context, brandsWanted, modelsWanted, false); } else { if (context.ConversationData.TryGetValue(BotConstants.FLOW_TYPE_KEY, out flowType)) { await Miscellany.InsertDelayAsync(context); if (flowType == BotConstants.BOTH_FLOW_TYPE) { await context.PostAsync("Sure. Let's start by choosing a new phone"); } else if (flowType == BotConstants.EQUIPMENT_FLOW_TYPE) { await context.PostAsync("Sure. I can help you to choose a new phone."); } else if (flowType == BotConstants.PLAN_FLOW_TYPE) { await context.PostAsync("Fantastic. Let's choose a new phone for you then."); } else { throw new Exception("Error...NodePhoneFlow::StartAsync() unknown flow key value : " + flowType); } } else { throw new Exception("Error...phone flow entered without flow key being assigned a value"); } reply = lastMsg.CreateReply("Have you decided already what you want or would you like some support in choosing what's the right phone for you?"); reply.SuggestedActions = suggestedActions; await Miscellany.InsertDelayAsync(context); await context.PostAsync(reply); context.Wait(MessageReceivedWithDecisionAsync); } } catch (Exception xception) { await context.PostAsync(xception.Message); } }
/// <summary> /// Every conversation turn for our Echo Bot will call this method. /// There are no dialogs used, since it's "single turn" processing, meaning a single /// request and response. /// </summary> /// <param name="turnContext">A <see cref="ITurnContext"/> containing all the data needed /// for processing this conversation turn. </param> /// <param name="cancellationToken">(Optional) A <see cref="CancellationToken"/> that can be used by other objects /// or threads to receive notice of cancellation.</param> /// <returns>A <see cref="Task"/> that represents the work queued to execute.</returns> /// <seealso cref="BotStateSet"/> /// <seealso cref="ConversationState"/> /// <seealso cref="IMiddleware"/> public async Task OnTurnAsync(ITurnContext turnContext, CancellationToken cancellationToken = default(CancellationToken)) { Reference = turnContext.Activity.GetConversationReference(); // Handle Message activity type, which is the main activity type for shown within a conversational interface // Message activities may contain text, speech, interactive cards, and binary or unknown attachments. // see https://aka.ms/about-bot-activity-message to learn more about the message and other activity types if (turnContext.Activity.Type == ActivityTypes.Message) { //This should be sent out from your backend responsbile for generating proactive message requests //Bellow you can find examples of supported content for proactive message by this sample if (turnContext.Activity.Text.ToLower().StartsWith("proactive")) { var card = new HeroCard { Text = "You can upload an image or select one of the following choices", Buttons = new List <CardAction>() { new CardAction(ActionTypes.ImBack, title: "1. Inline Attachment", value: "1"), new CardAction(ActionTypes.ImBack, title: "2. Internet Attachment", value: "2"), new CardAction(ActionTypes.ImBack, title: "3. Uploaded Attachment", value: "3"), } }; var sa = new SuggestedActions() { Actions = new List <CardAction>() { new CardAction() { Title = "Red", Type = ActionTypes.ImBack, Value = "Red" }, new CardAction() { Title = "Yellow", Type = ActionTypes.ImBack, Value = "Yellow" }, new CardAction() { Title = "Blue", Type = ActionTypes.ImBack, Value = "Blue" }, } }; var message = new ProactiveMessageRequestBody() { ConversationReference = await _accessors.ConversationReferenceState.GetAsync(turnContext), Message = "Hello", Attachments = new List <Attachment>() { card.ToAttachment(), card.ToAttachment() }, SuggestedActions = sa }; //SET this based on the adress of your proactive endpoint var localProactiveEndpoint = "http://localhost:3978/api/proactive"; await turnContext.SendActivityAsync("Proactive message incoming..."); // send the conversation reference and message to the bot's proactive endpoint var messageContent = JsonConvert.SerializeObject(message); //In production this would be implemented on the side of backend service, which initiates proactive messages using (var client = new HttpClient()) { var buffer = System.Text.Encoding.UTF8.GetBytes(messageContent); var byteContent = new ByteArrayContent(buffer); byteContent.Headers.ContentType = new MediaTypeHeaderValue("application/json"); var result = await client.PostAsync(localProactiveEndpoint, byteContent); } } else { // Get the conversation state from the turn context. var state = await _accessors.CounterState.GetAsync(turnContext, () => new CounterState()); // Bump the turn count for this conversation. state.TurnCount++; // Set the property using the accessor. await _accessors.CounterState.SetAsync(turnContext, state); // Save the new turn count into the conversation state. await _accessors.ConversationState.SaveChangesAsync(turnContext); // Echo back to the user whatever they typed. var responseMessage = $"Turn {state.TurnCount}: You sent '{turnContext.Activity.Text}'\n"; await turnContext.SendActivityAsync(responseMessage); } } else { if (turnContext.Activity.MembersAdded.Count > 0) { foreach (var m in turnContext.Activity.MembersAdded) { if (m.Id != turnContext.Activity.Recipient.Id) { // store the conversation reference for the newly added user // in production scenario you want to store conversation reference in an external store e.g. Cosmos DB, Table Storage etc. await _accessors.ConversationReferenceState.SetAsync(turnContext, turnContext.Activity.GetConversationReference()); await _accessors.ConversationState.SaveChangesAsync(turnContext); } } await turnContext.SendActivityAsync($"{turnContext.Activity.Type} event detected"); } } }