コード例 #1
0
        public Task <Object> Handle(AddInvoiceExceptionRecordToAirtableCommand request, CancellationToken cancellationToken)
        {
            const string airtableApiKey          = "keyouw8CITeZrgZqx";
            const string invoiceExceptionBaseKey = "appq4DBeNHZdRSoa1";

            var airTableBase = new AirtableBase(airtableApiKey, invoiceExceptionBaseKey);

            var airtableFields = new Fields();

            if (request.FlaggedJob != null)
            {
                airtableFields.FieldsCollection.Add("job_id", request.FlaggedJob.FlaggedJobId.ToString());
                airtableFields.FieldsCollection.Add("flagged_material_code", request.FlaggedJob.FlaggedMaterialCode);
                airtableFields.FieldsCollection.Add("technician_name", request.FlaggedJob.TechnicianName);
                airtableFields.FieldsCollection.Add("job_completed_date", DateTime.Parse(request.FlaggedJob.JobCompletedDate));
                airtableFields.FieldsCollection.Add("job_url", "https://go.servicetitan.com/#/Job/Index/" + request.FlaggedJob.FlaggedJobId.ToString());
                airtableFields.FieldsCollection.Add("service_code", request.FlaggedJob.ServiceCode);
            }
            if (request.InvoiceError != null)
            {
                airtableFields.FieldsCollection.Add("job_id", request.InvoiceError.FlaggedJobId.ToString());
                airtableFields.FieldsCollection.Add("flagged_material_code", request.InvoiceError.FlaggedMaterialCode);
                airtableFields.FieldsCollection.Add("technician_name", request.InvoiceError.TechnicianName);
                airtableFields.FieldsCollection.Add("job_completed_date", DateTime.Parse(request.InvoiceError.JobCompletedDate));
                airtableFields.FieldsCollection.Add("job_url", "https://go.servicetitan.com/#/Job/Index/" + request.InvoiceError.FlaggedJobId.ToString());
                airtableFields.FieldsCollection.Add("service_code", request.InvoiceError.ServiceCode);
            }

            var result = airTableBase.CreateRecord("exception_list", airtableFields, true).Result;


            return(Task.FromResult <Object>(result));
        }
コード例 #2
0
        //

        public async Task CreateRecordMethodAsync(AirtableBase airtableBase)
        {
            Task <AirtableCreateUpdateReplaceRecordResponse> task = airtableBase.CreateRecord(tablename, fields, conversion);
            var response = await task;


            OutRecord = response.Record;


            if (response.AirtableApiError.ErrorMessage != null)
            {
                // Error reporting
                errorMessageString = response.AirtableApiError.ErrorMessage;
            }
            else
            {
                // Do something with the retrieved 'record'
                errorMessageString = "Success!";
                OutRecord          = response.Record;
            }

            if (response.Success == true)
            {
                errorMessageString = "Success!";
            }
        }
コード例 #3
0
        public async Task <ResponseModel> AddRecord(RequestModel request, string appKey, string baseId)
        {
            var responseModel = new ResponseModel
            {
                ID         = Utilities.GenerateID(),
                Title      = request.Title,
                Text       = request.Text,
                ReceivedAt = DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ss.fffZ"),
            };

            using AirtableBase airtableBase = new AirtableBase(appKey, baseId);
            var fields = new Fields();

            fields.AddField("id", responseModel.ID);
            fields.AddField("Summary", responseModel.Title);
            fields.AddField("Message", responseModel.Text);
            fields.AddField("receivedAt", responseModel.ReceivedAt);

            Task <AirtableCreateUpdateReplaceRecordResponse> task = airtableBase.CreateRecord("Messages", fields);

            AirtableCreateUpdateReplaceRecordResponse response = await task;

            if (response.Success)
            {
                return(responseModel);
            }
            else if (response.AirtableApiError is AirtableApiException)
            {
                throw new InvalidOperationException(response.AirtableApiError.ErrorMessage);
            }
            else
            {
                throw new InvalidOperationException("Unknown error");
            }
        }
