public async Task <string> SendSmsAsync(string phone, string message, string countryCode)
        {
            try
            {
                var response = await $"{_settings.BaseUrl}/Accounts/{_settings.ApiKey}/Messages.json"
                               .WithBasicAuth(_settings.ApiKey, _settings.ApiSecret)
                               .PostUrlEncodedAsync(new
                {
                    To             = phone,
                    From           = _settings.GetFrom(countryCode),
                    Body           = message,
                    StatusCallback = $"{_baseUrl}/callback/twilio"
                }).ReceiveJson <TwilioResponse>();

                if (!string.IsNullOrEmpty(response.ErrorCode))
                {
                    var error = new
                    {
                        response.Sid,
                        Phone = response.To.SanitizePhone(),
                        countryCode,
                        response.Status,
                        response.ErrorCode,
                        response.ErrorMessage
                    };

                    if (response.AccountNotActive)
                    {
                        _log.WriteError(nameof(SendSmsAsync), error);
                    }
                    else
                    {
                        _log.WriteWarning(nameof(SendSmsAsync), error, "error sending sms");
                    }
                }
                else
                {
                    return(response.Sid);
                }
            }
            catch (FlurlHttpException ex)
            {
                var error = await ex.GetResponseJsonAsync <TwilioErrorResponse>();

                _log.WriteWarning(nameof(SendSmsAsync), error, "twilio: error sending sms");
            }

            return(null);
        }
        public async Task <string> SendSmsAsync(string phone, string message, string countryCode)
        {
            int index = 0;

            while (++index <= 5)
            {
                try
                {
                    var sw = new Stopwatch();
                    _log.WriteInfo(nameof(SendSmsAsync), new { Phone = phone.SanitizePhone(), CountryCode = countryCode },
                                   $"Sending sms to nexmo endpoint {_settings.BaseUrl}/sms/json");

                    sw.Start();
                    var response = await $"{_settings.BaseUrl}/sms/json"
                                   .WithTimeout(10)
                                   .PostUrlEncodedAsync(new
                    {
                        to         = phone,
                        from       = _settings.GetFrom(countryCode),
                        text       = message,
                        api_key    = _settings.ApiKey,
                        api_secret = _settings.ApiSecret,
                        callback   = $"{_baseUrl}/callback/nexmo"
                    }).ReceiveJson <NexmoResponse>();

                    sw.Stop();

                    _log.WriteInfo(nameof(SendSmsAsync), new { messagesCount = response.MessagesCount, ElapsedMsec = sw.ElapsedMilliseconds },
                                   $"Sms has been sent to nexmo endpoint {_settings.BaseUrl}/sms/json");

                    if (response.MessagesCount > 0)
                    {
                        var errors = response.Messages
                                     .Where(item => item.Status != NexmoStatus.Ok)
                                     .Select(item => new
                        {
                            Phone = phone.SanitizePhone(), item.Status, item.Error, item.RemainingBalance
                        })
                                     .ToList();

                        if (errors.Any())
                        {
                            var notEnoughFunds =
                                errors.FirstOrDefault(item => item.Status == NexmoStatus.PartnerQuotaExceeded);

                            if (notEnoughFunds != null)
                            {
                                _log.WriteError(nameof(SendSmsAsync), notEnoughFunds);
                            }
                            else
                            {
                                _log.WriteWarning(nameof(SendSmsAsync), errors, "error sending sms");
                            }
                        }

                        return(response.Messages.FirstOrDefault(item => item.Status == NexmoStatus.Ok)?.MessageId);
                    }
                }
                catch (Exception ex)
                {
                    _log.WriteWarning(nameof(SendSmsAsync), ex.Message, "nexmo: error sending sms", ex);
                }
            }

            return(null);
        }