HOW TO TEST ROBOMATIC REST API WITH FLUTTER?

Schallom Awolou
8 min readFeb 16, 2021

(Build a chat app — chat interface — with Flutter to communicate with RoboMatic)

In recent years, new tools have been designed to improve the interactions between human and machine. These are chatbots or virtual assistants. Even if the concept of chatbot goes back to the beginning of computers and human-machine interaction, it is only from 2016 onwards that they will be increasingly popular thanks to the involvement of large companies such as Google and Facebook.

A chatbot is a software designed to conduct conversations with human users using their natural languages. Conversations often require full understanding of words, sentences and contexts. There are :

Rule-based chatbots that have been designed for a specific need with predefined responses and limited interactions;

AI chatbots which use natural language processing (NLP) technologies to identify the user’s intent and translate the meaning to a machine in which it replies back with a suitable response or action.

Natural Language Processing (NLP) is a field of computer science, artificial intelligence and computational linguistics concerned with the interactions between computers and human (natural) languages.

Chatbots can be used in almost every field from marketing to medicine, social interaction (disrupted especially in this time of pandemic), entertainment …etc.

Too much talking !!!,

What is the main subject of this article?

To have some fun, I propose to test the integration of the RoboMatic.AI chatbot in a small Flutter application.

RoboMatic is a chatbot built by InfraDrive and under improvements since 2003. It’s based on a custom NLP engine built from scratch which can be integrated in desktop, web, mobile or IoT applications to be used in businesses or personal purposes.

You can build your own chatbot using this platform, then integrate it with your application using: embedded script, POST requests or Websocket connections.

We will use RapidAPI to access RoboMatic’s RestAPI. You will need to register and obtain your own x-rapidapi-host and x-rapidapi-key.

Here are the links:

Pre-requisites:

  • Register on RapidAPI and subscribe to RoboMatic API :
  • Make sure you have your x-rapidapi-host and x-rapidapi-key.

Here’s what you get:

  • Project setup and dependencies: Flutter SDK, version 1.22.5,
  • Packages

We will use:

Animated Splash Screen to build our splash screen. Learn more here.

http to make HTTP requests. Learn more here.

intl to format and parse date. Learn more here,

toast to display message toast. Learn more here.

So, let’s code. Just follow me along the steps.

1. Create a splash screen

Replace the code in main.dart with the following code:

import 'dart:core';
import 'package:flutter/material.dart';
import 'package:robomatic/ChatScreen.dart';
import 'package:animated_splash_screen/animated_splash_screen.dart';
import 'package:page_transition/page_transition.dart';

void main() {
runApp(new MyApp());
}

class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: "RoboMatic.AI Chatbot",
//home: new SplashScreen(),
home: AnimatedSplashScreen(
duration: 20500,
//image or logo
splash: "assets/images/roboHead.jpg",
splashIconSize: 500,
nextScreen: new MyChatScreen(),
splashTransition: SplashTransition.sizeTransition,
pageTransitionType: PageTransitionType.leftToRight,
backgroundColor: Colors.white70
)
);
}
}

As I told you before, for the splash screen, I used: Animated Splash Screen package. Learn more here.

2. Create a UI for displaying messages

We need a widget to display user’ chat message or RoboMatic response. A widget that represents a single chat message.

display messages

Create a StatelessWidget called MessageBox as follows:

MessageBox.dart

import 'package:flutter/material.dart';

