Skip to content

Latest commit

 

History

History

Bot.Builder.Community.Adapters.Infobip.Sms

Infobip SMS Adapter for Bot Builder v4 .NET SDK - PREVIEW

Build status

Branch Status Recommended NuGet package version
master Build status Preview available via MyGet (version 1.0.0-alpha3)

Description

This is part of the Bot Builder Community project which contains Bot Framework Components and other projects / packages for use with Bot Framework Composer and the Bot Builder .NET SDK v4.

The Infobip SMS adapter enables receiving and sending SMS messages. The Infobip SMS Adapter allows you to add an additional endpoint to your bot for receiving SMS messages. The Infobip endpoint can be used in conjunction with other channels meaning, for example, you can have a bot exposed on out of the box channels such as Facebook and Teams, but also via an Infobip (as well as side by side with the Google / Twitter Adapters also available from the Bot Builder Community Project).

Incoming SMS message requests are transformed, by the adapter, into Bot Framework Activites and then when your bot sends outgoing activities, the adapter transforms the outgoing Activity into an Infobip OMNI failover messages.

The adapter currently supports the following scenarios:

  • Send/receive text messages
  • Verification of incoming Infobip requests
  • Receive delivery reports
  • Callback data - You can add some data in every message and that data will be returned to bot in delivery report for that message
  • Full incoming request from Infobip is added to the incoming activity as ChannelData

Installation

Available via NuGet package Bot.Builder.Community.Adapters.Infobip.Sms

Install into your project using the following command in the package manager;

PM> Install-Package Bot.Builder.Community.Adapters.Infobip.Sms

Usage

Prerequisites

To receive SMS number you can open your free trial account here or contact Infobip support to help you with the process.

Set the Infobip SMS options

On the end of process you will get following parameters:

  • Api key - will be used for requests authentication and authorization
  • Base URL - endpoint on which messages will be sent
  • Sms number - will be used as subscriber number from which will be sent SMS outgoing messages
  • SMS scenario key - we are using OMNI failover API which can have multiple scenarios. This one will be used for sending SMS messages. For more details you can check here.

Also you will need to provide:

  • App secret - will be used for incoming request authentication
  • Bot URL - Infobip will forward all incoming SMS messages on this endpoint

To authenticate the requests, you'll need to configure the Adapter with the Base URL, API key, App secret, SMS number, SMS scenario key.

You could create in the project an appsettings.json file to set the Infobip options as follows:

{
  "InfobipApiBaseUrl": "",
  "InfobipApiKey": "",
  "InfobipAppSecret": "",
  "InfobipSmsNumber": "",
  "InfobipSmsScenarioKey": ""
}

Wiring up the Infobip SMS adapter in your bot

After you completed the configuration of your Infobip SMS adapter, you need to wire up the Infobip SMS adapter into your bot.

Install the Infobip SMS adapter NuGet package

Install into your project using the following command in the package manager;

PM> Install-Package Bot.Builder.Community.Adapters.Infobip.Sms

Create an Infobip SMS adapter class

Create a new class that inherits from the InfobipSmsAdapter class. This class will act as our adapter for the Infobip SMS channel. It includes error handling capabilities (much like the BotFrameworkAdapterWithErrorHandler class already in the sample, used for handling requests from Azure Bot Service).

  public class InfobipSmsAdapterWithErrorHandler: InfobipSmsAdapter
  {
      public InfobipSmsAdapterWithErrorHandler(InfobipSmsAdapterOptions infobipSmsOptions, IInfobipSmsClient infobipSmsClient, ILogger<InfobipSmsAdapterWithErrorHandler> logger)
          : base(infobipSmsOptions, infobipSmsClient, logger)
      {
          OnTurnError = async (turnContext, exception) =>
          {
              OnTurnError = async (turnContext, exception) =>
              {
                  // Log any leaked exception from the application.
                  logger.LogError($"Exception caught : {exception.Message}");

                  // Send a catch-all apology to the user.
                  await turnContext.SendActivityAsync("Sorry, it looks like something went wrong.");
              };
          };
      }
  }

You will also need to add the following using statements.

  using Bot.Builder.Community.Adapters.Infobip.Sms;
  using Microsoft.Extensions.Logging;

Create a new controller for handling Infobip SMS requests

You now need to create a new controller which will handle requests for incoming SMS messages, and delivery reports, on a new endpoint 'api/infobip/sms' instead of the default 'api/messages' used for requests from Azure Bot Service Channels. By adding an additional endpoint to your bot, you can accept requests from Bot Service channels (or additional adapters), as well as from Infobip, using the same bot.

  [Route("api/infobip/sms")]
  [ApiController]
  public class InfobipController : ControllerBase
  {
      private readonly InfobipSmsAdapter Adapter;
      private readonly IBot Bot;

      public InfobipController(InfobipSmsAdapter adapter, IBot bot)
      {
          Adapter = adapter;
          Bot = bot;
      }

      [HttpPost]
      public async Task PostAsync()
      {
          // Delegate the processing of the HTTP POST to the adapter.
          // The adapter will invoke the bot.
          await Adapter.ProcessAsync(Request, Response, Bot);
      }
  }

