163 lines
6.4 KiB
C#
163 lines
6.4 KiB
C#
using System.Net;
|
|
using System.Net.Mail;
|
|
using System.Text.Json;
|
|
using Fitness_core_BE.Interfaces.Services;
|
|
using Fitness_core_BE.Models.IOs;
|
|
|
|
namespace Fitness_core_BE.Services
|
|
{
|
|
/// <summary>
|
|
/// Combines the two outbound notification channels — SMS (Introps) and email (Gmail SMTP) —
|
|
/// into one service, matching the pattern already used by Core-Hex-Auth's ThirdPartyService.
|
|
/// </summary>
|
|
public class ThirdPartyService : IThirdPartyService
|
|
{
|
|
private readonly HttpClient _httpClient;
|
|
private readonly IConfiguration _config;
|
|
|
|
// Email (Gmail SMTP). Use a Gmail App Password, not the account password.
|
|
private readonly string _gmailUser;
|
|
private readonly string _gmailPassword;
|
|
private readonly string _gmailHost;
|
|
private readonly int _gmailPort;
|
|
private readonly string _gmailFromName;
|
|
|
|
public ThirdPartyService(IHttpClientFactory httpClientFactory, IConfiguration config)
|
|
{
|
|
_httpClient = httpClientFactory.CreateClient();
|
|
_config = config;
|
|
|
|
_gmailUser = Environment.GetEnvironmentVariable("GMAIL_USER") ?? config["Gmail:User"] ?? "";
|
|
_gmailPassword = Environment.GetEnvironmentVariable("GMAIL_APP_PASSWORD") ?? config["Gmail:AppPassword"] ?? "";
|
|
_gmailHost = config["Gmail:Host"] ?? "smtp.gmail.com";
|
|
_gmailPort = int.TryParse(config["Gmail:Port"], out var p) ? p : 587;
|
|
_gmailFromName = config["Gmail:FromName"] ?? "GYM OS";
|
|
}
|
|
|
|
// ---------- SMS ----------
|
|
|
|
public async Task<OtpResponse> SendSmsAsync(string mobileNumber, string? otpCode = null, string? message = null)
|
|
{
|
|
try
|
|
{
|
|
if (string.IsNullOrWhiteSpace(mobileNumber))
|
|
{
|
|
return new OtpResponse
|
|
{
|
|
StatusCode = 400,
|
|
Message = "Mobile number is required"
|
|
};
|
|
}
|
|
|
|
if (string.IsNullOrWhiteSpace(otpCode) && string.IsNullOrWhiteSpace(message))
|
|
{
|
|
return new OtpResponse
|
|
{
|
|
StatusCode = 400,
|
|
Message = "Either an OTP code or a message is required"
|
|
};
|
|
}
|
|
|
|
string contactNumber = mobileNumber;
|
|
string apiUrl = _config["Sms:ApiUrl"] ?? "https://backup.introps.com/Sms_common/send_sms";
|
|
string apiKey = Environment.GetEnvironmentVariable("SMS_API_KEY") ?? _config["Sms:ApiKey"] ?? "8989898989";
|
|
|
|
var msgText = string.IsNullOrWhiteSpace(message) ? $"Your otp code is: {otpCode}" : message;
|
|
|
|
var smsRequest = new SmsRequest
|
|
{
|
|
api_key = apiKey,
|
|
phone_number = contactNumber,
|
|
msg_text = msgText
|
|
};
|
|
|
|
var formContent = new FormUrlEncodedContent(new[]
|
|
{
|
|
new KeyValuePair<string, string>("api_key", smsRequest.api_key),
|
|
new KeyValuePair<string, string>("phone_number", smsRequest.phone_number),
|
|
new KeyValuePair<string, string>("msg_text", smsRequest.msg_text)
|
|
});
|
|
|
|
var response = await _httpClient.PostAsync(apiUrl, formContent);
|
|
var responseContent = await response.Content.ReadAsStringAsync();
|
|
|
|
if (response.IsSuccessStatusCode && responseContent.Contains("agent:d"))
|
|
{
|
|
string jsonString = responseContent.Split(new[] { "agent:d" }, StringSplitOptions.None)[1];
|
|
|
|
var responseJson = JsonSerializer.Deserialize<Dictionary<string, object>>(jsonString);
|
|
|
|
if (responseJson is not null &&
|
|
responseJson.TryGetValue("stt", out var statusValue) &&
|
|
statusValue?.ToString() == "ok")
|
|
{
|
|
Console.WriteLine($"SMS sent to {contactNumber}");
|
|
return new OtpResponse
|
|
{
|
|
StatusCode = 200,
|
|
Message = "SMS sent successfully."
|
|
};
|
|
}
|
|
}
|
|
|
|
Console.WriteLine($"Failed to send SMS to {contactNumber}. Response: {responseContent}");
|
|
return new OtpResponse
|
|
{
|
|
StatusCode = 500,
|
|
Message = "Failed to send SMS.",
|
|
ApiResponse = responseContent
|
|
};
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Console.WriteLine($"Exception sending SMS: {ex.Message}");
|
|
|
|
return new OtpResponse
|
|
{
|
|
StatusCode = 500,
|
|
Message = "Exception occurred while sending SMS.",
|
|
Error = ex.Message
|
|
};
|
|
}
|
|
}
|
|
|
|
// ---------- Email ----------
|
|
|
|
public async Task SendEmailAsync(string toEmail, string subject, string htmlBody, byte[]? attachment = null, string? attachmentName = null)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(_gmailUser) || string.IsNullOrWhiteSpace(_gmailPassword))
|
|
throw new InvalidOperationException("Gmail SMTP is not configured (set GMAIL_USER / GMAIL_APP_PASSWORD).");
|
|
|
|
using var mail = new MailMessage
|
|
{
|
|
From = new MailAddress(_gmailUser, _gmailFromName),
|
|
Subject = subject,
|
|
Body = htmlBody,
|
|
IsBodyHtml = true
|
|
};
|
|
mail.To.Add(toEmail);
|
|
|
|
MemoryStream? attachmentStream = null;
|
|
if (attachment != null)
|
|
{
|
|
attachmentStream = new MemoryStream(attachment);
|
|
mail.Attachments.Add(new Attachment(attachmentStream, attachmentName ?? "receipt.pdf", "application/pdf"));
|
|
}
|
|
|
|
try
|
|
{
|
|
using var client = new SmtpClient(_gmailHost, _gmailPort)
|
|
{
|
|
EnableSsl = true,
|
|
Credentials = new NetworkCredential(_gmailUser, _gmailPassword)
|
|
};
|
|
await client.SendMailAsync(mail);
|
|
}
|
|
finally
|
|
{
|
|
attachmentStream?.Dispose();
|
|
}
|
|
}
|
|
}
|
|
}
|