Initial Commit ...

This commit is contained in:
2024-01-25 04:51:13 +03:30
commit 2b05450746
21 changed files with 758 additions and 0 deletions
+8
View File
@@ -0,0 +1,8 @@
#
# DotNet ...
bin
obj
#
# Natural Docs ...
Documentation/*
View File
View File
+5
View File
@@ -0,0 +1,5 @@
namespace xMessageService.Constants {
public partial struct ConfigurationNodeNames {
public const string MESSAGE_NODE_NAME = "MessageConfiguration";
}
}
+5
View File
@@ -0,0 +1,5 @@
namespace xMessageService.Constants {
public struct xMessageServiceConstants {
public const string DEFAULT_EMPTY_PROVIDER = "EMPTY";
}
}
+142
View File
@@ -0,0 +1,142 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using xCommons.Extensions;
using xExceptions.Constants;
using xMessageService.Constants;
using xMessageService.Interfaces;
using xMessageService.Models;
using xMessageService.Providers;
namespace xMessageService.DI {
public static partial class XDIHelperExtension {
/// <summary>
/// Retrieve XMessage Configuration from App Settings
/// </summary>
/// <param name="config"></param>
/// <returns></returns>
public static XMessageConfiguration GetXMessageConfiguration (this IConfiguration config) {
//
var xMessageConfigSection = config.GetSection (ConfigurationNodeNames.MESSAGE_NODE_NAME);
var xMessageConfiguration = xMessageConfigSection.Get<XMessageConfiguration> ();
//
var defaultMailConfiguration = new Dictionary<string, XMailConfiguration> {
["EMPTY"] =
new XMailConfiguration {
Title = xMessageServiceConstants.DEFAULT_EMPTY_PROVIDER,
Host = "",
Port = 25,
EnableSsl = false,
Username = "",
Password = ""
}
};
//
var defaultSmsConfiguration = new Dictionary<string, XSmsConfiguration> {
["EMPTY"] =
new XSmsConfiguration {
ServiceUrl = "",
Username = "",
Password = "",
LineNumber = "",
UserApiKey = "",
SecretKey = "",
}
};
//
if (xMessageConfiguration.IsNull ()) {
//
xMessageConfiguration = new XMessageConfiguration {
DefaultSMSProvider = xMessageServiceConstants.DEFAULT_EMPTY_PROVIDER,
DefaultMailProvider = xMessageServiceConstants.DEFAULT_EMPTY_PROVIDER,
MailConfigurations = defaultMailConfiguration,
SmsConfigurations = defaultSmsConfiguration
};
//
// Warn Message is Default Configuration ...
Console.WriteLine ($"IMPORTANT: xMessageService Configuration is Default, so the Service can't works properly ...");
}
//
// Handle Default Mail Provider ...
if (xMessageConfiguration.DefaultMailProvider.IsNullOrEmpty ()) {
//
if (xMessageConfiguration.IsNull () ||
//
xMessageConfiguration.MailConfigurations.IsNull () ||
xMessageConfiguration.MailConfigurations.Count == 0) {
//
Console.WriteLine ("There is no defined Mail Provider Configurations ...");
xMessageConfiguration.DefaultMailProvider = xMessageServiceConstants.DEFAULT_EMPTY_PROVIDER;
}
//
if (xMessageConfiguration.DefaultMailProvider == xMessageServiceConstants.DEFAULT_EMPTY_PROVIDER) {
xMessageConfiguration.MailConfigurations = defaultMailConfiguration;
} else {
xMessageConfiguration.DefaultMailProvider = xMessageConfiguration.MailConfigurations.Keys.First ();
}
}
//
// Handle Default SMS Provider ...
if (xMessageConfiguration.DefaultSMSProvider.IsNullOrEmpty ()) {
//
if (xMessageConfiguration.IsNull () ||
xMessageConfiguration.SmsConfigurations.IsNull () ||
xMessageConfiguration.SmsConfigurations.Count == 0) {
//
Console.WriteLine ("There is no defined SMS Provider Configurations ...");
xMessageConfiguration.DefaultSMSProvider = xMessageServiceConstants.DEFAULT_EMPTY_PROVIDER;
}
//
if (xMessageConfiguration.DefaultSMSProvider == xMessageServiceConstants.DEFAULT_EMPTY_PROVIDER) {
xMessageConfiguration.SmsConfigurations = defaultSmsConfiguration;
} else {
xMessageConfiguration.DefaultSMSProvider = xMessageConfiguration.SmsConfigurations.Keys.First ();
}
}
//
return xMessageConfiguration;
}
/// <summary>
/// Register XMessage Service
/// </summary>
/// <param name="services"></param>
/// <param name="config"></param>
public static void AddXMessageService (this IServiceCollection services, IConfiguration config) {
//
var xMessageConfiguration = config.GetXMessageConfiguration ();
services.AddSingleton<XMessageConfiguration> (xMessageConfiguration);
//
// Register SMS Service ...
var xSmsService = new XSmsService (
xMessageConfiguration.DefaultSMSProvider,
xMessageConfiguration.SmsConfigurations
);
services.AddSingleton<IXSmsService> (xSmsService);
//
// Register Mail Service ...
var xMailService = new XMailService (
xMessageConfiguration.DefaultMailProvider,
xMessageConfiguration.MailConfigurations
);
services.AddSingleton<IXMailService> (xMailService);
//
// Register MEssage Provider ...
services.AddSingleton<IXMessageProvider, XMessageProvider> ();
}
}
}
View File
View File
+11
View File
@@ -0,0 +1,11 @@
using System.Threading.Tasks;
using xMessageService.Models;
namespace xMessageService.Interfaces {
public partial interface IXMailService {
Task SendMailAsync (
XMessage message,
string provider = null
);
}
}
+26
View File
@@ -0,0 +1,26 @@
using System;
using System.Threading.Tasks;
using xMessageService.Models;
namespace xMessageService.Interfaces {
public partial interface IXMessageProvider {
bool IsReady (
bool? checkMailService = false,
bool? checkSmsService = false
);
Task SendMailAsync (
XMessage message,
string provider = null,
bool throwException = true,
Exception exception = null
);
Task SendSmsAsync (
XMessage message,
string provider = null,
bool throwException = true,
Exception exception = null
);
}
}
+11
View File
@@ -0,0 +1,11 @@
using System.Threading.Tasks;
using xMessageService.Models;
namespace xMessageService.Interfaces {
public partial interface IXSmsService {
Task SendSmsAsync (
XMessage message,
string provider = null
);
}
}
+10
View File
@@ -0,0 +1,10 @@
namespace xMessageService.Models {
public partial class XMailConfiguration {
public string Title { get; set; }
public string Host { get; set; }
public int Port { get; set; }
public bool EnableSsl { get; set; }
public string Username { get; set; }
public string Password { get; set; }
}
}
+9
View File
@@ -0,0 +1,9 @@
using System.Collections.Generic;
using xModels.Base;
namespace xMessageService.Models {
public partial class XMessage : XBaseDto {
public HashSet<string> Recievers { get; set; } = new HashSet<string> ();
public string Message { get; set; }
}
}
+10
View File
@@ -0,0 +1,10 @@
using System.Collections.Generic;
namespace xMessageService.Models {
public partial class XMessageConfiguration {
public string DefaultSMSProvider { get; set; }
public string DefaultMailProvider { get; set; }
public IDictionary<string, XMailConfiguration> MailConfigurations { get; set; }
public IDictionary<string, XSmsConfiguration> SmsConfigurations { get; set; }
}
}
+10
View File
@@ -0,0 +1,10 @@
namespace xMessageService.Models {
public partial class XSmsConfiguration {
public string ServiceUrl { get; set; }
public string Username { get; set; }
public string Password { get; set; }
public string LineNumber { get; set; }
public string UserApiKey { get; set; }
public string SecretKey { get; set; }
}
}
+148
View File
@@ -0,0 +1,148 @@
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Mail;
using System.Threading.Tasks;
using xCommons.Extensions;
using xExceptions.Constants;
using xMessageService.Interfaces;
using xMessageService.Models;
namespace xMessageService.Providers {
public partial class XMailService : IXMailService {
private SmtpClient smtpClient;
private readonly string defaultProvider;
private readonly IDictionary<string, XMailConfiguration> configurations;
public XMailService (
string defaultProvider,
IDictionary<string, XMailConfiguration> configurations
) {
this.defaultProvider = defaultProvider;
this.configurations = configurations;
//
// Get instance of SMTP Client ...
PrepareSmtpClient ();
}
public Task SendMailAsync (
XMessage message,
string provider = null
) {
//
// Run Send Mail Asynchronous ...
return Task.Run (() => {
SendMail (message, provider);
});
}
#region Private ...
/// <summary>
/// Validate and Retrieve Provider Configuration for Service
/// </summary>
/// <param name="provider"></param>
/// <returns></returns>
private XMailConfiguration GetConfiguration (string provider = null) {
//
if (provider.IsNullOrEmpty ()) {
provider = defaultProvider;
}
//
if (!configurations.Keys.Contains (provider)) {
XException.MessageServiceInitialFailed.Throw ();
}
//
return configurations[provider];
}
/// <summary>
/// Prepare SMTP Client by Using Specified/Default Provider
/// </summary>
/// <param name="provider"></param>
private void PrepareSmtpClient (string provider = null) {
//
var config = GetConfiguration (provider);
if (config.IsNull()) {
return;
}
//
smtpClient = new SmtpClient () {
Host = config.Host,
Port = config.Port,
EnableSsl = config.EnableSsl,
UseDefaultCredentials = false,
Credentials = new NetworkCredential (
config.Username,
config.Password)
};
}
/// <summary>
/// Prepare Mail Message With Specified/Default Provider
/// </summary>
/// <param name="message"></param>
/// <param name="provider"></param>
/// <returns></returns>
private MailMessage PrepareMailMessage (
XMessage message,
string provider = null
) {
//
if (message == null ||
message.Message.IsNullOrEmpty () ||
message.Recievers.Count == 0) {
XException.InvalidMessage.Throw ();
}
//
var config = GetConfiguration (provider);
var mailMessage = new MailMessage () {
From = new MailAddress (config.Username),
Subject = config.Title,
Body = message.Message
};
//
foreach (var reciever in message.Recievers) {
mailMessage.To.Add (reciever);
}
//
return mailMessage;
}
/// <summary>
/// Send Mail Using Specified/Default Provider
/// </summary>
/// <param name="message"></param>
/// <param name="provider"></param>
private void SendMail (
XMessage message,
string provider = null
) {
//
if (smtpClient.IsNull()) {
//
Console.WriteLine ($"SMTP Error: MessageServiceInitialFailed ...");
XException.MessageServiceInitialFailed.Throw ();
}
//
var mailMessage = PrepareMailMessage (message, provider);
//
try {
smtpClient.Send (mailMessage);
} catch (Exception ex) {
//
Console.WriteLine ($"SMTP Error: {ex.Message}");
XException.MessageServiceInitialFailed.Throw ();
}
}
#endregion
}
}
+118
View File
@@ -0,0 +1,118 @@
using System;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using xCommons.Extensions;
using xExceptions.Constants;
using xMessageService.Interfaces;
using xMessageService.Models;
namespace xMessageService.Providers {
public partial class XMessageProvider : IXMessageProvider {
private readonly XMessageConfiguration configuration;
private readonly ILogger<XMessageProvider> logger;
private readonly IXSmsService smsService;
private readonly IXMailService mailService;
public XMessageProvider (
XMessageConfiguration configuration,
ILogger<XMessageProvider> logger,
IXSmsService smsService,
IXMailService mailService
) {
this.configuration = configuration;
this.logger = logger;
this.smsService = smsService;
this.mailService = mailService;
}
/// <summary>
/// Send a Mail Message
/// </summary>
/// <param name="message"></param>
/// <param name="provider"></param>
/// <param name="throwException"></param>
/// <param name="exception"></param>
/// <returns></returns>
public async Task SendMailAsync (
XMessage message,
string provider = null,
bool throwException = true,
Exception exception = null
) {
//
if (exception.IsNull ()) {
exception = XException.ActionFailed.ToException ();
}
//
try {
await mailService.SendMailAsync (message, provider);
} catch (Exception ex) {
//
logger.LogError ($"Exeption: {ex.Message}");
//
if (throwException) {
throw exception;
}
}
}
/// <summary>
/// Send SMS Message
/// </summary>
/// <param name="message"></param>
/// <returns></returns>
public async Task SendSmsAsync (
XMessage message,
string provider = null,
bool throwException = true,
Exception exception = null
) {
//
if (exception.IsNull ()) {
exception = XException.ActionFailed.ToException ();
}
//
try {
await smsService.SendSmsAsync (message, provider);
} catch {
if (throwException) {
throw exception;
}
}
}
/// <summary>
/// Check Message Provider is Ready or not
/// </summary>
/// <param name="checkMailService"></param>
/// <param name="checkSmsService"></param>
/// <returns></returns>
public bool IsReady (
bool? checkMailService = false,
bool? checkSmsService = false
) {
//
var result = true;
//
// Check Mail Service ...
if (checkMailService.HasValue &&
checkMailService.GetValueOrDefault ()) {
result = result && mailService != null;
}
//
// Check Sms Service ...
if (checkSmsService.HasValue &&
checkSmsService.GetValueOrDefault ()) {
result = result && smsService != null;
}
//
return result;
}
}
}
+181
View File
@@ -0,0 +1,181 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using PhoneNumbers;
using RestSharp;
using xCommons.Extensions;
using xExceptions.Constants;
using xMessageService.Interfaces;
using xMessageService.Models;
namespace xMessageService.Providers {
public partial class XSmsService : IXSmsService {
private string serviceUrl;
private readonly string defaultProvider;
private readonly IDictionary<string, XSmsConfiguration> configurations;
public XSmsService (
string defaultProvider,
IDictionary<string, XSmsConfiguration> configurations
) {
this.defaultProvider = defaultProvider;
this.configurations = configurations;
//
PrepareServiceUrl ();
}
public Task SendSmsAsync (
XMessage message,
string provider = null
) {
//
// Run Send SMS Asynchronous ...
return Task.Run (() => {
SendSMS (message, provider);
});
}
#region Private ...
/// <summary>
/// Prepare Service Url for Specified/Default Provider
/// </summary>
/// <param name="provider"></param>
private void PrepareServiceUrl (string provider = null) {
//
if (provider.IsNullOrEmpty ()) {
provider = defaultProvider;
}
//
var config = GetConfiguration (provider);
if (config.IsNull ()) {
return;
}
//
serviceUrl = config.ServiceUrl;
serviceUrl += "&username=" + config.Username + "&password=" + config.Password + "&";
}
/// <summary>
/// Prepare Service url for Integrating XMessage by
/// using Specified/Default Provider Configurations
/// </summary>
/// <param name="message"></param>
/// <param name="provider"></param>
private void PrepareSmsMessage (
XMessage message,
string provider = null
) {
//
if (message == null ||
message.Message.IsNullOrEmpty () ||
message.Recievers.Count == 0) {
XException.InvalidMessage.Throw ();
}
//
// Validating Mobile Numbers ...
var phoneNumberUtil = PhoneNumbers.PhoneNumberUtil.GetInstance ();
var recieversList = "";
//
PrepareServiceUrl (provider);
//
foreach (var reciever in message.Recievers) {
try {
//
var mPhoneNumber = phoneNumberUtil.Parse (reciever, null);
if (phoneNumberUtil.IsValidNumber (mPhoneNumber)) {
//
// Format Phone Numbers to the '+989120000000' pattern ...
var recieverPhone = phoneNumberUtil.Format (mPhoneNumber, PhoneNumberFormat.E164);
if (recieversList.Length > 0) {
recieversList += ",";
}
recieversList += reciever;
}
} catch { }
}
//
var config = GetConfiguration ();
//
// Preparing All Content and Configurations for Sending Messages ...
serviceUrl += "to=" +
recieversList +
"&message=" +
message.Message +
"&from=" +
config.LineNumber +
"&flash=" +
false;
}
/// <summary>
/// Send a Message as SMS by Specified/Default Provider
/// </summary>
/// <param name="message"></param>
/// <param name="provider"></param>
private void SendSMS (
XMessage message,
string provider = null
) {
//
if (serviceUrl.IsNullOrEmpty ()) {
//
Console.WriteLine ($"SMS Error: MessageServiceInitialFailed ...");
XException.MessageServiceInitialFailed.Throw ();
}
//
try {
//
// preparing Service Url based on message data ...
PrepareSmsMessage (message, provider);
//
// Implementing Service Calling Using RestSharp Library ...
// We Select RestSharp because it supports Sync/Async Calls ...
var client = new RestClient (serviceUrl);
var request = new RestRequest (Method.POST);
//
// Send Request ...
var response = client.Execute (request);
} catch (Exception ex) {
Console.WriteLine ($"SMS Error: {ex.Message}");
XException.MessageServiceInitialFailed.Throw ();
}
}
/// <summary>
/// Validate and Retrieve Provider Configuration for Service
/// </summary>
/// <param name="provider"></param>
/// <returns></returns>
private XSmsConfiguration GetConfiguration (string provider = null) {
//
if (
provider.IsNullOrEmpty () ||
provider.ToNormalString () == "empty"
) {
//
provider = defaultProvider;
return null;
}
//
if (!configurations.Keys.Contains (provider)) {
XException.MessageServiceInitialFailed.Throw ();
}
//
return configurations[provider];
}
#endregion
}
}
+23
View File
@@ -0,0 +1,23 @@
# xMessageService
it is a Part of xDashboard on SaherElm IT Center which provides:
- SMTP Mailing Service.
- SMS Sending Service.
- Message Models.
- etc.
this module has following dependencies :
- xCommons
- xModels
for configure and use this Module refer to DI.XDIHelperExtension.cs file.
## Maintainer
Hadi Khazaee asl
[https://www.saherelm.ir](https://www.saherelm.ir)
[hadi_khazaee_asl@yahoo.com](mailto:hadi_khazaee_asl@yahoo.com)
+7
View File
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<add key="nuget" value="https://api.nuget.org/v3/index.json" protocolVersion="3" />
<add key="liget" value="https://nuget.saherelmhub.ir/v3/index.json" protocolVersion="3" />
</packageSources>
</configuration>
+34
View File
@@ -0,0 +1,34 @@
<Project Sdk="Microsoft.NET.Sdk">
<!-- Runtime Definition -->
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<PackageId>xDashboard.xMessageService</PackageId>
<Version>1.0.0</Version>
<Authors>Hadi Khazaee Asl</Authors>
<Company>SaherElm IT Center</Company>
<Description>
provide all required tools for sending mail and sms in xDashboard project.
</Description>
<!-- Icon Definition -->
<PackageIcon>icon.png</PackageIcon>
</PropertyGroup>
<!-- Icon Handling -->
<ItemGroup>
<None Include="../../Resources/Images/favicon.png" Link="icon.png" Pack="true" PackagePath="\icon.png" />
</ItemGroup>
<!-- Local Modules -->
<ItemGroup>
<PackageReference Include="xDashboard.xModels" Version="1.0.0" />
<!-- <ProjectReference Include="../xModels/xModels.csproj" /> -->
</ItemGroup>
<!-- Dependencies -->
<ItemGroup>
<PackageReference Include="RestSharp" Version="106.6.10" />
</ItemGroup>
</Project>