Menu Apache FreeMarker Template Configuration

You can configure Apache FreeMarker template (FTL) files to handle announcement menus and interactive Unstructured Supplementary Service Data (USSD) menus.

A menu service is triggered when either of the following happens:
  • The USSD incoming service receives a Process-UnstructuredSS request from the network containing a menu service code.
  • The voice service receives an IDP that triggers a pricing plan that initiates a PostRating profile containing a menu service code.
The menu service code is attached to the MtxMenuNotification MDC and dispatched to the Notification Server through the ActiveMQ menu channel. The notification service triggers the mtxMenuNotification.ftl template to service the MtxMenuNotification.

All announcement and interactive USSD menu services use the same initial base template file to handle the different announcement and USSD menu service codes. This file is /opt/mtx/notifier/templates/menu/menu/mtxMenuNotification.ftl. You configure the base template to pick other template files, depending on the menu service selected.

In the following example mtxMenuNotification.ftl file, the service codes 100 and 200 are used to trigger the FTL files for each service:
<#setting output_encoding="UTF-8">
<#-- ---------------------------------------------------------------- -->
<#--  Header values that can be set within the FTL                    -->
<#--                                                                  -->
<#--  1) There are two flags to handle follow on conditions           -->
<#--     onSuccessEndOfMenuFlag & onFailureEndofMenuFlag              -->
<#--     both of these flags inform the USSD and                      -->
<#--     ANNOUNCEMENT service what action to take if                  -->
<#--     playing an announcement or sending a ussd                    -->
<#--     message within the service fails of succeeds.                -->
<#--     Both flags can be set to one of the following strings:       -->
<#--        sendMenu                                                  -->
<#--        releaseCall                                               -->
<#--        unchargedCall                                             -->
<#--        reauthorizeAndCharge                                      -->
<#--     e.g The usual setting for finishing the ussd session is      -->
<#--      request.setHeader('onSuccessEndOfMenuFlags','releaseCall')  -->
<#--      request.setHeader('onFailureEndOfMenuFlags','releaseCall')  -->
<#--         this will send the menu result to the device and close   -->
<#--         session.                                                 -->
<#--                                                                  -->
<#--     e.g The usual setting for normal ussd session is             -->
<#--      request.setHeader('onSuccessEndOfMenuFlags','sendMenu')     -->
<#--      request.setHeader('onFailureEndOfMenuFlags','sendMenu')     -->
<#--         this will send the menu result to the device and expect  -->
<#--         a response from the device leaving the session open.     -->
<#--                                                                  -->
<#--  2) xmlLogicalState this header value holds the logical          -->
<#--     state between successive menu actions/responses.             -->                       -->
<#--                                                                  -->
<#--  3) xmlHolding this header value holds string information        -->
<#--     as set by the freemarker FTL logic between                   -->
<#--     successive menu actions/responses.                           -->
<#--                                                                  -->
<#--  4) CamelHttpMethod this header value holds REST call actions    -->
<#--     to perform after the freemarker FTL has completed            -->
<#--     ZERO means do not perform a REST CALL                        -->
<#--     GET means do perform a REST CALL GET                         -->
<#--     PUT means do perform a REST CALL PUT                         --><#--                                                                  -->
<#-- ---------------------------------------------------------------- -->
<#t>${request.setHeader('onSuccessEndOfMenuFlags','sendMenu')}
<#t>${request.setHeader('onFailureEndOfMenuFlags','releaseCall')}
<#t>${request.setHeader('CamelHttpMethod', 'ZERO')}
<#if body.result == 3>
This section handles menu service code 100:
 <#-- ---------------------------------------------------- -->
  <#-- Switch on the SC selected by the user                -->
  <#-- ---------------------------------------------------- -->
  <#switch body.serviceCode>
    <#case 100>
      <#if body.logicalState == 0>

        <#-- ---------------------------------------------------- -->
        <#-- Ok let's start of by displaying the SC 100 Main Menu -->
        <#-- ---------------------------------------------------- -->
        <#t>${request.setHeader('xmlLogicalState', '100')}
        <#t>${request.setHeader('variableParts', '2020/03/02,456')}
        <#include "FtlMenus/mtx100MainMenu.ftl">
      <#else>

        <#-- ---------------------------------------------------- -->
        <#-- Otherwise just process the user's selections         -->
        <#-- ---------------------------------------------------- -->
        <#include "mtx100Main.ftl">
      </#if>
      <#break>
    <#case 200>
      <#if body.logicalState == 0>

        <#-- ---------------------------------------------------- -->
        <#-- Ok let's start of by displaying the SC 200 Main Menu -->
        <#-- ---------------------------------------------------- -->
        <#t>${request.setHeader('xmlLogicalState', '200')}
        <#t>${request.setHeader('variableParts', '2020/03/02,456')}
        <#include "FtlMenus/mtx200MainMenu.ftl">
      <#else>
        <#-- ---------------------------------------------------- -->
        <#-- Otherwise just process the user's selections         -->
        <#-- ---------------------------------------------------- -->
        <#include "mtx200Main.ftl">
      </#if>
      <#break>
  <#default>
    Unknown USSD Service code, call customer care.
    <#t>${request.setHeader('announcementProfileId', '998')}
  </#switch>
