Ejemplo n.º 1
0
        protected override void ExecuteMultipleWithRetry(List <EntityWrapper> entities, Func <EntityWrapper, OrganizationRequest> orgRequest)
        {
            var requests = new OrganizationRequestCollection();

            requests.AddRange(entities.Select(wrapper => orgRequest(wrapper)).ToArray());

            int cnt = 0;

            List <ExecuteMultipleResponseItem> responseWithResults = new List <ExecuteMultipleResponseItem>();

            foreach (OrganizationRequest request in requests)
            {
                try
                {
                    OrganizationResponse response = new UpsertResponse()
                    {
                    };
                    responseWithResults.Add(new ExecuteMultipleResponseItem()
                    {
                        Response = response, RequestIndex = cnt
                    });
                }
                catch (FaultException <OrganizationServiceFault> ex)
                {
                    responseWithResults.Add(new ExecuteMultipleResponseItem()
                    {
                        Fault = ex.Detail, RequestIndex = cnt
                    });
                }

                cnt++;
            }

            PopulateExecutionResults(entities, responseWithResults);
        }
Ejemplo n.º 2
0
        internal override OrganizationResponse Execute(OrganizationRequest orgRequest, EntityReference userRef)
        {
            var request  = MakeRequest <UpsertRequest>(orgRequest);
            var resp     = new UpsertResponse();
            var target   = request.Target;
            var entityId = db.GetEntityOrNull(target.ToEntityReferenceWithKeyAttributes())?.Id;

            if (entityId.HasValue)
            {
                var req = new UpdateRequest();
                target.Id  = entityId.Value;
                req.Target = target;
                core.Execute(req, userRef);
                resp.Results["RecordCreated"] = false;
                resp.Results["Target"]        = target.ToEntityReferenceWithKeyAttributes();
            }
            else
            {
                var req = new CreateRequest {
                    Target = target
                };
                target.Id = (core.Execute(req, userRef) as CreateResponse).id;
                resp.Results["RecordCreated"] = true;
                resp.Results["Target"]        = target.ToEntityReferenceWithKeyAttributes();
            }
            return(resp);
        }
Ejemplo n.º 3
0
        private UpsertResponse HandleUpsert(OrganizationRequest orgRequest, EntityReference userRef)
        {
            var request  = MakeRequest <UpsertRequest>(orgRequest);
            var resp     = new UpsertResponse();
            var target   = request.Target;
            var entityId = dataMethods.GetEntityId(target.ToEntityReferenceWithKeyAttributes());

            if (entityId.HasValue)
            {
                var req = new UpdateRequest();
                target.Id  = entityId.Value;
                req.Target = target;
                Execute(req, userRef);
                resp.Results["RecordCreated"] = false;
                resp.Results["Target"]        = target.ToEntityReferenceWithKeyAttributes();
            }
            else
            {
                var req = new CreateRequest();
                req.Target = target;
                target.Id  = (Execute(req, userRef) as CreateResponse).id;
                resp.Results["RecordCreated"] = true;
                resp.Results["Target"]        = target.ToEntityReferenceWithKeyAttributes();
            }
            return(resp);
        }
Ejemplo n.º 4
0
        public OrganizationResponse Execute(OrganizationRequest request, XrmFakedContext ctx)
        {
            var  upsertRequest = (UpsertRequest)request;
            bool recordCreated;

            var service = ctx.GetOrganizationService();

            var entityLogicalName = upsertRequest.Target.LogicalName;
            var entityId          = ctx.GetRecordUniqueId(upsertRequest.Target.ToEntityReferenceWithKeyAttributes(), validate: false);

            if (ctx.Data.ContainsKey(entityLogicalName) &&
                ctx.Data[entityLogicalName].ContainsKey(entityId))
            {
                recordCreated = false;
                service.Update(upsertRequest.Target);
            }
            else
            {
                recordCreated = true;
                entityId      = service.Create(upsertRequest.Target);
            }

            var result = new UpsertResponse();

            result.Results.Add("RecordCreated", recordCreated);
            result.Results.Add("Target", new EntityReference(entityLogicalName, entityId));
            return(result);
        }
Ejemplo n.º 5
0
        /// <summary>
        /// A shortcut for Upsert message. There is much more messages to create shortcut for, but this one is only useful for daily CRUD operations
        /// </summary>
        public static EntityReference Upsert(this IOrganizationService service, Entity entity)
        {
            UpsertResponse response = service.Execute <UpsertResponse>(new UpsertRequest()
            {
                Target = entity
            });

            return(response.Target);
        }
