2022-03-15 18:00:53 +00:00
|
|
|
// (c) Copyright Ascensio System SIA 2010-2022
|
|
|
|
//
|
|
|
|
// This program is a free software product.
|
|
|
|
// You can redistribute it and/or modify it under the terms
|
|
|
|
// of the GNU Affero General Public License (AGPL) version 3 as published by the Free Software
|
|
|
|
// Foundation. In accordance with Section 7(a) of the GNU AGPL its Section 15 shall be amended
|
|
|
|
// to the effect that Ascensio System SIA expressly excludes the warranty of non-infringement of
|
|
|
|
// any third-party rights.
|
|
|
|
//
|
|
|
|
// This program is distributed WITHOUT ANY WARRANTY, without even the implied warranty
|
|
|
|
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For details, see
|
|
|
|
// the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
|
|
|
|
//
|
|
|
|
// You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, EU, LV-1021.
|
|
|
|
//
|
|
|
|
// The interactive user interfaces in modified source and object code versions of the Program must
|
|
|
|
// display Appropriate Legal Notices, as required under Section 5 of the GNU AGPL version 3.
|
|
|
|
//
|
|
|
|
// Pursuant to Section 7(b) of the License you must retain the original Product logo when
|
|
|
|
// distributing the program. Pursuant to Section 7(e) we decline to grant you any rights under
|
|
|
|
// trademark law for use of our trademarks.
|
|
|
|
//
|
|
|
|
// All the Product's GUI elements, including illustrations and icon sets, as well as technical writing
|
|
|
|
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
|
|
|
|
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
2019-06-07 08:59:07 +00:00
|
|
|
|
2022-03-17 15:13:38 +00:00
|
|
|
namespace ASC.Web.Core.Sms;
|
|
|
|
|
|
|
|
[Scope(Additional = typeof(TwilioProviderExtention))]
|
|
|
|
public class SmsProviderManager
|
2019-06-07 08:59:07 +00:00
|
|
|
{
|
2022-04-15 09:08:06 +00:00
|
|
|
private readonly ConsumerFactory _consumerFactory;
|
2022-03-17 15:13:38 +00:00
|
|
|
|
2022-04-15 09:08:06 +00:00
|
|
|
public SmscProvider SmscProvider { get => _consumerFactory.Get<SmscProvider>(); }
|
|
|
|
public ClickatellProvider ClickatellProvider { get => _consumerFactory.Get<ClickatellProvider>(); }
|
|
|
|
public TwilioProvider TwilioProvider { get => _consumerFactory.Get<TwilioProvider>(); }
|
|
|
|
public ClickatellProvider ClickatellUSAProvider { get => _consumerFactory.Get<ClickatellUSAProvider>(); }
|
|
|
|
public TwilioProvider TwilioSaaSProvider { get => _consumerFactory.Get<TwilioSaaSProvider>(); }
|
2022-03-17 15:13:38 +00:00
|
|
|
|
|
|
|
public SmsProviderManager(ConsumerFactory consumerFactory)
|
2019-06-07 08:59:07 +00:00
|
|
|
{
|
2022-04-15 09:08:06 +00:00
|
|
|
_consumerFactory = consumerFactory;
|
2022-03-17 15:13:38 +00:00
|
|
|
}
|
2019-06-07 08:59:07 +00:00
|
|
|
|
2022-03-17 15:13:38 +00:00
|
|
|
public bool Enabled()
|
|
|
|
{
|
|
|
|
return SmscProvider.Enable() || ClickatellProvider.Enable() || ClickatellUSAProvider.Enable() || TwilioProvider.Enable() || TwilioSaaSProvider.Enable();
|
|
|
|
}
|
2019-06-07 08:59:07 +00:00
|
|
|
|
2022-03-17 15:13:38 +00:00
|
|
|
public Task<bool> SendMessageAsync(string number, string message)
|
|
|
|
{
|
|
|
|
if (!Enabled())
|
|
|
|
{
|
|
|
|
return Task.FromResult(false);
|
|
|
|
}
|
2019-06-07 08:59:07 +00:00
|
|
|
|
2022-03-17 15:13:38 +00:00
|
|
|
SmsProvider provider = null;
|
|
|
|
if (ClickatellProvider.Enable())
|
2019-12-20 11:17:01 +00:00
|
|
|
{
|
2022-03-17 15:13:38 +00:00
|
|
|
provider = ClickatellProvider;
|
2019-06-07 08:59:07 +00:00
|
|
|
}
|
|
|
|
|
2022-03-17 15:13:38 +00:00
|
|
|
string smsUsa;
|
|
|
|
if (ClickatellUSAProvider.Enable()
|
|
|
|
&& !string.IsNullOrEmpty(smsUsa = ClickatellProvider["clickatellUSA"]) && Regex.IsMatch(number, smsUsa))
|
2019-06-07 08:59:07 +00:00
|
|
|
{
|
2022-03-17 15:13:38 +00:00
|
|
|
provider = ClickatellUSAProvider;
|
2019-06-07 08:59:07 +00:00
|
|
|
}
|
|
|
|
|
2022-03-17 15:13:38 +00:00
|
|
|
if (provider == null && TwilioProvider.Enable())
|
2019-06-07 08:59:07 +00:00
|
|
|
{
|
2022-03-17 15:13:38 +00:00
|
|
|
provider = TwilioProvider;
|
|
|
|
}
|
2019-06-07 08:59:07 +00:00
|
|
|
|
2022-03-17 15:13:38 +00:00
|
|
|
if (provider == null && TwilioSaaSProvider.Enable())
|
|
|
|
{
|
|
|
|
provider = TwilioSaaSProvider;
|
|
|
|
}
|
2019-06-07 08:59:07 +00:00
|
|
|
|
2022-03-17 15:13:38 +00:00
|
|
|
if (SmscProvider.Enable()
|
|
|
|
&& (provider == null
|
|
|
|
|| SmscProvider.SuitableNumber(number)))
|
|
|
|
{
|
|
|
|
provider = SmscProvider;
|
|
|
|
}
|
2019-06-07 08:59:07 +00:00
|
|
|
|
2022-03-17 15:13:38 +00:00
|
|
|
if (provider == null)
|
|
|
|
{
|
|
|
|
return Task.FromResult(false);
|
|
|
|
}
|
2019-06-07 08:59:07 +00:00
|
|
|
|
2022-03-17 15:13:38 +00:00
|
|
|
return provider.SendMessageAsync(number, message);
|
|
|
|
}
|
|
|
|
}
|
2019-06-07 08:59:07 +00:00
|
|
|
|
2022-03-17 15:13:38 +00:00
|
|
|
public abstract class SmsProvider : Consumer
|
|
|
|
{
|
2022-05-26 09:01:54 +00:00
|
|
|
protected ILogger<SmsProvider> Log { get; }
|
2022-03-17 15:13:38 +00:00
|
|
|
protected IHttpClientFactory ClientFactory { get; }
|
|
|
|
protected ICache MemoryCache { get; set; }
|
2019-06-07 08:59:07 +00:00
|
|
|
|
2022-03-17 15:13:38 +00:00
|
|
|
protected virtual string SendMessageUrlFormat { get; set; }
|
|
|
|
protected virtual string GetBalanceUrlFormat { get; set; }
|
|
|
|
protected virtual string Key { get; set; }
|
|
|
|
protected virtual string Secret { get; set; }
|
|
|
|
protected virtual string Sender { get; set; }
|
2019-06-07 08:59:07 +00:00
|
|
|
|
2022-03-17 15:13:38 +00:00
|
|
|
protected SmsProvider()
|
|
|
|
{
|
2019-06-07 08:59:07 +00:00
|
|
|
}
|
|
|
|
|
2022-03-17 15:13:38 +00:00
|
|
|
protected SmsProvider(
|
|
|
|
TenantManager tenantManager,
|
|
|
|
CoreBaseSettings coreBaseSettings,
|
|
|
|
CoreSettings coreSettings,
|
|
|
|
IConfiguration configuration,
|
|
|
|
ICacheNotify<ConsumerCacheItem> cache,
|
|
|
|
ConsumerFactory consumerFactory,
|
2022-05-26 09:01:54 +00:00
|
|
|
ILogger<SmsProvider> logger,
|
2022-03-17 15:13:38 +00:00
|
|
|
IHttpClientFactory clientFactory,
|
|
|
|
ICache memCache,
|
|
|
|
string name, int order, Dictionary<string, string> props, Dictionary<string, string> additional = null)
|
|
|
|
: base(tenantManager, coreBaseSettings, coreSettings, configuration, cache, consumerFactory, name, order, props, additional)
|
2019-06-07 08:59:07 +00:00
|
|
|
{
|
2022-03-17 15:13:38 +00:00
|
|
|
MemoryCache = memCache;
|
2022-04-26 17:53:48 +00:00
|
|
|
Log = logger;
|
2022-03-17 15:13:38 +00:00
|
|
|
ClientFactory = clientFactory;
|
|
|
|
}
|
2019-06-07 08:59:07 +00:00
|
|
|
|
2022-03-17 15:13:38 +00:00
|
|
|
public virtual bool Enable()
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
2019-06-07 08:59:07 +00:00
|
|
|
|
2022-03-17 15:13:38 +00:00
|
|
|
private string SendMessageUrl()
|
|
|
|
{
|
|
|
|
return SendMessageUrlFormat
|
|
|
|
.Replace("{key}", Key)
|
|
|
|
.Replace("{secret}", Secret)
|
|
|
|
.Replace("{sender}", Sender);
|
|
|
|
}
|
2019-06-07 08:59:07 +00:00
|
|
|
|
2022-03-17 15:13:38 +00:00
|
|
|
public virtual async Task<bool> SendMessageAsync(string number, string message)
|
|
|
|
{
|
|
|
|
try
|
2019-06-07 08:59:07 +00:00
|
|
|
{
|
2022-03-17 15:13:38 +00:00
|
|
|
var url = SendMessageUrl();
|
|
|
|
url = url.Replace("{phone}", number).Replace("{text}", HttpUtility.UrlEncode(message));
|
|
|
|
|
2022-04-14 19:23:57 +00:00
|
|
|
var request = new HttpRequestMessage
|
|
|
|
{
|
|
|
|
RequestUri = new Uri(url)
|
|
|
|
};
|
2022-03-17 15:13:38 +00:00
|
|
|
request.Content.Headers.ContentType = new MediaTypeHeaderValue("application/x-www-form-urlencoded");
|
2019-06-07 08:59:07 +00:00
|
|
|
|
2022-03-17 15:13:38 +00:00
|
|
|
var httpClient = ClientFactory.CreateClient();
|
|
|
|
httpClient.Timeout = TimeSpan.FromMilliseconds(15000);
|
|
|
|
|
|
|
|
using var response = await httpClient.SendAsync(request);
|
|
|
|
using var stream = await response.Content.ReadAsStreamAsync();
|
|
|
|
if (stream != null)
|
|
|
|
{
|
|
|
|
using var reader = new StreamReader(stream);
|
|
|
|
var result = await reader.ReadToEndAsync();
|
2022-05-13 14:48:49 +00:00
|
|
|
Log.InformationSMSWasSend(number, result);
|
2022-03-17 15:13:38 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
catch (Exception ex)
|
2019-06-07 08:59:07 +00:00
|
|
|
{
|
2022-05-13 14:48:49 +00:00
|
|
|
Log.ErrorSendSms(ex);
|
2019-06-07 08:59:07 +00:00
|
|
|
}
|
2022-03-17 15:13:38 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
2019-06-07 08:59:07 +00:00
|
|
|
|
2022-03-17 15:13:38 +00:00
|
|
|
public class SmscProvider : SmsProvider, IValidateKeysProvider
|
|
|
|
{
|
|
|
|
public SmscProvider()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
public SmscProvider(
|
|
|
|
TenantManager tenantManager,
|
|
|
|
CoreBaseSettings coreBaseSettings,
|
|
|
|
CoreSettings coreSettings,
|
|
|
|
IConfiguration configuration,
|
|
|
|
ICacheNotify<ConsumerCacheItem> cache,
|
|
|
|
ConsumerFactory consumerFactory,
|
2022-05-26 09:01:54 +00:00
|
|
|
ILogger<SmsProvider> options,
|
2022-03-17 15:13:38 +00:00
|
|
|
IHttpClientFactory clientFactory,
|
|
|
|
ICache memCache,
|
|
|
|
string name, int order, Dictionary<string, string> props, Dictionary<string, string> additional = null)
|
|
|
|
: base(tenantManager, coreBaseSettings, coreSettings, configuration, cache, consumerFactory, options, clientFactory, memCache, name, order, props, additional)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
protected override string SendMessageUrlFormat
|
|
|
|
{
|
|
|
|
get { return "https://smsc.ru/sys/send.php?login={key}&psw={secret}&phones={phone}&mes={text}&fmt=3&sender={sender}&charset=utf-8"; }
|
|
|
|
}
|
|
|
|
|
|
|
|
protected override string GetBalanceUrlFormat
|
|
|
|
{
|
|
|
|
get { return "https://smsc.ru/sys/balance.php?login={key}&psw={secret}"; }
|
|
|
|
}
|
|
|
|
|
|
|
|
protected override string Key
|
|
|
|
{
|
|
|
|
get { return this["smsclogin"]; }
|
|
|
|
}
|
|
|
|
|
|
|
|
protected override string Secret
|
|
|
|
{
|
|
|
|
get { return this["smscpsw"]; }
|
|
|
|
}
|
|
|
|
|
|
|
|
protected override string Sender
|
|
|
|
{
|
|
|
|
get { return this["smscsender"]; }
|
|
|
|
}
|
|
|
|
|
|
|
|
public override bool Enable()
|
|
|
|
{
|
|
|
|
return
|
|
|
|
!string.IsNullOrEmpty(Key)
|
|
|
|
&& !string.IsNullOrEmpty(Secret);
|
|
|
|
}
|
|
|
|
|
|
|
|
public async Task<string> GetBalanceAsync(Tenant tenant, bool eraseCache = false)
|
|
|
|
{
|
|
|
|
var tenantCache = tenant == null ? Tenant.DefaultTenant : tenant.Id;
|
|
|
|
|
|
|
|
var key = "sms/smsc/" + tenantCache;
|
|
|
|
if (eraseCache)
|
2019-06-07 08:59:07 +00:00
|
|
|
{
|
2022-03-17 15:13:38 +00:00
|
|
|
MemoryCache.Remove(key);
|
2019-06-07 08:59:07 +00:00
|
|
|
}
|
|
|
|
|
2022-03-17 15:13:38 +00:00
|
|
|
var balance = MemoryCache.Get<string>(key);
|
|
|
|
|
|
|
|
if (string.IsNullOrEmpty(balance))
|
2019-06-07 08:59:07 +00:00
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
2022-03-17 15:13:38 +00:00
|
|
|
var url = GetBalanceUrl();
|
2019-06-07 08:59:07 +00:00
|
|
|
|
2022-04-14 19:23:57 +00:00
|
|
|
var request = new HttpRequestMessage
|
|
|
|
{
|
|
|
|
RequestUri = new Uri(url)
|
|
|
|
};
|
2022-01-24 19:44:18 +00:00
|
|
|
request.Content.Headers.ContentType = new MediaTypeHeaderValue("application/x-www-form-urlencoded");
|
2021-10-21 14:56:31 +00:00
|
|
|
|
2022-01-13 11:19:39 +00:00
|
|
|
var httpClient = ClientFactory.CreateClient();
|
2022-03-17 15:13:38 +00:00
|
|
|
httpClient.Timeout = TimeSpan.FromMilliseconds(1000);
|
2019-06-07 08:59:07 +00:00
|
|
|
|
2022-01-31 14:35:36 +00:00
|
|
|
using var response = await httpClient.SendAsync(request);
|
|
|
|
using var stream = await response.Content.ReadAsStreamAsync();
|
2019-08-15 15:08:40 +00:00
|
|
|
if (stream != null)
|
2019-06-07 08:59:07 +00:00
|
|
|
{
|
2019-08-15 15:08:40 +00:00
|
|
|
using var reader = new StreamReader(stream);
|
2022-01-31 14:35:36 +00:00
|
|
|
var result = await reader.ReadToEndAsync();
|
2022-05-13 14:48:49 +00:00
|
|
|
Log.InformationSmsBalaceReturned(result);
|
2022-03-17 15:13:38 +00:00
|
|
|
|
|
|
|
balance = result;
|
2019-06-07 08:59:07 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
catch (Exception ex)
|
|
|
|
{
|
2022-05-13 14:48:49 +00:00
|
|
|
Log.ErrorRequestSms(ex);
|
2022-03-17 15:13:38 +00:00
|
|
|
balance = string.Empty;
|
2019-06-07 08:59:07 +00:00
|
|
|
}
|
|
|
|
|
2022-03-17 15:13:38 +00:00
|
|
|
MemoryCache.Insert(key, balance, TimeSpan.FromMinutes(1));
|
2019-06-07 08:59:07 +00:00
|
|
|
}
|
|
|
|
|
2022-03-17 15:13:38 +00:00
|
|
|
return balance;
|
|
|
|
}
|
2019-06-07 08:59:07 +00:00
|
|
|
|
2022-03-17 15:13:38 +00:00
|
|
|
private string GetBalanceUrl()
|
|
|
|
{
|
|
|
|
return GetBalanceUrlFormat
|
|
|
|
.Replace("{key}", Key)
|
|
|
|
.Replace("{secret}", Secret);
|
|
|
|
}
|
2019-06-07 08:59:07 +00:00
|
|
|
|
2022-03-17 15:13:38 +00:00
|
|
|
public bool SuitableNumber(string number)
|
|
|
|
{
|
|
|
|
var smsCis = this["smsccis"];
|
|
|
|
return !string.IsNullOrEmpty(smsCis) && Regex.IsMatch(number, smsCis);
|
|
|
|
}
|
2019-06-07 08:59:07 +00:00
|
|
|
|
2022-03-17 15:13:38 +00:00
|
|
|
public bool ValidateKeys()
|
|
|
|
{
|
|
|
|
return double.TryParse(GetBalanceAsync(TenantManager.GetCurrentTenant(false), true).Result, NumberStyles.Number, CultureInfo.InvariantCulture, out var balance) && balance > 0;
|
|
|
|
}
|
|
|
|
}
|
2019-06-07 08:59:07 +00:00
|
|
|
|
2022-03-17 15:13:38 +00:00
|
|
|
public class ClickatellProvider : SmsProvider
|
|
|
|
{
|
|
|
|
protected override string SendMessageUrlFormat
|
|
|
|
{
|
|
|
|
get { return "https://platform.clickatell.com/messages/http/send?apiKey={secret}&to={phone}&content={text}&from={sender}"; }
|
|
|
|
}
|
2019-06-07 08:59:07 +00:00
|
|
|
|
2022-03-17 15:13:38 +00:00
|
|
|
protected override string Secret
|
|
|
|
{
|
|
|
|
get { return this["clickatellapiKey"]; }
|
|
|
|
}
|
2019-06-07 08:59:07 +00:00
|
|
|
|
2022-03-17 15:13:38 +00:00
|
|
|
protected override string Sender
|
|
|
|
{
|
|
|
|
get { return this["clickatellSender"]; }
|
|
|
|
}
|
2019-06-07 08:59:07 +00:00
|
|
|
|
2022-03-17 15:13:38 +00:00
|
|
|
public override bool Enable()
|
|
|
|
{
|
|
|
|
return !string.IsNullOrEmpty(Secret);
|
|
|
|
}
|
2019-06-07 08:59:07 +00:00
|
|
|
|
2022-03-17 15:13:38 +00:00
|
|
|
public ClickatellProvider()
|
|
|
|
{
|
|
|
|
}
|
2019-06-07 08:59:07 +00:00
|
|
|
|
2022-03-17 15:13:38 +00:00
|
|
|
public ClickatellProvider(
|
|
|
|
TenantManager tenantManager,
|
|
|
|
CoreBaseSettings coreBaseSettings,
|
|
|
|
CoreSettings coreSettings,
|
|
|
|
IConfiguration configuration,
|
|
|
|
ICacheNotify<ConsumerCacheItem> cache,
|
|
|
|
ConsumerFactory consumerFactory,
|
2022-04-26 17:53:48 +00:00
|
|
|
ILogger<ClickatellProvider> options,
|
2022-03-17 15:13:38 +00:00
|
|
|
IHttpClientFactory clientFactory,
|
|
|
|
ICache memCache,
|
|
|
|
string name, int order, Dictionary<string, string> props, Dictionary<string, string> additional = null)
|
|
|
|
: base(tenantManager, coreBaseSettings, coreSettings, configuration, cache, consumerFactory, options, clientFactory, memCache, name, order, props, additional)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
}
|
2021-10-12 10:14:33 +00:00
|
|
|
|
2022-03-17 15:13:38 +00:00
|
|
|
public class ClickatellUSAProvider : ClickatellProvider
|
|
|
|
{
|
|
|
|
public ClickatellUSAProvider()
|
|
|
|
{
|
|
|
|
}
|
2019-08-15 15:08:40 +00:00
|
|
|
|
2022-03-17 15:13:38 +00:00
|
|
|
public ClickatellUSAProvider(
|
|
|
|
TenantManager tenantManager,
|
|
|
|
CoreBaseSettings coreBaseSettings,
|
|
|
|
CoreSettings coreSettings,
|
|
|
|
IConfiguration configuration,
|
|
|
|
ICacheNotify<ConsumerCacheItem> cache,
|
|
|
|
ConsumerFactory consumerFactory,
|
2022-04-26 17:53:48 +00:00
|
|
|
ILogger<ClickatellUSAProvider> options,
|
2022-03-17 15:13:38 +00:00
|
|
|
IHttpClientFactory clientFactory,
|
|
|
|
ICache memCache,
|
|
|
|
string name, int order, Dictionary<string, string> additional = null)
|
|
|
|
: base(tenantManager, coreBaseSettings, coreSettings, configuration, cache, consumerFactory, options, clientFactory, memCache, name, order, null, additional)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
}
|
2019-06-07 08:59:07 +00:00
|
|
|
|
2022-03-17 15:13:38 +00:00
|
|
|
[Scope]
|
|
|
|
public class TwilioProvider : SmsProvider, IValidateKeysProvider
|
|
|
|
{
|
|
|
|
protected override string Key
|
|
|
|
{
|
|
|
|
get { return this["twilioAccountSid"]; }
|
|
|
|
}
|
2019-06-07 08:59:07 +00:00
|
|
|
|
2022-03-17 15:13:38 +00:00
|
|
|
protected override string Secret
|
|
|
|
{
|
|
|
|
get { return this["twilioAuthToken"]; }
|
|
|
|
}
|
2019-06-07 08:59:07 +00:00
|
|
|
|
2022-03-17 15:13:38 +00:00
|
|
|
protected override string Sender
|
|
|
|
{
|
|
|
|
get { return this["twiliosender"]; }
|
|
|
|
}
|
2019-06-07 08:59:07 +00:00
|
|
|
|
2022-04-15 09:08:06 +00:00
|
|
|
private readonly AuthContext _authContext;
|
|
|
|
private readonly TenantUtil _tenantUtil;
|
|
|
|
private readonly SecurityContext _securityContext;
|
|
|
|
private readonly BaseCommonLinkUtility _baseCommonLinkUtility;
|
|
|
|
private readonly TwilioProviderCleaner _twilioProviderCleaner;
|
2019-06-07 08:59:07 +00:00
|
|
|
|
2022-03-17 15:13:38 +00:00
|
|
|
public override bool Enable()
|
|
|
|
{
|
|
|
|
return
|
|
|
|
!string.IsNullOrEmpty(Key)
|
|
|
|
&& !string.IsNullOrEmpty(Secret)
|
|
|
|
&& !string.IsNullOrEmpty(Sender);
|
2019-06-07 08:59:07 +00:00
|
|
|
}
|
|
|
|
|
2022-03-17 15:13:38 +00:00
|
|
|
public override Task<bool> SendMessageAsync(string number, string message)
|
2019-06-07 08:59:07 +00:00
|
|
|
{
|
2022-03-17 15:13:38 +00:00
|
|
|
if (!number.StartsWith('+'))
|
2019-06-07 08:59:07 +00:00
|
|
|
{
|
2022-03-17 15:13:38 +00:00
|
|
|
number = "+" + number;
|
2019-06-07 08:59:07 +00:00
|
|
|
}
|
|
|
|
|
2022-03-17 15:13:38 +00:00
|
|
|
var twilioRestClient = new TwilioRestClient(Key, Secret);
|
2019-06-07 08:59:07 +00:00
|
|
|
|
2022-03-17 15:13:38 +00:00
|
|
|
try
|
2019-06-07 08:59:07 +00:00
|
|
|
{
|
2022-03-17 15:13:38 +00:00
|
|
|
var smsMessage = MessageResource.Create(new PhoneNumber(number), body: message, @from: new PhoneNumber(Sender), client: twilioRestClient);
|
2022-05-13 14:48:49 +00:00
|
|
|
Log.InformationSmsWasSendTo(number, smsMessage.Status);
|
2022-03-17 15:13:38 +00:00
|
|
|
if (!smsMessage.ErrorCode.HasValue)
|
|
|
|
{
|
|
|
|
return Task.FromResult(true);
|
|
|
|
}
|
2022-05-13 14:48:49 +00:00
|
|
|
Log.ErrorSendSmsWithCode(smsMessage.ErrorCode.Value, smsMessage.ErrorMessage);
|
2019-06-07 08:59:07 +00:00
|
|
|
}
|
2022-03-17 15:13:38 +00:00
|
|
|
catch (Exception ex)
|
2019-06-07 08:59:07 +00:00
|
|
|
{
|
2022-05-13 14:48:49 +00:00
|
|
|
Log.ErrorSendSmsViaTiwilio(ex);
|
2019-06-07 08:59:07 +00:00
|
|
|
}
|
|
|
|
|
2022-03-17 15:13:38 +00:00
|
|
|
return Task.FromResult(false);
|
2019-06-07 08:59:07 +00:00
|
|
|
}
|
|
|
|
|
2022-03-17 15:13:38 +00:00
|
|
|
public TwilioProvider()
|
2019-06-07 08:59:07 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2022-03-17 15:13:38 +00:00
|
|
|
public TwilioProvider(
|
|
|
|
AuthContext authContext,
|
|
|
|
TenantUtil tenantUtil,
|
|
|
|
SecurityContext securityContext,
|
|
|
|
BaseCommonLinkUtility baseCommonLinkUtility,
|
|
|
|
TwilioProviderCleaner twilioProviderCleaner,
|
|
|
|
TenantManager tenantManager,
|
|
|
|
CoreBaseSettings coreBaseSettings,
|
|
|
|
CoreSettings coreSettings,
|
|
|
|
IConfiguration configuration,
|
|
|
|
ICacheNotify<ConsumerCacheItem> cache,
|
|
|
|
ConsumerFactory consumerFactory,
|
2022-04-26 17:53:48 +00:00
|
|
|
ILogger<TwilioProvider> options,
|
2022-03-17 15:13:38 +00:00
|
|
|
IHttpClientFactory clientFactory,
|
|
|
|
ICache memCache,
|
|
|
|
string name, int order, Dictionary<string, string> props)
|
|
|
|
: base(tenantManager, coreBaseSettings, coreSettings, configuration, cache, consumerFactory, options, clientFactory, memCache, name, order, props)
|
2019-06-07 08:59:07 +00:00
|
|
|
{
|
2022-04-15 09:08:06 +00:00
|
|
|
_authContext = authContext;
|
|
|
|
_tenantUtil = tenantUtil;
|
|
|
|
_securityContext = securityContext;
|
|
|
|
_baseCommonLinkUtility = baseCommonLinkUtility;
|
|
|
|
_twilioProviderCleaner = twilioProviderCleaner;
|
2022-03-17 15:13:38 +00:00
|
|
|
}
|
2019-06-07 08:59:07 +00:00
|
|
|
|
|
|
|
|
2022-03-17 15:13:38 +00:00
|
|
|
public bool ValidateKeys()
|
|
|
|
{
|
|
|
|
try
|
2019-06-07 08:59:07 +00:00
|
|
|
{
|
2022-04-15 09:08:06 +00:00
|
|
|
new VoipService.Twilio.TwilioProvider(Key, Secret, _authContext, _tenantUtil, _securityContext, _baseCommonLinkUtility).GetExistingPhoneNumbers();
|
2022-03-17 15:13:38 +00:00
|
|
|
return true;
|
2019-06-07 08:59:07 +00:00
|
|
|
}
|
2022-03-17 15:13:38 +00:00
|
|
|
catch (Exception)
|
2019-06-07 08:59:07 +00:00
|
|
|
{
|
2022-03-17 15:13:38 +00:00
|
|
|
return false;
|
2019-06-07 08:59:07 +00:00
|
|
|
}
|
2022-03-17 15:13:38 +00:00
|
|
|
}
|
2019-06-07 08:59:07 +00:00
|
|
|
|
2022-03-17 15:13:38 +00:00
|
|
|
public void ClearOldNumbers()
|
|
|
|
{
|
2022-04-15 09:08:06 +00:00
|
|
|
_twilioProviderCleaner.ClearOldNumbers(Key, Secret);
|
2019-06-07 08:59:07 +00:00
|
|
|
}
|
2022-03-17 15:13:38 +00:00
|
|
|
}
|
2019-06-07 08:59:07 +00:00
|
|
|
|
2022-03-17 15:13:38 +00:00
|
|
|
[Scope]
|
|
|
|
public class TwilioSaaSProvider : TwilioProvider
|
|
|
|
{
|
|
|
|
public TwilioSaaSProvider()
|
2019-06-07 08:59:07 +00:00
|
|
|
{
|
2022-03-17 15:13:38 +00:00
|
|
|
}
|
2019-06-07 08:59:07 +00:00
|
|
|
|
2022-03-17 15:13:38 +00:00
|
|
|
public TwilioSaaSProvider(
|
|
|
|
AuthContext authContext,
|
|
|
|
TenantUtil tenantUtil,
|
|
|
|
SecurityContext securityContext,
|
|
|
|
BaseCommonLinkUtility baseCommonLinkUtility,
|
|
|
|
TwilioProviderCleaner twilioProviderCleaner,
|
|
|
|
TenantManager tenantManager,
|
|
|
|
CoreBaseSettings coreBaseSettings,
|
|
|
|
CoreSettings coreSettings,
|
|
|
|
IConfiguration configuration,
|
|
|
|
ICacheNotify<ConsumerCacheItem> cache,
|
|
|
|
ConsumerFactory consumerFactory,
|
2022-04-26 17:53:48 +00:00
|
|
|
ILogger<TwilioSaaSProvider> options,
|
2022-03-17 15:13:38 +00:00
|
|
|
IHttpClientFactory clientFactory,
|
|
|
|
ICache memCache,
|
|
|
|
string name, int order)
|
|
|
|
: base(authContext, tenantUtil, securityContext, baseCommonLinkUtility, twilioProviderCleaner, tenantManager, coreBaseSettings, coreSettings, configuration, cache, consumerFactory, options, clientFactory, memCache, name, order, null)
|
|
|
|
{
|
2020-08-26 14:34:21 +00:00
|
|
|
}
|
2022-03-17 15:13:38 +00:00
|
|
|
}
|
2020-08-26 14:34:21 +00:00
|
|
|
|
2022-03-17 15:13:38 +00:00
|
|
|
[Scope]
|
|
|
|
public class TwilioProviderCleaner
|
|
|
|
{
|
2022-04-15 09:08:06 +00:00
|
|
|
private readonly VoipDao _voipDao;
|
|
|
|
private readonly AuthContext _authContext;
|
|
|
|
private readonly TenantUtil _tenantUtil;
|
|
|
|
private readonly SecurityContext _securityContext;
|
|
|
|
private readonly BaseCommonLinkUtility _baseCommonLinkUtility;
|
2022-03-17 15:13:38 +00:00
|
|
|
|
|
|
|
public TwilioProviderCleaner(VoipDao voipDao, AuthContext authContext, TenantUtil tenantUtil, SecurityContext securityContext, BaseCommonLinkUtility baseCommonLinkUtility)
|
2020-08-26 14:34:21 +00:00
|
|
|
{
|
2022-04-15 09:08:06 +00:00
|
|
|
_voipDao = voipDao;
|
|
|
|
_authContext = authContext;
|
|
|
|
_tenantUtil = tenantUtil;
|
|
|
|
_securityContext = securityContext;
|
|
|
|
_baseCommonLinkUtility = baseCommonLinkUtility;
|
2022-03-17 15:13:38 +00:00
|
|
|
}
|
2020-08-26 14:34:21 +00:00
|
|
|
|
2022-03-17 15:13:38 +00:00
|
|
|
public void ClearOldNumbers(string key, string secret)
|
|
|
|
{
|
|
|
|
if (string.IsNullOrEmpty(key) || string.IsNullOrEmpty(secret))
|
2020-08-26 14:34:21 +00:00
|
|
|
{
|
2022-03-17 15:13:38 +00:00
|
|
|
return;
|
2020-08-26 14:34:21 +00:00
|
|
|
}
|
|
|
|
|
2022-04-15 09:08:06 +00:00
|
|
|
var provider = new VoipService.Twilio.TwilioProvider(key, secret, _authContext, _tenantUtil, _securityContext, _baseCommonLinkUtility);
|
2020-08-26 14:34:21 +00:00
|
|
|
|
2022-04-15 09:08:06 +00:00
|
|
|
var numbers = _voipDao.GetNumbers();
|
2022-03-17 15:13:38 +00:00
|
|
|
foreach (var number in numbers)
|
|
|
|
{
|
|
|
|
provider.DisablePhone(number);
|
2022-04-15 09:08:06 +00:00
|
|
|
_voipDao.DeleteNumber(number.Id);
|
2019-06-07 08:59:07 +00:00
|
|
|
}
|
|
|
|
}
|
2022-03-17 15:13:38 +00:00
|
|
|
}
|
2020-04-17 14:07:44 +00:00
|
|
|
|
2022-03-17 15:13:38 +00:00
|
|
|
public static class TwilioProviderExtention
|
|
|
|
{
|
|
|
|
public static void Register(DIHelper services)
|
2020-04-17 14:07:44 +00:00
|
|
|
{
|
2022-03-17 15:13:38 +00:00
|
|
|
services.TryAdd<TwilioSaaSProvider>();
|
2020-04-17 14:07:44 +00:00
|
|
|
}
|
2022-03-17 15:13:38 +00:00
|
|
|
}
|