コード例 #4
0
        public static async Task ReportScores(Set set, double gain, double loss)
        {
            using (AirtableBase airtableBase = new AirtableBase(Globals.BotSettings.AppKey, Globals.BotSettings.BaseId))
            {
                Fields fields = new Fields();

                string[] alphaPlayers = set.AlphaTeam.Players.Select(e => e.AirtableId).ToArray();
                string[] bravoPlayers = set.BravoTeam.Players.Select(e => e.AirtableId).ToArray();

                fields.AddField("Date", DateTime.Now);
                fields.AddField("Alpha Players", alphaPlayers);
                fields.AddField("Bravo Players", bravoPlayers);
                fields.AddField("Alpha Score", set.AlphaTeam.Score);
                fields.AddField("Bravo Score", set.BravoTeam.Score);
                fields.AddField("Gain", gain);
                fields.AddField("Loss", loss);
                fields.AddField("A SZ",
                                set.AlphaTeam.OrderedMatchResults
                                .Select((e, index) => new { Score = e, set.Stages[index].Mode })
                                .Where(e => e.Score == 1 && e.Mode == GameMode.SplatZones)
                                .Aggregate(0, (e, f) => e + f.Score));
                fields.AddField("B SZ",
                                set.BravoTeam.OrderedMatchResults
                                .Select((e, index) => new { Score = e, set.Stages[index].Mode })
                                .Where(e => e.Score == 1 && e.Mode == GameMode.SplatZones)
                                .Aggregate(0, (e, f) => e + f.Score));
                fields.AddField("A TC",
                                set.AlphaTeam.OrderedMatchResults
                                .Select((e, index) => new { Score = e, set.Stages[index].Mode })
                                .Where(e => e.Score == 1 && e.Mode == GameMode.TowerControl)
                                .Aggregate(0, (e, f) => e + f.Score));
                fields.AddField("B TC",
                                set.BravoTeam.OrderedMatchResults
                                .Select((e, index) => new { Score = e, set.Stages[index].Mode })
                                .Where(e => e.Score == 1 && e.Mode == GameMode.TowerControl)
                                .Aggregate(0, (e, f) => e + f.Score));
                fields.AddField("A RM",
                                set.AlphaTeam.OrderedMatchResults
                                .Select((e, index) => new { Score = e, set.Stages[index].Mode })
                                .Where(e => e.Score == 1 && e.Mode == GameMode.Rainmaker)
                                .Aggregate(0, (e, f) => e + f.Score));
                fields.AddField("B RM",
                                set.BravoTeam.OrderedMatchResults
                                .Select((e, index) => new { Score = e, set.Stages[index].Mode })
                                .Where(e => e.Score == 1 && e.Mode == GameMode.Rainmaker)
                                .Aggregate(0, (e, f) => e + f.Score));
                fields.AddField("A CB",
                                set.AlphaTeam.OrderedMatchResults
                                .Select((e, index) => new { Score = e, set.Stages[index].Mode })
                                .Where(e => e.Score == 1 && e.Mode == GameMode.ClamBlitz)
                                .Aggregate(0, (e, f) => e + f.Score));
                fields.AddField("B CB",
                                set.BravoTeam.OrderedMatchResults
                                .Select((e, index) => new { Score = e, set.Stages[index].Mode })
                                .Where(e => e.Score == 1 && e.Mode == GameMode.ClamBlitz)
                                .Aggregate(0, (e, f) => e + f.Score));

                await airtableBase.CreateRecord("Draft Log", fields, true);
            }
        }
コード例 #5
0
        //=========================== CREATE/POST ===========================================
        public async Task <AirtableCreateUpdateReplaceRecordResponse> Create(RecordCreateRequest req)
        {
            using (AirtableBase airtableBase = new AirtableBase(appKey, baseId))
            {
                var fields = new Fields();
                fields.AddField("Title", req.Title);
                fields.AddField("Priority", req.Priority);
                fields.AddField("Status", req.Status);
                fields.AddField("Due Date", req.DueDate);

                AirtableCreateUpdateReplaceRecordResponse response = await airtableBase.CreateRecord(tableName, fields, true);

                if (!response.Success)
                {
                    if (response.AirtableApiError is AirtableApiException)
                    {
                        errorMessage = response.AirtableApiError.ErrorMessage;
                    }
                    else
                    {
                        errorMessage = "Unknown error";
                    }
                    // Report errorMessage
                }
                else
                {
                    // Do something with your created record.
                    Console.WriteLine("ok");
                }
                return(response);
            }
        }