Ejemplo n.º 6
0
        public static async Task <Microsoft.Xrm.Sdk.Entity> PromptNextQuestion(IDialogContext context, IOrganizationService service, Microsoft.Xrm.Sdk.Entity cxCurrentStep, Microsoft.Xrm.Sdk.Entity cxNextStep, IMessageActivity message)
        {
            Microsoft.Xrm.Sdk.Entity cxStep = service.Retrieve(cxNextStep.LogicalName, cxNextStep.Id, new ColumnSet(true));

            //update conversation to initiate any workflow triggers
            Microsoft.Xrm.Sdk.Entity upsConversation = new Microsoft.Xrm.Sdk.Entity("aspect_cxconversation", "aspect_conversationid", message.Conversation.Id);
            upsConversation["aspect_nextcxstepid"] = new EntityReference(cxNextStep.LogicalName, cxNextStep.Id);
            UpsertResponse upsResponse = (UpsertResponse)service.Execute(new UpsertRequest()
            {
                Target = upsConversation
            });

            string responseText = ReplaceOutputText(service, (EntityReference)upsResponse["Target"], (string)cxStep["aspect_message"]);

            //Create a conversation message with outbound message
            Microsoft.Xrm.Sdk.Entity conversationMessageOutbound = new Microsoft.Xrm.Sdk.Entity("aspect_cxconversationmessage");
            conversationMessageOutbound["aspect_cxconversationid"] = new EntityReference("aspect_cxconversation", "aspect_conversationid", message.Conversation.Id);
            conversationMessageOutbound["aspect_cxstepid"]         = new EntityReference(cxNextStep.LogicalName, cxNextStep.Id);
            conversationMessageOutbound["aspect_direction"]        = true;
            conversationMessageOutbound["aspect_name"]             = message.Id;
            conversationMessageOutbound["aspect_message"]          = responseText;
            service.Create(conversationMessageOutbound);

            //Update conversation to reflect the current step
            Microsoft.Xrm.Sdk.Entity upsConversation2 = new Microsoft.Xrm.Sdk.Entity("aspect_cxconversation", "aspect_conversationid", message.Conversation.Id);
            upsConversation2["aspect_currentcxstepid"] = new EntityReference(cxNextStep.LogicalName, cxNextStep.Id);
            upsConversation2["aspect_lastanswer"]      = message.Text;
            upsConversation2["aspect_nextcxstepid"]    = null;
            service.Execute(new UpsertRequest()
            {
                Target = upsConversation2
            });

            //send outbound message
            IMessageActivity responseMessage = context.MakeMessage();

            responseMessage.Text      = responseText;
            responseMessage.Speak     = responseText;
            responseMessage.InputHint = Dynamics.CXGetAnswers(service, cxStep);
            responseMessage.Value     = JsonConvert.SerializeObject(new Dynamics.CXInformation()
            {
                //CXBotId = ((Guid)(((AliasedValue)["aspect_cxbot.aspect_cxbotid"]).Value)).ToString(),
                CXBotName          = (string)(((AliasedValue)cxCurrentStep["aspect_cxbot.aspect_name"]).Value),
                AudioDirectory     = cxCurrentStep.Contains("aspect_cxbot.aspect_audiodirectory") ? (string)(((AliasedValue)cxCurrentStep["aspect_cxbot.aspect_audiodirectory"]).Value) : string.Empty,
                RecordingDirectory = cxCurrentStep.Contains("aspect_cxbot.aspect_recordingdirectory") ? (string)(((AliasedValue)cxCurrentStep["aspect_cxbot.aspect_recordingdirectory"]).Value) : string.Empty,
                CXStepId           = cxStep.Id.ToString(),
                CXStepAudio        = cxStep.Contains("aspect_audio") ? (string)cxStep["aspect_audio"] : string.Empty,
                CXText             = responseText,
                CXAnswers          = CXGetAnswers(service, cxStep),
                CXType             = Dynamics.CXGetType((OptionSetValue)cxStep["aspect_type"])
            });
            await context.PostAsync(responseMessage);

            return(cxNextStep);
        }
        public void ProcessUpsert(String Filename)
        {
            Console.WriteLine("Executing upsert operation.....");
            XmlTextReader tr   = new XmlTextReader(Filename);
            XmlDocument   xdoc = new XmlDocument();

            xdoc.Load(tr);
            XmlNodeList xnlNodes = xdoc.DocumentElement.SelectNodes("/products/product");

            foreach (XmlNode xndNode in xnlNodes)
            {
                String productCode     = xndNode.SelectSingleNode("Code").InnerText;
                String productName     = xndNode.SelectSingleNode("Name").InnerText;
                String productCategory = xndNode.SelectSingleNode("Category").InnerText;
                String productMake     = xndNode.SelectSingleNode("Make").InnerText;

                //use alternate key for product
                Entity productToCreate = new Entity("sample_product", "sample_productcode", productCode);

                productToCreate["sample_name"]     = productName;
                productToCreate["sample_category"] = productCategory;
                productToCreate["sample_make"]     = productMake;
                UpsertRequest request = new UpsertRequest()
                {
                    Target = productToCreate
                };

                try
                {
                    // Execute UpsertRequest and obtain UpsertResponse.
                    UpsertResponse response = (UpsertResponse)_serviceProxy.Execute(request);
                    if (response.RecordCreated)
                    {
                        Console.WriteLine("New record {0} is created!", productName);
                    }
                    else
                    {
                        Console.WriteLine("Existing record {0} is updated!", productName);
                    }
                }

                // Catch any service fault exceptions that Microsoft Dynamics CRM throws.
                catch (FaultException <Microsoft.Xrm.Sdk.OrganizationServiceFault> )
                {
                    throw;
                }
            }
            // Prompts to view the sample_product entity records.
            // If you choose "y", IE will be launched to display the new or updated records.
            if (PromptForView())
            {
                ViewEntityListInBrowser();
            }
        }
