Creating an Azure HTTP Function to Import Custom Events into Outlook through URL/ Custom Calendar Part1

 In this tutorial, you'll learn how to set up your development environment, create an Azure HTTP function using Python, and deploy it to Azure. This function will allow users to import custom events into their Outlook calendar.

Prerequisites

Before you begin, make sure you have the following:

  • A free Azure account (or an existing one)
  • Basic knowledge of Python and Azure functions

Step 1: Setting Up Your Development Environment

  1. Create a Free Azure Account

    • Visit the Azure Free Account page and click on Start for free.
    • Follow the on-screen instructions to set up your account.
  2. Install Azure Functions Core Tools

    • For Linux users:
      bash
      wget -q https://packages.microsoft.com/config/ubuntu/$(lsb_release -rs)/packages-microsoft-prod.deb sudo dpkg -i packages-microsoft-prod.deb sudo apt-get update sudo apt-get install azure-functions-core-tools-4
    • For Windows users, download and install the latest version of Azure Functions Core Tools from the official documentation.
  3. Install Visual Studio Code (VS Code)

  4. Install VS Code Extensions

    • Open VS Code, go to the Extensions view (Ctrl+Shift+X), and install the following:
      • Python (by Microsoft) - For Python development
      • Azure Functions (by Microsoft) - To create, debug, and deploy Azure functions directly from VS Code
  5. Verify Python Installation

    • Ensure Python is installed on your system by running:
      bash
      python --version
    • If Python is not installed, follow the official guide to install it.

Step 2: Setting Up Your Azure Function Project

  1. Create a Project Directory in VSCode   "OutlookAPI"

    1. Create a New Azure Function

      • In VS Code, click on the Azure icon on the Activity Bar.
      • Click on the Create New Project button (a lightning bolt with a plus sign).
      • Choose your current directory for the project location.
      • Select Python as the language.
      • Choose your Python interpreter (e.g., Python 3.9).
      • Select HTTP trigger as the function template.
      • Name your function (e.g., HttpTriggerQuick).
      • Set the authorization level to Anonymous.
    2. Review the Project Structure

      • Your project should now contain:
        • A .vscode folder with configuration settings
        • A __init__.py file where your function code will reside
        • A function.json file with your function configuration
        • A local.settings.json file for local development settings
        • A requirements.txt file listing your project's dependencies

    Step 4: Writing the Function Code

    This section is where you'll add your custom code to handle the HTTP requests and import events into Outlook.

    import logging
    from datetime import datetime
    from icalendar import Calendar, Event
    import azure.functions as func
    import uuid
    
    app = func.FunctionApp(http_auth_level=func.AuthLevel.ANONYMOUS)
    
    @app.route(route="EkasminAPI")
    def EkasminAPI(req: func.HttpRequest) -> func.HttpResponse:
        logging.info('Python HTTP trigger function processed a request.')
    
        name = req.params.get('name')
        if not name:
            try:
                req_body = req.get_json()
            except ValueError:
                pass
            else:
                name = req_body.get('name')
    
        if name:
            logging.info('Generating calendar...')
    
            # List of events with their details
            events = [
                {
                    'summary': 'Event 1',
                    'description': 'Description for Event 1',
                    'start': datetime(2024, 8, 25, 10, 0, 0),
                    'end': datetime(2024, 8, 25, 11, 0, 0),
                },
                {
                    'summary': 'Event 2',
                    'description': 'Description for Event 2',
                    'start': datetime(2024, 8, 26, 10, 0, 0),
                    'end': datetime(2024, 8, 26, 11, 0, 0),
                },
                {
                    'summary': 'Event 3',
                    'description': 'Description for Event 3',
                    'start': datetime(2024, 8, 29, 10, 0, 0),
                    'end': datetime(2024, 8, 29, 11, 0, 0),
                }
            ]
    
            # Create calendar
            cal = Calendar()
            cal.add('prodid', '-//My Calendar Application//Ekasmin.com//')
            cal.add('version', '2.0')
    
            # Log the number of events to be processed
            logging.info(f'Number of events: {len(events)}')
    
            # Add events to the calendar
            for i, event_data in enumerate(events, start=1):
                logging.info(f'Processing event {i}: {event_data["summary"]}')
                try:
                    event = Event()
                    event.add('summary', event_data['summary'])
                    event.add('description', event_data['description'])
                    event.add('dtstart', event_data['start'])
                    event.add('dtend', event_data['end'])
                    event.add('dtstamp', datetime.now())
                    event.add('uid', str(uuid.uuid4()))  # Generate a unique ID for each event
                    cal.add_component(event)  # Add the event to the calendar
                    logging.info(f'Event {i} added.')
                except Exception as e:
                    logging.error(f'Error processing event {i}: {e}')
                    continue
    
            # Convert to iCalendar format
            ical_str = cal.to_ical().decode('utf-8')
    
            # Log the output to verify all events are added
            logging.info(f'Generated iCalendar file: {ical_str}')
    
            # Return the iCalendar string as a response with the correct MIME type
            return func.HttpResponse(ical_str, mimetype='text/calendar')
    
        else:
            return func.HttpResponse(
                "This HTTP triggered function executed successfully. Pass a name in the query string or in the request body for a personalized response.",
                status_code=200
            )
    


    Step 4: Testing the Function Locally

    1. Run the Function Locally

      • Press F5 in VS Code to start the local Azure Function runtime.
      • VS Code will open a terminal, install any necessary dependencies, and start the function.
      • The terminal will display a local HTTP endpoint (e.g., http://localhost:7071/api/HttpTriggerQuick).
    2. Test Using Postman

      • Open Postman.
      • Create a new GET or POST request to the local endpoint.
      • Check the response to verify the function is working as expected.

    Step 5: Deploying the Function to Azure

    1. Log In to Azure

      • In VS Code, click on the Azure icon and sign in to your Azure account.
    2. Create an Azure Function App

      • Click on the Create Function App in Azure button.
      • Enter a globally unique name for your function app (e.g., QuickFunction4242).
      • Select your Python version and Azure region.
    3. Deploy the Function

      • Once the function app is created, right-click on your project in VS Code and select Deploy to Function App.
      • Choose the function app you just created.
      • Confirm the deployment when prompted.
    4. Test the Deployed Function

      • Copy the production endpoint URL from Azure and test it using Postman.
      • Verify that your function is running correctly in the cloud.

    Step 6: Clean Up Resources

    • To avoid any charges, delete the resource group associated with your function app after testing:
      • Go to the Azure portal, find your resource group, and delete it.

    Conclusion

    You've now successfully set up your environment, created an Azure HTTP function, tested it locally, and deployed it to Azure. This function can now be used to import custom events into Outlook.

Wait for Part 2 Where I will modify these events by integrating to some other applications.


Comments