Spread the love

When it comes to notifying external systems about changes in Business Central, there are several approaches available. Let’s explore these options before diving into Business Events, which offers the best of both worlds.

Web Hooks

Web hooks provide a basic notification system that alerts external URLs when records change in subscribed tables. While straightforward, this approach has some limitations:

  • Only provides a link to an API page that must be called separately
  • Triggers notifications for any change to a record, regardless of relevance

Custom REST Implementation

Creating a custom REST solution offers more control:

  • Allows custom payload definition
  • Provides precise control over trigger conditions
  • However, requires maintaining custom code

Business Events

Business Events combines the best aspects of both approaches above, offering:

  • Simplified setup process
  • Selective notification triggering
  • Customizable payloads
  • No custom code maintenance

This blog post will focus on Business Events, exploring how this feature provides an elegant solution for external system notifications by combining the simplicity of webhooks with the flexibility of custom implementations.

Setting Up Business Events Categories

Before we can start implementing Business Events, we need to establish a categorization system. This is done by extending the base EventCategory enum in Business Central.

Creating the Event Category Extension

First, let’s look at the code that defines our custom event category:

namespace fredborg.BcBusinessEvents;

using System.Integration;

enumextension 60100 EventCategory extends EventCategory
{
    value(60100; customer)
    {
        Caption = 'customer';
    }
}

Let’s break down what this code does:

  • We’re creating an extension to the standard EventCategory enum
  • The extension is placed in the fredborg.BcBusinessEvents namespace
  • We’re adding a new category value customer with ID 60100
  • This category will be used to group all customer-related business events

This is a crucial first step as it provides a structured way to organize our business events. By categorizing events, we make them easier to manage and maintain, especially when working with multiple event types in larger applications.

All the code for this implementation can be found in my GitHub repository at dfredborg/BcBusinessEvents: Business Central Business Events

Implementing Business Events for Customer Changes

After setting up our event category, the next step is to create the actual Business Event implementation. This involves two main components: defining the event and creating the trigger mechanism.

Defining the External Business Event

First, let’s create a codeunit that defines our External Business Event:

namespace fredborg.customer.businessEvents;
using System.Integration;
using Microsoft.Sales.Customer;
using fredborg.BcBusinessEvents;

codeunit 60100 CustomerBusinessEvents
{
    [ExternalBusinessEvent('customerNameChanged', 
        'Name of customer changed', 
        'Triggered when customer name is changed', 
        EventCategory::customer)]
    procedure CustomerDescriptionChanged(CustomerId: Guid; Name: Text[250])
    begin
    end;
}

Let’s break down the key elements:

  • The ExternalBusinessEvent attribute requires four parameters:
    1. Event name: ‘customerNameChanged’
    2. Display name: ‘Name of customer changed’
    3. Description: ‘Triggered when customer name is changed’
    4. Category: Our custom customer category
  • The procedure parameters define our payload:
    • CustomerId (GUID)
    • Name (Text[250])

⚠️ Security Note: Since Business Events don’t support OAuth or other security mechanisms, avoid including sensitive data in the payload.

Creating the Event Trigger

Next, we need to set up the trigger mechanism using an Event Subscriber:

[EventSubscriber(ObjectType::Table, Database::Customer, 'OnAfterValidateEvent', 'Name', false, false)]
local procedure OnAfterValidateEventCustomerName(var Rec: Record Customer)
begin
    CustomerDescriptionChanged(Rec.SystemId, Rec."Name");
end;

This subscriber:

  • Listens for changes to the Name field in the Customer table
  • Triggers our Business Event whenever a customer’s name is modified
  • Passes the customer’s SystemId and new name as the payload

The complete implementation combines both the event definition and trigger in a single codeunit:

codeunit 60100 CustomerBusinessEvents
{
    [ExternalBusinessEvent('customerNameChanged', 'Name of customer changed', 'Triggered when customer name is changed', EventCategory::customer)]
    procedure CustomerDescriptionChanged(CustomerId: Guid; Name: Text[250])
    begin
    end;

    [EventSubscriber(ObjectType::Table, Database::Customer, 'OnAfterValidateEvent', 'Name', false, false)]
    local procedure OnAfterValidateEventCustomerName(var Rec: Record Customer)
    begin
        CustomerDescriptionChanged(Rec.SystemId, Rec."Name");
    end;
}

