Skip to content

hetp94/AzureFunctionApp

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

📧 Azure Function App - SendEmail

This Azure Function App provides a centralized email sending service that can be consumed by various applications using JWT-based authentication. It includes:

  • SendEmail Function: Accepts email payloads and sends emails
  • GetToken Function: Authenticates client apps and issues JWT tokens
  • Built-in validation against a database table for allowed client apps

🚀 Features

  • Centralized email dispatch service
  • JWT-based authentication
  • Request validation with client AppName and API key
  • Database logging of email requests
  • Retry-safe design for resilience
  • Easily consumable by .NET (C#/VB.NET), Python, etc.

📂 Project Structure


🧪 Prerequisites

  • .NET 6 or later
  • Azure CLI or Azure Functions Core Tools
  • Azure Storage Account (for function app)
  • SQL Database (for app authentication and logging)
  • SMTP credentials or integration with SendGrid

⚙️ Setup Instructions

  1. Clone this repository
  2. Set up local settings:
{
  "IsEncrypted": false,
  "Values": {
    "AzureWebJobsStorage": "UseDevelopmentStorage=true",
    "FUNCTIONS_WORKER_RUNTIME": "dotnet",
    "JwtSecret": "<your-secret>",
    "ConnectionStrings:DefaultConnection": "<your-sql-connection-string>"
  }
}
  1. Add SQL Tables
CREATE TABLE AllowedApps (
    Id INT PRIMARY KEY IDENTITY,
    AppName NVARCHAR(100) NOT NULL,
    ApiKey NVARCHAR(200) NOT NULL,
    IsActive BIT NOT NULL
);

CREATE TABLE EmailLog (
    Id INT PRIMARY KEY IDENTITY,
    AppName NVARCHAR(100),
    MailTo NVARCHAR(200),
    MailFrom NVARCHAR(200),
    Subject NVARCHAR(500),
    Body NVARCHAR(MAX),
    Priority NVARCHAR(20),
    Status NVARCHAR(20),
    RetryCount INT,
    CreatedAt DATETIME DEFAULT GETDATE()
);

🔐 Authentication

  1. The client app sends a POST request to /api/gettoken with its AppName and ApiKey
  2. The function returns a JWT if the credentials match an active app in the database
  3. The client must include the token in the Authorization header as Bearer when calling /api/SendEmail

🧪 API Endpoints

POST /api/gettoken

Request Body:
{
  "AppName": "ClientApp1",
  "ApiKey": "your-api-key"
}

Response:
{
  "token": "<jwt-token>"
}

POST /api/SendEmail

Headers:

Authorization: Bearer <jwt-token>

Body:

{
  "AppName": "ClientApp1",
  "MailTo": "to@example.com",
  "MailFrom": "from@example.com",
  "MailSubject": "Hello",
  "Body": "Test email",
  "Priority": "High"
}

🔗 Client Integration Example

✅ Step 1: EmailService.cs

public class EmailService
{
    private readonly HttpClient _httpClient;
    private readonly ILogger<EmailService> _logger;
    private string _jwtToken;
    private readonly string _authUrl = "https://your-func-url/api/gettoken";
    private readonly string _functionUrl = "https://your-func-url/api/SendEmail";

    public EmailService(HttpClient httpClient, ILogger<EmailService> logger)
    {
        _httpClient = httpClient;
        _logger = logger;
    }

    public async Task InitializeAsync(string appName, string apiKey)
    {
        var authRequest = new { AppName = appName, ApiKey = apiKey };
        var response = await _httpClient.PostAsJsonAsync(_authUrl, authRequest);
        response.EnsureSuccessStatusCode();

        var authResponse = await response.Content.ReadFromJsonAsync<AuthResponse>();
        _jwtToken = authResponse.Token;
    }

    public async Task SendEmailAsync(EmailRequest emailRequest)
    {
        _httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", _jwtToken);
        var response = await _httpClient.PostAsJsonAsync(_functionUrl, emailRequest);
        response.EnsureSuccessStatusCode();
    }
}

✅ Step 2: Controller Usage

[ApiController]
[Route("api/[controller]")]
public class EmailController : ControllerBase
{
    private readonly EmailService _emailService;

    public EmailController(EmailService emailService)
    {
        _emailService = emailService;
    }

    [HttpPost]
    public async Task<IActionResult> SendEmail()
    {
        await _emailService.InitializeAsync("ClientApp1", "your-api-key");

        await _emailService.SendEmailAsync(new EmailRequest
        {
            AppName = "ClientApp1",
            MailTo = "to@example.com",
            MailFrom = "from@example.com",
            MailSubject = "Sample Subject",
            Body = "Test Body",
            Priority = "High"
        });

        return Ok("Email sent.");
    }
}

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages