Build a Football Chatbot with the Oracle Digital Assistant – Part 2 (Backend Integration)

In the previous post I created a Chatbot with a Dialog Flow that allows users to ask for results, fixtures, league standings and scorers for a particular team. All of that data was hardcoded.

Now it’s the time time to do some Backend Integration and bring real live data to the Chatbot!!

Backend API

I found a football API in the RapidAPI Marketplace. It’s freemium, which means I can make some requests per day free of charge. The API itself is quite good, and accurate -> API-Football

I spend some time playing with this API in Postman, and it requires an orchestration of requests before making the final request. For example, we need to retrieve leagues and teams, find the proper id and only then ask for the Fixtures or Results.

/v2/fixtures/team/33/last/10 -> 33 is the team ID, last refers to the last fixtures, and 10 is the number of results returned

Due to this required orchestration I will implement this in the Oracle Integration Cloud (OIC) as it makes life easier.

EDIT: I have a new post with a pure Node.js backend implementation.

OIC Implementation

The services will be exposed as REST endpoints and I will make some shortcuts, but in the end it fetches the data from the backend, picks up some attributes and concatenates them into a readable format.

The below screenshot is the output of the request for the next 1 fixtures for a team : /v2/fixtures/team/212/next/1

The exact REST response looks like this below. There are more attributes that could be used, but I kept it simple.

<executeResponse xmlns="http://xmlns.oracle.com/cloud/adapter/REST/GetFixturesRapidAPI_REQUEST/types">
  <response-wrapper xmlns="http://xmlns.oracle.com/cloud/adapter/REST/GetFixturesRapidAPI/types">
    <api>
      <results>1</results>
      <fixtures>
        <fixture_id>652235</fixture_id>
        <league_id>2771</league_id>
        <league>
          <name>UEFA Champions League</name>
          <country>World</country>
          <logo>https://media.api-sports.io/football/leagues/2.png</logo>
          <flag />
        </league>
        <event_date>2021-03-09T20:00:00+00:00</event_date>
        <event_timestamp>1615320000</event_timestamp>
        <firstHalfStart />
        <secondHalfStart />
        <round>8th Finals</round>
        <status>Not Started</status>
        <statusShort>NS</statusShort>
        <elapsed>0</elapsed>
        <venue>Allianz Stadium</venue>
        <referee />
        <homeTeam>
          <team_id>496</team_id>
          <team_name>Juventus</team_name>
          <logo>https://media.api-sports.io/football/teams/496.png</logo>
        </homeTeam>
        <awayTeam>
          <team_id>212</team_id>
          <team_name>FC Porto</team_name>
          <logo>https://media.api-sports.io/football/teams/212.png</logo>
        </awayTeam>
        <goalsHomeTeam />
        <goalsAwayTeam />
        <score>
          <halftime />
          <fulltime />
          <extratime />
          <penalty />
        </score>
      </fixtures>
    </api>
  </response-wrapper>
  <HTTPHeaders />
  <ConnectivityProperties xmlns="http://xmlns.oracle.com/cloud/adapter/connectivityproperties/REST/GetFixturesRapidAPI_REQUEST/RESTOUTRES">
    <RestAPI>
      <http.response.status>200</http.response.status>
      <http.response.reason>OK</http.response.reason>
      <http.target.endpoint.uri>https://api-football-v1.p.rapidapi.com/v2/fixtures/team/212/next/1</http.target.endpoint.uri>
    </RestAPI>
  </ConnectivityProperties>
</executeResponse>

Note: after the game finishes, the above fields with score and goals will be filled.

Node.js SDK

The Node.js SDK is the main developer resource for Oracle Digital Assistant integrations. This is where we actually develop the custom component. The Football API requests could be directly handled here, but I made a design decision to bring that logic into OIC, which simplifies the custom component implementation.

Follow the instructions here to install the SDK locally.

npm install -g @oracle/bots-node-sdk

Create a Component Service

bots-node-sdk init footballapicc--name footballapicc

Add a Custom Component to Existing Service

bots-node-sdk init component <newcomponentname> custom 

At the end you should have a component service (footballapicc) with all the custom components.

GetResults.js

Below is my getresults.js implementation. I used the node-fetch module to handle the REST requests. This module is already part of the node.js package. If you choose to use any other module, then, when packaging, those modules need to be explicitly added.

I used this and this pages to guide me thru this implementation.

This is the bare minimum to make everything work, it does not implement any proper error handling.

'use strict';
// You can use your favorite http client package to make REST calls, however, the node fetch API is pre-installed with the bots-node-sdk.
// Documentation can be found at https://www.npmjs.com/package/node-fetch
// Un-comment the next line if you want to make REST calls using node-fetch. 
 const fetch = require("node-fetch");

module.exports = {
  metadata: () => ({
    name: 'getresults',
    properties: {
      team: { required: true, type: 'string' },
    },
    supportedActions: ['sucess', 'failure']
  }),
  invoke: (conversation, done) => {
  
    conversation.logger().info("This is my first CC");

    fetch('https://xxx.ocp.oraclecloud.com:443/ic/api/integration/v1/flows/rest/DEMO_DA_GETRESULTS_002/1.0/results',{method:'GET', 
    headers: {'Authorization': 'Basic ZGFuaWVsbXRlaXhlaXJhxxx=='}})
  .then((response) => {
    return response.json();    
  })
  .then((data) => {    
    const c = data.results; 
    conversation.reply(c); 
    conversation.transition('sucess');
    conversation.keepTurn(false);
    done();
  })
  .catch((err) => {
    done(err);
  });  
  }
};

Note that the code calls the OIC endpoint, and passes the output directly to the Dialog Flow.

Once all is done you can package the component with:

bots-node-sdk pack

This will create a .tgz file that will be used in the next step.

Debugging

I used these instructions in order to debug the code locally – Extremely useful as it allows to make corrections on the fly, and call them from the skill running in ODA.

Create a new Component in the Skill

The Dialog Flow also needs to be updated , so that the custom component is called from the state.

Example below for Results. It will call the state CC which will then call GetResults custom component. At this moment I am not passing the team name to keep this simple (it’s hardcoded in the OIC side).

Results:
    component: System.Output
    properties:
      text: "Let me check that for you!"
      keepTurn: true
    transitions:
      next:
        CC
CC: 
    component: "getresults"
    properties: 
      # This should be the variable that the user inputs. I made a shortcut here
      team: "F.C.Porto"  
    transitions:
      return: done

  

Putting Everything Together

I have also deployed the other custom components (getfixtures / gettable / getscorer), which are all the same but with different OIC endpoints. Below the test for getfixtures.

And the OIC monitoring page obviously tracks all the requests!

I have used most of my daily free API requests, so I will stop here 🙂

What’s Next?

We now have a working chatbot that replies with real live data to simple queries about football (all for the same team, yes I know).

In the next post I will show how to create a dedicated channel to communicate with this Bot!

1 Trackback / Pingback

  1. Updated Backend Integration with Node.js Bot SDK for the Football Chatbot – Tech Trantor

Comments are closed.