public async void ProcessNode(JToken node, JToken section = null) { if (node == null) { return; } ClearButtonTimer(); //Replaceing verbs node = JToken.Parse(VerbProcessor.Process(node.ToString())); var parsedNode = node.ToObject <ChatNode>(); if (parsedNode.Buttons != null && parsedNode.Buttons.Count > 0) { ClearButtons(); } if (parsedNode.NodeType == NodeTypeEnum.ApiCall) { ToggleTyping(true); try { var paramDict = new Dictionary <string, object>(); foreach (var reqParam in parsedNode.RequiredVariables) { if (reqParam == "HISTORY") //Custom Variable { paramDict[reqParam] = ChatThread.Where(x => x.SectionType != SectionTypeEnum.Typing).ToArray(); } else { paramDict[reqParam] = ButtonActionHelper.GetSavedValue(reqParam); } } var nextNodeId = parsedNode.NextNodeId; //Default switch (parsedNode.ApiMethod.ToUpper()) { case "GET": { var query = string.Join("&", paramDict.Select(x => $"{x.Key}={Uri.EscapeDataString(x.Value + "")}")); var api = string.IsNullOrWhiteSpace(query) ? parsedNode.ApiUrl : parsedNode.ApiUrl + "?" + query; var resp = await APIHelper.HitAsync <Dictionary <string, object> >(api); if (resp.ContainsKey("NextNodeId")) { nextNodeId = resp["NextNodeId"] + ""; } ButtonActionHelper.HandleSaveMultiple(resp); } break; case "POST": { var resp = await APIHelper.HitPostAsync <Dictionary <string, object>, Dictionary <string, object> >(parsedNode.ApiUrl, paramDict); if (resp.ContainsKey("NextNodeId")) { nextNodeId = resp["NextNodeId"] + ""; } } break; default: Utils.ShowDialog($"{parsedNode.ApiMethod} ApiType Unknown!"); break; } NavigateToNode(nextNodeId); } catch (HttpRequestException ex) { ToggleTyping(false); Utils.ShowDialog(ex.ToString()); NavigateToNode(parsedNode.NextNodeId); } catch (Exception ex) { ToggleTyping(false); Utils.ShowDialog(ex.ToString()); NavigateToNode(parsedNode.NextNodeId); } } else if (node["Sections"] == null || node["Sections"].Children().Count() == 0) { ToggleTyping(false); await ProcessButtonsAsync(node); } else if (node["Sections"] != null && node["Sections"].Children().Count() > 0) { var sectionsSource = node["Sections"]; var currentSectionSource = section ?? sectionsSource.First; //Replaceing verbs currentSectionSource = JToken.Parse(VerbProcessor.Process(currentSectionSource.ToString())); SectionTypeEnum secType = (SectionTypeEnum)Enum.Parse(typeof(SectionTypeEnum), currentSectionSource["SectionType"].ToString()); Section parsedSection = null; bool showTyping = false; switch (secType) { case SectionTypeEnum.Image: parsedSection = currentSectionSource.ToObject <ImageSection>(); showTyping = true; break; case SectionTypeEnum.Text: parsedSection = currentSectionSource.ToObject <TextSection>(); break; case SectionTypeEnum.Gif: parsedSection = currentSectionSource.ToObject <GifSection>(); showTyping = true; break; case SectionTypeEnum.Video: parsedSection = currentSectionSource.ToObject <VideoSection>(); break; case SectionTypeEnum.Audio: parsedSection = currentSectionSource.ToObject <AudioSection>(); break; case SectionTypeEnum.EmbeddedHtml: parsedSection = currentSectionSource.ToObject <EmbeddedHtmlSection>(); break; case SectionTypeEnum.Link: case SectionTypeEnum.Graph: case SectionTypeEnum.Carousel: Utils.ShowDialog($"{secType} Coming soon!"); break; default: break; } if (parsedSection != null) { if (parsedSection.DelayInMs > 50 || showTyping) //Add 'typing' bubble if delay is grather than 50 ms { ToggleTyping(true); } //Wait for delay MilliSeconds and then continue with chat Dispatcher.Dispatch(async() => { var precacheSucess = await PrecacheSection(parsedSection); //Remove 'typing' bubble ToggleTyping(false); var sectionIndex = (sectionsSource.Children().ToList().FindIndex(x => x["_id"].ToString() == parsedSection._id)); if (precacheSucess) { if (sectionIndex == 0) //First section in node, send View Event { await Task.Run(async() => { try { await APIHelper.TrackEvent(Utils.GetViewEvent(parsedNode.Id, Utils.DeviceId)); } catch (Exception ex) { await Utils.ShowDialogAsync(ex.ToString()); } }); } AddIncommingSection(parsedSection); } var remainingSections = sectionsSource.Children().Count() - (sectionIndex + 1); if (remainingSections > 0) { var nextSection = sectionsSource.ElementAt(sectionIndex + 1); ProcessNode(node, nextSection); } else { await ProcessButtonsAsync(node); } }, parsedSection.DelayInMs); } } }
public async void Execute(object parameter) { if (parameter is Button button) { switch (button.ButtonType) { case ButtonTypeEnum.PostText: if (!button.Hidden) { ButtonActionHelper.HandlePostTextToThread(button.ButtonText); } break; case ButtonTypeEnum.OpenUrl: ButtonActionHelper.HandleOpenUrl(button.Url); break; case ButtonTypeEnum.GetText: if (string.IsNullOrWhiteSpace(button.VariableValue)) { return; } ButtonActionHelper.HandleSaveTextInput(button.VariableName, button.VariableValue); if (!button.Hidden) { ButtonActionHelper.HandlePostTextToThread(button.PrefixText + button.VariableValue + button.PostfixText); } break; case ButtonTypeEnum.GetEmail: if (string.IsNullOrWhiteSpace(button.VariableValue)) { return; } if (!Utils.IsValidEmail(button.VariableValue)) { Utils.ShowDialog("Invalid format"); return; } ButtonActionHelper.HandleSaveTextInput(button.VariableName, button.VariableValue); if (!button.Hidden) { ButtonActionHelper.HandlePostTextToThread(button.PrefixText + button.VariableValue + button.PostfixText); } break; case ButtonTypeEnum.GetNumber: if (string.IsNullOrWhiteSpace(button.VariableValue)) { return; } double d; if (!double.TryParse(button.VariableValue, out d)) { Utils.ShowDialog("Invalid format"); return; } ButtonActionHelper.HandleSaveTextInput(button.VariableName, d.ToString()); if (!button.Hidden) { ButtonActionHelper.HandlePostTextToThread(button.PrefixText + d.ToString() + button.PostfixText); } break; case ButtonTypeEnum.GetPhoneNumber: if (string.IsNullOrWhiteSpace(button.VariableValue)) { return; } if (!Utils.IsValidPhoneNumber(button.VariableValue)) { Utils.ShowDialog("Invalid format"); return; } ButtonActionHelper.HandleSaveTextInput(button.VariableName, button.VariableValue); if (!button.Hidden) { ButtonActionHelper.HandlePostTextToThread(button.PrefixText + button.VariableValue + button.PostfixText); } break; case ButtonTypeEnum.GetItemFromSource: var valueToSave = button.Items.FirstOrDefault(x => x.Value == button.VariableValue); if (valueToSave.Key == null && valueToSave.Value == null) { Utils.ShowDialog("Invalid value"); return; } ButtonActionHelper.HandleSaveTextInput(button.VariableName, valueToSave.Key); if (!button.Hidden) { ButtonActionHelper.HandlePostTextToThread(button.PrefixText + button.VariableValue + button.PostfixText); } break; case ButtonTypeEnum.GetAddress: { bool done = false; while (!done) { var ad = new AddressDialog(); var res = await ad.ShowAsync(); switch (res) { case Windows.UI.Xaml.Controls.ContentDialogResult.Primary: if (Utils.ValidateStrings(ad.City, ad.PinCode, ad.Country, ad.Latitude == 0 ? "" : ad.Latitude.ToString(), ad.Longitude == 0 ? "" : ad.Longitude.ToString(), ad.StreetAddress)) { ButtonActionHelper.HandleSaveTextInput("CITY", ad.City); ButtonActionHelper.HandleSaveTextInput("COUNTRY", ad.Country); ButtonActionHelper.HandleSaveTextInput("PINCODE", ad.PinCode); ButtonActionHelper.HandleSaveTextInput("LAT", ad.Latitude.ToString()); ButtonActionHelper.HandleSaveTextInput("LNG", ad.Longitude.ToString()); ButtonActionHelper.HandleSaveTextInput("STREET_ADDRESS", ad.StreetAddress); if (!button.Hidden) { ButtonActionHelper.HandlePostTextToThread($"{ad.StreetAddress}\r\n\r\nCity: {ad.City}\r\nCountry: {ad.Country}\r\nPin: {ad.PinCode}"); } done = true; } break; default: break; } if (!done) { await Utils.ShowDialogAsync("All fields in address are mandatory!"); } } } break; case ButtonTypeEnum.GetImage: case ButtonTypeEnum.GetAudio: case ButtonTypeEnum.GetVideo: var image = await ButtonActionHelper.HandleSaveMediaInputAsync(button.VariableName, button.ButtonType); ButtonActionHelper.HandlePostMediaToThread(image, button.ButtonType); break; case ButtonTypeEnum.NextNode: if (!button.Hidden) { ButtonActionHelper.HandlePostTextToThread(button.ButtonText); } if (!string.IsNullOrWhiteSpace(button.VariableName) && button.VariableValue != null) //VariableValue should be != null only { ButtonActionHelper.HandleSaveTextInput(button.VariableName, button.VariableValue); } break; case ButtonTypeEnum.DeepLink: await ButtonActionHelper.HandleDeepLinkAsync(button.DeepLinkUrl); if (!button.Hidden) { ButtonActionHelper.HandlePostTextToThread(button.ButtonText); } break; default: Utils.ShowDialog($"Button type: {button.ButtonType} not supported"); break; } ButtonActionHelper.NavigateToNode(button.NextNodeId); } }
public async Task ProcessButtonsAsync(JToken node) { ClearButtonTimer(); var parsedNode = node.ToObject <ChatNode>(); if (parsedNode.Buttons == null || parsedNode.Buttons.Count == 0) { return; } ClearButtons(); var allButtons = node["Buttons"].ToObject <List <Button> >(); foreach (var btnSrc in allButtons.Where(x => x.Kind == ButtonKind.ClickInput)) { if (string.IsNullOrWhiteSpace(btnSrc.ButtonName)) { btnSrc.ButtonName = btnSrc.ButtonText; } var btn = btnSrc.DeepCopy(); if (btn.DoesRepeat) { var repeatOn = ButtonActionHelper.GetSavedArray(btn.RepeatOn); if (repeatOn != null) { var max = btn.MaxRepeats == 0 ? repeatOn.Count - 1 : btn.MaxRepeats; for (int i = btn.StartPosition; i <= max; i++) { var b = btn.DeepCopy(); b.VariableName = node["VariableName"] + ""; b.NodeId = parsedNode.Id; ButtonActionHelper.ClearSavedValue(b.RepeatAs); ButtonActionHelper.HandleSaveTextInput(b.RepeatAs, repeatOn[i] + ""); b.ButtonName = VerbProcessor.Process(b.ButtonName, false); b.ButtonText = VerbProcessor.Process(b.ButtonText, false); if (btn.ButtonType == ButtonTypeEnum.GetText && !string.IsNullOrWhiteSpace(btn.DefaultText)) { btn.VariableValue = btn.DefaultText; } ButtonActionHelper.ClearSavedValue(b.RepeatAs); CurrentClickButtons.Add(b); } } } else { btn.VariableName = node["VariableName"] + ""; btn.NodeId = parsedNode.Id; if (btn.ButtonType == ButtonTypeEnum.GetText && !string.IsNullOrWhiteSpace(btn.DefaultText)) { btn.VariableValue = btn.DefaultText; } btn.ButtonName = VerbProcessor.Process(btn.ButtonName); btn.ButtonText = VerbProcessor.Process(btn.ButtonText); CurrentClickButtons.Add(btn); } } foreach (var btn in allButtons.Where(x => x.Kind == ButtonKind.TextInput)) { if (string.IsNullOrWhiteSpace(btn.ButtonName)) { btn.ButtonName = btn.ButtonText; } btn.VariableName = node["VariableName"] + ""; btn.NodeId = parsedNode.Id; btn.ButtonName = VerbProcessor.Process(btn.ButtonName); btn.ButtonText = VerbProcessor.Process(btn.ButtonText); try { if (btn.ButtonType == ButtonTypeEnum.GetItemFromSource) { btn.ItemsSource = (await APIHelper.HitAsync <Dictionary <string, string> >(btn.Url)); btn.Items = btn.ItemsSource; } } catch { #if DEBUG if (Debugger.IsAttached) { btn.ItemsSource = JsonConvert.DeserializeObject <Dictionary <string, string> >("{\r\n \"ADVERTISING & MARKETING SERVICES\": \"Advertising & Marketing Services\",\r\n \"AEROSPACE\": \"Aerospace\",\r\n \"ARCHITECTURE\": \"Architecture\",\r\n \"ARTS & CRAFTS\": \"Arts & Crafts\",\r\n \"AUTOMOTIVE\": \"Automotive\",\r\n \"BANK\": \"Bank\",\r\n \"BIOTECHNOLOGY\": \"Biotechnology\",\r\n \"BOOK STORE\": \"Book Store\",\r\n \"BLOGS\": \"Blogs\",\r\n \"BUSINESS SERVICES\": \"Business Services\",\r\n \"CARS\": \"Cars\",\r\n \"USED CARS\": \"Used Cars\",\r\n \"CARGO & LOGISTICS\": \"Cargo & Logistics\",\r\n \"CATERING\": \"Catering\",\r\n \"CHEMICALS\": \"Chemicals\",\r\n \"COLLEGE\": \"College\",\r\n \"COMMUNITY\": \"Community\",\r\n \"COMPUTERS\": \"Computers\",\r\n \"CONSTRUCTION MATERIAL\": \"Construction Material\",\r\n \"CONSULTANTS\": \"Consultants\",\r\n \"EDUCATION\": \"Education\",\r\n \"ELECTRONICS\": \"Electronics\",\r\n \"ENERGY\": \"Energy\",\r\n \"ENTERTAINMENT\": \"Entertainment\",\r\n \"EQUIPMENT\": \"Equipment\",\r\n \"EVENT PLANNING SERVICES\": \"Event Planning Services\",\r\n \"EVENTS\": \"Events\",\r\n \"EXPORTS\": \"Exports\",\r\n \"FASHION - APPAREL\": \"Fashion - Apparel\",\r\n \"FASHION - FOOTWEAR\": \"Fashion - Footwear\",\r\n \"F&B - BAKERY\": \"F&B - Bakery\",\r\n \"F&B - BARS\": \"F&B - Bars\",\r\n \"F&B - CAFE\": \"F&B - Cafe\",\r\n \"F&B - RESTAURANTS\": \"F&B - Restaurants\",\r\n \"FREELANCER\": \"Freelancer\",\r\n \"FLOWER SHOP\": \"Flower Shop\",\r\n \"FINANCIAL SERVICES\": \"Financial Services\",\r\n \"FURNITURE\": \"Furniture\",\r\n \"GENERAL SERVICES\": \"General Services\",\r\n \"GIFTS & NOVELTIES\": \"Gifts & Novelties\",\r\n \"GROCERY\": \"Grocery\",\r\n \"GAMING\": \"Gaming\",\r\n \"GARDEN\": \"Garden\",\r\n \"HOME FURNISHINGS\": \"Home Furnishings\",\r\n \"HEALTH & FITNESS\": \"Health & Fitness\",\r\n \"HOME APPLIANCES\": \"Home Appliances\",\r\n \"HARDWARE & SANITARY-WARE\": \"Hardware & Sanitary-Ware\",\r\n \"HOME MAINTENANCE\": \"Home Maintenance\",\r\n \"HOME CARE\": \"Home Care\",\r\n \"HOTEL & MOTELS\": \"Hotel & Motels\",\r\n \"HOSPITAL\": \"Hospital\",\r\n \"HYPERMARKET\": \"Hypermarket\",\r\n \"INSURANCE\": \"Insurance\",\r\n \"INTERIOR DESIGN\": \"Interior Design\",\r\n \"KINDER GARTEN\": \"Kinder Garten\",\r\n \"KIDS GOODS\": \"Kids Goods\",\r\n \"KITCHEN EQUIPMENT\": \"Kitchen Equipment\",\r\n \"LEGAL SERVICES\": \"Legal Services\",\r\n \"MANUFACTURERS\": \"Manufacturers\",\r\n \"MEDICAL - DENTAL\": \"Medical - Dental\",\r\n \"MEDICAL - GENERAL\": \"Medical - General\",\r\n \"MEDIA & NEWS\": \"Media & News\",\r\n \"MINING\": \"Mining\",\r\n \"NATURAL & AYURVEDA\": \"Natural & Ayurveda\",\r\n \"NON-PROFIT ORGANIZATION\": \"Non-Profit Organization\",\r\n \"OFFICE SUPPLIES\": \"Office Supplies\",\r\n \"OTHER RETAIL\": \"Other Retail\",\r\n \"OUTDOOR & SPORTING GOODS\": \"Outdoor & Sporting Goods\",\r\n \"PETS\": \"Pets\",\r\n \"PHOTOGRAPHY\": \"Photography\",\r\n \"POLITICAL ORGANIZATION\": \"Political Organization\",\r\n \"REAL ESTATE & CONSTRUCTION\": \"Real Estate & Construction\",\r\n \"RELIGIOUS ORGANIZATION\": \"Religious Organization\",\r\n \"SPA\": \"Spa\",\r\n \"SPORTS\": \"Sports\",\r\n \"SHOPPING COMPLEX\": \"Shopping Complex\",\r\n \"SOFTWARE\": \"Software\",\r\n \"SCIENCE & ENGINEERING\": \"Science & Engineering\",\r\n \"SECURITY\": \"Security\",\r\n \"TELECOMMUNICATION\": \"Telecommunication\",\r\n \"TOURISM\": \"Tourism\",\r\n \"TRADING\": \"Trading\",\r\n \"TRANSPORTATION SERVICE\": \"Transportation Service\",\r\n \"TRAINING INSTITUTES\": \"Training Institutes\",\r\n \"TUITIONS & COACHING\": \"Tuitions & Coaching\",\r\n \"WATCHES\": \"Watches\",\r\n \"WATCHES & JEWELRY\": \"Watches & Jewelry\"\r\n}"); btn.Items = btn.ItemsSource; } #endif } CurrentTextInputButtons.Add(btn); } //Handling node timeout to default button var defaultBtn = allButtons.FirstOrDefault(x => x.DefaultButton && !Utils.IGNORED_DEFAULT_BUTTONS.Contains(x.ButtonType)); if (defaultBtn != null && parsedNode.TimeoutInMs >= 0) { buttonTimeoutTimer = new DispatcherTimer() { Interval = TimeSpan.FromMilliseconds(parsedNode.TimeoutInMs) }; buttonTimeoutTimer.Tick += (s, e) => { ClearButtonTimer(); defaultBtn.VariableName = node["VariableName"] + ""; defaultBtn.NodeId = parsedNode.Id; defaultBtn.ButtonName = VerbProcessor.Process(defaultBtn.ButtonName); defaultBtn.ButtonText = VerbProcessor.Process(defaultBtn.ButtonText); defaultBtn.Action.Execute(defaultBtn); }; buttonTimeoutTimer.Start(); } }
public async void ProcessNode(JToken node, JToken section = null) { if (node == null) { Utils.ShowDialog("Node not found!"); return; } ClearButtonTimer(); //Replacing verbs node = JToken.Parse(VerbProcessor.Process(node.ToString())); var parsedNode = node.ToObject <ChatNode>(); if (parsedNode.Buttons != null && parsedNode.Buttons.Count > 0) { ClearButtons(); } if (parsedNode.NodeType == NodeTypeEnum.HandoffToAgent) { await Utils.ShowDialogAsync("'HandoffToAgent' not supported in simulator"); } else if (parsedNode.NodeType == NodeTypeEnum.ApiCall) { ToggleTyping(true); try { var paramDict = new Dictionary <string, object>(); if (parsedNode.RequiredVariables != null) { foreach (var reqParam in parsedNode.RequiredVariables) { if (reqParam == "HISTORY") //Custom Variable { paramDict[reqParam] = ChatThread.Where(x => x.SectionType != SectionTypeEnum.Typing).ToArray(); } else { paramDict[reqParam] = ButtonActionHelper.GetSavedValue(reqParam); } } } var nextNodeId = parsedNode.NextNodeId; //Default switch (parsedNode.ApiMethod.ToUpper()) { case "GET": { var query = string.Join("&", paramDict.Select(x => $"{x.Key}={Uri.EscapeDataString(x.Value + "")}")); var api = string.IsNullOrWhiteSpace(query) ? parsedNode.ApiUrl : parsedNode.ApiUrl + (parsedNode.ApiUrl?.Contains("?") == true ? "&" : "?") + query; var resp = await APIHelper.HitAsync <JObject>(api); if (!string.IsNullOrWhiteSpace(resp["NextNodeId"] + "")) { nextNodeId = resp["NextNodeId"] + ""; } ButtonActionHelper.HandleSaveMultiple(resp.ToObject <Dictionary <string, object> >()); var apiNextNodeId = ExtractNextNodeIdFromAPIResp(parsedNode, resp); if (!string.IsNullOrWhiteSpace(apiNextNodeId)) { nextNodeId = apiNextNodeId; } } break; case "POST": { var resp = await APIHelper.HitPostAsync <Dictionary <string, object>, JObject>(parsedNode.ApiUrl, paramDict); if (!string.IsNullOrWhiteSpace(resp["NextNodeId"] + "")) { nextNodeId = resp["NextNodeId"] + ""; } var apiNextNodeId = ExtractNextNodeIdFromAPIResp(parsedNode, resp); if (!string.IsNullOrWhiteSpace(apiNextNodeId)) { nextNodeId = apiNextNodeId; } } break; default: Utils.ShowDialog($"{parsedNode.ApiMethod} ApiMethod Unsupported!"); break; } NavigateToNode(nextNodeId); } catch (Exception ex) { ToggleTyping(false); Utils.ShowDialog($"API[{parsedNode.ApiMethod}]: {parsedNode.ApiUrl }\r\nRequired Vars: {(parsedNode.RequiredVariables == null ? "" : string.Join(",", parsedNode.RequiredVariables))}\r\nError: " + ex.Message); NavigateToNode(parsedNode.NextNodeId); } } else if (node["Sections"] == null || node["Sections"].Children().Count() == 0) { ToggleTyping(false); await ProcessButtonsAsync(node); } else if (node["Sections"] != null && node["Sections"].Children().Count() > 0) { var sectionsSource = node["Sections"]; var currentSectionSource = section ?? sectionsSource.First; //Replacing verbs currentSectionSource = JToken.Parse(VerbProcessor.Process(currentSectionSource.ToString())); SectionTypeEnum secType = (SectionTypeEnum)Enum.Parse(typeof(SectionTypeEnum), currentSectionSource["SectionType"].ToString()); Section parsedSection = null; bool showTyping = false; switch (secType) { case SectionTypeEnum.Image: parsedSection = currentSectionSource.ToObject <ImageSection>(); showTyping = true; break; case SectionTypeEnum.Text: parsedSection = currentSectionSource.ToObject <TextSection>(); break; case SectionTypeEnum.Gif: parsedSection = currentSectionSource.ToObject <GifSection>(); showTyping = true; break; case SectionTypeEnum.Video: parsedSection = currentSectionSource.ToObject <VideoSection>(); break; case SectionTypeEnum.Audio: parsedSection = currentSectionSource.ToObject <AudioSection>(); break; case SectionTypeEnum.EmbeddedHtml: parsedSection = currentSectionSource.ToObject <EmbeddedHtmlSection>(); break; case SectionTypeEnum.PrintOTP: parsedSection = currentSectionSource.ToObject <PrintOTPSection>(); break; case SectionTypeEnum.Carousel: { parsedSection = currentSectionSource.ToObject <CarouselSection>(); (parsedSection as CarouselSection).Items = VerbProcessor.ProcessCarousalItems((parsedSection as CarouselSection).Items, parsedNode); } break; case SectionTypeEnum.Link: case SectionTypeEnum.Graph: Utils.ShowDialog($"{secType} Coming soon!"); break; default: break; } #if DEBUG if (Debugger.IsAttached) { if (parsedSection != null) { parsedSection.DelayInMs = 0; } } else { if (parsedSection != null && parsedSection.DelayInMs <= 0) { parsedSection.DelayInMs = 2000; } } #endif if (parsedSection != null) { if (parsedSection.DelayInMs > 50 || showTyping) //Add 'typing' bubble if delay is greater than 50 ms { ToggleTyping(true); } //Wait for delay MilliSeconds and then continue with chat Dispatcher.Dispatch(async() => { var precacheSucess = await PrecacheSection(parsedSection); //Remove 'typing' bubble ToggleTyping(false); var sectionIndex = (sectionsSource.Children().ToList().FindIndex(x => x["_id"].ToString() == parsedSection._id)); if (precacheSucess) { if (parsedNode.NodeType == NodeTypeEnum.Card) { parsedSection.Title = VerbProcessor.Process(parsedNode.CardHeader); parsedSection.Caption = VerbProcessor.Process(parsedNode.CardFooter); if (parsedNode.Placement == null || parsedNode.Placement == Placement.Incoming) { AddIncommingSection(parsedSection); } else if (parsedNode.Placement == Placement.Outgoing) { AddOutgoingSection(parsedSection); } else if (parsedNode.Placement == Placement.Center) { AddCenterSection(parsedSection); } } else { AddIncommingSection(parsedSection); } } var remainingSections = sectionsSource.Children().Count() - (sectionIndex + 1); if (remainingSections > 0) { var nextSection = sectionsSource.ElementAt(sectionIndex + 1); ProcessNode(node, nextSection); } else { await ProcessButtonsAsync(node); } }, parsedSection.DelayInMs); } } }
public async void Execute(object parameter) { if (parameter is Button button) { var parentNode = MainPageViewModel.CurrentInstance.GetNodeById(button.NodeId); var parsedParentNode = parentNode?.ToObject <ChatNode>(); //Special Case: Print OTP Section if (Utils.IsSectionTypePresentInNode(parentNode, SectionTypeEnum.PrintOTP)) { button.VariableValue = PrintOTPSection.OTP; } if (string.IsNullOrWhiteSpace(button.ButtonText)) { button.ButtonText = button.ButtonName; } var userData = new Dictionary <string, string>(); switch (button.ButtonType) { case ButtonTypeEnum.PostText: if (!button.Hidden && button.PostToChat) { ButtonActionHelper.HandlePostTextToThread(button.ButtonText); } break; case ButtonTypeEnum.OpenUrl: ButtonActionHelper.HandleOpenUrl(button.Url); break; case ButtonTypeEnum.GetText: if (string.IsNullOrWhiteSpace(button.VariableValue)) { return; } if (!Utils.IsValidTextButton(button)) { Utils.ShowDialog($"The text should not be empty and it should be between {button.MinLength} and {button.MaxLength}"); return; } ButtonActionHelper.HandleSaveTextInput(button.VariableName, button.VariableValue); userData[button.VariableName] = button.VariableValue; if (!button.Hidden && button.PostToChat) { ButtonActionHelper.HandlePostTextToThread(button.PrefixText + button.VariableValue + button.PostfixText); } break; case ButtonTypeEnum.GetEmail: if (string.IsNullOrWhiteSpace(button.VariableValue)) { return; } if (!Utils.IsValidEmail(button.VariableValue)) { Utils.ShowDialog("Invalid format"); return; } ButtonActionHelper.HandleSaveTextInput(button.VariableName, button.VariableValue); userData[button.VariableName] = button.VariableValue; if (!button.Hidden && button.PostToChat) { ButtonActionHelper.HandlePostTextToThread(button.PrefixText + button.VariableValue + button.PostfixText); } break; case ButtonTypeEnum.GetNumber: if (string.IsNullOrWhiteSpace(button.VariableValue)) { return; } double d; if (!double.TryParse(button.VariableValue, out d)) { Utils.ShowDialog("Invalid format"); return; } ButtonActionHelper.HandleSaveTextInput(button.VariableName, d.ToString()); userData[button.VariableName] = d.ToString(); if (!button.Hidden && button.PostToChat) { ButtonActionHelper.HandlePostTextToThread(button.PrefixText + d.ToString() + button.PostfixText); } break; case ButtonTypeEnum.GetPhoneNumber: if (string.IsNullOrWhiteSpace(button.VariableValue)) { return; } if (!Utils.IsValidPhoneNumber(button.VariableValue)) { Utils.ShowDialog("Invalid format"); return; } ButtonActionHelper.HandleSaveTextInput(button.VariableName, button.VariableValue); userData[button.VariableName] = button.VariableValue; if (!button.Hidden && button.PostToChat) { ButtonActionHelper.HandlePostTextToThread(button.PrefixText + button.VariableValue + button.PostfixText); } break; case ButtonTypeEnum.GetItemFromSource: var valueToSave = button.Items?.FirstOrDefault(x => x.Value == button.VariableValue); if (valueToSave?.Key == null && valueToSave?.Value == null) { Utils.ShowDialog("Invalid value"); return; } ButtonActionHelper.HandleSaveTextInput(button.VariableName, valueToSave?.Key); userData[button.VariableName] = valueToSave?.Key; if (!button.Hidden && button.PostToChat) { ButtonActionHelper.HandlePostTextToThread(button.PrefixText + button.VariableValue + button.PostfixText); } break; case ButtonTypeEnum.GetAddress: { bool done = false; while (!done) { var ad = new AddressDialog(); var res = await ad.ShowAsync(); switch (res) { case Windows.UI.Xaml.Controls.ContentDialogResult.Primary: if (Utils.ValidateStrings(ad.City, ad.PinCode, ad.Country, ad.Latitude == 0 ? "" : ad.Latitude.ToString(), ad.Longitude == 0 ? "" : ad.Longitude.ToString(), ad.StreetAddress)) { ButtonActionHelper.HandleSaveTextInput("CITY", ad.City); ButtonActionHelper.HandleSaveTextInput("COUNTRY", ad.Country); ButtonActionHelper.HandleSaveTextInput("PINCODE", ad.PinCode); ButtonActionHelper.HandleSaveTextInput("LAT", ad.Latitude.ToString()); ButtonActionHelper.HandleSaveTextInput("LNG", ad.Longitude.ToString()); ButtonActionHelper.HandleSaveTextInput("STREET_ADDRESS", ad.StreetAddress); #region User Data Fill userData["CITY"] = ad.City; userData["COUNTRY"] = ad.Country; userData["PINCODE"] = ad.PinCode; userData["LAT"] = ad.Latitude.ToString(); userData["LNG"] = ad.Longitude.ToString(); userData["STREET_ADDRESS"] = ad.StreetAddress; #endregion if (!button.Hidden && button.PostToChat) { ButtonActionHelper.HandlePostTextToThread($"{ad.StreetAddress}\r\n\r\nCity: {ad.City}\r\nCountry: {ad.Country}\r\nPin: {ad.PinCode}"); } done = true; } break; default: break; } if (!done) { await Utils.ShowDialogAsync("All fields in address are mandatory!"); } } } break; case ButtonTypeEnum.GetImage: case ButtonTypeEnum.GetFile: case ButtonTypeEnum.GetAudio: case ButtonTypeEnum.GetVideo: var mediaUrl = await ButtonActionHelper.HandleSaveMediaInputAsync(button.VariableName, button.ButtonType); if (string.IsNullOrWhiteSpace(mediaUrl)) { return; } userData[button.VariableName] = mediaUrl; ButtonActionHelper.HandlePostMediaToThread(mediaUrl, button.ButtonType); break; case ButtonTypeEnum.NextNode: if (!button.Hidden && button.PostToChat) { ButtonActionHelper.HandlePostTextToThread(button.ButtonText); } if (!string.IsNullOrWhiteSpace(button.VariableName) && button.VariableValue != null) //VariableValue should be != null only { ButtonActionHelper.HandleSaveTextInput(button.VariableName, button.VariableValue); } break; case ButtonTypeEnum.DeepLink: await ButtonActionHelper.HandleDeepLinkAsync(button.DeepLinkUrl); if (!button.Hidden && button.PostToChat) { ButtonActionHelper.HandlePostTextToThread(button.ButtonText); } break; case ButtonTypeEnum.GetAgent: await Utils.ShowDialogAsync("Agent chat not supported in simulator"); if (!button.Hidden && button.PostToChat) { ButtonActionHelper.HandlePostTextToThread(button.ButtonText); } break; case ButtonTypeEnum.FetchChatFlow: if (!button.Hidden && button.PostToChat) { ButtonActionHelper.HandlePostTextToThread(button.ButtonText); } if (!string.IsNullOrWhiteSpace(button.VariableName) && button.VariableValue != null) //VariableValue should be != null only { ButtonActionHelper.HandleSaveTextInput(button.VariableName, button.VariableValue); } await ButtonActionHelper.HandleFetchChatFlowAsync(button.Url); break; case ButtonTypeEnum.GetDate: { var cd = new DateTimePickerDialog() { IsDateVisible = true }; cd.Title = "Pick a date"; var res = await cd.ShowAsync(); if (res == UWPControls.ContentDialogResult.Primary) { button.VariableValue = cd.ChoosenDate.ToString("yyyy-MM-dd"); ButtonActionHelper.HandleSaveTextInput(button.VariableName, button.VariableValue); ButtonActionHelper.HandleSaveTextInput(button.VariableName + "_DISPLAY", cd.ChoosenDate.ToString("dd MMM, yyyy")); userData[button.VariableName] = button.VariableValue; if (!button.Hidden && button.PostToChat) { ButtonActionHelper.HandlePostTextToThread(button.VariableValue); } } else { return; } } break; case ButtonTypeEnum.GetDateTime: { var cd = new DateTimePickerDialog() { IsDateVisible = true, IsTimeVisible = true }; cd.Title = "Pick date time"; var res = await cd.ShowAsync(); if (res == UWPControls.ContentDialogResult.Primary) { DateTimeOffset dtLocal = cd.ChoosenDate.Date + cd.ChoosenTime; DateTime dtUTC = DateTime.Parse(dtLocal.ToString(), null, DateTimeStyles.AdjustToUniversal); button.VariableValue = JsonConvert.SerializeObject(dtUTC).Trim('"'); var display = dtLocal.ToString("dd MMM, yyyy hh:mm:ss tt"); ButtonActionHelper.HandleSaveTextInput(button.VariableName, button.VariableValue); ButtonActionHelper.HandleSaveTextInput(button.VariableName + "_DISPLAY", display); ButtonActionHelper.HandleSaveTextInput(button.VariableName + "_DISPLAY2", dtUTC.ToString("dd MMM, yyyy hh:mm:ss tt")); ButtonActionHelper.HandleSaveTextInput(button.VariableName + "_DISPLAY3", JsonConvert.SerializeObject(dtUTC).Trim('"')); userData[button.VariableName] = button.VariableValue; if (!button.Hidden && button.PostToChat) { ButtonActionHelper.HandlePostTextToThread(display); } } else { return; } } break; case ButtonTypeEnum.GetTime: { var cd = new DateTimePickerDialog() { IsTimeVisible = true }; cd.Title = "Pick time"; var res = await cd.ShowAsync(); if (res == UWPControls.ContentDialogResult.Primary) { button.VariableValue = JsonConvert.SerializeObject(cd.ChoosenTime).Trim('"'); var display = new DateTime(cd.ChoosenTime.Ticks).ToString("hh:mm tt"); ButtonActionHelper.HandleSaveTextInput(button.VariableName, button.VariableValue); ButtonActionHelper.HandleSaveTextInput(button.VariableName + "_DISPLAY", display); ButtonActionHelper.HandleSaveTextInput(button.VariableName + "_DISPLAY2", new DateTime(cd.ChoosenTime.Ticks).ToString("HH:mm")); userData[button.VariableName] = button.VariableValue; if (!button.Hidden && button.PostToChat) { ButtonActionHelper.HandlePostTextToThread(display); } } else { return; } } break; case ButtonTypeEnum.GetLocation: { var loc = await Utils.GetCurrentGeoLocation(); button.VariableValue = $"{(float)loc.Coordinate.Point.Position.Latitude},{(float)loc.Coordinate.Point.Position.Longitude}"; ButtonActionHelper.HandleSaveTextInput(button.VariableName, button.VariableValue); userData[button.VariableName] = button.VariableValue; if (!button.Hidden && button.PostToChat) { var mapUrl = $"https://maps.googleapis.com/maps/api/staticmap?center={button.VariableValue}&zoom=15&size=300x150&markers=color:red|label:A|{button.VariableValue}&key=" + Utils.Config.GoogleMapsAPIKey; ButtonActionHelper.HandlePostMediaToThread(mapUrl, ButtonTypeEnum.GetImage, button.VariableValue); } } break; default: Utils.ShowDialog($"Button type: {button.ButtonType} not supported"); break; } trackViewEvent(button, userData); ButtonActionHelper.NavigateToNode(button.NextNodeId); } else if (parameter is CarouselButton cButton) { var userData = new Dictionary <string, string>(); switch (cButton.Type) { case CardButtonType.NextNode: if (!string.IsNullOrWhiteSpace(cButton.VariableName) && cButton.VariableValue != null) //VariableValue should be != null only { ButtonActionHelper.HandleSaveTextInput(cButton.VariableName, cButton.VariableValue); userData[cButton.VariableName] = cButton.VariableValue; } break; case CardButtonType.DeepLink: await ButtonActionHelper.HandleDeepLinkAsync(cButton.Url); break; case CardButtonType.OpenUrl: ButtonActionHelper.HandleOpenUrl(cButton.Url); break; default: Utils.ShowDialog($"Button type: {cButton.Type} not supported"); break; } trackViewEvent(cButton, userData); ButtonActionHelper.NavigateToNode(cButton.NextNodeId); } }
public async void Execute(object parameter) { if (parameter is Button button) { var parentNode = MainPageViewModel.CurrentInstance.GetNodeById(button.NodeId); var parsedParentNode = parentNode?.ToObject <ChatNode>(); //Special Case: Print OTP Section if (Utils.IsSectionTypePresentInNode(parentNode, SectionTypeEnum.PrintOTP)) { button.VariableValue = PrintOTPSection.OTP; } var userData = new Dictionary <string, string>(); switch (button.ButtonType) { case ButtonTypeEnum.PostText: if (!button.Hidden && button.PostToChat) { ButtonActionHelper.HandlePostTextToThread(button.ButtonText); } break; case ButtonTypeEnum.OpenUrl: ButtonActionHelper.HandleOpenUrl(button.Url); break; case ButtonTypeEnum.GetText: if (string.IsNullOrWhiteSpace(button.VariableValue)) { return; } ButtonActionHelper.HandleSaveTextInput(button.VariableName, button.VariableValue); userData[button.VariableName] = button.VariableValue; if (!button.Hidden && button.PostToChat) { ButtonActionHelper.HandlePostTextToThread(button.PrefixText + button.VariableValue + button.PostfixText); } break; case ButtonTypeEnum.GetEmail: if (string.IsNullOrWhiteSpace(button.VariableValue)) { return; } if (!Utils.IsValidEmail(button.VariableValue)) { Utils.ShowDialog("Invalid format"); return; } ButtonActionHelper.HandleSaveTextInput(button.VariableName, button.VariableValue); userData[button.VariableName] = button.VariableValue; if (!button.Hidden && button.PostToChat) { ButtonActionHelper.HandlePostTextToThread(button.PrefixText + button.VariableValue + button.PostfixText); } break; case ButtonTypeEnum.GetNumber: if (string.IsNullOrWhiteSpace(button.VariableValue)) { return; } double d; if (!double.TryParse(button.VariableValue, out d)) { Utils.ShowDialog("Invalid format"); return; } ButtonActionHelper.HandleSaveTextInput(button.VariableName, d.ToString()); userData[button.VariableName] = d.ToString(); if (!button.Hidden && button.PostToChat) { ButtonActionHelper.HandlePostTextToThread(button.PrefixText + d.ToString() + button.PostfixText); } break; case ButtonTypeEnum.GetPhoneNumber: if (string.IsNullOrWhiteSpace(button.VariableValue)) { return; } if (!Utils.IsValidPhoneNumber(button.VariableValue)) { Utils.ShowDialog("Invalid format"); return; } ButtonActionHelper.HandleSaveTextInput(button.VariableName, button.VariableValue); userData[button.VariableName] = button.VariableValue; if (!button.Hidden && button.PostToChat) { ButtonActionHelper.HandlePostTextToThread(button.PrefixText + button.VariableValue + button.PostfixText); } break; case ButtonTypeEnum.GetItemFromSource: var valueToSave = button.Items?.FirstOrDefault(x => x.Value == button.VariableValue); if (valueToSave?.Key == null && valueToSave?.Value == null) { Utils.ShowDialog("Invalid value"); return; } ButtonActionHelper.HandleSaveTextInput(button.VariableName, valueToSave?.Key); userData[button.VariableName] = valueToSave?.Key; if (!button.Hidden && button.PostToChat) { ButtonActionHelper.HandlePostTextToThread(button.PrefixText + button.VariableValue + button.PostfixText); } break; case ButtonTypeEnum.GetAddress: { bool done = false; while (!done) { var ad = new AddressDialog(); var res = await ad.ShowAsync(); switch (res) { case Windows.UI.Xaml.Controls.ContentDialogResult.Primary: if (Utils.ValidateStrings(ad.City, ad.PinCode, ad.Country, ad.Latitude == 0 ? "" : ad.Latitude.ToString(), ad.Longitude == 0 ? "" : ad.Longitude.ToString(), ad.StreetAddress)) { ButtonActionHelper.HandleSaveTextInput("CITY", ad.City); ButtonActionHelper.HandleSaveTextInput("COUNTRY", ad.Country); ButtonActionHelper.HandleSaveTextInput("PINCODE", ad.PinCode); ButtonActionHelper.HandleSaveTextInput("LAT", ad.Latitude.ToString()); ButtonActionHelper.HandleSaveTextInput("LNG", ad.Longitude.ToString()); ButtonActionHelper.HandleSaveTextInput("STREET_ADDRESS", ad.StreetAddress); #region User Data Fill userData["CITY"] = ad.City; userData["COUNTRY"] = ad.Country; userData["PINCODE"] = ad.PinCode; userData["LAT"] = ad.Latitude.ToString(); userData["LNG"] = ad.Longitude.ToString(); userData["STREET_ADDRESS"] = ad.StreetAddress; #endregion if (!button.Hidden && button.PostToChat) { ButtonActionHelper.HandlePostTextToThread($"{ad.StreetAddress}\r\n\r\nCity: {ad.City}\r\nCountry: {ad.Country}\r\nPin: {ad.PinCode}"); } done = true; } break; default: break; } if (!done) { await Utils.ShowDialogAsync("All fields in address are mandatory!"); } } } break; case ButtonTypeEnum.GetImage: case ButtonTypeEnum.GetAudio: case ButtonTypeEnum.GetVideo: var mediaUrl = await ButtonActionHelper.HandleSaveMediaInputAsync(button.VariableName, button.ButtonType); userData[button.VariableName] = mediaUrl; ButtonActionHelper.HandlePostMediaToThread(mediaUrl, button.ButtonType); break; case ButtonTypeEnum.NextNode: if (!button.Hidden && button.PostToChat) { ButtonActionHelper.HandlePostTextToThread(button.ButtonText); } if (!string.IsNullOrWhiteSpace(button.VariableName) && button.VariableValue != null) //VariableValue should be != null only { ButtonActionHelper.HandleSaveTextInput(button.VariableName, button.VariableValue); } break; case ButtonTypeEnum.DeepLink: await ButtonActionHelper.HandleDeepLinkAsync(button.DeepLinkUrl); if (!button.Hidden && button.PostToChat) { ButtonActionHelper.HandlePostTextToThread(button.ButtonText); } break; case ButtonTypeEnum.GetAgent: if (MainPageViewModel.CurrentInstance != null) { MainPageViewModel.CurrentInstance.AgentChat(); } if (!button.Hidden && button.PostToChat) { ButtonActionHelper.HandlePostTextToThread(button.ButtonText); } break; case ButtonTypeEnum.FetchChatFlow: if (!button.Hidden && button.PostToChat) { ButtonActionHelper.HandlePostTextToThread(button.ButtonText); } if (!string.IsNullOrWhiteSpace(button.VariableName) && button.VariableValue != null) //VariableValue should be != null only { ButtonActionHelper.HandleSaveTextInput(button.VariableName, button.VariableValue); } await ButtonActionHelper.HandleFetchChatFlowAsync(button.Url); break; default: Utils.ShowDialog($"Button type: {button.ButtonType} not supported"); break; } trackViewEvent(button, userData); ButtonActionHelper.NavigateToNode(button.NextNodeId); } else if (parameter is CarouselButton cButton) { var userData = new Dictionary <string, string>(); switch (cButton.Type) { case CardButtonType.NextNode: if (!string.IsNullOrWhiteSpace(cButton.VariableName) && cButton.VariableValue != null) //VariableValue should be != null only { ButtonActionHelper.HandleSaveTextInput(cButton.VariableName, cButton.VariableValue); userData[cButton.VariableName] = cButton.VariableValue; } break; case CardButtonType.DeepLink: await ButtonActionHelper.HandleDeepLinkAsync(cButton.Url); break; case CardButtonType.OpenUrl: ButtonActionHelper.HandleOpenUrl(cButton.Url); break; default: Utils.ShowDialog($"Button type: {cButton.Type} not supported"); break; } trackViewEvent(cButton, userData); ButtonActionHelper.NavigateToNode(cButton.NextNodeId); } }