diff --git a/Mailtrap.sln b/Mailtrap.sln index 5bcf15c9..a4b8061b 100644 --- a/Mailtrap.sln +++ b/Mailtrap.sln @@ -102,6 +102,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Mailtrap.Example.ContactEve EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Mailtrap.Example.EmailTemplates", "examples\Mailtrap.Example.EmailTemplates\Mailtrap.Example.EmailTemplates.csproj", "{A52169E1-8653-4B7D-9F14-84837E237E43}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Mailtrap.Example.Templates", "examples\Mailtrap.Example.Templates\Mailtrap.Example.Templates.csproj", "{9A59D8CF-688C-4DA6-9CF6-F9C892783910}" +EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Mailtrap.Example.Email.BatchSend", "examples\Mailtrap.Example.Email.BatchSend\Mailtrap.Example.Email.BatchSend.csproj", "{9922946A-03DA-4AC6-8AA6-ADEC5EF2E9EB}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Mailtrap.Example.ContactExports", "examples\Mailtrap.Example.ContactExports\Mailtrap.Example.ContactExports.csproj", "{8791C343-7B1E-4206-A954-A0CFD573E460}" @@ -422,6 +424,18 @@ Global {A52169E1-8653-4B7D-9F14-84837E237E43}.Release|x64.Build.0 = Release|Any CPU {A52169E1-8653-4B7D-9F14-84837E237E43}.Release|x86.ActiveCfg = Release|Any CPU {A52169E1-8653-4B7D-9F14-84837E237E43}.Release|x86.Build.0 = Release|Any CPU + {9A59D8CF-688C-4DA6-9CF6-F9C892783910}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9A59D8CF-688C-4DA6-9CF6-F9C892783910}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9A59D8CF-688C-4DA6-9CF6-F9C892783910}.Debug|x64.ActiveCfg = Debug|Any CPU + {9A59D8CF-688C-4DA6-9CF6-F9C892783910}.Debug|x64.Build.0 = Debug|Any CPU + {9A59D8CF-688C-4DA6-9CF6-F9C892783910}.Debug|x86.ActiveCfg = Debug|Any CPU + {9A59D8CF-688C-4DA6-9CF6-F9C892783910}.Debug|x86.Build.0 = Debug|Any CPU + {9A59D8CF-688C-4DA6-9CF6-F9C892783910}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9A59D8CF-688C-4DA6-9CF6-F9C892783910}.Release|Any CPU.Build.0 = Release|Any CPU + {9A59D8CF-688C-4DA6-9CF6-F9C892783910}.Release|x64.ActiveCfg = Release|Any CPU + {9A59D8CF-688C-4DA6-9CF6-F9C892783910}.Release|x64.Build.0 = Release|Any CPU + {9A59D8CF-688C-4DA6-9CF6-F9C892783910}.Release|x86.ActiveCfg = Release|Any CPU + {9A59D8CF-688C-4DA6-9CF6-F9C892783910}.Release|x86.Build.0 = Release|Any CPU {9922946A-03DA-4AC6-8AA6-ADEC5EF2E9EB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {9922946A-03DA-4AC6-8AA6-ADEC5EF2E9EB}.Debug|Any CPU.Build.0 = Debug|Any CPU {9922946A-03DA-4AC6-8AA6-ADEC5EF2E9EB}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -583,6 +597,7 @@ Global {5CEEEC08-7F1F-4F75-BC8D-6E80C54C21FD} = {09E18837-1DDE-4EAF-80EC-DA55557C81EB} {AA91FC07-FE50-4DE1-A388-7AA0DB35C84A} = {09E18837-1DDE-4EAF-80EC-DA55557C81EB} {A52169E1-8653-4B7D-9F14-84837E237E43} = {09E18837-1DDE-4EAF-80EC-DA55557C81EB} + {9A59D8CF-688C-4DA6-9CF6-F9C892783910} = {09E18837-1DDE-4EAF-80EC-DA55557C81EB} {9922946A-03DA-4AC6-8AA6-ADEC5EF2E9EB} = {09E18837-1DDE-4EAF-80EC-DA55557C81EB} {8791C343-7B1E-4206-A954-A0CFD573E460} = {09E18837-1DDE-4EAF-80EC-DA55557C81EB} {11894B20-F780-4FC9-8140-3601EBF54C10} = {09E18837-1DDE-4EAF-80EC-DA55557C81EB} diff --git a/README.md b/README.md index b4768b0c..db5f02d1 100644 --- a/README.md +++ b/README.md @@ -308,6 +308,7 @@ private static SendEmailRequest TemplateBasedRequest() ### General +- Templates management (experimental) – [`examples/Mailtrap.Example.Templates`](examples/Mailtrap.Example.Templates/) - Email Templates management – [`examples/Mailtrap.Example.EmailTemplates`](examples/Mailtrap.Example.EmailTemplates/) - Account access management – [`examples/Mailtrap.Example.AccountAccess`](examples/Mailtrap.Example.AccountAccess/) - Permissions management – [`examples/Mailtrap.Example.Permissions`](examples/Mailtrap.Example.Permissions/) diff --git a/examples/Mailtrap.Example.Templates/Mailtrap.Example.Templates.csproj b/examples/Mailtrap.Example.Templates/Mailtrap.Example.Templates.csproj new file mode 100644 index 00000000..6b512ec9 --- /dev/null +++ b/examples/Mailtrap.Example.Templates/Mailtrap.Example.Templates.csproj @@ -0,0 +1 @@ + diff --git a/examples/Mailtrap.Example.Templates/Program.cs b/examples/Mailtrap.Example.Templates/Program.cs new file mode 100644 index 00000000..c4ea854e --- /dev/null +++ b/examples/Mailtrap.Example.Templates/Program.cs @@ -0,0 +1,77 @@ +using Mailtrap; +using Mailtrap.Accounts; +using Mailtrap.Templates; +using Mailtrap.Templates.Models; +using Mailtrap.Templates.Requests; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Logging; + + +HostApplicationBuilder hostBuilder = Host.CreateApplicationBuilder(args); + +IConfigurationSection config = hostBuilder.Configuration.GetSection("Mailtrap"); + +hostBuilder.Services.AddMailtrapClient(config); + +using IHost host = hostBuilder.Build(); + +ILogger logger = host.Services.GetRequiredService>(); +IMailtrapClient mailtrapClient = host.Services.GetRequiredService(); + +try +{ + var accountId = 12345; + IAccountResource accountResource = mailtrapClient.Account(accountId); + + // Get resource for templates collection + ITemplateCollectionResource templatesResource = accountResource.Templates(); + + // Get the first page of templates, 50 per page + var filter = new TemplateListFilter { Token = 1, PerPage = 50 }; + TemplateList page = await templatesResource.GetAll(filter); + + logger.LogInformation("Found {Count} templates on the first page.", page.Data.Count); + logger.LogInformation("Next page token: {NextToken}", page.Pagination?.NextToken); + + // Create a dedicated template so the update and delete below never touch an existing one + var createTemplateRequest = new CreateTemplateRequest + { + Name = "MyFirstTemplate", + Category = "TestCategory", + Subject = "TestSubject", + BodyHtml = "

This is HTML body

", + BodyText = "This is text body" + }; + Template template = await templatesResource.Create(createTemplateRequest); + logger.LogInformation("Created template {Name} with Id {Id}.", template.Name, template.Id); + + // Get resource for specific template + ITemplateResource templateResource = accountResource.Template(template.Id); + + // Get details + Template templateResponse = await templateResource.GetDetails(); + logger.LogInformation("Template Name from resource: {Name}", templateResponse.Name); + logger.LogInformation("Template Id from resource: {Id}", templateResponse.Id); + + // Update template details, only the properties that are set are changed + var updateTemplateRequest = new UpdateTemplateRequest + { + Name = "updatedTemplate", + BodyHtml = "

This is updated HTML body

" + }; + Template updateTemplateResponse = await templateResource.Update(updateTemplateRequest); + logger.LogInformation("Updated Template: Name={Name}, Id={Id}", updateTemplateResponse.Name, updateTemplateResponse.Id); + + // Delete template + // Beware that template resource becomes invalid after deletion and should not be used anymore + await templateResource.Delete(); + logger.LogInformation("Template Deleted."); +} +catch (Exception ex) +{ + logger.LogError(ex, "An error occurred during API call."); + Environment.ExitCode = 1; + return; +} diff --git a/examples/Mailtrap.Example.Templates/Properties/launchSettings.json b/examples/Mailtrap.Example.Templates/Properties/launchSettings.json new file mode 100644 index 00000000..b8daf491 --- /dev/null +++ b/examples/Mailtrap.Example.Templates/Properties/launchSettings.json @@ -0,0 +1,10 @@ +{ + "profiles": { + "Project": { + "commandName": "Project", + "environmentVariables": { + "DOTNET_ENVIRONMENT": "Development" + } + } + } +} diff --git a/examples/Mailtrap.Example.Templates/appsettings.json b/examples/Mailtrap.Example.Templates/appsettings.json new file mode 100644 index 00000000..7cf4089d --- /dev/null +++ b/examples/Mailtrap.Example.Templates/appsettings.json @@ -0,0 +1,17 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "System": "Warning", + "Microsoft": "Warning" + }, + "Debug": { + "LogLevel": { + "Default": "Debug" + } + } + }, + "Mailtrap": { + "ApiToken": "" + } +} diff --git a/src/Mailtrap.Abstractions/Accounts/IAccountResource.cs b/src/Mailtrap.Abstractions/Accounts/IAccountResource.cs index 6ddfad51..bf27a78c 100644 --- a/src/Mailtrap.Abstractions/Accounts/IAccountResource.cs +++ b/src/Mailtrap.Abstractions/Accounts/IAccountResource.cs @@ -162,6 +162,9 @@ public interface IAccountResource : IRestResource /// /// Gets email template collection resource for the account, represented by this resource instance. /// + /// + /// For the paginated, experimental /api/templates endpoints, see . + /// /// /// /// Email template collection resource for the account, represented by this resource instance. @@ -185,6 +188,42 @@ public interface IAccountResource : IRestResource /// public IEmailTemplateResource EmailTemplate(long emailTemplateId); + /// + /// Gets template collection resource for the account, represented by this resource instance. + /// + /// + /// + /// The /api/templates endpoints are experimental: their request and response shapes may change + /// before general availability. + /// + /// + /// + /// Template collection resource for the account, represented by this resource instance. + /// + public ITemplateCollectionResource Templates(); + + /// + /// Gets resource for specific template, identified by . + /// + /// + /// + /// The /api/templates endpoints are experimental: their request and response shapes may change + /// before general availability. + /// + /// + /// + /// ID of template to get resource for. + /// + /// + /// + /// Resource for the template with specified ID. + /// + /// + /// + /// When is less than or equal to zero. + /// + public ITemplateResource Template(long templateId); + /// /// Gets suppression collection resource for the account, represented by this resource instance. /// diff --git a/src/Mailtrap.Abstractions/GlobalUsings.cs b/src/Mailtrap.Abstractions/GlobalUsings.cs index 72c1c1ae..b32001a5 100644 --- a/src/Mailtrap.Abstractions/GlobalUsings.cs +++ b/src/Mailtrap.Abstractions/GlobalUsings.cs @@ -95,6 +95,10 @@ global using Mailtrap.Suppressions.Models; global using Mailtrap.Suppressions.Requests; global using Mailtrap.Suppressions.Validators; +global using Mailtrap.Templates; +global using Mailtrap.Templates.Models; +global using Mailtrap.Templates.Requests; +global using Mailtrap.Templates.Validators; global using Mailtrap.TrackingOptOuts; global using Mailtrap.TrackingOptOuts.Models; global using Mailtrap.TrackingOptOuts.Requests; diff --git a/src/Mailtrap.Abstractions/Templates/ITemplateCollectionResource.cs b/src/Mailtrap.Abstractions/Templates/ITemplateCollectionResource.cs new file mode 100644 index 00000000..feb76eab --- /dev/null +++ b/src/Mailtrap.Abstractions/Templates/ITemplateCollectionResource.cs @@ -0,0 +1,45 @@ +namespace Mailtrap.Templates; + + +/// +/// Represents the templates collection resource, served by the paginated /api/templates endpoints. +/// +/// +/// The endpoints are experimental: their request and response shapes may change before general availability. +/// +public interface ITemplateCollectionResource : IRestResource +{ + /// + /// Gets a page of template details. + /// + /// + /// + /// Pagination parameters, or to get the first page with the default page size. + /// + /// + /// + /// Token to control operation cancellation. + /// + /// + /// + /// Page of template details with pagination metadata. + /// + public Task GetAll(TemplateListFilter? filter = null, CancellationToken cancellationToken = default); + + /// + /// Creates a new template with details specified by . + /// + /// + /// + /// Request containing template details for creation. + /// + /// + /// + /// + /// + /// + /// + /// Created template details. + /// + public Task