class MessageBox extends StatelessWidget {
MessageBox({this.sender, this.message, this.side, this.datetime});
final String sender;
final String message;
final String side;
final String datetime;

@override
Widget build(BuildContext context) {
return Container(
margin: const EdgeInsets.symmetric(vertical: 10.0),

child: side == 'leftside'//if sender is robomatic
? Container(
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
//datetime
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Row(

crossAxisAlignment: CrossAxisAlignment.center,

children: <Widget>[

Container(
margin: EdgeInsets.only(left: 6.0),
decoration: BoxDecoration(
color:Color.fromRGBO(85,75,200, 1.0),
border: Border.all(
color:Color.fromRGBO(85,75,200, 1.0),
width: .25,
style: BorderStyle.solid),
borderRadius: BorderRadius.only(
topRight: Radius.circular(0.0),
topLeft: Radius.circular(0.0),
bottomRight: Radius.circular(5.0),
bottomLeft: Radius.circular(5.0),
),
),
alignment: Alignment.bottomLeft,
padding: const EdgeInsets.only(
top: 0.0, bottom: 8.0, left: 8.0, right: 8.0),
child: Text(
datetime,
style: TextStyle(
fontSize: 12.0,
color: Colors.white,
),
),
width: 180.0,
),

],
),
//message
Stack(
children: <Widget>[

Container(
margin: EdgeInsets.only(left: 6.0),
decoration: new BoxDecoration(
color:Colors.white,
border: new Border.all(
color:Colors.white,
width: .25,
style: BorderStyle.solid),
borderRadius: BorderRadius.only(
topRight: Radius.circular(5.0),
topLeft: Radius.circular(5.0),
bottomRight: Radius.circular(0.0),
bottomLeft: Radius.circular(0.0),
),
),
alignment: Alignment.bottomLeft,
padding: const EdgeInsets.all(8.0),
child: new Text(
message,
style:TextStyle(
fontFamily: 'Roboto',
fontSize: 20.0,
color: Colors.black,
),
),
width: 180.0,
),
],
),

//sender
Container(
margin: EdgeInsets.only(left: 6.0),
decoration: BoxDecoration(
color: Colors.white70,
border: Border.all(
color: Colors.white70,
width: .25,
style: BorderStyle.solid),
borderRadius: BorderRadius.only(
topRight: Radius.circular(0.0),
topLeft: Radius.circular(0.0),
bottomRight: Radius.circular(5.0),
bottomLeft: Radius.circular(5.0),
),
),
alignment: Alignment.bottomLeft,
padding: const EdgeInsets.only(
top: 0.0, bottom: 8.0, left: 8.0, right: 8.0),
child: Text(
sender,
style: TextStyle(
fontSize: 12.0,
color: Colors.black54,
),
),
width: 180.0,
),
],
),
],
))
: Row( //if sender is user
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
//datetime
Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: <Widget>[
Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Container(
margin: EdgeInsets.only(right: 6.0),
decoration: BoxDecoration(
color:Color.fromRGBO(85,75,200, 1.0),
border: Border.all(
color:Color.fromRGBO(85,75,200, 1.0),
width: .25,
style: BorderStyle.solid),
borderRadius: BorderRadius.only(
topRight: Radius.circular(0.0),
topLeft: Radius.circular(0.0),
bottomRight: Radius.circular(5.0),
bottomLeft: Radius.circular(5.0),
),
),
alignment: Alignment.bottomRight,
padding: const EdgeInsets.only(
top: 0.0, bottom: 8.0, left: 8.0, right: 8.0),
child: Text(
datetime,
style: TextStyle(
fontSize: 12.0,
color: Colors.white,
),
),
width: 180.0,
),

],
),
//message
Stack(
alignment: Alignment.topRight,
children: <Widget>[
Container(
margin: EdgeInsets.only(right: 6.0),
decoration: BoxDecoration(
color: Color.fromRGBO(127, 124, 255, 1.0),
border: Border.all(
color: Color.fromRGBO(127, 124, 255, 1.0),
width: .25,
style: BorderStyle.solid),
borderRadius: BorderRadius.only(
topRight: Radius.circular(5.0),
topLeft: Radius.circular(5.0),
bottomRight: Radius.circular(0.0),
bottomLeft: Radius.circular(0.0),
),
),
alignment: Alignment.bottomRight,
padding: const EdgeInsets.all(8.0),
child: Text(
message,
style: TextStyle(
fontFamily: 'Roboto',
fontSize: 22.0,
color: Color(0xffffffff),
),
),
width: 180.0,
),
],
),

//sender
Container(
margin: EdgeInsets.only(right: 6.0),
decoration: BoxDecoration(
color: Colors.white70,
border: Border.all(
color: Colors.white70,
width: .25,
style: BorderStyle.solid),
borderRadius: BorderRadius.only(
topRight: Radius.circular(0.0),
topLeft: Radius.circular(0.0),
bottomRight: Radius.circular(5.0),
bottomLeft: Radius.circular(5.0),
),
),
alignment: Alignment.bottomRight,
padding: const EdgeInsets.only(
top: 0.0, bottom: 8.0, left: 8.0, right: 8.0),
child: Text(
sender,
style: TextStyle(
fontSize: 12.0,
color: Colors.black54,
),
),
width: 180.0,
),
],
),
],
),
);
}
}

The widget in question is composed of a Row which display a Container containing (oh la la ça pique les yeux) the date and the time the message was sent, a Container containing the message itself and a Container containing the sender’s name.

Depending on the sender of the message(user or RoboMatic), the widget containing the message will appear on the left or right side of the screen. This is why the variable side exists.

For this UI, I was inspired by:

*this codelab:

https://codelabs.flutter-io.cn/codelabs/flutter/index.html#0

*and this repository:

3. Build the chat screen

Create a file called MyChatScreen.dart

import 'dart:core';

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart';

import 'package:intl/intl.dart';

import 'package:robomatic/Message.dart';
import 'dart:convert';
import 'dart:convert' as convert;
import 'package:toast/toast.dart';