You will also need to add the following using statements.

  using Bot.Builder.Community.Adapters.Infobip.Sms;
  using Microsoft.AspNetCore.Mvc;
  using Microsoft.Bot.Builder;
  using System.Threading.Tasks;

Inject Infobip SMS Adapter In Your Bot Startup.cs

Add the following line into the ConfigureServices method within your Startup.cs file, which will register your Infobip SMS adapter with two dependencies and make it available for your new controller class. The configuration settings, described in the previous step, will be automatically used by the adapter.

  //Add dependencies for Infobip SMS Adapter
  services.AddSingleton<InfobipSmsAdapterOptions>();
  services.AddSingleton<IInfobipSmsClient, InfobipSmsClient>();

  // Add Infobip Sms Adapter with error handler
  services.AddSingleton<InfobipSmsAdapter, InfobipSmsAdapterWithErrorHandler>();

Once added, your ConfigureServices method shold look like this.

  public void ConfigureServices(IServiceCollection services)
  {
      services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

      // Create the Bot Framework Adapter with error handling enabled.
      services.AddSingleton<IBotFrameworkHttpAdapter, AdapterWithErrorHandler>();

      //Add dependencies for Infobip SMS Adapter
      services.AddSingleton<InfobipSmsAdapterOptions>();
      services.AddSingleton<IInfobipSmsClient, InfobipSmsClient>();

      // Add Infobip Sms Adapter with error handler
      services.AddSingleton<InfobipSmsAdapter, InfobipSmsAdapterWithErrorHandler>();

      // Create the bot as a transient. In this case the ASP Controller is expecting an IBot.
      services.AddTransient<IBot, EchoBot>();
  }

You will also need to add the following using statement, in addition to those already present in the Startup.cs file.

  using Bot.Builder.Community.Adapters.Infobip.Sms;

Incoming SMS message requests to Bot Framework Activity mapping

All messages sent by end-user Infobip will forward to your endpoint. End-users can send to your bot several different message types. You can read about the different message types in the Infobip developer documentation.

Here are details about common details for all Activity types:

  • All activities will have end user subscriber number as ConversationId
  • All Infobip request messages will be available in ChannelData
  • ActivityId will be Infobip messageId
  • All activites will have ChannelId property value equal to InfobipSmsConstants.ChannelName

Here are how the adapter handles different message request types.

  • SMS Message Requests -> Message Activity Text property will contain content of message. TextFormat will be always plain.
  activity.Text = response.Message.CleanText;
  activity.TextFormat = TextFormatTypes.Plain;
  • Delivery report -> Event Activity For each message that you send out, we will send you a delivery report on Infobip endpoint as Event Activity. Activity name will be "DELIVERY". That payload will be in ChannelData property. More details about payload and statuses are available here. You can use this to check is message delivered to end-user. You can use this to see is your message seen by user.

Outgoing Bot Framework Activity to Infobip SMS message mapping

Each Activity will be converted to one SMS message.

Before sending message we need to select SMS as channel by setting ChannelId property of activity to SMS.

activity.ChannelId = InfobipChannel.Sms;
  • Message Activity -> SMS Message If you want send SMS Message add message content to Text property of Activity. If you want set message options, you can do that manualy accrording to this documentation.
  var message = "Hello world!";
  activity.Text = message;
  //or
  activity = MessageFactory.Text(message);

  //SMS message options(NOT MANDATORY)
  var smsOptions = new InfobipOmniSmsMessageOptions();
  smsOptions.ValidityPeriodTimeUnit = InfobipSmsOptions.ValidityPeriodTimeUnitTypes.Hours;
  smsOptions.ValidityPeriod = 12;
  smsOptions.Transliteration = InfobipSmsOptions.TransliterationTypes.All;

  activity.AddInfobipOmniSmsMessageOptions(smsOptions);

Callback data

For each message you can add some custom data and that data will be returned to bot in delivery report for that message.

Send callback data:

  var callbackData = new Dictionary<string, string>
  {
      {"data1", "true"},
      {"data2", "12"}
  };

  activity.AddInfobipCallbackData(callbackData);

Get callback data from delivery report:

  var callbackData = activity.Entities
                    .First(x => x.Type == InfobipEntityType.CallbackData);
  var sentData = callbackData.GetAs<Dictionary<string, string>>();

Useful links