diff --git a/Directory.Packages.props b/Directory.Packages.props
index 0602fe2658..9acb8f8bf7 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -168,6 +168,7 @@
+
@@ -177,4 +178,4 @@
-
+
\ No newline at end of file
diff --git a/framework/Volo.Abp.sln b/framework/Volo.Abp.sln
index ca1a85fd8d..f716082008 100644
--- a/framework/Volo.Abp.sln
+++ b/framework/Volo.Abp.sln
@@ -473,6 +473,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.BlobStoring.Google
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.ExceptionHandling.Tests", "test\Volo.Abp.ExceptionHandling.Tests\Volo.Abp.ExceptionHandling.Tests.csproj", "{E50739A7-5E2F-4EB5-AEA9-554115CB9613}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.Sms.TencentCloud", "src\Volo.Abp.Sms.TencentCloud\Volo.Abp.Sms.TencentCloud.csproj", "{BE7109C5-7368-4688-8557-4A15D3F4776A}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.Sms.TencentCloud.Tests", "test\Volo.Abp.Sms.TencenCloud.Tests\Volo.Abp.Sms.TencentCloud.Tests.csproj", "{C753DDD6-5699-45F8-8669-08CE0BB816DE}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -1411,6 +1415,14 @@ Global
{E50739A7-5E2F-4EB5-AEA9-554115CB9613}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E50739A7-5E2F-4EB5-AEA9-554115CB9613}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E50739A7-5E2F-4EB5-AEA9-554115CB9613}.Release|Any CPU.Build.0 = Release|Any CPU
+ {BE7109C5-7368-4688-8557-4A15D3F4776A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {BE7109C5-7368-4688-8557-4A15D3F4776A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {BE7109C5-7368-4688-8557-4A15D3F4776A}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {BE7109C5-7368-4688-8557-4A15D3F4776A}.Release|Any CPU.Build.0 = Release|Any CPU
+ {C753DDD6-5699-45F8-8669-08CE0BB816DE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {C753DDD6-5699-45F8-8669-08CE0BB816DE}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {C753DDD6-5699-45F8-8669-08CE0BB816DE}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {C753DDD6-5699-45F8-8669-08CE0BB816DE}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -1649,6 +1661,8 @@ Global
{DEEB5200-BBF9-464D-9B7E-8FC035A27E94} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6}
{40FB8907-9CF7-44D0-8B5F-538AC6DAF8B9} = {447C8A77-E5F0-4538-8687-7383196D04EA}
{E50739A7-5E2F-4EB5-AEA9-554115CB9613} = {447C8A77-E5F0-4538-8687-7383196D04EA}
+ {BE7109C5-7368-4688-8557-4A15D3F4776A} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6}
+ {C753DDD6-5699-45F8-8669-08CE0BB816DE} = {447C8A77-E5F0-4538-8687-7383196D04EA}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {BB97ECF4-9A84-433F-A80B-2A3285BDD1D5}
diff --git a/framework/src/Volo.Abp.Sms.TencentCloud/FodyWeavers.xml b/framework/src/Volo.Abp.Sms.TencentCloud/FodyWeavers.xml
new file mode 100644
index 0000000000..2ad59ce186
--- /dev/null
+++ b/framework/src/Volo.Abp.Sms.TencentCloud/FodyWeavers.xml
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff --git a/framework/src/Volo.Abp.Sms.TencentCloud/FodyWeavers.xsd b/framework/src/Volo.Abp.Sms.TencentCloud/FodyWeavers.xsd
new file mode 100644
index 0000000000..ffa6fc4b78
--- /dev/null
+++ b/framework/src/Volo.Abp.Sms.TencentCloud/FodyWeavers.xsd
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.
+
+
+
+
+ A comma-separated list of error codes that can be safely ignored in assembly verification.
+
+
+
+
+ 'false' to turn off automatic generation of the XML Schema file.
+
+
+
+
+
\ No newline at end of file
diff --git a/framework/src/Volo.Abp.Sms.TencentCloud/Volo.Abp.Sms.TencentCloud.abppkg b/framework/src/Volo.Abp.Sms.TencentCloud/Volo.Abp.Sms.TencentCloud.abppkg
new file mode 100644
index 0000000000..f4bad072d2
--- /dev/null
+++ b/framework/src/Volo.Abp.Sms.TencentCloud/Volo.Abp.Sms.TencentCloud.abppkg
@@ -0,0 +1,3 @@
+{
+ "role": "lib.framework"
+}
\ No newline at end of file
diff --git a/framework/src/Volo.Abp.Sms.TencentCloud/Volo.Abp.Sms.TencentCloud.abppkg.analyze.json b/framework/src/Volo.Abp.Sms.TencentCloud/Volo.Abp.Sms.TencentCloud.abppkg.analyze.json
new file mode 100644
index 0000000000..83fe6d66b9
--- /dev/null
+++ b/framework/src/Volo.Abp.Sms.TencentCloud/Volo.Abp.Sms.TencentCloud.abppkg.analyze.json
@@ -0,0 +1,63 @@
+{
+ "name": "Volo.Abp.Sms.TencentCloud",
+ "hash": "",
+ "contents": [
+ {
+ "namespace": "Volo.Abp.Sms.TencentCloud",
+ "dependsOnModules": [
+ {
+ "declaringAssemblyName": "Volo.Abp.Sms",
+ "namespace": "Volo.Abp.Sms",
+ "name": "AbpSmsModule"
+ }
+ ],
+ "implementingInterfaces": [
+ {
+ "name": "IAbpModule",
+ "namespace": "Volo.Abp.Modularity",
+ "declaringAssemblyName": "Volo.Abp.Core",
+ "fullName": "Volo.Abp.Modularity.IAbpModule"
+ },
+ {
+ "name": "IOnPreApplicationInitialization",
+ "namespace": "Volo.Abp.Modularity",
+ "declaringAssemblyName": "Volo.Abp.Core",
+ "fullName": "Volo.Abp.Modularity.IOnPreApplicationInitialization"
+ },
+ {
+ "name": "IOnApplicationInitialization",
+ "namespace": "Volo.Abp",
+ "declaringAssemblyName": "Volo.Abp.Core",
+ "fullName": "Volo.Abp.IOnApplicationInitialization"
+ },
+ {
+ "name": "IOnPostApplicationInitialization",
+ "namespace": "Volo.Abp.Modularity",
+ "declaringAssemblyName": "Volo.Abp.Core",
+ "fullName": "Volo.Abp.Modularity.IOnPostApplicationInitialization"
+ },
+ {
+ "name": "IOnApplicationShutdown",
+ "namespace": "Volo.Abp",
+ "declaringAssemblyName": "Volo.Abp.Core",
+ "fullName": "Volo.Abp.IOnApplicationShutdown"
+ },
+ {
+ "name": "IPreConfigureServices",
+ "namespace": "Volo.Abp.Modularity",
+ "declaringAssemblyName": "Volo.Abp.Core",
+ "fullName": "Volo.Abp.Modularity.IPreConfigureServices"
+ },
+ {
+ "name": "IPostConfigureServices",
+ "namespace": "Volo.Abp.Modularity",
+ "declaringAssemblyName": "Volo.Abp.Core",
+ "fullName": "Volo.Abp.Modularity.IPostConfigureServices"
+ }
+ ],
+ "contentType": "abpModule",
+ "name": "AbpSmsTencentCloudModule",
+ "summary": null
+ }
+ ]
+}
\ No newline at end of file
diff --git a/framework/src/Volo.Abp.Sms.TencentCloud/Volo.Abp.Sms.TencentCloud.csproj b/framework/src/Volo.Abp.Sms.TencentCloud/Volo.Abp.Sms.TencentCloud.csproj
new file mode 100644
index 0000000000..3077ff392e
--- /dev/null
+++ b/framework/src/Volo.Abp.Sms.TencentCloud/Volo.Abp.Sms.TencentCloud.csproj
@@ -0,0 +1,26 @@
+
+
+
+
+
+ netstandard2.0;netstandard2.1;net8.0;net9.0
+ enable
+ Nullable
+ Volo.Abp.Sms.TencentCloud
+ Volo.Abp.Sms.TencentCloud
+ $(AssetTargetFallback);portable-net45+win8+wp8+wpa81;
+ false
+ false
+ false
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/framework/src/Volo.Abp.Sms.TencentCloud/Volo/Abp/Sms/TencentCloud/AbpSmsTencentCloudModule.cs b/framework/src/Volo.Abp.Sms.TencentCloud/Volo/Abp/Sms/TencentCloud/AbpSmsTencentCloudModule.cs
new file mode 100644
index 0000000000..b846a53e9d
--- /dev/null
+++ b/framework/src/Volo.Abp.Sms.TencentCloud/Volo/Abp/Sms/TencentCloud/AbpSmsTencentCloudModule.cs
@@ -0,0 +1,15 @@
+using Microsoft.Extensions.DependencyInjection;
+using Volo.Abp.Modularity;
+
+namespace Volo.Abp.Sms.TencentCloud;
+
+[DependsOn(typeof(AbpSmsModule))]
+public class AbpSmsTencentCloudModule : AbpModule
+{
+ public override void ConfigureServices(ServiceConfigurationContext context)
+ {
+ var configuration = context.Services.GetConfiguration();
+
+ Configure(configuration.GetSection("AbpTencentCloudSms"));
+ }
+}
diff --git a/framework/src/Volo.Abp.Sms.TencentCloud/Volo/Abp/Sms/TencentCloud/AbpTencentCloudSmsOptions.cs b/framework/src/Volo.Abp.Sms.TencentCloud/Volo/Abp/Sms/TencentCloud/AbpTencentCloudSmsOptions.cs
new file mode 100644
index 0000000000..cec86d9b36
--- /dev/null
+++ b/framework/src/Volo.Abp.Sms.TencentCloud/Volo/Abp/Sms/TencentCloud/AbpTencentCloudSmsOptions.cs
@@ -0,0 +1,14 @@
+namespace Volo.Abp.Sms.TencentCloud;
+
+public class AbpTencentCloudSmsOptions
+{
+ public string SmsSdkAppId { get; set; } = default!;
+
+ public string SecretKey { get; set; } = default!;
+
+ public string SecretId { get; set; } = default!;
+
+ public string Endpoint { get; set; } = "sms.tencentcloudapi.com";
+
+ public string Region { get; set; } = "ap-guangzhou";
+}
diff --git a/framework/src/Volo.Abp.Sms.TencentCloud/Volo/Abp/Sms/TencentCloud/TencentCloudSmsProperties.cs b/framework/src/Volo.Abp.Sms.TencentCloud/Volo/Abp/Sms/TencentCloud/TencentCloudSmsProperties.cs
new file mode 100644
index 0000000000..7253a85ba6
--- /dev/null
+++ b/framework/src/Volo.Abp.Sms.TencentCloud/Volo/Abp/Sms/TencentCloud/TencentCloudSmsProperties.cs
@@ -0,0 +1,8 @@
+namespace Volo.Abp.Sms.TencentCloud;
+
+public static class TencentCloudSmsProperties
+{
+ public const string SignName = "SignName";
+
+ public const string TemplateId = "TemplateId";
+}
\ No newline at end of file
diff --git a/framework/src/Volo.Abp.Sms.TencentCloud/Volo/Abp/Sms/TencentCloud/TencentCloudSmsSender.cs b/framework/src/Volo.Abp.Sms.TencentCloud/Volo/Abp/Sms/TencentCloud/TencentCloudSmsSender.cs
new file mode 100644
index 0000000000..fa3c585576
--- /dev/null
+++ b/framework/src/Volo.Abp.Sms.TencentCloud/Volo/Abp/Sms/TencentCloud/TencentCloudSmsSender.cs
@@ -0,0 +1,51 @@
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using Microsoft.Extensions.Options;
+using TencentCloud.Common;
+using TencentCloud.Common.Profile;
+using TencentCloud.Sms.V20210111;
+using TencentCloud.Sms.V20210111.Models;
+using Volo.Abp.DependencyInjection;
+
+namespace Volo.Abp.Sms.TencentCloud;
+
+public class TencentCloudSmsSender : ISmsSender, ITransientDependency
+{
+ protected AbpTencentCloudSmsOptions Options { get; }
+
+ public TencentCloudSmsSender(IOptionsMonitor options)
+ {
+ Options = options.CurrentValue;
+ }
+
+ public virtual async Task SendAsync(SmsMessage smsMessage)
+ {
+ var client = CreateClient();
+
+ await client.SendSms(new SendSmsRequest()
+ {
+ SmsSdkAppId = Options.SmsSdkAppId,
+ SignName = smsMessage.Properties.GetOrDefault(TencentCloudSmsProperties.SignName) as string,
+ TemplateId = smsMessage.Properties.GetOrDefault(TencentCloudSmsProperties.TemplateId) as string,
+ TemplateParamSet = smsMessage.Text.Split(','),
+ PhoneNumberSet = [smsMessage.PhoneNumber]
+ });
+ }
+
+ protected virtual SmsClient CreateClient()
+ {
+ var credential = new Credential
+ {
+ SecretId = Options.SecretId,
+ SecretKey = Options.SecretKey
+ };
+ var clientProfile = new ClientProfile
+ {
+ HttpProfile = new HttpProfile
+ {
+ Endpoint = Options.Endpoint
+ }
+ };
+ return new SmsClient(credential, Options.Region, clientProfile);
+ }
+}
diff --git a/framework/test/Volo.Abp.Sms.TencenCloud.Tests/Volo.Abp.Sms.TencentCloud.Tests.abppkg b/framework/test/Volo.Abp.Sms.TencenCloud.Tests/Volo.Abp.Sms.TencentCloud.Tests.abppkg
new file mode 100644
index 0000000000..a686451fbc
--- /dev/null
+++ b/framework/test/Volo.Abp.Sms.TencenCloud.Tests/Volo.Abp.Sms.TencentCloud.Tests.abppkg
@@ -0,0 +1,3 @@
+{
+ "role": "lib.test"
+}
\ No newline at end of file
diff --git a/framework/test/Volo.Abp.Sms.TencenCloud.Tests/Volo.Abp.Sms.TencentCloud.Tests.csproj b/framework/test/Volo.Abp.Sms.TencenCloud.Tests/Volo.Abp.Sms.TencentCloud.Tests.csproj
new file mode 100644
index 0000000000..cd63f915d1
--- /dev/null
+++ b/framework/test/Volo.Abp.Sms.TencenCloud.Tests/Volo.Abp.Sms.TencentCloud.Tests.csproj
@@ -0,0 +1,26 @@
+
+
+
+
+
+ net9.0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Always
+
+
+
+
diff --git a/framework/test/Volo.Abp.Sms.TencenCloud.Tests/Volo/Abp/Sms/TencentCloud/AbpSmsTencentCloudTestBase.cs b/framework/test/Volo.Abp.Sms.TencenCloud.Tests/Volo/Abp/Sms/TencentCloud/AbpSmsTencentCloudTestBase.cs
new file mode 100644
index 0000000000..dfc666f21f
--- /dev/null
+++ b/framework/test/Volo.Abp.Sms.TencenCloud.Tests/Volo/Abp/Sms/TencentCloud/AbpSmsTencentCloudTestBase.cs
@@ -0,0 +1,11 @@
+using Volo.Abp.Testing;
+
+namespace Volo.Abp.Sms.TencentCloud;
+
+public class AbpSmsTencentCloudTestBase : AbpIntegratedTest
+{
+ protected override void SetAbpApplicationCreationOptions(AbpApplicationCreationOptions options)
+ {
+ options.UseAutofac();
+ }
+}
diff --git a/framework/test/Volo.Abp.Sms.TencenCloud.Tests/Volo/Abp/Sms/TencentCloud/AbpSmsTencentCloudTestsModule.cs b/framework/test/Volo.Abp.Sms.TencenCloud.Tests/Volo/Abp/Sms/TencentCloud/AbpSmsTencentCloudTestsModule.cs
new file mode 100644
index 0000000000..5062c18867
--- /dev/null
+++ b/framework/test/Volo.Abp.Sms.TencenCloud.Tests/Volo/Abp/Sms/TencentCloud/AbpSmsTencentCloudTestsModule.cs
@@ -0,0 +1,15 @@
+using Microsoft.Extensions.DependencyInjection;
+using Volo.Abp.Modularity;
+
+namespace Volo.Abp.Sms.TencentCloud;
+
+[DependsOn(typeof(AbpSmsTencentCloudModule))]
+public class AbpSmsTencentCloudTestsModule : AbpModule
+{
+ public override void ConfigureServices(ServiceConfigurationContext context)
+ {
+ var configuration = context.Services.GetConfiguration();
+
+ Configure(configuration.GetSection("AbpTencentCloudSms"));
+ }
+}
diff --git a/framework/test/Volo.Abp.Sms.TencenCloud.Tests/Volo/Abp/Sms/TencentCloud/TencentCloudSmsSenderTests.cs b/framework/test/Volo.Abp.Sms.TencenCloud.Tests/Volo/Abp/Sms/TencentCloud/TencentCloudSmsSenderTests.cs
new file mode 100644
index 0000000000..9198f9b86d
--- /dev/null
+++ b/framework/test/Volo.Abp.Sms.TencenCloud.Tests/Volo/Abp/Sms/TencentCloud/TencentCloudSmsSenderTests.cs
@@ -0,0 +1,36 @@
+using System.Threading.Tasks;
+using Microsoft.Extensions.Configuration;
+using Xunit;
+
+namespace Volo.Abp.Sms.TencentCloud;
+
+public class TencentCloudSmsSenderTests : AbpSmsTencentCloudTestBase
+{
+ private readonly ISmsSender _smsSender;
+ private readonly IConfiguration _configuration;
+
+ public TencentCloudSmsSenderTests()
+ {
+ _configuration = GetRequiredService();
+ _smsSender = GetRequiredService();
+ }
+
+ [Fact]
+ public async Task SendSms_Test()
+ {
+ var config = _configuration.GetSection("AbpTencentCloudSms");
+
+ // Please fill in the real parameters in the appsettings.json file.
+ if (config["SecretId"] == "")
+ {
+ return;
+ }
+
+ var msg = new SmsMessage(config["TargetPhoneNumber"],
+ config["TemplateParam"]);
+ msg.Properties.Add(TencentCloudSmsProperties.SignName, config["SignName"]);
+ msg.Properties.Add(TencentCloudSmsProperties.TemplateId, config["TemplateId"]);
+
+ await _smsSender.SendAsync(msg);
+ }
+}
diff --git a/framework/test/Volo.Abp.Sms.TencenCloud.Tests/appsettings.json b/framework/test/Volo.Abp.Sms.TencenCloud.Tests/appsettings.json
new file mode 100644
index 0000000000..44d4611caf
--- /dev/null
+++ b/framework/test/Volo.Abp.Sms.TencenCloud.Tests/appsettings.json
@@ -0,0 +1,13 @@
+{
+ "AbpTencentCloudSms": {
+ "SecretId": "",
+ "SecretKey": "",
+ "Region": "",
+ "SmsSdkAppId": "",
+ "Endpoint": "",
+ "TargetPhoneNumber": "",
+ "SignName": "",
+ "TemplateId": "",
+ "TemplateParam": ""
+ }
+}
\ No newline at end of file
diff --git a/nupkg/common.ps1 b/nupkg/common.ps1
index 860644dc4b..89264d0b07 100644
--- a/nupkg/common.ps1
+++ b/nupkg/common.ps1
@@ -232,6 +232,7 @@ $projects = (
"framework/src/Volo.Abp.Settings",
"framework/src/Volo.Abp.Sms",
"framework/src/Volo.Abp.Sms.Aliyun",
+ "framework/src/Volo.Abp.Sms.TencentCloud",
"framework/src/Volo.Abp.Specifications",
"framework/src/Volo.Abp.TestBase",
"framework/src/Volo.Abp.TextTemplating",