Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions Mailtrap.sln
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Mailtrap.Example.TestingMes
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Mailtrap.Example.Factory", "examples\Mailtrap.Example.Factory\Mailtrap.Example.Factory.csproj", "{AB1237F4-D074-4D3C-9AE4-6794BD30EA71}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Mailtrap.Example.Contact", "examples\Mailtrap.Example.Contact\Mailtrap.Example.Contact.csproj", "{3F8D2B21-5C6E-4A9A-9C3B-9F1D2A7B8C64}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -161,6 +163,10 @@ Global
{AB1237F4-D074-4D3C-9AE4-6794BD30EA71}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AB1237F4-D074-4D3C-9AE4-6794BD30EA71}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AB1237F4-D074-4D3C-9AE4-6794BD30EA71}.Release|Any CPU.Build.0 = Release|Any CPU
{3F8D2B21-5C6E-4A9A-9C3B-9F1D2A7B8C64}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3F8D2B21-5C6E-4A9A-9C3B-9F1D2A7B8C64}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3F8D2B21-5C6E-4A9A-9C3B-9F1D2A7B8C64}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3F8D2B21-5C6E-4A9A-9C3B-9F1D2A7B8C64}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -183,6 +189,7 @@ Global
{AB9CF980-EAC5-4BC4-AC85-FFA0770FF7DA} = {09E18837-1DDE-4EAF-80EC-DA55557C81EB}
{F6357CAB-06C6-4603-99E7-1EDB79ACA8E8} = {09E18837-1DDE-4EAF-80EC-DA55557C81EB}
{AB1237F4-D074-4D3C-9AE4-6794BD30EA71} = {09E18837-1DDE-4EAF-80EC-DA55557C81EB}
{3F8D2B21-5C6E-4A9A-9C3B-9F1D2A7B8C64} = {09E18837-1DDE-4EAF-80EC-DA55557C81EB}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {0FF614CC-FEBC-4C66-B3FC-FCB73EE511D7}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk">
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Http" VersionOverride="9.0.8" />
<PackageReference Include="System.Text.Json" VersionOverride="9.0.7" />
</ItemGroup>
<ItemGroup>
<Content Include="appsettings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
</Project>
81 changes: 81 additions & 0 deletions examples/Mailtrap.Example.Contact/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
using Mailtrap;
using Mailtrap.Accounts;
using Mailtrap.Contacts;
using Mailtrap.Contacts.Models;
using Mailtrap.Contacts.Requests;
using Mailtrap.Contacts.Responses;
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<Program> logger = host.Services.GetRequiredService<ILogger<Program>>();
IMailtrapClient mailtrapClient = host.Services.GetRequiredService<IMailtrapClient>();

