Adventures in Azure: Curbside Pickup Sample App

With all that is going on with COVID-19 and the impact that it is having on retailers, I took a couple of days and wrote a curb-side app that would allow customers to notify a retailer, or any vendor for that matter, that they had arrived to pick-up their order.

Please note, this is an incomplete solution.

It might not match your specific business requirements, and is meant more as a Starter Kit.

The app is composed of two Blazor Web Apps, the first, the Retailer Portal and the second, the Customer Portal.

Retailer Portal
Customer Portal

The app is powered by two backend C# .NET Core Azure Function Apps, fronted by Azure API Management. The first function app powers the Customer Portal, and the second powers the Retailer Portal.

The code can be found at https://github.com/mattruma/MJR057.

The solution is built using a variety of resources in Azure and requires a Twilio account for SMS messaging.

Workflows

The app supports three major workflows.

The Order Received workflow receives order information from a third-party system, e.g. POS system and sends and SMS message to the customer letting them know the order has been received.

Order Received Workflow

The Customer Arrived workflow notifies the retailer that the customer has arrived and is ready to pick up their order. It also sends a SMS message to the customer letting them know a team member will be out soon to deliver their order.

The Order Delivered workflow marks the order as delivered to the customer and sends an SMS message to the customer thanking them for the order.

Order Delivered Workflow

Azure

You will need to create the following resources in Azure:

  • Resource Group
  • App Service Plan
  • Web App for Blazor1App
  • Web App for Blazor2App
  • Azure Storage Account
  • Function App for FunctionApp1
  • Function App for FunctionApp2
  • Cosmos Account
    • Cosmos Database called orders
    • Cosmos Containers called orders and locations.

I am using Azure API Management to front my Azure Functions, but you could modify the Web Apps to use the Azure Functions directly.

I would also recommend using App Insights to monitor your application and Azure Key Vault to protect your secrets.

Working on a PowerShell script to set this all up, but that is still a work in progress.

Projects

ClassLibrary1

The ClassLibrary1 project contains code that is shared with the FunctionApp1 and FunctionApp2 projects.

FunctionApp1

The FunctionApp1 project is backend for the BlazorApp1 project, the Customer Portal.

It consists of two functions.

The OrderRetrieve function retrieves the order that the customer has arrived to pick up.

The CustomerArrive function marks the order has customer has arrived and let’s the customer know a team member will be right out with their order.

Your local.settings.json file should look like:

{
  "IsEncrypted": false,
  "Values": {
    "AzureWebJobsStorage": "UseDevelopmentStorage=true",
    "FUNCTIONS_WORKER_RUNTIME": "dotnet",
    "TWILIO_ACCOUNTSIDSETTING": "",
    "TWILIO_AUTHTOKENSETTING": "",
    "TWILIO_FROM": "",
    "COSMOSDB_CONNECTIONSTRING": "",
    "COSMOSDB_DATABASEID": "orders",
    "CUSTOMERARRIVE_TEMPLATE_1": "Hi {{CustomerName}}, you arrived safely! One of our team members will be right out with your order!",
    "CUSTOMERARRIVE_TEMPLATE_2": "Hi {{CustomerName}}, we look forward to seeing you soon! Let us know when you are here by updating your status at https://localhost:44383/orders/{{Id}}!"
  }
}

Update the endpoint in the TEMPLATE settings to point to the Customer Portal.

FunctionApp2

The FunctionApp2 project is backend for the BlazorApp2 project, the Retailer Portal.

It consists of four functions.

The OrderReceived function takes ingests and order from a third-party systems, adds it to the database, and sends an SMS message to the customer letting them know when their order will be ready for pick up.

The LocationList function retrieves a list of all the locations that will be used to limit the display of orders..

The OrderList function retrieves a list of orders for a location by date.

The OrderDeliver function marks the order has delivered to the customer and sends an SMS message to the customer thanking them for the order.

Your local.settings.json file should look like:

{
  "IsEncrypted": false,
  "Values": {
    "AzureWebJobsStorage": "UseDevelopmentStorage=true",
    "FUNCTIONS_WORKER_RUNTIME": "dotnet",
    "TWILIO_ACCOUNTSIDSETTING": "",
    "TWILIO_AUTHTOKENSETTING": "",
    "TWILIO_FROM": "",
    "COSMOSDB_CONNECTIONSTRING": "",
    "COSMOSDB_DATABASEID": "orders",
    "CUSTOMERARRIVE_TEMPLATE_1": "Hi {{CustomerName}}, you arrived safely! One of our team members will be right out with your order!",
    "CUSTOMERARRIVE_TEMPLATE_2": "Hi {{CustomerName}}, we look forward to seeing you soon! Let us know when you are here by updating your status at https://localhost:44383/orders/{{Id}}!"
  }
}

Update the endpoint in the TEMPLATE settings to point to the Customer Portal.

BlazorApp1

The BlazorApp1 project is the Customer Portal, where the customer can let the retails know that they have arrived and are ready to pick their order up.

Your appsettings.json file should look like:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*",
  "API_ENDPOINT": "",
  "API_KEY": ""
}

For me, API_ENDPOINT points to my APIM instance, you could modify to point directly to the Azure Functions using the Admin key, not recommended, but you could do that.

BlazorApp2

The BlazorApp2 project is the Retailer Portal, where team members can view orders for a location, see if the customer has arrived and mark them as delivered.

Your appsettings.json file should look like:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*",
  "API_ENDPOINT": "",
  "API_KEY": "",
  "PICKUP_ENDPOINT": ""
}

The PICKUP_ENDPOINT is the endpoint location of the Customer Portal.

Notes

Some things I have not done yet, but would like to:

  • Auto refresh the orders page so has changes comes in, the page reflects them without a manual refresh.
  • Provide an option where the Retailer can notify the customer that their order is ready, in case there is a delay in the pick up, e.g. when I place an order with Home Depot, they notify me when my order is ready to be picked up.
  • Support email for notifications.
  • Support paging in the user interface, right now only the backend supports it.

I am going to go ahead and post this article even though it is incomplete, it will be a work in progress. I figured better to get this out earlier and give everyone early access and possibly get some feedback.

Leave a Reply

Your email address will not be published.