Portal Community
5-Minute Walkthrough By the end of this guide, you'll send a test email using SMTP. No complex setup — just the essentials.

Prerequisites

5-Step Process

Step 1: Prepare Your SMTP Credentials

Gather these from your email provider:

Step 2: Create a Named Credential in the Database

Insert a credential into AIExt_Credentials table:

INSERT INTO AIExt_Credentials (
  Name,
  DisplayMetadata,
  EncryptedData,
  TenantID,
  CredentialTypeID,
  Enabled,
  CreatedOn,
  CreatedBy
) VALUES (
  'email-primary',
  '{
    "provider": "smtp",
    "fromEmail": "noreply@yourdomain.com",
    "fromName": "BizFirst Notifications",
    "host": "smtp.gmail.com",
    "port": 587,
    "ssl": false
  }',
  -- Encrypted password (use CredentialEncryptionService in production)
  0x...,
  1,  -- TenantID
  1,  -- PasswordRecord type
  1,
  GETUTCDATE(),
  1
);
Encryption Required The EncryptedData field must contain AES-256-GCM encrypted password. Use ICredentialEncryptionService.EncryptAsync() in your code. Never store plaintext passwords.

Step 3: Call the Email Service from C#

// Inject dependencies
private readonly IEmailService _emailService;
private readonly ITenantSettingsService _tenantSettingsService;

public YourService(IEmailService emailService, ITenantSettingsService tenantSettingsService)
{
    _emailService = emailService;
    _tenantSettingsService = tenantSettingsService;
}

// Send an email (credential name resolved from TenantSettings)
public async Task SendWelcomeEmail(int tenantID, string to, CancellationToken ct)
{
    // Get configured credential name from TenantSettings (defaults to "email-primary")
    var credentialName = await _tenantSettingsService.GetAsync<string>(
        tenantID,
        "EmailCredentialName",
        defaultValue: "email-primary",
        ct);

    var result = await _emailService.SendAsync(
        tenantID: tenantID,
        to: to,
        subject: "Welcome to BizFirst",
        html: "<h1>Hello!</h1><p>This is a test email.</p>",
        credentialName: credentialName,  // Resolved from tenant settings
        ct: ct
    );

    if (result.Success)
    {
        Console.WriteLine($"Email sent! Message ID: {result.MessageID}");
    }
    else
    {
        Console.WriteLine($"Failed: {result.ErrorMessage}");
    }
}

Step 4: Verify Dependency Injection

Make sure all email services are registered in your DI container:

// In your Startup.cs or Program.cs
services.AddAiEmailServices();        // Core orchestration
services.AddSmtpEmailDispatcher();    // SMTP provider
services.AddSesEmailDispatcher();     // AWS SES provider
services.AddGmailEmailDispatcher();   // Gmail OAuth2 provider

Step 5: Send a Test Email

Run your application and execute the send code above. Check:

Common Issues & Solutions

Issue: "Credential not found"

Cause: Named credential configured in TenantSettings (or the default "email-primary") doesn't exist for this tenant.

Solution:

  1. Check what credential name is configured: SELECT * FROM TenantSettings WHERE Key='EmailCredentialName' AND TenantID=1;
  2. If not found, system defaults to "email-primary"
  3. Verify that credential exists: SELECT * FROM AIExt_Credentials WHERE Name=@credentialName AND TenantID=1 AND Deleted=0 AND Enabled=1;
  4. If missing, insert it following Step 2 above

Issue: "SMTP authentication failed"

Cause: Username/password incorrect or SMTP server rejects credentials.

Solution:

Issue: "Invalid provider: xyz"

Cause: DisplayMetadata contains unknown provider name.

Solution: Use one of: "smtp", "ses", "gmail"

Next Steps

Now that you've sent your first email:

  1. First-Time Configuration — Learn the full setup process
  2. Credentials Design — Understand encryption and security
  3. SMTP Deep Dive — Advanced SMTP configuration
  4. Production Deployment — Prepare for production