Ejemplo n.º 8
0
        public async void GivenAnIdentityProvider_WhenUpsertOnNonExisting_ThenIdentityProviderIsCreated()
        {
            var identityProviderToCreate = GetIdentityProvider("testnew", "audnew", "http://authnew");
            var upsertResponse           = new UpsertResponse <IdentityProvider>(identityProviderToCreate, UpsertOutcome.Created, "someEtag");

            _controlPlaneDataStore.UpsertIdentityProviderAsync(identityProviderToCreate, null, CancellationToken.None).Returns(upsertResponse);

            UpsertResponse <IdentityProvider> retUpsertResponse = await _rbacService.UpsertIdentityProviderAsync(identityProviderToCreate, null, CancellationToken.None);

            Assert.Equal(UpsertOutcome.Created, upsertResponse.OutcomeType);
            VerifyIdentityProvider("testnew", "audnew", "http://authnew", "1.0", upsertResponse.Resource);
        }
        public void GetOperationTypeWithExecuteMultipleResponseItemHavingUpsertResponse()
        {
            var response     = new UpsertResponse();
            var responseItem = new ExecuteMultipleResponseItem
            {
                Response = response
            };
            OperationType actual = OperationType.Update;

            FluentActions.Invoking(() => actual = responseItem.GetOperationType())
            .Should()
            .NotThrow();

            actual.Should().Be(OperationType.Update);
        }
        public static XrmResponse UpsertEntity(Entity entityRecord, IOrganizationService service)
        {
            if (entityRecord == null)
            {
                return(null);
            }
            if (service == null)
            {
                return(null);
            }

            XrmResponse xrmResponse = null;

            if (service != null)
            {
                UpsertRequest request = new UpsertRequest()
                {
                    Target = entityRecord
                };



                // Execute UpsertRequest and obtain UpsertResponse.
                UpsertResponse response = (UpsertResponse)service.Execute(request);
                if (response.RecordCreated)
                {
                    xrmResponse = new XrmResponse
                    {
                        Id         = response.Target.Id.ToString(),
                        EntityName = entityRecord.LogicalName,
                        Create     = true
                    }
                }
                ;
                else
                {
                    xrmResponse = new XrmResponse()
                    {
                        Id         = response.Target.Id.ToString(),
                        EntityName = entityRecord.LogicalName,
                        Create     = false
                    }
                };
            }


            return(xrmResponse);
        }
Ejemplo n.º 11
0
        private Guid CreateSdkImage(Guid stepId, XmlElement sdkstepImageNode, string messageName, IOrganizationService service)
        {
            Guid   createdImageId = Guid.Empty;
            Entity image          = new Entity("sdkmessageprocessingstepimage", new Guid(sdkstepImageNode.GetAttribute("Id")));

            switch (messageName)
            {
            case "Create":
                image["messagepropertyname"] = "Id";
                break;

            case "SetState":
            case "SetStateDynamicEntity":
                image["messagepropertyname"] = "EntityMoniker";
                break;

            case "Send":
            case "DeliverIncoming":
            case "DeliverPromote":
                image["messagepropertyname"] = "EmailId";
                break;

            default:
                image["messagepropertyname"] = "Target";
                break;
            }

            Console.WriteLine("Registering the sdk image: " + sdkstepImageNode.GetAttribute("Name"));
            image["imagetype"]   = new OptionSetValue(Convert.ToInt32(sdkstepImageNode.GetAttribute("ImageType")));
            image["entityalias"] = sdkstepImageNode.GetAttribute("EntityAlias");
            image["name"]        = sdkstepImageNode.GetAttribute("Name");
            image["attributes"]  = sdkstepImageNode.GetAttribute("Attributes");
            image["sdkmessageprocessingstepid"] = new EntityReference("sdkmessageprocessingstep", stepId);
            UpsertRequest upsertsdkImage = new UpsertRequest();

            upsertsdkImage.Target = image;
            UpsertResponse upsertSdkImageReponse = (UpsertResponse)service.Execute(upsertsdkImage);

            if (upsertSdkImageReponse.RecordCreated)
            {
                createdImageId = upsertSdkImageReponse.Target.Id;
            }

            return(createdImageId);
        }
Ejemplo n.º 12
0
        public async void GivenAnIdentityProvider_WhenUpsertWithValidationFailure_ThenInvalidDefintionExceptionIsThrown(string name, string authority, string audience)
        {
            var identityProviderToUpdate = Substitute.ForPartsOf <IdentityProvider>();

            identityProviderToUpdate.Name.Returns(name);
            identityProviderToUpdate.Authority.Returns(authority);
            identityProviderToUpdate.Audience.Returns(new List <string> {
                audience
            });

            identityProviderToUpdate.ValidateAuthority().Returns(Enumerable.Empty <ValidationResult>());

            var upsertResponse = new UpsertResponse <IdentityProvider>(identityProviderToUpdate, UpsertOutcome.Updated, "someEtag");

            _controlPlaneDataStore.UpsertIdentityProviderAsync(identityProviderToUpdate, null, CancellationToken.None).Returns(upsertResponse);
            var exception = await Assert.ThrowsAsync <InvalidDefinitionException>(() => _rbacService.UpsertIdentityProviderAsync(identityProviderToUpdate, null, CancellationToken.None));

            Assert.True(exception.Issues.Count() > 0);
        }