</#if>
This section handles menu service code 200:
 <#case 200>
      <#if body.logicalState == 0>

        <#-- ---------------------------------------------------- -->
        <#-- Ok let's start of by displaying the SC 200 Main Menu -->
        <#-- ---------------------------------------------------- -->
        <#t>${request.setHeader('xmlLogicalState', '200')}
        <#t>${request.setHeader('variableParts', '2020/03/02,456')}
        <#include "FtlMenus/mtx200MainMenu.ftl">
      <#else>
        <#-- ---------------------------------------------------- -->
        <#-- Otherwise just process the user's selections         -->
        <#-- ---------------------------------------------------- -->
        <#include "mtx200Main.ftl">
      </#if>
      <#break>
  <#default>
    Unknown USSD Service code, call customer care.
    <#t>${request.setHeader('announcementProfileId', '998')}
  </#switch>
</#if>

In this example, for the menu service code of 200, the mtxMenuNotification.ftl loads the template file, mtx200MainMenu.ftl. The contents of the file are as follows:

<#t>${request.setHeader('announcementProfileId', '200')}
Press 0 for friends and family
Press 1 for purchase/cancel an offer
Press 2 to exit

Suppose a subscriber requests the USSD menu service with the service code of 200 (for example, by entering "*200*" on their handset). The FreeMarker template logic returns the USSD menu options listed in the mtx200MainMenu.ftl file, such as “Press 0 for friends and family”.

If the MATRIXX voice service triggers the menu service code, the menu service logic sets the PostRating announcement profile ID to 200. The voice service also sends the IDs for the announcements listed in that profile to the IVR.

In this way different template files can be maintained for different menu options and associated with the user determined service code.

The resultant menu options or resultant data is sent back to the USSD service or voice service, through the ActiveMQ menu channel, in an MtxMenuRequestMsg MDC.

Logical State

Using a menu service is an iterative process in which the subscriber makes menu selections and results are returned. To allow for more than one message between the subscriber and the menu service, the menu service maintains a dialog and persists a logical state in MATRIXX Engine. As the subscriber progresses through the menu hierarchy, the FreeMarker logic uses the logical state to move through the different template files.

The following excerpt provides an example showing how you can use the logical state in the FreeMarker logic:
<#if body.logicalState == 0>
     <#t>${request.setHeader('xmlLogicalState', '100')}
     <#t>${request.setHeader('variableParts', '2020/03/02,456')}
     <#include "FtlMenus/mtx100MainMenu.ftl">
<#else>
     <#include "mtx100Main.ftl">
