ODC with Bots for Teams - Respond to Messages

Stefan WeberStefan Weber
7 min read

This is the third part of the ODC with Bots for Teams series. In part two, we set up an Azure Bot resource in your Azure tenant and connected it to a REST API endpoint in OutSystems Developer Cloud, known as the Messaging Endpoint. We tested this setup using the "Test with Web Chat" feature and checked the received messages in the debugger.

In this tutorial, we will parse incoming messages and respond to them using the Bot Connector API.

💡
Make sure you have saved all the values from the previous tutorial: the Application ID, Tenant ID, and Client Secret.

Demo Application

This article series includes a demo application called "ODC with Bots for Teams Demo," available on ODC Forge. Be sure to download the version of the application that matches each article in this series.

For this article, you need to install Version 0.2 from ODC Forge.

  • In the ODC Portal, go to Forge - All Assets.

  • Search for "ODC with Bots for Teams Demo".

  • Click on the Asset (Do not click on Install on the tile!).

  • Switch to the Version tab and click on Install next to Version 0.2.

Version 0.2 depends on other Forge components:

  • OAuthTokenExchange - An external logic library that helps retrieve access tokens easily.

  • Bot Framework Service API - A connector library for using Bot Connector API endpoints.

Responding to Messages

In the introduction to this series, I explained the different types of activities a messaging endpoint can receive from a channel. The most important type is a message. The messaging endpoint receives this activity when someone sends a text message in a conversation where the bot is involved.

In this article, we will explore how to respond to a message activity.

We will use a pattern I came up with after several tries. I believe it provides the most flexible and adaptable way to build bots with OutSystems Developer Cloud. The main idea is that a single messaging endpoint—the one we already created—can be used for multiple connected Azure Bot resources. Additionally, multiple bots can be built as ODC applications to respond to incoming activities. At a glance this pattern involves the following steps

  • Handle Inbound Request - Our messaging endpoint receives the entire activity payload as text. In this first step, we partially deserialize the request and store the whole payload in an entity record, along with some additional data, for later retrieval. Finally, we trigger an event with the activity details.

  • Subscribe and Handle Event - Next, we handle the event. For simplicity in the demo, we handle the event directly in the demo application, but you can also create a separate application, subscribe to the event, and handle it there. Handling involves checking the activity type, retrieving the whole activity payload from the entity, deserializing the necessary parts, and then performing actions to respond to the activity.

  • Authorize with Connector API - To send a message back to the conversation, we need to authorize with the Connector API. In our handler, we request an access token using our Entra application registration details.

  • Build and Send Response - Finally, we create a response message and send it to the conversation through the Connector API.

Demo Application Settings

Before we go through the implementation details, let's configure the demo application's settings.

In the previous part of this series you created and configured Azure Bot resource and an attached Entra application registration. Make sure that you have copied Application (client) ID and the generated Client Secret from the application registration.

In ODC Portal - Apps, select "ODC with Bots for Teams Demo."

In the Configuration tab, set the following values:

  • EntraClientId - Application (client) ID from the Entra application registration

  • EntraClientSecret - Client Secret value from the Entra application registration

With our configuration set, we can now proceed with the implementation details.

Handle Inbound Activities

The exposed Messaging REST API endpoint receives activities from a channel. For more information on the different activity types, see the Introduction article. In the endpoint action flow, we perform the following steps:

  • Deserialize part of the activity payload

  • Create an entity record with basic activity details and the full payload

  • Trigger an OnBotActivity event

Switch to ODC Studio and double-click the Messages endpoint in Logic - Integrations - REST - MessagingEndpoint.

  • DeserializeInboundActivity - This server action converts the received text payload into a BasicActivity structure, which includes some parts of the full activity payload.

  • Activity_Create - This server action creates a record in the Activity entity with details of the inbound activity and the full payload received as binary data. (Note the conversion from text to binary data)

  • OnBotActivity - This event trigger uses property values from the deserialized activity payload as the event payload. The purpose of the event parameters is to provide a handler with enough information about an activity to determine if it should be handled.