Ejemplo n.º 13
0
        private Guid RegisterWorkflowTypes(EntityReference pluginAssembly, XmlElement workflowTypeNode, IOrganizationService service)
        {
            Guid   workflowTypeId   = Guid.Empty;
            Entity pluginTypeEntity = new Entity("plugintype", new Guid(workflowTypeNode.GetAttribute("Id")));

            pluginTypeEntity["typename"]                  = workflowTypeNode.GetAttribute("TypeName");
            pluginTypeEntity["friendlyname"]              = workflowTypeNode.GetAttribute("friendlyname");
            pluginTypeEntity["name"]                      = workflowTypeNode.GetAttribute("Name");
            pluginTypeEntity["pluginassemblyid"]          = pluginAssembly;
            pluginTypeEntity["workflowactivitygroupname"] = workflowTypeNode.GetAttribute("WorkflowActivityGroupName");
            pluginTypeEntity["isworkflowactivity"]        = true;
            UpsertRequest upsertPluginTypeRequest = new UpsertRequest();

            upsertPluginTypeRequest.Target = pluginTypeEntity;
            UpsertResponse upsertPluginTypeResponse = (UpsertResponse)service.Execute(upsertPluginTypeRequest);

            if (upsertPluginTypeResponse.RecordCreated)
            {
                workflowTypeId = upsertPluginTypeResponse.Target.Id;
            }

            return(workflowTypeId);
        }
Ejemplo n.º 14
0
        public void RegisterPluginsFromXml(string registrationXmlPath, string pluginsDllFilePath, IOrganizationService service)
        {
            RetrievePluginTypes retrievePluginTypes = new RetrievePluginTypes();
            string      strPluginDllName            = Path.GetFileName(pluginsDllFilePath);
            XmlDocument xmlDoc = new XmlDocument();

            xmlDoc.Load(registrationXmlPath);
            XmlNodeList xnList = xmlDoc.DocumentElement.SelectNodes("/Register/Solutions/Solution[@Assembly='" + strPluginDllName + "']");

            foreach (XmlElement node in xnList)
            {
                var id = node.GetAttribute("Id");
                UnRegisterPlugins unregisterPlugins = new UnRegisterPlugins();
                Console.WriteLine("Unregistering the plugin assembly: " + strPluginDllName);
                unregisterPlugins.UnRegisterPluginTypes(new Guid(id), service);
                var    sourceType     = Convert.ToInt32(node.GetAttribute("SourceType").ToString());
                var    isolationMode  = Convert.ToInt32(node.GetAttribute("IsolationMode").ToString());
                Entity pluginAssembly = new Entity("pluginassembly", new Guid(id));
                pluginAssembly["isolationmode"] = new OptionSetValue(isolationMode);
                pluginAssembly["sourcetype"]    = new OptionSetValue(sourceType);
                pluginAssembly["content"]       = Convert.ToBase64String(File.ReadAllBytes(pluginsDllFilePath));
                UpsertRequest upsertpluginAssemblyRequest = new UpsertRequest();
                upsertpluginAssemblyRequest.Target = pluginAssembly;
                UpsertResponse upsertPluginAssemblyResponse = (UpsertResponse)service.Execute(upsertpluginAssemblyRequest);
                node.Attributes["Id"].Value = upsertPluginAssemblyResponse.Target.Id.ToString();
                pluginAssembly.Id           = upsertPluginAssemblyResponse.Target.Id;
                XmlNodeList workflowTypeList = node.SelectNodes("WorkflowTypes/WorkflowType");
                foreach (XmlElement workflowType in workflowTypeList)
                {
                    Guid workflowTypeId = RegisterWorkflowTypes(new EntityReference(pluginAssembly.LogicalName, upsertPluginAssemblyResponse.Target.Id), workflowType, service);
                    workflowType.Attributes["Id"].Value = workflowTypeId.ToString();
                }

                XmlNodeList pluginTypeList = node.SelectNodes("PluginTypes/Plugin");
                foreach (XmlElement pluginType in pluginTypeList)
                {
                    Console.WriteLine("Registering the plugin type: " + pluginType.GetAttribute("TypeName"));
                    Entity pluginTypeEntity = new Entity("plugintype", new Guid(pluginType.GetAttribute("Id")));
                    pluginTypeEntity["typename"]         = pluginType.GetAttribute("TypeName");
                    pluginTypeEntity["friendlyname"]     = pluginType.GetAttribute("friendlyname");
                    pluginTypeEntity["name"]             = pluginType.GetAttribute("Name");
                    pluginTypeEntity["pluginassemblyid"] = new EntityReference(pluginAssembly.LogicalName, pluginAssembly.Id);
                    UpsertRequest upsertPluginTypeRequest = new UpsertRequest();
                    upsertPluginTypeRequest.Target = pluginTypeEntity;
                    UpsertResponse upsertPluginTypeResponse = (UpsertResponse)service.Execute(upsertPluginTypeRequest);
                    if (upsertPluginTypeResponse.RecordCreated)
                    {
                        pluginType.Attributes["Id"].Value = upsertPluginTypeResponse.Target.Id.ToString();
                    }

                    XmlNodeList sdksteps = pluginType.SelectNodes("Steps/Step");
                    foreach (XmlElement sdkmessageStepNode in sdksteps)
                    {
                        Console.WriteLine("Registering the sdk step: " + sdkmessageStepNode.GetAttribute("Name"));
                        Entity sdkmessageProcessingStep = new Entity("sdkmessageprocessingstep", new Guid(sdkmessageStepNode.GetAttribute("Id")));
                        sdkmessageProcessingStep["name"]        = sdkmessageStepNode.GetAttribute("Name");
                        sdkmessageProcessingStep["description"] = sdkmessageStepNode.GetAttribute("Description");
                        Guid messageId = retrievePluginTypes.GetSdkMessageId(sdkmessageStepNode.GetAttribute("MessageName"), service);
                        sdkmessageProcessingStep["sdkmessageid"]        = new EntityReference("sdkmessage", messageId);
                        sdkmessageProcessingStep["plugintypeid"]        = new EntityReference("plugintype", upsertPluginTypeResponse.Target.Id);
                        sdkmessageProcessingStep["mode"]                = new OptionSetValue(Convert.ToInt32(sdkmessageStepNode.GetAttribute("Mode")));  //0=sync,1=async
                        sdkmessageProcessingStep["rank"]                = Convert.ToInt32(sdkmessageStepNode.GetAttribute("Rank"));
                        sdkmessageProcessingStep["stage"]               = new OptionSetValue(Convert.ToInt32(sdkmessageStepNode.GetAttribute("Stage"))); //10-preValidation, 20-preOperation, 40-PostOperation
                        sdkmessageProcessingStep["supporteddeployment"] = new OptionSetValue(Convert.ToInt32(sdkmessageStepNode.GetAttribute("SupportedDeployment")));
                        Guid messageFitlerId = retrievePluginTypes.GetSdkMessageFilterId(sdkmessageStepNode.GetAttribute("PrimaryEntityName"), messageId, service);
                        sdkmessageProcessingStep["sdkmessagefilterid"] = new EntityReference("sdkmessagefilter", messageFitlerId);
                        UpsertRequest upsertPluginStepsRequest = new UpsertRequest();
                        upsertPluginStepsRequest.Target = sdkmessageProcessingStep;
                        UpsertResponse upsertPluginStepResponse = (UpsertResponse)service.Execute(upsertPluginStepsRequest);
                        if (upsertPluginStepResponse.RecordCreated)
                        {
                            sdkmessageStepNode.Attributes["Id"].Value = upsertPluginStepResponse.Target.Id.ToString();
                        }

                        string      messageName   = sdkmessageStepNode.GetAttribute("MessageName");
                        XmlNodeList sdkstepImages = sdkmessageStepNode.SelectNodes("Images/Image");
                        foreach (XmlElement sdkstepImageNode in sdkstepImages)
                        {
                            Guid createdImageId = CreateSdkImage(upsertPluginStepResponse.Target.Id, sdkstepImageNode, messageName, service);
                            if (createdImageId != Guid.Empty)
                            {
                                sdkstepImageNode.Attributes["Id"].Value = createdImageId.ToString();
                            }
                        }
                    }
                }
            }

            xmlDoc.Save(registrationXmlPath);
        }