コード例 #6
0
        public async Task <IActionResult> Get()
        {
            var host      = Request.Host.ToString();
            var isMobile  = _deviceResolver.Device.Type == DeviceType.Mobile;
            var isCrawler = _crawlerResolver.Crawler != null;
            var type      = isMobile ? "Mobile Redirection" : "Desktop Redirection";
            var ip        = HttpContext.Connection.RemoteIpAddress?.ToString();
            var userAgent = Request.Headers["User-Agent"].ToString();
            var referer   = Request.Headers["Referer"].ToString();
            var hasEntry  = _memoryCache.TryGetValue <DomainMappingValue>(host, out var value);

            _ = Task.Run(async() =>
            {
                using var airtableBaseInTask =
                          new AirtableBase(_configuration["Airtable:Key"], _configuration["Airtable:Base"]);
                await airtableBaseInTask.CreateRecord("Views", new Fields
                {
                    FieldsCollection = new Dictionary <string, object>
                    {
                        ["BaseDomain"]   = host,
                        ["Ip"]           = ip,
                        ["UserAgent"]    = userAgent,
                        ["RedirectedTo"] = isMobile ? "Mobile" : "Desktop",
                        ["Referrer"]     = referer
                    }
                });
            });

            if (isCrawler && hasEntry)
            {
                var content = isMobile ? value.Mobile.Html : value.Desktop.Html;
                return(Content(content, "text/html"));
            }
            else
            {
                using var airtableBase =
                          new AirtableBase(_configuration["Airtable:Key"], _configuration["Airtable:Base"]);
                var response = await airtableBase.ListRecords(
                    "Redirections", fields : new[] { type }, filterByFormula : "{Base Address} = '" + host + "'",
                    view : "Main", maxRecords : 1);

                if (!response.Success)
                {
                    return(BadRequest());
                }

                var airtableRecord = response.Records.FirstOrDefault();
                if (airtableRecord == null)
                {
                    return(BadRequest());
                }
                var address = "https://" + airtableRecord.Fields[type];

                return(base.Redirect(address));
            }
        }
コード例 #7
0
        public async Task CreateAfk(AfkObject data)
        {
            Fields field = new Fields();

            field.AddField("id", data.Id);
            field.AddField("isAfk", data.IsAfk);
            field.AddField("message", data.Message);

            await Base.CreateRecord(table, field);
        }
コード例 #8
0
        public async Task <Thing> CreateThingAsync(Thing thing)
        {
            var response = await Airtable.CreateRecord(TABLE_NAME, thing.GetFields());

            if (response.Success)
            {
                return(new Thing(response.Record));
            }

            return(null);
        }
コード例 #9
0
        public async Task CreateWaifuRecord(WaifuObject data)
        {
            Fields field = new Fields();

            field.AddField("userId", data.Id);
            field.AddField("Waifus", data.Waifus);
            field.AddField("Levels", data.Levels);
            field.AddField("Lewds", data.Lewds);
            field.AddField("Feeds", data.Feeds);
            field.AddField("LastModifiedHour", data.LastModifiedHour);

            await Base.CreateRecord(table, field);
        }
コード例 #10
0
        public async Task CreateCooldowns(CooldownObject data)
        {
            Fields field = new Fields();

            field.AddField("Daily", data.Daily);
            field.AddField("Bless", data.Bless);
            field.AddField("Pluck", data.Pluck);
            field.AddField("Vote", data.Vote);
            field.AddField("Work", data.Work);
            field.AddField("Thievery", data.Thievery);
            field.AddField("userId", data.Id);

            await Base.CreateRecord(table, field);
        }
コード例 #11
0
        public async Task <AirtableCreateUpdateReplaceRecordResponse> CreateRecordAsAsync(LogMessage msg)
        {
            AirtableCreateUpdateReplaceRecordResponse response;

            using (AirtableBase airtableBase = new AirtableBase(appKey, baseId))
            {
                var fields = new Fields();
                fields.AddField(Constants.ID, msg.Id);
                fields.AddField(Constants.SUMMARY, msg.Title);
                fields.AddField(Constants.MESSAGE, msg.Text);
                fields.AddField(Constants.RECEIVEDAT, msg.ReceivedAt);
                Task <AirtableCreateUpdateReplaceRecordResponse> task = airtableBase.CreateRecord("Messages", fields, true);
                response = await task;
            }

            return(response);
        }