💡
You might wonder why we aren't doing any authorization checks, and you're absolutely right. In a production environment, we need to verify if a request truly comes from one of our configured channels through the Azure Bot resource. I will discuss this in a later part of the series. For now, just remember that your messaging endpoint is public.

Handle Event

Select the OnBotActivity event in Events - Events.

The demo application defines an in-app event handler called BotHandlerSimpleTextResponse (Logic - Bots). Using an event instead of handling everything directly within the Messaging endpoint allows you to build multiple bots within ODC. These bots can subscribe to this event and handle it based on conditional checks of the event parameters.

Bot Handler

Open the server action BotHandlerSimpleTextResponse in Logic - Bots.

  • IsMessageType - This condition checks if the activity type is a message. If it isn't, the action flow ends because we only want to handle messages. At this point, you can add more checks, like verifying the BotId.

  • Activity_Get - This action retrieves the full payload as text from the Activity entity.

  • DeserializePayload - This action deserializes parts of the full payload. Here, we only deserialize the parts relevant for this bot handler to respond to the activity.

  • OutboundMessagePayload - Here, we create a new activity of type message with text. Note the mandatory "From" assignment where we assign the Recipient object, which is our Bot.

  • GetConnectorAPIAcccesToken - Before sending the activity to the Connector API, we need to acquire an access token, which this server action returns.

💡
Note that this action uses an external logic function from the OAuthTokenExchange Forge component, a component I built for easier retrieval of access tokens using client credential or authorization code OAuth 2.0 flows.
  • Connector_SendToConversation - This uses an action from the Bot Framework Service API Forge component to send the response activity to the conversation.

Bot Framework Service API

Calls to the Connector API are made to a dynamic serviceUrl that depends on the channel that sent the activity. For example, the "Test in Web Chat" feature in the Azure Portal uses a serviceUrl of webchat.botframework.com, while activities from a Teams channel have a serviceUrl starting with smba.trafficmanager.net. The exact serviceUrl depends on the channel and sometimes the region of your bot, which is why the serviceUrl must always be deserialized from the inbound activity.

💡
As you may already know, ODC does not support dynamic base URLs for REST APIs by default. Check the OnBeforeRequestHandler in Logic - Integrations - REST - BotConnectorAPI for a pattern on how to use a dynamic base URL.

Activity Schema

The demo application includes the fixed elements of the Bot Activity Schema (Data - Structures - Schema) that you can use to build your own payloads.

Try it

Switch to the Azure Portal and select your Azure Bot resource. Go to the Settings - Test in Web Chat menu. Type anything in the chat window, and you should see the message:

Congratulations! You have successfully set up your ODC bot. 🎉

I recommend starting the demo application in debugging mode and setting some breakpoints to observe how the application processes the incoming message activity.

Summary

In part 3 of the ODC with Bots for Teams article series, we explored the steps needed to handle an inbound message activity using the Test in Web Chat feature of the Azure portal. We learned how to deserialize the inbound activity and manage it asynchronously with an in-app event handler.

In the next part of the series, we will activate the Microsoft Teams channel for our Bot resource and create a configuration package to add the bot to the Microsoft Teams client application.

0
Subscribe to my newsletter

Read articles from Stefan Weber directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Stefan Weber
Stefan Weber

As a seasoned Senior Director at Telelink Business Services EAD, a leading IT full-service provider headquartered in Sofia, Bulgaria, I lead the charge in our Application Services Practice. In this role, I spearhead the development of tailored software solutions using no-code/low-code platforms and cutting-edge cloud-ready/cloud-native solutions based on the Microsoft .NET stack. Throughout my diverse career, I've accumulated a wealth of experience in various capacities, both technically and personally. The constant desire to create innovative software solutions led me to the world of Low-Code and the OutSystems platform. I remain captivated by how closely OutSystems aligns with traditional software development, offering a seamless experience devoid of limitations. While my managerial responsibilities primarily revolve around leading and inspiring my teams, my passion for solution development with OutSystems remains unwavering. My personal focus extends to integrating our solutions with leading technologies such as Amazon Web Services, Microsoft 365, Azure, and more. In 2023, I earned recognition as an OutSystems Most Valuable Professional, one of only 80 worldwide, and concurrently became an AWS Community Builder.