Example #1
0
        static void Main(string[] args)
        {
            Program app = new Program();

            try
            {
                String[] arguments = Environment.GetCommandLineArgs();
                app.httpClient = CrmAPIHelper.CreateConnection(arguments);
                app.RegisterWebHook();
            }
            catch (System.Exception ex)
            {
                DisplayException(ex);
            }
            finally
            {
                if (app.httpClient != null)
                {
                    app.httpClient.Dispose();
                }
            }
        }
Example #2
0
        private void RegisterWebHook()
        {
            //create a service endpoint
            var webhookUrl = "https://requestbin.fullcontact.com/1ei5sfk1";
            // header values -- not needed for request bin but added here to demonstrate the xml structure
            XmlDocument xmlDocument = new XmlDocument();
            XmlElement  xmlElement  = xmlDocument.CreateElement("settings");
            XmlElement  xmlElement1 = xmlDocument.CreateElement("setting");

            xmlElement1.SetAttribute("name", "Test-Auth-Header");
            xmlElement1.SetAttribute("value", "SECRETKEY");
            xmlElement.AppendChild(xmlElement1);
            xmlDocument.AppendChild(xmlElement);
            var authValue = xmlDocument.InnerXml.ToString();

            // replace with desired name for web hook service endpoint
            var webhookName = Guid.NewGuid().ToString();

            var serviceEndpoint = new JObject();

            serviceEndpoint.Add("authvalue", authValue);
            serviceEndpoint.Add("authtype", 5);
            serviceEndpoint.Add("connectionmode", 1);
            serviceEndpoint.Add("contract", 8);
            serviceEndpoint.Add("name", webhookName);
            serviceEndpoint.Add("url", webhookUrl);

            string jsonContent = serviceEndpoint.ToString(); // for debug

            StringContent requestContent = new StringContent(serviceEndpoint.ToString(), Encoding.UTF8, "application/json");
            var           response       = httpClient.PostAsync("serviceendpoints", requestContent).Result;

            if (!response.IsSuccessStatusCode)
            {
                Console.WriteLine("The create service endpoint request failed with a status of '{0}'",
                                  response.ReasonPhrase);
            }
            else if (response.Headers.Contains("OData-EntityId"))
            {
                var serviceendpointUrl = response.Headers.GetValues("OData-EntityId").FirstOrDefault();
                serviceendpointUrl = serviceendpointUrl.Substring(serviceendpointUrl.LastIndexOf('/'));

                // Retrieve the plugintype, sdkmessage, and sdkmessagefilter data we will need to create the webhook triggers
                JObject webhookPluginType;
                webhookPluginType = CrmAPIHelper.RetrieveSingleRecord(httpClient, "plugintypes", new string[] { "plugintypeid" }, "name eq 'Microsoft.Crm.Servicebus.WebHookPlugin'");

                JObject updateMessage;
                updateMessage = CrmAPIHelper.RetrieveSingleRecord(httpClient, "sdkmessages", new string[] { "sdkmessageid" }, "name eq 'Update'");

                JObject updateMessageFilter;
                updateMessageFilter = CrmAPIHelper.RetrieveSingleRecord(httpClient,
                                                                        "sdkmessagefilters",
                                                                        new string[] { "sdkmessagefilterid" },
                                                                        $"primaryobjecttypecode eq 'opportunity' and sdkmessageid/sdkmessageid eq { updateMessage["sdkmessageid"] }");

                JObject createMessage;
                createMessage = CrmAPIHelper.RetrieveSingleRecord(httpClient, "sdkmessages", new string[] { "sdkmessageid" }, "name eq 'Create'");

                JObject createMessageFilter;
                createMessageFilter = CrmAPIHelper.RetrieveSingleRecord(httpClient,
                                                                        "sdkmessagefilters",
                                                                        new string[] { "sdkmessagefilterid" },
                                                                        $"primaryobjecttypecode eq 'opportunity' and sdkmessageid/sdkmessageid eq { createMessage["sdkmessageid"] }");


                // Processing steps that should trigger the webhook
                // Trigger on update of opportunity fields name (topic) and budgetamount
                var updateStep = new JObject();
                updateStep.Add("asyncautodelete", false); // Change to true for production!!
                updateStep.Add("filteringattributes", "name,budgetamount");
                updateStep.Add("mode", 1);
                updateStep.Add("name", $"{webhookName} opportunity update");
                updateStep.Add("description", $"{webhookName} opportunity update");
                updateStep.Add("rank", 1);
                updateStep.Add("stage", 40);
                updateStep.Add("supporteddeployment", 0);
                updateStep.Add("*****@*****.**", $"/sdkmessagefilters({ updateMessageFilter["sdkmessagefilterid"].ToString() })");
                updateStep.Add("*****@*****.**", $"/sdkmessages({ updateMessage["sdkmessageid"].ToString() })");
                updateStep.Add("*****@*****.**", serviceendpointUrl);

                jsonContent = updateStep.ToString(); // for debug

                requestContent = new StringContent(updateStep.ToString(), Encoding.UTF8, "application/json");
                response       = httpClient.PostAsync("sdkmessageprocessingsteps", requestContent).Result;
                if (!response.IsSuccessStatusCode)
                {
                    Console.WriteLine("The update opportunity trigger request failed with a status of '{0}'",
                                      response.ReasonPhrase);
                }

                var createStep = new JObject();
                createStep.Add("asyncautodelete", false); // Change to true for production!!
                createStep.Add("mode", 1);
                createStep.Add("name", $"{webhookName} opportunity create");
                createStep.Add("description", $"{webhookName} opportunity create");
                createStep.Add("rank", 1);
                createStep.Add("stage", 40);
                createStep.Add("supporteddeployment", 0);
                createStep.Add("*****@*****.**", $"/sdkmessagefilters({ createMessageFilter["sdkmessagefilterid"].ToString() })");
                createStep.Add("*****@*****.**", $"/sdkmessages({ createMessage["sdkmessageid"].ToString() })");
                createStep.Add("*****@*****.**", $"/plugintypes({ webhookPluginType["plugintypeid"].ToString() })");
                createStep.Add("*****@*****.**", serviceendpointUrl);

                jsonContent = createStep.ToString(); // for debug

                requestContent = new StringContent(createStep.ToString(), Encoding.UTF8, "application/json");
                response       = httpClient.PostAsync("sdkmessageprocessingsteps", requestContent).Result;
                if (!response.IsSuccessStatusCode)
                {
                    Console.WriteLine("The create opportunity trigger request failed with a status of '{0}'",
                                      response.ReasonPhrase);
                }
            }
        }