コード例 #12
0
        public async Task CreateUserProfile(UserObject data)
        {
            Fields field = new Fields();

            field.AddField("ID", data.Id);
            field.AddField("Disable", data.Disable);
            field.AddField("balance", data.Balance);
            field.AddField("xp", data.Xp);
            field.AddField("level", data.Level);
            field.AddField("votes", data.Votes);
            field.AddField("description", data.Description);
            field.AddField("background", data.Background);
            field.AddField("birthday", data.Birthday);
            field.AddField("marry", data.Marry);
            field.AddField("ownBgName", data.OwnBgNames);
            field.AddField("ownBgUrl", data.OwnBgUrl);
            field.AddField("weekly", data.OwnBgNames);

            await Base.CreateRecord(table, field);
        }
コード例 #13
0
        public static async Task RegisterPlayer(ulong discordId, double startingPowerLevel, string nickname)
        {
            using (AirtableBase airtableBase = new AirtableBase(Globals.BotSettings.AppKey, Globals.BotSettings.BaseId))
            {
                Fields fields = new Fields();
                fields.AddField("Name", nickname);
                fields.AddField("DiscordID", discordId.ToString());
                fields.AddField("Starting Power", startingPowerLevel);

                if ((await GetAllPlayerRecords()).All(e =>
                                                      e.Fields["DiscordID"].ToString() != discordId.ToString(CultureInfo.InvariantCulture)))
                {
                    AirtableCreateUpdateReplaceRecordResponse response =
                        await airtableBase.CreateRecord("Draft Standings", fields, true);

                    if (!response.Success)
                    {
                        Console.WriteLine(response.AirtableApiError.ErrorMessage);
                    }
                }
            }
        }
コード例 #14
0
ファイル: AirtableService.cs プロジェクト: dhnnjy11/AJJ
        public async Task CreateRecordsIntoAirtable()
        {
            using (AirtableBase airtableBase = new AirtableBase(appKey, baseId))
            {
                // Create Attachments list
                //var attachmentList = new List<AirtableAttachment>();
                //attachmentList.Add(new AirtableAttachment { Url = "https://upload.wikimedia.org/wikipedia/en/d/d1/Picasso_three_musicians_moma_2006.jpg" });

                var fields = new Fields();
                fields.AddField("User Email", "Pablo Picasso");
                fields.AddField("Notes", "Spanish expatriate Pablo Picasso was one of the greatest and most influential artists of the 20th century, as well as the co-creator of Cubism.");

                //fields.AddField("Attachments", attachmentList);
                //fields.AddField("On Display?", false);

                Task <AirtableCreateUpdateReplaceRecordResponse> task = airtableBase.CreateRecord("New Users", fields, true);
                var response = await task;

                if (!response.Success)
                {
                    string errorMessage = null;
                    if (response.AirtableApiError is AirtableApiException)
                    {
                        errorMessage = response.AirtableApiError.ErrorMessage;
                    }
                    else
                    {
                        errorMessage = "Unknown error";
                    }
                    // Report errorMessage
                }
                else
                {
                    var record = response.Record;
                    // Do something with your created record.
                }
            }
        }