try
{
var accountId = 12345;
IAccountResource accountResource = mailtrapClient.Account(accountId);

var contactEmail = "[email protected]";

// Get resource for contacts collection
IContactCollectionResource contactsResource = accountResource.Contacts();

// Get all contacts for account
IList<Contact> contacts = await contactsResource.GetAll();

Contact? contact = contacts
.FirstOrDefault(p => string.Equals(p.Email, contactEmail, StringComparison.OrdinalIgnoreCase));


if (contact is null)
{
logger.LogWarning("No contact found. Creating.");

// Create contact
var createContactRequest = new CreateContactRequest(contactEmail);
createContactRequest.Fields.Add("first_name", "John");
createContactRequest.Fields.Add("last_name", "Doe");
CreateContactResponse createContactResponse = await contactsResource.Create(createContactRequest);
contact = createContactResponse.Contact;
}
else
{
logger.LogInformation("Contact found.");
}

// Get resource for specific contact
IContactResource contactResource = accountResource.Contact(contact.Id);

// Get details
ContactResponse contactResponse = await contactResource.GetDetails();
Contact contactDetails = contactResponse.Contact;
logger.LogInformation("Contact: {Contact}", contactDetails);

// Update contact details
var updateContactRequest = new UpdateContactRequest("[email protected]");
UpdateContactResponse updateContactResponse = await contactResource.Update(updateContactRequest);
Contact updatedContact = updateContactResponse.Contact;
logger.LogInformation("Updated Contact: {Contact}", updatedContact);

// Delete contact
// Beware that contact resource becomes invalid after deletion and should not be used anymore
await contactResource.Delete();
logger.LogInformation("Contact Deleted.");
}
catch (Exception ex)
{
logger.LogError(ex, "An error occurred during API call.");
Environment.FailFast(ex.Message);
throw;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"profiles": {
"Project": {
"commandName": "Project",
"environmentVariables": {
"DOTNET_ENVIRONMENT": "Development"
}
}
}
}
17 changes: 17 additions & 0 deletions examples/Mailtrap.Example.Contact/appsettings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"System": "Warning",
"Microsoft": "Warning"
},
"Debug": {
"LogLevel": {
"Default": "Debug"
}
}
},
"Mailtrap": {
"ApiToken": "<API_KEY>"
}
}
46 changes: 36 additions & 10 deletions src/Mailtrap.Abstractions/Accounts/IAccountResource.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ public interface IAccountResource : IRestResource
/// <summary>
/// Gets account access collection resource for the account, represented by this resource instance.
/// </summary>
///
///
/// <returns>
/// Account access collection resource for the account, represented by this resource instance.
/// </returns>
Expand All @@ -22,7 +22,7 @@ public interface IAccountResource : IRestResource
/// <param name="accessId">
/// ID of account access to get resource for.
/// </param>
///
///
/// <returns>
/// Resource for the account access with specified ID.
/// </returns>
Expand All @@ -36,7 +36,7 @@ public interface IAccountResource : IRestResource
/// <summary>
/// Gets permissions resource for the account, represented by this resource instance.
/// </summary>
///
///
/// <returns>
/// Permissions resource for the account, represented by this resource instance.
/// </returns>
Expand All @@ -46,7 +46,7 @@ public interface IAccountResource : IRestResource
/// <summary>
/// Gets billing resource for the account, represented by this resource instance.
/// </summary>
///
///
/// <returns>
/// Billing resource for the account, represented by this resource instance.
/// </returns>
Expand All @@ -56,7 +56,7 @@ public interface IAccountResource : IRestResource
/// <summary>
/// Gets sending domain collection resource for the account, represented by this resource instance.
/// </summary>
///
///
/// <returns>
/// Sending domain collection resource for the account, represented by this resource instance.
/// </returns>
Expand All @@ -69,7 +69,7 @@ public interface IAccountResource : IRestResource
/// <param name="domainId">
/// ID of sending domain to get resource for.
/// </param>
///
///
/// <returns>
/// Resource for the sending domain with specified ID.
/// </returns>
Expand All @@ -83,7 +83,7 @@ public interface IAccountResource : IRestResource
/// <summary>
/// Gets project collection resource for the account, represented by this resource instance.
/// </summary>
///
///
/// <returns>
/// Project collection resource for the account, represented by this resource instance.
/// </returns>
Expand All @@ -96,7 +96,7 @@ public interface IAccountResource : IRestResource
/// <param name="projectId">
/// ID of project to get resource for.
/// </param>
///
///
/// <returns>
/// Resource for the project with specified ID.
/// </returns>
Expand All @@ -110,7 +110,7 @@ public interface IAccountResource : IRestResource
/// <summary>
/// Gets inbox collection resource for the account, represented by this resource instance.
/// </summary>
///
///
/// <returns>
/// Inbox collection resource for the account, represented by this resource instance.
/// </returns>
Expand All @@ -123,7 +123,7 @@ public interface IAccountResource : IRestResource
/// <param name="inboxId">
/// ID of inbox to get resource for.
/// </param>
///
///
/// <returns>
/// Resource for the inbox with specified ID.
/// </returns>
Expand All @@ -132,4 +132,30 @@ public interface IAccountResource : IRestResource
/// When <paramref name="inboxId"/> is less than or equal to zero.
/// </exception>
public IInboxResource Inbox(long inboxId);

/// <summary>
/// Gets contact collection resource for the account, represented by this resource instance.
/// </summary>
///
/// <returns>
/// Contact collection resource for the account, represented by this resource instance.
/// </returns>
public IContactCollectionResource Contacts();

/// <summary>
/// Gets resource for specific contact, identified by <paramref name="idOrEmail"/>.
/// </summary>
///
/// <param name="idOrEmail">
/// ID or email of contact to get resource for.
/// </param>
///
/// <returns>
/// Resource for the contact with specified ID or email.
/// </returns>
///
/// <exception cref="ArgumentOutOfRangeException">
/// When <paramref name="idOrEmail"/> is null or empty.
/// </exception>
public IContactResource Contact(string idOrEmail);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
namespace Mailtrap.Contacts.Converters;

/// <summary>
/// Converts DateTimeOffset to Unix time milliseconds for JSON serialization.
/// </summary>
internal sealed class DateTimeToUnixMsNullableJsonConverter : JsonConverter<DateTimeOffset?>
{
public override DateTimeOffset? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (reader.TokenType == JsonTokenType.Null)
{
return null;
}

if (reader.TokenType != JsonTokenType.Number)
{
throw new JsonException($"Expected number for Unix time milliseconds but got {reader.TokenType}.");
}

var ms = reader.GetInt64();
return DateTimeOffset.FromUnixTimeMilliseconds(ms);
}

public override void Write(Utf8JsonWriter writer, DateTimeOffset? value, JsonSerializerOptions options)
{
if (value is null)
{
writer.WriteNullValue();
return;
}

writer.WriteNumberValue(value.Value.ToUnixTimeMilliseconds());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
namespace Mailtrap.Contacts;

/// <summary>
/// Represents Contacts collection resource..
/// </summary>
public interface IContactCollectionResource : IRestResource
{
/// <summary>
/// Gets contacts.
/// </summary>
///
/// <param name="cancellationToken">
/// Token to control operation cancellation.
/// </param>
///
/// <returns>
/// Collection of contact details.
/// </returns>
public Task<IList<Contact>> GetAll(CancellationToken cancellationToken = default);

/// <summary>
/// Creates a new contact with details specified by <paramref name="request"/>.
/// </summary>
///
/// <param name="request">
/// Request containing contact details for creation.
/// </param>
///
/// <param name="cancellationToken">
/// <inheritdoc cref="GetAll(CancellationToken)" path="/param[@name='cancellationToken']"/>
/// </param>
///
/// <returns>
/// Created contact details.
/// </returns>
public Task<CreateContactResponse> Create(CreateContactRequest request, CancellationToken cancellationToken = default);
}
Loading