Email - SendGrid
Configure and use SendGrid for transactional email in AuthScape.
AuthScape includes a SendGrid email provider for sending transactional emails.
Configuration
Add SendGrid configuration to appsettings.json:
json
{"Email": {"DefaultFromEmail": "noreply@yourapp.com","DefaultFromName": "Your App","DefaultProvider": "SendGrid","Providers": {"SendGrid": {"Enabled": true,"ApiKey": "SG.your_api_key_here"}}}}
Service Registration
Register the email service in Startup.cs:
csharp
services.AddEmailService(Configuration, "Email");
Implementation
The SendGridEmailProvider uses the official SendGrid NuGet package:
csharp
public class SendGridEmailProvider : IEmailProvider{private readonly SendGridConfig _config;private readonly ILogger<SendGridEmailProvider> _logger;private readonly SendGridClient _client;public string ProviderName => "SendGrid";public SendGridEmailProvider(IOptions<EmailConfiguration> emailConfig,ILogger<SendGridEmailProvider> logger){var config = emailConfig.Value;if (config.Providers.TryGetValue("SendGrid", out var providerConfig)&& providerConfig is SendGridConfig sendGridConfig){_config = sendGridConfig;}if (!string.IsNullOrEmpty(_config.ApiKey)){_client = new SendGridClient(_config.ApiKey);}}public bool IsConfigured(){return _config?.Enabled == true && !string.IsNullOrEmpty(_config?.ApiKey);}public async Task<IEmailResponse> SendEmailAsync(IEmailMessage message,CancellationToken cancellationToken = default){if (!IsConfigured()){return EmailResponse.Failure(ProviderName, "SendGrid is not configured.");}var from = new EmailAddress(message.FromEmail, message.FromName);var msg = new SendGridMessage();msg.SetFrom(from);msg.Subject = message.Subject;msg.PlainTextContent = message.TextContent;msg.HtmlContent = message.HtmlContent;// Add recipientsforeach (var recipient in message.To){msg.AddTo(new EmailAddress(recipient.Email, recipient.Name));}// Add CC recipientsforeach (var cc in message.Cc ?? Enumerable.Empty<EmailRecipient>()){msg.AddCc(new EmailAddress(cc.Email, cc.Name));}// Add BCC recipientsforeach (var bcc in message.Bcc ?? Enumerable.Empty<EmailRecipient>()){msg.AddBcc(new EmailAddress(bcc.Email, bcc.Name));}// Add reply-toif (!string.IsNullOrEmpty(message.ReplyToEmail)){msg.SetReplyTo(new EmailAddress(message.ReplyToEmail, message.ReplyToName));}// Add attachmentsforeach (var attachment in message.Attachments ?? Enumerable.Empty<EmailAttachment>()){var base64Content = Convert.ToBase64String(attachment.Content);msg.AddAttachment(attachment.FileName, base64Content, attachment.ContentType);}// Add categories (tags)if (message.Tags?.Any() == true){msg.AddCategories(message.Tags);}var response = await _client.SendEmailAsync(msg, cancellationToken);if (response.IsSuccessStatusCode){var messageId = response.Headers.GetValues("X-Message-Id")?.FirstOrDefault();return EmailResponse.Success(ProviderName, messageId, (int)response.StatusCode);}else{var errorBody = await response.Body.ReadAsStringAsync();return EmailResponse.Failure(ProviderName, errorBody, (int)response.StatusCode);}}}
Usage Examples
Basic Email
csharp
public class NotificationService{private readonly IEmailService _emailService;public async Task SendWelcomeEmail(string email, string name){var message = new EmailMessage{To = new[] { new EmailRecipient(email, name) },Subject = "Welcome to Our Platform",HtmlContent = $@"<h1>Welcome, {name}!</h1><p>Thank you for signing up. We're excited to have you!</p>"};await _emailService.SendEmailAsync(message);}}
Email with Attachments
csharp
public async Task SendInvoiceEmail(string email, string name, byte[] pdfContent){var message = new EmailMessage{To = new[] { new EmailRecipient(email, name) },Subject = "Your Invoice",HtmlContent = "<p>Please find your invoice attached.</p>",Attachments = new[]{new EmailAttachment{FileName = "invoice.pdf",Content = pdfContent,ContentType = "application/pdf"}}};await _emailService.SendEmailAsync(message);}
Email with CC and BCC
csharp
public async Task SendTeamNotification(string primaryEmail, string[] ccEmails, string subject, string body){var message = new EmailMessage{To = new[] { new EmailRecipient(primaryEmail) },Cc = ccEmails.Select(e => new EmailRecipient(e)).ToList(),Subject = subject,HtmlContent = body};await _emailService.SendEmailAsync(message);}
Email with Tags/Categories
csharp
public async Task SendMarketingEmail(string email, string name){var message = new EmailMessage{To = new[] { new EmailRecipient(email, name) },Subject = "Special Offer Inside!",HtmlContent = "<p>Check out our latest deals...</p>",Tags = new[] { "marketing", "newsletter", "promo" }};await _emailService.SendEmailAsync(message);}
Frontend API Call
javascript
import { apiService } from 'authscape';// Send email via backend APIawait apiService().post('/Notifications/Send', {email: 'user@example.com',name: 'John Doe',subject: 'Hello!',body: '<p>This is a test email.</p>'});
SendGrid Dashboard Features
With SendGrid, you get access to:
- Email Activity - Track sent, delivered, opened, clicked
- Analytics - Engagement metrics and reports
- Templates - Dynamic templates with variables
- Suppressions - Manage bounces and unsubscribes
- Webhooks - Real-time event notifications
Error Handling
csharp
var result = await _emailService.SendEmailAsync(message);if (result.Success){_logger.LogInformation("Email sent. MessageId: {MessageId}", result.MessageId);}else{_logger.LogError("Email failed. Provider: {Provider}, Error: {Error}, StatusCode: {StatusCode}",result.ProviderName,result.ErrorMessage,result.StatusCode);}
Best Practices
- Verify your domain - Configure SPF, DKIM, and DMARC
- Use API keys with minimal scope - Only grant necessary permissions
- Handle bounces - Set up webhooks for bounce notifications
- Use templates - For consistent email styling
- Monitor deliverability - Check SendGrid analytics regularly
Environment Variables
For production, use environment variables instead of appsettings:
bash
Email__Providers__SendGrid__ApiKey=SG.your_api_key
Next Steps
- Email - Mailgun - Alternative email provider
- Email - SMTP - Generic SMTP support
- Invitations - User invitation emails