コード例 #15
0
        public static async Task <IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req,
            ILogger log)
        {
            log.LogInformation("C# HTTP trigger function processed a request.");

            string rotation = await new StreamReader(req.Body).ReadToEndAsync();

            using (AirtableBase airtableBase = new AirtableBase(
                       Environment.GetEnvironmentVariable("airtableApiKey"),
                       Environment.GetEnvironmentVariable("airtableBaseId")))
            {
                log.LogInformation("Airtable connection initialized.");

                var rotationNumber          = int.Parse(new Regex(@"(^\d+)", RegexOptions.Multiline).Match(rotation).Groups[1].Value);
                var rotationStartDateString = new Regex(@" (\d{2}[A-Z]{3})").Match(rotation).Groups[1].Value;
                var rotationStartDate       = monthConverter[rotationStartDateString.Substring(2, 3)] + "/" +
                                              int.Parse(rotationStartDateString.Substring(0, 2)) + "/" +
                                              DateTime.Now.Year;
                var rotationNumberOfAttendants = new Regex(@"([0-9]+) F\/A").Match(rotation).Groups[1].Value;
                log.LogInformation($"Parsed rotation #{rotationNumber}-{rotationStartDate}.");

                // Update rotation
                log.LogInformation("Updating rotation.");
                var rotationRecordId = req.Headers["Airtable-Record-Id"][0];
                var rotationLookup   = airtableBase.RetrieveRecord("Rotations", rotationRecordId).GetAwaiter().GetResult();
                if (!rotationLookup.Success)
                {
                    log.LogError(rotationLookup.AirtableApiError.ErrorMessage);
                    return(new StatusCodeResult(500));
                }
                log.LogInformation("Looked up rotation successfully.");
                var rotationFields = new Fields();
                rotationFields.AddField("Rotation #", rotationNumber);
                rotationFields.AddField("Date", rotationStartDate);
                var rotationUpdate = airtableBase.UpdateRecord("People", rotationFields, rotationRecordId).GetAwaiter().GetResult();
                if (!rotationUpdate.Success)
                {
                    log.LogError(rotationUpdate.AirtableApiError.ErrorMessage);
                    return(new StatusCodeResult(500));
                }
                log.LogInformation("Updated rotation successfully.");

                // Add flight attendants
                for (int i = 0; i < int.Parse(rotationNumberOfAttendants); i++)
                {
                    log.LogInformation($"Starting to process flight attendant {i}.");
                    var flightAttendantRecord = new Regex($@"^{Convert.ToChar(65 + i)} 0([0-9]*) ([A-Za-z]*)([A-Za-z ]*)", RegexOptions.Multiline).Match(rotation);
                    var faEmployeeId          = int.Parse(flightAttendantRecord.Groups[1].Value);

                    var faLookup = airtableBase.ListRecords("People", null, null, $"{{Employee ID}} = {faEmployeeId}").GetAwaiter().GetResult();

                    if (!faLookup.Success)
                    {
                        log.LogError(faLookup.AirtableApiError.ErrorMessage);
                        return(new StatusCodeResult(500));
                    }
                    log.LogInformation($"Looked up flight attendant {faLookup} successfully.");

                    if (!faLookup.Records.Any())
                    {
                        log.LogInformation("Adding flight attendant.");
                        var fields = new Fields();
                        fields.AddField("Employee ID", faEmployeeId);
                        fields.AddField("First name", flightAttendantRecord.Groups[2].Value);
                        fields.AddField("Last name", flightAttendantRecord.Groups[3].Value);
                        var result = airtableBase.CreateRecord("People", fields).GetAwaiter().GetResult();
                        if (!result.Success)
                        {
                            log.LogError(result.AirtableApiError.ErrorMessage);
                            return(new StatusCodeResult(500));
                        }
                        log.LogInformation("Added flight attendant successfully.");
                    }
                    else
                    {
                        log.LogInformation("Flight attendant already registered.");
                    }
                }
            }
            return((ActionResult) new OkResult());
        }