class MyChatScreen extends StatefulWidget {
const MyChatScreen({Key key, this.title}) : super(key: key);
final String title;

@override
_MyChatState createState() => new _MyChatState();
}

class _MyChatState extends State<MyChatScreen> {

@override
void initState() {
super.initState();

}
@override
void dispose() {

super.dispose();
}

@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: AppBar(

title: Text('Chat with RoboMatic' ,style: TextStyle(
//color: Colors.amber,
color:Colors.white,
fontSize: 19.0,
fontFamily: "Roboto",
fontStyle: FontStyle.normal,
fontWeight: FontWeight.bold,
),),
//backgroundColor: Colors.black,
backgroundColor: Color.fromRGBO(54,54,154,1.0),
centerTitle: true,
shadowColor: Colors.black12,
bottomOpacity: 0.5,
toolbarOpacity: 0.8,

),
);
}





}

— Add a UI for composing messages

First of all, let’s add a body to our Scaffold:

@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: AppBar(

title: Text('Chat with RoboMatic' ,style: TextStyle(
//color: Colors.amber,
color:Colors.white,
fontSize: 19.0,
fontFamily: "Roboto",
fontStyle: FontStyle.normal,
fontWeight: FontWeight.bold,
),),
//backgroundColor: Colors.black,
backgroundColor: Color.fromRGBO(54,54,154,1.0),
centerTitle: true,
shadowColor: Colors.black12,
bottomOpacity: 0.5,
toolbarOpacity: 0.8,

),
//new
//Add body to our Scaffold
body: Container( //New
width: double.infinity,
height: double.infinity,
color:Color.fromRGBO(85,75,200, 1.0),
child: Container(
child: Column(
children: <Widget>[
Container(
decoration:
BoxDecoration(color: Theme.of(context).cardColor),
child: IconTheme(
data: IconThemeData(
color: Theme.of(context).accentColor),
child: Container(
margin: const EdgeInsets.symmetric(horizontal: 2.0),
child: Row(
children: <Widget>[


//child widgets (input field and scrolling list) will be added here


],
),
))),
],
),
)),
);

Roughly speaking, our body consists of a large Container whose child is another Container which, in turn, contains a Column widget. The Column widget which lays out its direct children vertically will take child widgets, a scrolling list and a row for an input field.

Widget for composing messages

We need that widget to allows users to enter chat messages by typing a non-empty string and send their typed messages by pressing the graphical Send button next to the input field.

We use a TextEditingController object to manage interactions with the field:

  • Read contents of the input field,
  • Clear the text typed once submitted,
class _MyChatState extends State<MyChatScreen> {
final _textController = TextEditingController();//new

@override
void initState() {
super.initState();

}
//Override dispose method
@override
void dispose() {
_textController.dispose();//new
super.dispose();
}

Add an interactive text input field:

Our body become:

Add a new method to _MyChatState() class:

The callback method _handleSubmit() allows to notify when the user submits a message. _handleSubmit() returns a future that completes some operations. Future is a core Dart class for working with asynchronous operations. Because it doesn’t return a usable value,_handleSubmit() has the type Future<void>.

The Send button onPressed property, use an anonymous function to invoke the _handleSubmit() method. This callback method first allows to notify when the user submits a message. The message is passed by using _textController. The values of the parameters side and datetime are passed also (they will be need later).

— Implement a chat message list

We can use a List member called _messages to get the list of chat messages and show it in the UI. This list must be scrollable so that users can view the chat history. Each list item is a MessageBox instance.

In _MyChatState() class:

Once the message is sent by the user, the application adds the new message to the list of messages thanks to setState() call.

The _handleSubmit() method’s new face is set out as follows:

Place the message list

We will need a ListView widget to display the list of messages. Modify the build() method as follows:

For more explanations on all the widgets used for all these UIs please refer to this link:

Get response from RoboMatic

Remember, the _handleSubmit() method allows to add the message entered by the user to the messages list. This same method should allow to send the user’s message to the API for a response. So modify the _handleSubmit() method as follows :

In setState(), we called a new method, botMaticApiRequest(), that will allow us to :

  • Send the user’s message to RoboMatic;
  • Retrieve the response from RoboMatic;
  • Add RoboMatic’s response to the messages list;

This is botMaticApiRequest() :

The documentation of RoboMatic.AI has all the details on the parameters you can insert and how you can use them. There is the link for the documentation: https://robomatic.ai/#

4. Get full source code

Sorry for the length of this article. But all in all you can clone the project from my GitHub. Please give it a star while cloning.

Schlomosys/RoboMatic: A chat app- chat interface — with Flutter to communicate with RoboMatic (github.com)

Thanks for reading this article ❤

And if something went wrong, let me know in the comments section.

--

--

Schallom Awolou
0 Followers

Backend Software Developer, Technical Writer