Code Examples
Real-world code examples ready to use. Copy, paste, and customize according to your needs.
6
Code Examples
3
Difficulty Levels
15+
Features
100%
Tested
Basic
A simple SMTP server in its most basic form
BasicExample.cs
using Zetian;
// Basic SMTP server - accepts all messages
using var server = new SmtpServerBuilder()
.Port(25)
.ServerName("My SMTP Server")
.MaxMessageSizeMB(10)
.Build();
server.MessageReceived += async (sender, e) => {
Console.WriteLine($"New message from {e.Message.From}");
Console.WriteLine($"Subject: {e.Message.Subject}");
// Save message to file
var fileName = $"message_{e.Message.Id}.eml";
await e.Message.SaveToFileAsync(fileName);
};
await server.StartAsync();
Console.WriteLine("SMTP Server is running on port 25");
Async/AwaitEvent-DrivenProduction Ready
Authenticated
Secure server with username and password
AuthenticatedExample.cs
using Zetian;
using Zetian.Authentication;
// Authenticated SMTP server
using var server = new SmtpServerBuilder()
.Port(587)
.RequireAuthentication()
.AllowPlainTextAuthentication() // For testing without TLS
.AuthenticationHandler(async (username, password) =>
{
// Example: Check hardcoded credentials
if (username == "testuser" && password == "testpass")
{
return AuthenticationResult.Succeed(username);
}
// In production, validate against a database:
// if (await CheckDatabase(username, password))
// return AuthenticationResult.Succeed(username);
return AuthenticationResult.Fail();
})
.AddAuthenticationMechanism("PLAIN")
.AddAuthenticationMechanism("LOGIN")
.Build();
server.MessageReceived += (sender, e) => {
if (e.Session.IsAuthenticated)
{
Console.WriteLine($"User {e.Session.AuthenticatedIdentity} sent message");
Console.WriteLine($"Subject: {e.Message.Subject}");
}
};
await server.StartAsync();
Console.WriteLine("SMTP Server with authentication on port 587");
Async/AwaitEvent-DrivenProduction Ready
Secure
Encrypted connections with STARTTLS
SecureExample.cs
using Zetian;
using Zetian.Authentication;
// Secure SMTP server with TLS/SSL support
using var server = new SmtpServerBuilder()
.Port(587)
.Certificate("certificate.pfx", "password")
.RequireSecureConnection()
.RequireAuthentication()
.SimpleAuthentication("admin", "admin123")
.Build();
server.SessionCreated += (sender, e) => {
Console.WriteLine($"New {(e.Session.IsSecure ? "SECURE" : "INSECURE")} connection");
Console.WriteLine($" From: {e.Session.RemoteEndPoint}");
};
server.MessageReceived += (sender, e) => {
if (e.Session.IsSecure)
{
Console.WriteLine("Message received over secure connection");
}
};
await server.StartAsync();
Console.WriteLine("Secure SMTP Server running with STARTTLS support on port 587");
Async/AwaitEvent-DrivenProduction Ready
Rate Limited
Speed limiting for spam protection
RateLimitedExample.cs
using Zetian.Extensions;
using Zetian.Extensions.RateLimiting;
// SMTP server protected with rate limiting
using var server = new SmtpServerBuilder()
.Port(25)
.MaxConnections(100)
.MaxConnectionsPerIP(5)
.Build();
// Add rate limiting - 100 messages per hour per IP
server.AddRateLimiting(RateLimitConfiguration.PerHour(100));
// Alternative configurations:
// server.AddRateLimiting(RateLimitConfiguration.PerMinute(10));
// server.AddRateLimiting(RateLimitConfiguration.PerDay(1000));
server.MessageReceived += (sender, e) => {
Console.WriteLine($"Message from {e.Session.RemoteEndPoint}");
// Rate limiting is handled automatically
// Messages exceeding limit get SMTP error 421
};
server.ErrorOccurred += (sender, e) => {
if (e.Exception.Message.Contains("rate limit"))
Console.WriteLine($"Rate limit exceeded: {e.Session?.RemoteEndPoint}");
};
await server.StartAsync();
Console.WriteLine("Rate-limited server on port 25");
Async/AwaitEvent-DrivenProduction Ready
Custom Processing
Domain and content-based filtering
CustomProcessingExample.cs
using Zetian;
// Protocol-level filtering
using var server = new SmtpServerBuilder()
.Port(25)
// Only accept messages from these domains
.WithSenderDomainWhitelist("trusted.com", "partner.org")
// Block these domains
.WithSenderDomainBlacklist("spam.com", "junk.org")
// Only accept messages to these domains
.WithRecipientDomainWhitelist("mydomain.com", "mycompany.com")
.Build();
// Event-based filtering
server.MessageReceived += (sender, e) => {
var message = e.Message;
// Check for spam words
var spamWords = new[] { "viagra", "lottery", "winner" };
if (spamWords.Any(word => message.Subject?.Contains(word, StringComparison.OrdinalIgnoreCase) ?? false))
{
e.Cancel = true;
e.Response = new SmtpResponse(550, "Message rejected: Spam detected");
return;
}
// Check message size
if (message.Size > 10_000_000) // 10MB
{
e.Cancel = true;
e.Response = new SmtpResponse(552, "Message too large");
return;
}
Console.WriteLine("Message passed all filters");
};
await server.StartAsync();
Async/AwaitEvent-DrivenProduction Ready
Message Storage
Saving messages to file system or database
MessageStorageExample.cs
using Zetian;
using Zetian.Storage;
using System.Text.Json;
// SMTP server with built-in file storage
using var server = new SmtpServerBuilder()
.Port(25)
// Save messages to file system automatically
.WithFileMessageStore(@"C:\smtp_messages", createDateFolders: true)
.Build();
// Using custom message store
// var customStore = new JsonMessageStore(@"C:\email_storage");
// var server = new SmtpServerBuilder()
// .Port(25)
// .MessageStore(customStore)
// .Build();
// Log when messages are received and stored
server.MessageReceived += (sender, e) => {
Console.WriteLine($"Message {e.Message.Id} saved");
Console.WriteLine($"From: {e.Message.From?.Address}");
Console.WriteLine($"Subject: {e.Message.Subject}");
};
// Use custom store: .MessageStore(new JsonMessageStore(@"C:\email_storage"))
await server.StartAsync();
// Custom JSON-based message store
public class JsonMessageStore : IMessageStore
{
private readonly string _directory;
public JsonMessageStore(string directory)
{
_directory = directory;
Directory.CreateDirectory(directory);
}
public async Task<bool> SaveAsync(
ISmtpSession session,
ISmtpMessage message,
CancellationToken ct)
{
var dateFolder = Path.Combine(_directory, DateTime.Now.ToString("yyyy-MM-dd"));
Directory.CreateDirectory(dateFolder);
// Save raw message
var emlFile = Path.Combine(dateFolder, $"{message.Id}.eml");
await message.SaveToFileAsync(emlFile);
// Save metadata as JSON
var metadata = new {
Id = message.Id,
From = message.From?.Address,
Recipients = message.Recipients.Select(r => r.Address).ToArray(),
Subject = message.Subject,
TextBody = message.TextBody,
HtmlBody = message.HtmlBody,
Size = message.Size,
ReceivedDate = DateTime.UtcNow,
SessionId = session.Id,
RemoteEndPoint = (session.RemoteEndPoint as IPEndPoint)?.Address?.ToString(),
IsAuthenticated = session.IsAuthenticated,
AuthenticatedUser = session.AuthenticatedIdentity
};
var jsonFile = Path.Combine(dateFolder, $"{message.Id}.json");
await File.WriteAllTextAsync(jsonFile,
JsonSerializer.Serialize(metadata,
new JsonSerializerOptions { WriteIndented = true }), ct);
return true;
}
}
Async/AwaitEvent-DrivenProduction Ready
Looking for More Examples?
Find more examples and test scenarios in our GitHub repository.
View All Examples on GitHub