コード例 #16
0
        public static async Task PenalizePlayer(ulong discordId, int points, string notes)
        {
            AirtableRecord playerRecord = await GetPlayerRecord(discordId);

            using (AirtableBase airtableBase = new AirtableBase(Globals.BotSettings.AppKey, Globals.BotSettings.BaseId))
            {
                Fields adjustmentsFields = new Fields();
                adjustmentsFields.AddField("Player", playerRecord.Id);
                adjustmentsFields.AddField("Points", -points);
                adjustmentsFields.AddField("Notes", notes);

                Task <AirtableCreateUpdateReplaceRecordResponse> createRecordTask =
                    airtableBase.CreateRecord("Adjustments", adjustmentsFields, true);

                AirtableCreateUpdateReplaceRecordResponse createRecordResponse = await createRecordTask;

                if (!createRecordResponse.Success)
                {
                    string errorMessage = createRecordResponse.AirtableApiError != null
                        ? createRecordResponse.AirtableApiError.ErrorMessage
                        : "Unknown error";

                    SdlAirTableException exception = new SdlAirTableException(
                        errorMessage,
                        SdlAirTableException.AirtableErrorType.CommunicationError);

                    Logger.Error(exception);
                    throw exception;
                }

                AirtableRecord record = createRecordResponse.Record;

                if (!playerRecord.Fields.ContainsKey("Adjustments"))
                {
                    playerRecord.Fields["Adjustments"] = new JArray();
                }

                IEnumerable <JToken> updatedAdjustmentIds = ((JArray)playerRecord.Fields["Adjustments"]).Append(record.Id);

                Fields updatePlayerFields = new Fields();
                updatePlayerFields.AddField("Adjustments", updatedAdjustmentIds.ToArray());

                Task <AirtableCreateUpdateReplaceRecordResponse> updateRecordTask =
                    airtableBase.UpdateRecord("Draft Standings", updatePlayerFields, playerRecord.Id, true);

                AirtableCreateUpdateReplaceRecordResponse updateRecordResponse = await updateRecordTask;

                if (!updateRecordResponse.Success)
                {
                    string errorMessage = updateRecordResponse.AirtableApiError != null
                        ? updateRecordResponse.AirtableApiError.ErrorMessage
                        : "Unknown error";

                    SdlAirTableException exception = new SdlAirTableException(
                        errorMessage,
                        SdlAirTableException.AirtableErrorType.CommunicationError);

                    Logger.Error(exception);
                    throw exception;
                }
            }
        }
