Email and SMS Helpers
PearDrop provides CLI helpers to quickly add email and SMS capabilities to your application with zero configuration boilerplate.
Email Helper
Add Email to Your Project
peardrop add email-helper --from-email "support@myapp.com" --from-name "MyApp Support"
The CLI automatically:
- Adds the
PearDrop.HelpersNuGet package - Configures email providers (MailHog for dev, SendGrid for production)
- Sets up Docker Compose with MailHog
- Registers
IEmailServicein your dependency injection
Development Workflow
During development, emails are sent to MailHog (a local SMTP server and web UI):
-
Start MailHog:
docker-compose up -d -
Send emails from your code:
public class UserService
{
private readonly IEmailService emailService;
public UserService(IEmailService emailService)
{
this.emailService = emailService;
}
public async Task SendWelcomeEmailAsync(string userEmail, string userName)
{
await this.emailService.SendEmailAsync(
toEmail: userEmail,
subject: "Welcome to MyApp",
htmlBody: $"<h1>Hello {userName}!</h1><p>Welcome to our app.</p>");
}
} -
View sent emails: Open http://localhost:8025 in your browser to see all emails sent during testing
Production Configuration
For production, configure SendGrid:
-
Get a SendGrid API key from sendgrid.com
-
Update
appsettings.json:{
"Email": {
"Provider": "SendGrid",
"FromEmail": "support@myapp.com",
"FromDisplayName": "MyApp Support",
"SendGrid": {
"ApiKey": "SG.xxxxxxxxxxxxx"
}
}
} -
Never commit API keys - use Azure Key Vault or environment variables in production
Command Options
peardrop add email-helper [OPTIONS]
| Option | Description | Default |
|---|---|---|
--from-email | Default sender email | noreply@peardrop.app |
--from-name | Default sender display name | PearDrop Application |
--smtp-host | SMTP hostname (dev) | localhost |
--smtp-port | SMTP port (dev) | 1025 |
--skip-config | Skip configuration changes | false |
--skip-registration | Skip Program.cs injection | false |
SMS Helper
Add SMS to Your Project
peardrop add sms-helper --twilio-account-sid "ACxxx" --twilio-auth-token "abc123" --twilio-from-phone "+15551234567"
The CLI automatically:
- Adds the
PearDrop.HelpersNuGet package - Configures SMS providers (LocalEmail for dev, Twilio for production)
- Registers
ISmsServicein your dependency injection
Development Workflow
During development, SMS messages are sent as formatted emails via MailHog. This lets you test SMS content without Twilio costs:
-
Start MailHog:
docker-compose up -d -
Send SMS from your code:
public class AuthenticationService
{
private readonly ISmsService smsService;
public AuthenticationService(ISmsService smsService)
{
this.smsService = smsService;
}
public async Task SendMfaCodeAsync(string phoneNumber, string code)
{
await this.smsService.SendSmsAsync(
toPhoneNumber: phoneNumber,
message: $"Your verification code is: {code}. This code expires in 10 minutes.");
}
} -
View SMS in MailHog:
- Open http://localhost:8025
- Each SMS appears as an email with subject like
[LOCAL SMS] Message to +15551234567 - See the exact formatting users will receive
Benefits of LocalEmail for Development
✅ No costs - Don't pay for test SMS
✅ See exact content - View formatted messages before sending
✅ Safe testing - No risk of sending to real phone numbers
✅ Easy debugging - Check formatting and content visually
Production Configuration
For production, use Twilio:
-
Sign up at twilio.com
-
Get your credentials:
- Account SID
- Auth Token
- Phone number to send from
-
Update
appsettings.json:{
"Sms": {
"Provider": "Twilio",
"Twilio": {
"AccountSid": "ACa1b2c3d4e5f6...",
"AuthToken": "your-actual-token",
"FromPhoneNumber": "+15551234567"
}
}
} -
Secure your credentials - Never commit to source control, use environment variables/key vault
Command Options
peardrop add sms-helper [OPTIONS]
| Option | Description | Default |
|---|---|---|
--twilio-account-sid | Twilio Account SID | Placeholder |
--twilio-auth-token | Twilio Auth Token | Placeholder |
--twilio-from-phone | From phone (E.164 format) | +15551234567 |
--dev-email | Email for LocalEmail (dev) | developer@localhost |
--skip-config | Skip configuration changes | false |
--skip-registration | Skip Program.cs injection | false |
Best Practices
Email
- Always use descriptive sender names - Users should know where emails come from
- Include unsubscribe links - SendGrid and professional email services require this
- Test email formatting - Use MailHog to verify HTML renders correctly
- Use templates - SendGrid supports templates to reduce boilerplate
SMS
- Keep messages short - SMS has character limits, keep under 160 characters
- Don't include sensitive data - Phone numbers may be shared devices
- Test number formats - Use E.164 format (e.g., +15551234567)
- Set expiration times - Always include code/link validity windows
- Rate limit - Prevent brute force by limiting SMS sends per user/hour
Both
- Separate templates - Different tone for transactional vs. marketing messages
- Localization - Consider time zones and language preferences
- Audit logging - Log all sent emails/SMS for compliance
- Error handling - Gracefully handle delivery failures
Troubleshooting
MailHog Not Responding
# Check if MailHog is running
docker ps | grep mailhog
# Restart it
docker-compose restart mailhog
# View logs
docker logs mailhog
Emails Not Appearing in MailHog
- Check
appsettings.Development.jsonuseslocalhost:1025 - Verify provider is set to
"Smtp"in development - Check application logs for error messages
SendGrid API Key Invalid
- Verify API key is complete (starts with
SG.) - Check API key has "Mail Send" permissions
- Confirm it's stored in the right setting
Twilio SMS Not Sending in Production
- Verify phone numbers in E.164 format:
+1before country code - Check account has credits/active subscription
- Confirm phone number is verified with Twilio
- View Twilio logs in Twilio Console for delivery status
UI Integration with Radzen
The email and SMS helpers integrate seamlessly with the Radzen component library for styled, professional notification and form components.
Example: Contact Form with Notifications
@page "/contact"
@inject IEmailService emailService
@inject NotificationService notificationService
<RadzenCard Style="margin: 20px;">
<h2>Send Us Feedback</h2>
<RadzenFormField Text="Your Email">
<RadzenTextBox @bind-Value="email" />
</RadzenFormField>
<RadzenFormField Text="Subject">
<RadzenTextBox @bind-Value="subject" />
</RadzenFormField>
<RadzenFormField Text="Message">
<RadzenTextArea @bind-Value="message" Rows="6" />
</RadzenFormField>
<RadzenButton Text="Send Feedback" Click="SendFeedback" Style="margin-top: 20px;" />
</RadzenCard>
@code {
private string email = "";
private string subject = "";
private string message = "";
private async Task SendFeedback()
{
try
{
await emailService.SendAsync(new EmailMessage
{
To = "support@myapp.com",
ReplyTo = email,
Subject = $"Feedback: {subject}",
Body = message,
IsHtml = false
});
notificationService.Notify(new NotificationMessage
{
Severity = NotificationSeverity.Success,
Summary = "Message Sent",
Detail = "Thank you for your feedback!",
Duration = 4000
});
// Clear form
email = subject = message = "";
}
catch (Exception ex)
{
notificationService.Notify(new NotificationMessage
{
Severity = NotificationSeverity.Error,
Summary = "Send Failed",
Detail = ex.Message,
Duration = 5000
});
}
}
}
To add Radzen UI to your project:
peardrop feature radzen
See Radzen Helper Feature for complete component library, theming options, and integration examples. Both email and SMS helpers work perfectly with Radzen's built-in notification and form components.