using AutoMapper; using DigitalData.Core.Abstractions.Client; using DigitalData.Core.Client; using EnvelopeGenerator.Application.Configurations.GtxMessaging; using EnvelopeGenerator.Application.Contracts; using EnvelopeGenerator.Application.DTOs.Messaging; using EnvelopeGenerator.Application.Extensions; using EnvelopeGenerator.Domain.HttpResponse; using Microsoft.Extensions.Caching.Distributed; using Microsoft.Extensions.Options; namespace EnvelopeGenerator.Application.Services { public class GtxMessagingService : IMessagingService { private readonly IHttpClientService _smsClient; private readonly SmsParams _smsParams; private readonly IMapper _mapper; private readonly ICodeGenerator _codeGen; private readonly IDistributedCache _cache; public string ServiceProvider { get; } private readonly DistributedCacheEntryOptions _codeCacheOptions; public GtxMessagingService(IHttpClientService smsClient, IOptions smsParamsOptions, IMapper mapper, ICodeGenerator codeGenerator, IDistributedCache distributedCache) { _smsClient = smsClient; _smsParams = smsParamsOptions.Value; _mapper = mapper; ServiceProvider = GetType().Name.Replace("Service", string.Empty); _codeGen = codeGenerator; _cache = distributedCache; _codeCacheOptions = new() { AbsoluteExpirationRelativeToNow = smsParamsOptions.Value.CodeCacheValidityPeriod }; } public async Task SendSmsAsync(string recipient, string message) { return await _smsClient.FetchAsync(queryParams: new Dictionary() { { _smsParams.RecipientQueryParamName, recipient }, { _smsParams.MessageQueryParamName, message } }) .ThenAsync(res => res.Json()) .ThenAsync(_mapper.Map); } public async Task SendSmsCodeAsync(string recipient, string envelopeReceiverId) { var code_expiration_key = string.Format(_smsParams.CodeExpirationCacheKeyFormat, envelopeReceiverId); var code_key = string.Format(_smsParams.CodeCacheKeyFormat, envelopeReceiverId); var code = await _cache.GetStringAsync(code_key); if (code is null) { code = _codeGen.GenerateCode(_smsParams.CodeLength); await _cache.SetStringAsync(code_key, code, _codeCacheOptions); var expiration = DateTime.Now + _smsParams.CodeCacheValidityPeriod; await _cache.SetDateTimeAsync(code_expiration_key, expiration, _codeCacheOptions); var res = await SendSmsAsync(recipient: recipient, message: code); res.Expiration = expiration; return res; } else { var code_expiration = await _cache.GetDateTimeAsync(code_expiration_key); return code_expiration is null ? new() { Ok = false } : new() { Ok = false, AllowedAt = code_expiration }; } } } }