With this implementation, external systems can now subscribe to notifications about customer name changes in Business Central. The setup is clean, maintainable, and follows best practices for Business Events implementation.

Subscribing to Business Events

After setting up our Business Event, the next step is to subscribe to it. Let’s walk through this process.

Creating the Subscription

To subscribe to a Business Event, you’ll need to make a POST request to the Business Central API endpoint:

https://api.businesscentral.dynamics.com/v2.0/{tenantId}/{environment}/api/microsoft/runtime/v1.0/externaleventsubscriptions

Required Payload Structure

{    
    "companyName": "{company name}",    
    "companyId": "{company ID}",    
    "eventName": "{Name of the event}",    
    "appId": "{APP ID where the ExternalBusinessEvent is created}",    
    "notificationUrl": "{URL for notification}",    
    "clientState": "" 
}

Example Subscription Request

{    
    "companyName": "CRONUS Danmark A/S",    
    "companyId": "25d2c782-5ae6-ee11-a200-6045bdacd822",    
    "eventName": "customerNameChanged",    
    "appId": "8d496aa9-5872-4e5e-8cae-0e1c04bb044b",    
    "notificationUrl": "https://prod-120.westus.logic.azure.com:443/workflows/19a91eb5f6ca463a8c657729d5e108e1/triggers/manual/paths/invoke?api-version=2016-06-01&sp=%2Ftriggers%2Fmanual%2Frun&sv=1.0&sig=7XbXuolLpEbRMl2TwaK3vRRSQM2bCRYV5",    
    "clientState": "" 
}

⚠️ Important: The app registration used for creating the subscription must have the EXT. EVENTS - SUBSCR permission set.

Handling the Event Notifications

When a customer’s name is changed, subscribers will receive a payload like this:

{
    "value": [
        {
            "appId": "8d496aa9-5872-4e5e-8cae-0e1c04bb044b",
            "eventName": "customerNameChanged",
            "timestamp": "2024-11-08T09:23:22.9930000Z",
            "initiatingUserAADObjectId": "203cb4bf-cf2f-4047-980f-c0fabdedfacf",
            "companyName": "CRONUS Danmark A/S",
            "companyId": "25d2c782-5ae6-ee11-a200-6045bdacd822",
            "payload": {
                "CustomerId": "0ac72272-5be6-ee11-a200-6045bdacd822",
                "Name": "Kontorcentralen A/S TEST"
            },
            "clientState": "",
            "eventVersion": "0.0"
        }
    ]
}

The payload includes:

  • Event metadata (timestamp, initiating user, company information)
  • The custom payload we defined (CustomerId and Name)
  • Version information

Integration Possibilities

External Business Events can be integrated with various systems:

  • Power Automate flows (as shown in our example)
  • Power Apps
  • Virtual tables
  • Any system capable of receiving webhook notifications

This makes Business Events a powerful tool for building integrated solutions with Business Central at the center.

A successful subscription will return a status code 201 (Created), indicating that your system is now ready to receive notifications about customer name changes.

Conclusion

Business Events in Business Central represents a significant step forward in system integration capabilities. By combining the simplicity of webhooks with the flexibility of custom implementations, it offers a robust solution for real-time data synchronization without the maintenance overhead of custom code.

Key advantages of using Business Events include:

  • Simple setup and configuration
  • Fine-grained control over when notifications are triggered
  • Customizable payloads that match your specific needs
  • Seamless integration with Power Platform and other external systems
  • Minimal code maintenance compared to custom REST implementations

While webhooks and custom REST solutions still have their place in specific scenarios, Business Events provides an elegant middle ground that will satisfy most integration requirements. The ability to selectively trigger notifications and control the payload structure makes it an ideal choice for modern, event-driven architectures.

One important consideration to keep in mind is the security limitation regarding OAuth authentication. As such, it’s crucial to carefully consider what data you include in your event payloads and ensure sensitive information is handled through more secure channels.

Whether you’re building Power Platform solutions, integrating with third-party systems, or simply need to keep external systems informed about changes in Business Central, Business Events provides a powerful and maintainable way to achieve your goals.

The complete code for this implementation is available on GitHub at dfredborg/BcBusinessEvents, where you can explore the implementation in detail and adapt it to your specific needs.

Leave a Reply