Ejemplo n.º 15
0
        public virtual async Task <HttpResponseMessage> Post([FromBody] Activity activity)
        {
            // check if activity is of type message
            if (activity != null && activity.GetActivityType() == ActivityTypes.Message)
            {
                await Conversation.SendAsync(activity, () => new EchoDialog());
            }

            if (activity.GetActivityType() == ActivityTypes.ConversationUpdate)
            {
                // Handle conversation state changes, like members being added and removed
                // Use Activity.MembersAdded and Activity.MembersRemoved and Activity.Action for info
                // Not available in all channels
                IConversationUpdateActivity iConversationUpdated = activity as IConversationUpdateActivity;
                ConnectorClient             connector            = new ConnectorClient(new System.Uri(activity.ServiceUrl));
                if (iConversationUpdated != null)
                {
                    if ((string)activity.Text == "Address" || (activity.From.Name == "User" && iConversationUpdated.MembersAdded.Where(m => m.Id == iConversationUpdated.Recipient.Id).Count() > 0))
                    {
                        //Initialize the CRM connection
                        IOrganizationService service = Dynamics.GetService();

                        //Extract the direct line address (if applicable)
                        CXAddress address = JsonConvert.DeserializeObject <CXAddress>(activity.Value != null ? (string)activity.Value : "{}");
                        if (address.Address == null)
                        {
                            address.Address = "3145783471";
                            address.Message = "Initialize Conversation";
                            address.Bot     = "Default Bot";
                        }



                        //get bot
                        EntityCollection botResults = service.RetrieveMultiple(new FetchExpression(string.Format(@"<fetch version='1.0' output-format='xml-platform' mapping='logical' distinct='false' no-lock='true'>
                                        <entity name='aspect_cxbot'>
                                        <attribute name='aspect_cxbotid' />
                                        <attribute name='aspect_name' />
                                        <attribute name='createdon' />
                                        <order attribute='aspect_name' descending='false' />
                                        <filter type='and'>
                                            <filter type='or'>
                                            <condition attribute='aspect_name' operator='eq' value='{0}' />
                                            <condition attribute='aspect_default' operator='eq' value='1' />
                                            </filter>
                                        </filter>
                                        </entity>
                                    </fetch>", address.Bot == null ? string.Empty : address.Bot)));

                        if (botResults.Entities.Count() == 0)
                        {
                            var responseMessage = activity.CreateReply();
                            responseMessage.Text  = "There is currently no default CX bot configured in your environment or the bot speicified does not exist.";
                            responseMessage.Speak = "There is currently no default CX bot configured in your environment or the bot speicified does not exist.";
                            ResourceResponse msgResponse = connector.Conversations.ReplyToActivity(responseMessage);
                            return(new HttpResponseMessage(System.Net.HttpStatusCode.Accepted));
                        }

                        Xrm.Sdk.Entity cxBot           = botResults.Entities[0];
                        var            namedMatchedBot = (from b in botResults.Entities where (string)b["aspect_name"] == address.Address select b);
                        if (namedMatchedBot.Count() > 0)
                        {
                            cxBot = namedMatchedBot.First();
                        }



                        //get first step
                        Xrm.Sdk.Entity cxCurrentStep = service.RetrieveMultiple(new FetchExpression(string.Format(@"<fetch mapping='logical' version='1.0' distinct='false' output-format='xml-platform' no-lock='true'>
                                        <entity name='aspect_cxstep'>
                                        <all-attributes />
                                        <link-entity name='aspect_cxbot' to='aspect_cxbotid' from='aspect_cxbotid' alias='aspect_cxbot'>
                                            <all-attributes />
                                        </link-entity>
                                        <order descending='false' attribute='aspect_name' />
                                        <filter type='and'>
                                            <condition value='1' attribute='aspect_root' operator='eq' />
                                            <condition value='{0}' attribute='aspect_cxbotid' operator='eq' />
                                        </filter>
                                        </entity>
                                    </fetch>", cxBot.Id))).Entities[0];


                        //create initial conversation
                        Xrm.Sdk.Entity cxConversation = new Xrm.Sdk.Entity("aspect_cxconversation", "aspect_conversationid", activity.Conversation.Id);
                        cxConversation["aspect_name"]            = activity.Conversation.Id;
                        cxConversation["aspect_from"]            = address.Address;
                        cxConversation["aspect_lastanswer"]      = address.Message;
                        cxConversation["aspect_cxbotid"]         = new EntityReference(cxBot.LogicalName, cxBot.Id);
                        cxConversation["aspect_currentcxstepid"] = new EntityReference(cxCurrentStep.LogicalName, cxCurrentStep.Id);
                        UpsertResponse cxConversationResponse = (UpsertResponse)service.Execute(new UpsertRequest()
                        {
                            Target = cxConversation
                        });

                        if (!string.IsNullOrEmpty(address.Message))
                        {
                            //Create a conversation message with the initial
                            Xrm.Sdk.Entity conversationClient = new Xrm.Sdk.Entity("aspect_cxconversationmessage");
                            conversationClient["aspect_cxconversationid"] = new EntityReference("aspect_cxconversation", "aspect_conversationid", activity.Conversation.Id);
                            conversationClient["aspect_cxstepid"]         = new EntityReference(cxCurrentStep.LogicalName, cxCurrentStep.Id);
                            conversationClient["aspect_direction"]        = false;
                            conversationClient["aspect_name"]             = activity.Conversation.Id;
                            service.Create(conversationClient);
                        }


                        //ROUTE TO NEXT QUESTION
                        while (cxCurrentStep != null)
                        {
                            //FIRE ENTRY SEARCHES
                            Dynamics.ExecuteSearch(service, (EntityReference)cxConversationResponse.Results["Target"], new EntityReference(cxCurrentStep.LogicalName, cxCurrentStep.Id), true);

                            //FIRE ENTRY WORKFLOW
                            Dynamics.FireWorkflow(service, cxCurrentStep, false);


                            switch (Dynamics.CXGetType((OptionSetValue)cxCurrentStep["aspect_type"]))
                            {
                            case "MESSAGE":
                                var cxNextStep = await Dynamics.PromptInitialQuestion(activity
                                                                                      , connector
                                                                                      , service
                                                                                      , new Xrm.Sdk.Entity(((EntityReference)cxConversationResponse.Results["Target"]).LogicalName)
                                {
                                    Id = ((EntityReference)cxConversationResponse.Results["Target"]).Id
                                }
                                                                                      , cxCurrentStep);

                                if (cxNextStep != null)
                                {
                                    cxCurrentStep = service.RetrieveMultiple(new FetchExpression(string.Format(@"<fetch mapping='logical' version='1.0' distinct='false' output-format='xml-platform' no-lock='true'>
                                                            <entity name='aspect_cxstep'>
                                                            <all-attributes />
                                                            <link-entity name='aspect_cxbot' to='aspect_cxbotid' from='aspect_cxbotid' alias='aspect_cxbot'>
                                                                <all-attributes />
                                                            </link-entity>
                                                            <filter type='and'>
                                                                <condition value='{0}' attribute='aspect_cxstepid' operator='eq' />
                                                            </filter>
                                                            </entity>
                                                        </fetch>", cxNextStep.Id))).Entities[0];
                                }
                                break;

                            case "QUESTION":
                            case "MENU":
                            case "RECORD":
                            case "TRANSFER":
                                if (cxCurrentStep != null)
                                {
                                    await Dynamics.PromptInitialQuestion(activity
                                                                         , connector
                                                                         , service
                                                                         , new Xrm.Sdk.Entity(((EntityReference)cxConversationResponse.Results["Target"]).LogicalName)
                                    {
                                        Id = ((EntityReference)cxConversationResponse.Results["Target"]).Id
                                    }
                                                                         , cxCurrentStep);

                                    cxCurrentStep = null;
                                }
                                break;
                            }
                        }
                    }
                }

                await HandleSystemMessage(activity);
            }
            else
            {
                await HandleSystemMessage(activity);
            }

            return(new HttpResponseMessage(System.Net.HttpStatusCode.Accepted));
        }
Ejemplo n.º 16
0
        public async Task MessageReceivedAsync(IDialogContext context, IAwaitable <IMessageActivity> argument)
        {
            var message = await argument;


            IOrganizationService service = Dynamics.GetService();


            //Get the current and next step
            Xrm.Sdk.Entity  cxCurrentStep = Dynamics.GetCXCurrentStepEntityByConversationId(service, message.Conversation.Id);
            EntityReference cxNextStep    = cxCurrentStep.Contains("aspect_nextcxstepid") ? (EntityReference)cxCurrentStep["aspect_nextcxstepid"] : null;


            //Create a conversation message with the users response
            Xrm.Sdk.Entity conversationClient = new Xrm.Sdk.Entity("aspect_cxconversationmessage");
            conversationClient["aspect_cxconversationid"] = new EntityReference("aspect_cxconversation", "aspect_conversationid", message.Conversation.Id);
            conversationClient["aspect_cxstepid"]         = new EntityReference(cxCurrentStep.LogicalName, cxCurrentStep.Id);
            conversationClient["aspect_direction"]        = false;
            conversationClient["aspect_name"]             = message.Id;
            conversationClient["aspect_message"]          = message.Text;
            service.Create(conversationClient);


            //TODO: Check global utterances
            Xrm.Sdk.Entity globalUtterance = service.RetrieveMultiple(new FetchExpression(string.Format(@"<fetch mapping='logical' version='1.0' distinct='false' output-format='xml-platform' no-lock='true'>
                                                      <entity name='aspect_cxglobalutterance'>
                                                        <attribute name='aspect_cxglobalutteranceid' />
                                                        <attribute name='aspect_cxstepid' />
                                                        <attribute name='aspect_answers' />
                                                        <order descending='false' attribute='aspect_name' />
                                                        <filter type='and'>
                                                          <condition value='%{0}%' attribute='aspect_answers' operator='like' />
                                                        </filter>
                                                      </entity>
                                                    </fetch>", HttpUtility.UrlEncode(message.Text)))).Entities.FirstOrDefault();


            if (globalUtterance != null)
            {
                cxNextStep = (EntityReference)globalUtterance["aspect_cxstepid"];
            }
            else
            {
                //validate user input
                string utteranceMatch = UtteranceMatch(message.Text, (string)(cxCurrentStep.Contains("aspect_answers") ? (string)cxCurrentStep["aspect_answers"] : null));
                if (Dynamics.CXGetType((OptionSetValue)cxCurrentStep["aspect_type"]) == "MENU")
                {
                    Xrm.Sdk.EntityCollection cxStepAnswers = service.RetrieveMultiple(new FetchExpression(string.Format(@"<fetch mapping='logical' version='1.0' distinct='false' output-format='xml-platform' no-lock='true'>
                                                    <entity name='aspect_cxstepanswer'>
                                                    <all-attributes />
                                                    <order descending='false' attribute='aspect_name' />
                                                    <filter type='and'>
                                                        <condition value='{0}' attribute='aspect_cxstepid' operator='eq' />
                                                    </filter>
                                                    </entity>
                                                </fetch>", cxCurrentStep.Id)));

                    foreach (Xrm.Sdk.Entity e in cxStepAnswers.Entities)
                    {
                        utteranceMatch = UtteranceMatch(message.Text, e.Contains("aspect_answers") ? (string)e["aspect_answers"] : null);
                        if (!string.IsNullOrEmpty(utteranceMatch))
                        {
                            cxNextStep = e.Contains("aspect_nextcxstepid") ? (EntityReference)e["aspect_nextcxstepid"] : null;
                            break;
                        }
                    }
                }

                if (utteranceMatch == null)
                {
                    string         noMatchMessage  = string.Format("I'm sorry, I didn't understand '{0}'.", message.Text); //TODO make this message come from CX Bot
                    Xrm.Sdk.Entity noMatchResponse = new Xrm.Sdk.Entity("aspect_cxconversationmessage");
                    conversationClient["aspect_cxconversationid"] = new EntityReference("aspect_cxconversation", "aspect_conversationid", message.Conversation.Id);
                    conversationClient["aspect_cxstepid"]         = new EntityReference(cxCurrentStep.LogicalName, cxCurrentStep.Id);
                    conversationClient["aspect_direction"]        = true;
                    conversationClient["aspect_name"]             = message.Id;
                    conversationClient["aspect_message"]          = noMatchMessage;
                    service.Create(conversationClient);

                    IMessageActivity responseNoMatchMessage = context.MakeMessage();
                    responseNoMatchMessage.Text  = string.Format(noMatchMessage);
                    responseNoMatchMessage.Value = message.Value;
                    await context.PostAsync(responseNoMatchMessage);

                    context.Wait(MessageReceivedAsync);
                    return;
                }
            }


            //Update the last answer in the conversation
            Microsoft.Xrm.Sdk.Entity upsConversation2 = new Microsoft.Xrm.Sdk.Entity("aspect_cxconversation", "aspect_conversationid", message.Conversation.Id);
            upsConversation2["aspect_lastanswer"] = message.Text;
            UpsertResponse cxConversationResponse = (UpsertResponse)service.Execute(new UpsertRequest()
            {
                Target = upsConversation2
            });


            int maxLoopCount     = 10;
            int currentLoopCount = 0;


            //EXECUTE EXIT SEARCH
            Dynamics.ExecuteSearch(service, (EntityReference)cxConversationResponse.Results["Target"], new EntityReference(cxCurrentStep.LogicalName, cxCurrentStep.Id), false);

            //FIRE EXIT WORKFLOW
            Dynamics.FireWorkflow(service, cxCurrentStep, false);

            //REFRESH THE NEXT CX STEP IN CASE A SEARCH/WORKFLOW ALTERED IT
            Xrm.Sdk.Entity rerouteCXStep = Dynamics.GetCXNextStepEntityByConversationId(service, message.Conversation.Id, cxNextStep);

            if (rerouteCXStep != null)
            {
                cxNextStep = new EntityReference(rerouteCXStep.LogicalName, rerouteCXStep.Id);
            }

            while (cxNextStep != null && currentLoopCount <= maxLoopCount)
            {
                if (currentLoopCount > 0)
                {
                    //EXECUTE EXIT SEARCH
                    Dynamics.ExecuteSearch(service, (EntityReference)cxConversationResponse.Results["Target"], new EntityReference(cxCurrentStep.LogicalName, cxCurrentStep.Id), false);

                    //FIRE EXIT WORKFLOW
                    Dynamics.FireWorkflow(service, cxCurrentStep, false);

                    //REFRESH THE NEXT CX STEP IN CASE A SEARCH/WORKFLOW ALTERED IT
                    rerouteCXStep = Dynamics.GetCXNextStepEntityByConversationId(service, message.Conversation.Id, cxNextStep);
                }

                //EXIT IF THERE IS NO NEXT STEP
                if (cxNextStep == null)
                {
                    return;
                }

                //FIRE ENTRY WORKFLOW
                Dynamics.FireWorkflow(service, rerouteCXStep, true);

                //EXECUTE ENTRY SEARCH
                Dynamics.ExecuteSearch(service, (EntityReference)cxConversationResponse.Results["Target"], new EntityReference(rerouteCXStep.LogicalName, rerouteCXStep.Id), true);


                //process question
                switch (Dynamics.CXGetType((OptionSetValue)rerouteCXStep["aspect_type"]))
                {
                case "MESSAGE":
                    await Dynamics.PromptNextQuestion(context, service, cxCurrentStep, rerouteCXStep, message);

                    cxCurrentStep = Dynamics.GetCXCurrentStepEntityByConversationId(service, message.Conversation.Id);
                    cxNextStep    = cxCurrentStep.Contains("aspect_nextcxstepid") ? (EntityReference)cxCurrentStep["aspect_nextcxstepid"] : null;
                    if (cxNextStep == null)
                    {
                        //if the path ended with a search but no default next step execute the exit workflows
                        //EXECUTE EXIT SEARCH
                        Dynamics.ExecuteSearch(service, (EntityReference)cxConversationResponse.Results["Target"], new EntityReference(cxCurrentStep.LogicalName, cxCurrentStep.Id), false);
                        //REFRESH THE NEXT CX STEP IN CASE A SEARCH/WORKFLOW ALTERED IT
                        rerouteCXStep = Dynamics.GetCXNextStepEntityByConversationId(service, message.Conversation.Id, cxNextStep);
                        if (rerouteCXStep != null && rerouteCXStep.Id != cxCurrentStep.Id)
                        {
                            cxNextStep = new EntityReference(rerouteCXStep.LogicalName, rerouteCXStep.Id);
                        }
                    }
                    currentLoopCount++;
                    break;

                case "QUESTION":
                case "MENU":
                case "RECORD":
                case "TRANSFER":
                    await Dynamics.PromptNextQuestion(context, service, cxCurrentStep, rerouteCXStep, message);

                    cxNextStep = null;
                    break;
                }
            }

            context.Wait(MessageReceivedAsync);
        }