</#if>
  1. When a menu service is first triggered, the logical state is initially set to 0 (zero), and the FreeMarker logic executes the if statement to:
    • Load the mtx100MainMenu.ftl file containing the main menu options for the service.
    • Set the logical state to the value of the menu ID.
      You set the logical state in the xmlLogicalState header variable, for example, the following line sets the logical state to 100:
      <#t>${request.setHeader('xmlLogicalState', '100')}
  2. If the subscriber has already chosen an option from the menu, the logical state contains the value 100. In this case, the FreeMarker logic executes the else statement to load the mtx100Main.ftl file for handling the subscriber's chosen option.

REST Calls

To offer menu services with more functionality, the FreeMarker templates can perform REST calls that trigger RS Gateway. You can use the following header parameters in FTL files for menu services to start REST calls and handle the call results:
  • CamelHttpMethod
  • restCallMethod
  • restCallInitiator
  • restCallParameters
  • restCallBody
  • restCallBodyResult
For example, the following lines set FTL REST parameters for a PUT REST call:
<#-- Set up REST CALL parameters and body-->
      <#t>${request.setHeader('restCallMethod', 'json/subscriber')}
      <#t>${request.setHeader('CamelHttpMethod', 'PUT')} 
      <#-- Who is the initiator, device (initiatorDeviceId) or subscriber (initiatorId) -->
      <#t>${request.setHeader('restCallInitiator', headers.initiatorId)} 
      <#t>${request.setHeader('restCallParameters', 'offers')} 
      <#t>${request.setHeader('restCallBody','{
    "$": "MtxRequestSubscriberPurchaseOffer",
    "ExecuteMode": "advice",
    "OfferRequestArray": [
        {
            "$": "MtxPurchasedOfferData",
            "ExternalId": "1"
        }
    ]
}')}
Based on the REST call results (restCallBodyResults data), the following lines:
  • Set the PostRating profile to use for announcing the results to a subscriber using a voice service.
  • Define the USSD messages to send to a subscriber using a USSD service.
<#case 256> 
    <#t>${request.setHeader('CamelHttpMethod', 'ZERO')} 
    <#t>${request.setHeader('xmlLogicalState', '0')}
    <#t>${request.setHeader('announcementProfileId', '256')}
    <#list headers.restCallBodyResult as key, value>
      <#if key?string == '_resultCode'>
        <#if value != 0>
          Your purchase Offer has failed result code:${value}, please call 0808 000 0155<#lt>
        <#else>
          Your purchase Offer has succeeded<#lt>
        </#if>
        <#break>
      </#if>
    </#list>
    Press 0 to return to service code 200 Main Menu<#lt>
    <#break> 
For more information about REST calls and how to use them, see the discussion about using the MATRIXX REST API in MATRIXX Business API SDK.

Setting Announcement Variable Values

The elementary message IDs for announcements in PlayAnnouncement or PromptAndCollectUserInformation (PACUI) operations can include variable parts for up to five variables. These variables can be of the following types: integer, number, time, date, and price. You use the FTL header called variableParts to set the variable values. The variableParts header is a string that can contain a list of up to five comma-separated values which you set using the Apache FreeMarker setHeader() function. For example:
<#t>${request.setHeader('variableParts', '2020/03/04,${bal.availableAmount}')}
The comma-separated list of values is stored in the ServiceInfo.VcsInfo.MenuVariableDataList field in the MtxDiamRoMsg MDC, or a descendant of this MDC. To use the variable values in menu announcements, you must specify this field when creating announcement variables in My MATRIXX. The comma-separated list of values must match the type and sequence index specified for the announcement variables. In the preceding example, the respective types for each variable are date and price, and the sequence index values are 1 and 2. For more information about configuring announcement variables in My MATRIXX, see the discussion about announcement variables in My MATRIXX Help.
You can populate values in the variableParts list with:
  • A specific value, such as 256.
  • Resultant information from a REST call.
  • An MDC field value from one of the MDCs attached to the MtxMenuNotification and passed to the Apache Camel notification server. For information about available MDC fields, see the discussion about custom data values.