Example #3
0
        private void OpportunityCurrencyExample()
        {
            StringContent       requestContent;
            HttpResponseMessage response;

            // Issue WhoAmI request to get the organization ID
            response = httpClient.GetAsync("WhoAmI", HttpCompletionOption.ResponseContentRead).Result;
            var organizationId = JsonConvert.DeserializeObject <JObject>(response.Content.ReadAsStringAsync().Result)["OrganizationId"].ToString();

            // Retrieve the base currency ID for the organization
            response = httpClient.GetAsync($"organizations({ organizationId })?$expand=basecurrencyid($select=transactioncurrencyid,currencysymbol,exchangerate,isocurrencycode)").Result;
            var baseCurrency = (JObject)JsonConvert.DeserializeObject <JObject>(response.Content.ReadAsStringAsync().Result)["basecurrencyid"];

            // Retrieve the USD and CAD currencies
            response = httpClient.GetAsync("transactioncurrencies?$select=transactioncurrencyid,currencysymbol,isocurrencycode,exchangerate&$filter=isocurrencycode eq 'CAD' or isocurrencycode eq 'USD'").Result;
            JObject cad = null;
            JObject usd = null;

            if (response.StatusCode == HttpStatusCode.OK) //200
            {
                JObject body = JsonConvert.DeserializeObject <JObject>
                                   (response.Content.ReadAsStringAsync().Result);

                if (!body.ContainsKey("value") || body["value"] == null || !body["value"].Any() || body["value"].Count() != 2)
                {
                    throw new Exception("Could not retrieve currencies");
                }
                else
                {
                    foreach (var currency in body["value"])
                    {
                        if (currency["isocurrencycode"].ToString() == "USD")
                        {
                            usd = (JObject)currency;
                        }
                        else
                        {
                            cad = (JObject)currency;
                        }
                    }
                }

                if (usd == null || cad == null)
                {
                    throw new Exception("Could not retrieve currencies");
                }
            }
            else
            {
                throw new CrmHttpResponseException(response.Content);
            }


            // Create the potential customer for our opportunity if it does not already exist
            var    accountName = "Canadian Account";
            string accountUrl  = "";
            var    account     = CrmAPIHelper.RetrieveSingleRecord(httpClient, "accounts", new string[] { "accountid" }, $"name eq '{ accountName }'");

            if (account == null)
            {
                account = new JObject();
                account.Add("accountid", Guid.NewGuid());
                account.Add("name", accountName);
                account.Add("*****@*****.**", $"/transactioncurrencies({ cad["transactioncurrencyid"].ToString() })");

                requestContent = new StringContent(account.ToString(), Encoding.UTF8, "application/json");
                response       = httpClient.PostAsync("accounts", requestContent).Result;

                if (!response.IsSuccessStatusCode)
                {
                    throw new Exception($"The request failed with a status of '{ response.ReasonPhrase }'");
                }
                else
                {
                    accountUrl = response.Headers.GetValues("OData-EntityId").FirstOrDefault();
                    accountUrl = accountUrl.Substring(accountUrl.LastIndexOf('/'));
                }
            }
            else
            {
                accountUrl = $"/accounts({ account["accountid"].ToString() })";
            }


            // Create an opportunity with an associated competitor
            var opportunityName = $"Canadian Opportunity { Guid.NewGuid().ToString() }";
            var opportunity     = new JObject();

            opportunity.Add("name", opportunityName);
            opportunity.Add("budgetamount", 1000);
            opportunity.Add("*****@*****.**", accountUrl);
            opportunity.Add("*****@*****.**", $"/transactioncurrencies({ cad["transactioncurrencyid"].ToString() })");

            // Create 3 competitors with the opportunity in a deep insert
            JArray competitors = new JArray();

            for (int i = 0; i < 3; i++)
            {
                var competitor = new JObject();
                competitor.Add("name", "Competitor " + Guid.NewGuid().ToString());
                competitors.Add(competitor);
            }
            opportunity.Add("opportunitycompetitors_association", competitors);

            /* example of the json body for this request:
             * {
             * "name": "Canadian Opportunity 1b28859f-4c9c-451a-b25a-67bf79bb8908",
             * "budgetamount": 1000,
             * "*****@*****.**": "/accounts(585d24d8-9d7d-4553-b2b6-e8c225e24f69)",
             * "*****@*****.**": "/transactioncurrencies(31aab109-0e05-e911-a95f-000d3a1ccf71)",
             * "opportunitycompetitors_association": [
             *  {
             *    "name": "Competitor ae862edf-2683-4bb1-b11c-4745052e4801"
             *  },
             *  {
             *    "name": "Competitor 1a82e99d-0294-47a9-8c35-606ecdc85151"
             *  },
             *  {
             *    "name": "Competitor 8699c39e-93ab-4566-9742-890d1ff3827b"
             *  }
             * ]
             * }
             */

            requestContent = new StringContent(opportunity.ToString(), Encoding.UTF8, "application/json");
            response       = httpClient.PostAsync("opportunities", requestContent).Result;

            if (!response.IsSuccessStatusCode)
            {
                throw new Exception($"The request failed with a status of '{ response.ReasonPhrase }'");
            }
            else if (response.Headers.Contains("OData-EntityId"))
            {
                var opportunityUrl = response.Headers.GetValues("OData-EntityId").FirstOrDefault();

                // Retrieve the opportunity, expanding the competitors collection so we can get the identifiers for them.
                // Let's also treat this like we are exporting an opportunity from Dynamics and we want to convert the
                // currency to USD, so we'll also expand the transaction currency so we can get the up-to-date exchange rate
                response = httpClient.GetAsync(opportunityUrl + "?$select=name,budgetamount&$expand=transactioncurrencyid($select=exchangerate,isocurrencycode,currencysymbol),opportunitycompetitors_association($select=name,competitorid)").Result;

                opportunity = JsonConvert.DeserializeObject <JObject>(response.Content.ReadAsStringAsync().Result);
                Console.WriteLine($"Created opportunity \"{ opportunity["name"] }\" with ID { opportunity["opportunityid"] }");
                Console.WriteLine();

                competitors = (JArray)opportunity["opportunitycompetitors_association"];
                Console.WriteLine("Created competitors:");
                foreach (var competitorResult in competitors)
                {
                    var competitor = (JObject)competitorResult;
                    Console.WriteLine($"Competitor name: \"{ competitor["name"] }\", ID: { competitor["competitorid"] }");
                }
                Console.WriteLine();

                var opportunityCurrency = (JObject)opportunity["transactioncurrencyid"];
                Console.WriteLine($"The opportunity has a currency of { opportunityCurrency["isocurrencycode"] } and a budget amount of { opportunityCurrency["currencysymbol"] }{ opportunity["budgetamount"] }");
                Console.WriteLine();

                // Convert to the base currency
                var budgetAmount         = Convert.ToDecimal(opportunity["budgetamount"]);
                var toBaseExchangeRate   = Convert.ToDecimal(opportunityCurrency["exchangerate"]);
                var budgetInBaseCurrency = Math.Round(budgetAmount / toBaseExchangeRate, 2);
                Console.WriteLine($"Budget amount converted to base currency of { baseCurrency["isocurrencycode"] } is: { baseCurrency["currencysymbol"] }{ budgetInBaseCurrency }");

                // Convert to USD
                var toUsdExchangeRate = Convert.ToDecimal(usd["exchangerate"]);
                var budgetInUsd       = budgetInBaseCurrency * toUsdExchangeRate;
                Console.WriteLine($"Budget amount converted to USD is: ${ budgetInUsd }");
            }
        }