コード例 #17
0
ファイル: DomainController.cs プロジェクト: franklbt/mfork
        public async Task <IActionResult> Post([FromBody] DomainRequest request)
        {
            if (!IsValidDomain(request.Domain))
            {
                return(BadRequest(new DomainResponse {
                    Error = "Invalid domain"
                }));
            }

            var domain    = string.Join(".", request.Domain.Split(".").TakeLast(2));
            var subDomain = string.Join(".", request.Domain.Split(".").SkipLast(2));

            var credentials = new AzureCredentialsFactory()
                              .FromServicePrincipal(
                _configuration["Azure:ClientId"],
                _configuration["Azure:ClientSecret"],
                _configuration["Azure:TenantId"],
                AzureEnvironment.AzureGlobalCloud
                );

            var azure = Azure
                        .Configure()
                        .WithRetryPolicy(new RetryPolicy(new TransientErrorIgnoreStrategy(), 0))
                        .Authenticate(credentials)
                        .WithSubscription(_configuration["Azure:SubscriptionId"]);

            var webApp = await azure.AppServices.WebApps.GetByIdAsync(
                _configuration["Azure:AppId"]);

            try
            {
                webApp.Update()
                .DefineHostnameBinding()
                .WithThirdPartyDomain(domain)
                .WithSubDomain(subDomain)
                .WithDnsRecordType(CustomHostNameDnsRecordType.CName)
                .Attach()
                .Apply();
            }
            catch (Exception e)
            {
                return(BadRequest(new DomainResponse {
                    Error = "Unable to validate domain ownership"
                }));
            }

            _ = Task.Run(async() =>
            {
                using var airtableBase = new AirtableBase(_configuration["Airtable:Key"], _configuration["Airtable:Base"]);
                try
                {
                    HttpClient httpClient = new HttpClient {
                        BaseAddress = new Uri(_configuration["Acme:Endpoint"])
                    };
                    AcmeProtocolClient acme = new AcmeProtocolClient(httpClient, usePostAsGet: true);

                    var acmeDir    = await acme.GetDirectoryAsync();
                    acme.Directory = acmeDir;

                    await acme.GetNonceAsync();

                    var account  = await acme.CreateAccountAsync(new[] { "mailto:" + _configuration["Acme:Email"] }, true);
                    acme.Account = account;

                    var order = await acme.CreateOrderAsync(new[] { request.Domain });
                    if (order.Payload.Status == "invalid")
                    {
                        return;
                    }

                    var authorizationUrl = order.Payload.Authorizations.FirstOrDefault();
                    if (string.IsNullOrEmpty(authorizationUrl))
                    {
                        return;
                    }
                    var authorization = await acme.GetAuthorizationDetailsAsync(authorizationUrl);

                    foreach (var challenge in authorization.Challenges.Where(x => x.Type == "http-01").ToList())
                    {
                        var challengeValidationDetails = (Http01ChallengeValidationDetails)
                                                         AuthorizationDecoder.DecodeChallengeValidation(authorization, challenge.Type, acme.Signer);

                        var path        = challengeValidationDetails.HttpResourcePath;
                        var token       = path.Split("/", StringSplitOptions.RemoveEmptyEntries).Last();
                        var value       = challengeValidationDetails.HttpResourceValue;
                        var contentType = challengeValidationDetails.HttpResourceContentType;

                        await airtableBase.CreateRecord("Acme", new Fields
                        {
                            FieldsCollection = new Dictionary <string, object>
                            {
                                ["Token"]       = token,
                                ["Value"]       = value,
                                ["ContentType"] = contentType
                            }
                        });

                        await Task.Delay(10 * 1000);
                        var challengeUpdated = await acme.AnswerChallengeAsync(challenge.Url);
                    }

                    //Wait for challenge to be resolved
                    var waitUntil = DateTime.Now.AddSeconds(300);
                    Authorization authorizationUpdated;
                    do
                    {
                        await Task.Delay(10 * 1000);
                        authorizationUpdated = await acme.GetAuthorizationDetailsAsync(authorizationUrl);
                    } while (authorizationUpdated.Status != "valid" && DateTime.Now < waitUntil);

                    if (authorizationUpdated.Status != "valid")
                    {
                        return;
                    }

                    //Generate certificate private key and CSR (Certificate signing request)
                    var keyPair = PkiKeyPair.GenerateEcdsaKeyPair(256);
                    var csr     = new PkiCertificateSigningRequest($"CN={request.Domain}", keyPair, PkiHashAlgorithm.Sha256);
                    var certCsr = csr.ExportSigningRequest(PkiEncodingFormat.Der);

                    order = await acme.FinalizeOrderAsync(order.Payload.Finalize, certCsr);
                    if (order.Payload.Status != "valid")
                    {
                        return;
                    }

                    if (string.IsNullOrEmpty(order.Payload.Certificate))
                    {
                        //Wait for certificate
                        var waitUntil2 = DateTime.Now.AddSeconds(300);
                        while (DateTime.Now < waitUntil2)
                        {
                            await Task.Delay(10 * 1000);
                            order = await acme.GetOrderDetailsAsync(order.OrderUrl, existing: order);

                            if (!string.IsNullOrEmpty(order.Payload.Certificate))
                            {
                                break;
                            }
                        }
                    }
                    if (string.IsNullOrEmpty(order.Payload.Certificate))
                    {
                        return;
                    }

                    var certResp = await acme.GetAsync(order.Payload.Certificate);
                    if (!certResp.IsSuccessStatusCode)
                    {
                        return;
                    }

                    var certByteArray = await certResp.Content.ReadAsByteArrayAsync();

                    //Export PFX file
                    var pfxPassword = _configuration["Acme:PfxPassword"];
                    var privateKey  = keyPair.PrivateKey;

                    using var cert = new X509Certificate2(certByteArray);

                    X509Chain chain = new X509Chain();
                    chain.Build(cert);
                    List <PkiCertificate> chainList = new List <PkiCertificate>();
                    foreach (var e in chain.ChainElements)
                    {
                        chainList.Add(PkiCertificate.From(e.Certificate));
                    }

                    var pfx = chainList[0].Export(PkiArchiveFormat.Pkcs12,
                                                  chain: chainList.Skip(1),
                                                  privateKey: privateKey,
                                                  password: pfxPassword?.ToCharArray());

                    webApp.Update()
                    .DefineSslBinding()
                    .ForHostname(request.Domain)
                    .WithPfxByteArrayToUpload(pfx, pfxPassword)
                    .WithSniBasedSsl()
                    .Attach()
                    .Apply();
                }
                catch (Exception e)
                {
                    await airtableBase.CreateRecord("Logs", new Fields
                    {
                        FieldsCollection = new Dictionary <string, object>
                        {
                            ["Hostname"] = request.Domain,
                            ["Event"]    = "exception-thrown",
                            ["Data"]     = JsonConvert.SerializeObject(e)
                        }
                    });
                }
            });



            return(Ok(new DomainResponse {
                IsSuccessful = true
            }));
        }