Dialogflow in flutter

Here are the steps to making a simple Flutter chatbot application using Dialogflow

Shirsh Shukla
10 min readApr 29, 2024

Hello and welcome, in this article I will show you how to build a flutter chatbot app using the dialogflow tool which is a tool created by Google, so you don’t have to know any machine learning or NLP (Natural Language Processing) skills in order to create your own chatbots.

Let’s take a look at how we will create the chat application. In the first step, we will create the back-end using Dialogflow, which means you will get the entire console and dashboard, and will only have to add some phrases and responses.

Having completed the first step, we will proceed to the second step where we will download the API key in the json format from your Google cloud console.

In this second step, you will use the API key to communicate with the client and the server, thereby creating a JSON communication.

In the second step, we’ll build our Flutter application client site, and then in the third step, we’ll create our Flutter application. By using the API key within the Flutter application, we can communicate with our dialog flow and retrieve everything we’ve created in the dialog flow.

To get started, you need to go to dialogflow.cloud.google.com and you’ll have to log in first. But What is Dialogflow?

Dialogflow is an amazing tool by Google that allows you to create your own chat bots. It is used for Natural Language Processing using machine learning. Using natural language processing, it recognizes user intents, entities and enables developers to build interactive and dynamic conversation interfaces.

It is possible to create your own chat bot, which you can integrate into your apps and websites right now, so in this article, we will show you how to create a chat bot using the dialog flow at the back end. We will use the cloud google console to access the Google APIs in our Flutter app, and we will call the APIs and we will create a chat board or an app board.

so first of all let’s click on this sign in with google and i’m going to sign in with one of my accounts.

As you can see in the screenshot, I am currently within the dialogflow,

Using this dialog flow, we will begin by creating a chat bot, let’s say, an action board. That way the bot will have all my information, and if you ask in a chat screen, for example, who Shirsh Shukla is, this chatbot will answer right away, and who Shirsh Shukla is, what he does, all those answers will be answered by this bot, so the first thing you need to do is click on the Create an Agent button.

So let’s say I’m going to give this agent the name “ShirshShuklaInfoBot” and click on it to create an agent.

In order to clarify what I am going to build, I have given a big name. However, you can give any name of your choosing. You don’t need to do anything except click on Create right and everything will be done automatically right, and as soon as you create the agent, you will need to go to this account and you will get your project ID, so let’s get to it.

In the screenshot, you can see that my agent was created automatically, and I’m now on this screen that displays intents, entities, knowledge, but let’s click on this settings icon.

Here is the project ID (which is highlighted) so you just have to see that project id and then you need to go to google console and log in with the same Gmail account and you’ll see that a project is automatically created for you right away. We just need to go there and get our json API key so you can use it to communicate with the dialogflow chatbot.

Using a Google cloud platform and Google console, I will log in with my same account, so you will see the same project you see over here. You can see my project ID at the top of the page.

It’s just that we have to select this project in our cloud platform console. Over here, we’ll have to get our credentials or the json API key, so you need to click on credentials in the APIs and Services section, and you can then click on create credentials or click on the service account link.

The first thing we need to do is create a service account, and then we’ll be able to create an API key, so just create a service account and give it any name we like, like “ShirshBot”, and then click on create and continue and click on done.

After that, select “Grant this service account access to project” and then “DialogFlow API Admin”.

Lastly, click CONTINUE, and then click on “Grant users access to this service account (optional)” and click DONE.

Afterwards, click credentials here, and your Service account will appear.

Then click “KEYS” and “create new key”

Here two options are showing, so just click on “JSON” and click on “CREATE”.

Your work has been completed in Google Cloud Console so now we need to move on to Dialogflow.

Then click on intents now you can already see two intents in the intents, the default fallback intent, and the default welcome intent.

Let’s click on the default welcome intent and you’ll see some answers and some questions, so what are these? These are training phrases. In other words, the user is going to write phrases like hello, hi, hey there, hello there, so your bot will respond to those phrases, as you can see from the responses section. Hello how are you doing? Hello, how can I help? Good day.

As a result, these are the responses that your bot will give, as well as the questions your user will ask, so we need to create your own intent so that you can add your own expressions, your own responses, but for now, we’ll create our own intent.

We were given a welcome intent and a fallback intent, which is for those situations when your bot does not understand something, so here in the responses, you can see I didn’t get that. Could you repeat it? I didn’t understand that. So these are the responses that your bot will be giving if, for example, the user says xyz and your bot does not understand it, so then the bot will provide these answers.

So let’s go back to intents again, click on create intent again and then let’s go to this training phrase and some responses. You can see the training phrases and responses here, but we need to add them step by step, so to start, I’m going to create an intent to ask Shirsh Shukla who is.

So I’m just introducing Shirsh Shukla so I’ve added the first user expression and clicked enter as well as added responses about me that’s action that I’ve added one answer to.

Similar to that, you can add multiple responses according to your needs. It is primarily about learning how to create chatbots using this platform without knowing anything about NLP and machine learning so that if you are creating a real chatbot for a company, then you should also add multiple responses to it.

Let’s start over coding and we’ll build a simple chatbot in Flutter, similar to this.

For the first step, make a flutter project and add one of the most famous dialog flow flutter dependencies dialog_flowtter, this project is also available on github, you can find it there.

  dialog_flowtter: any

and then create assets folder inside our flutter project and rename our json file as ‘dialog_flow_auth.json’ and add this inside assests folder.

and declare this into pubspec.yaml file,

  assets:
- assets/dialog_flow_auth.json

Now let’s write our code, so this is over chat screen, which i write on ‘main.dart’ class.

import 'package:dialog_flowtter/dialog_flowtter.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'message_view.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);

@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Dialog Flow Chat',
theme: ThemeData(
brightness: Brightness.dark,
primaryColor: Colors.deepPurple,
fontFamily: 'Roboto',
),
home: const Home(),
);
}
}

class Home extends StatefulWidget {
const Home({Key? key}) : super(key: key);

@override
ChatScreenState createState() => ChatScreenState();
}

class ChatScreenState extends State<Home> {
late DialogFlowtter dialogFlowtter;
late final TextEditingController _controller;
late final ScrollController _scrollController;
bool isLoading = false;

List<Map<String, dynamic>> messages = [];

@override
void initState() {
super.initState();
_controller = TextEditingController();
_scrollController = ScrollController();
initializeDialogFlowtter();
}

Future<void> initializeDialogFlowtter() async {
try {
setState(() {
isLoading = true;
});
dialogFlowtter = await DialogFlowtter.fromFile();
} catch (e) {
if (kDebugMode) {
print('Error initializing DialogFlowtter: $e');
}
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: const Text('Initialization Error'),
content: const Text('Failed to initialize DialogFlowtter.'),
actions: [
TextButton(
onPressed: () {
Navigator.pop(context);
// Handle initialization error gracefully
},
child: const Text('OK'),
),
],
);
},
);
} finally {
setState(() {
isLoading = false;
});
}
}

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Dialog Flow Chat'),
),
body: Container(
decoration: const BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [Colors.deepPurple, Colors.deepPurpleAccent],
),
),
child: Column(
children: [
Expanded(
child: MessagesScreen(
messages: messages,
scrollController: _scrollController,
),
),
Container(
padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 8),
color: Colors.transparent,
child: Row(
children: [
Expanded(
child: TextField(
controller: _controller,
style: const TextStyle(color: Colors.white),
decoration: InputDecoration(
hintText: 'Type a message...',
hintStyle: const TextStyle(color: Colors.grey),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(25.0),
borderSide: const BorderSide(
color: Colors.white,
width: 2.0,
),
),
filled: true,
fillColor: Colors.white.withOpacity(0.2),
contentPadding: const EdgeInsets.all(12.0),
),
onSubmitted: (text) {
sendMessage(text);
_controller.clear();
},
),
),
IconButton(
onPressed: () {
sendMessage(_controller.text);
_controller.clear();
},
icon: const Icon(Icons.send),
)
],
),
),
if (isLoading) const CircularProgressIndicator(),
],
),
),
);
}

void sendMessage(String text) async {
if (text.isEmpty) {
if (kDebugMode) {
print('Message is empty');
}
} else {
setState(() {
addMessage(Message(text: DialogText(text: [text])), true);
});

try {
final response = await dialogFlowtter.detectIntent(
queryInput: QueryInput(text: TextInput(text: text)),
);
if (response.message != null) {
setState(() {
addMessage(response.message!);
});
}
} catch (e) {
if (kDebugMode) {
print('Error sending message to DialogFlowtter: $e');
}
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: const Text('Error'),
content: const Text('Failed to send message to DialogFlowtter.'),
actions: [
TextButton(
onPressed: () {
Navigator.pop(context);
// Handle error gracefully
},
child: const Text('OK'),
),
],
);
},
);
}
}
}

void addMessage(Message message, [bool isUserMessage = false]) {
setState(() {
messages.add({'message': message, 'isUserMessage': isUserMessage});
});
_scrollController.animateTo(
_scrollController.position.maxScrollExtent,
duration: const Duration(milliseconds: 300),
curve: Curves.easeOut,
);
}
}

and this is ‘message_view.dart’ class, which is using for showing message in list with simple chat view.

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';

class MessagesScreen extends StatefulWidget {
final List messages;
final ScrollController scrollController;
const MessagesScreen({Key? key, required this.messages,required this.scrollController}) : super(key: key);

@override
MessageScreenState createState() => MessageScreenState();
}

class MessageScreenState extends State<MessagesScreen> {
@override
Widget build(BuildContext context) {
var w = MediaQuery.of(context).size.width;
return ListView.separated(
controller: widget.scrollController,
itemBuilder: (context, index) {
return Container(
margin: const EdgeInsets.all(10),
child: Row(
mainAxisAlignment: widget.messages[index]['isUserMessage']
? MainAxisAlignment.end
: MainAxisAlignment.start,
children: [
GestureDetector(
onLongPress: () {
// Handle long press on the message
if (kDebugMode) {
print('Long press on message: ${widget.messages[index]['message']}');
}
},
child: Container(
padding: const EdgeInsets.symmetric(vertical: 14, horizontal: 14),
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
bottomLeft: const Radius.circular(20),
topRight: const Radius.circular(20),
bottomRight: Radius.circular(
widget.messages[index]['isUserMessage'] ? 0 : 20,
),
topLeft: Radius.circular(
widget.messages[index]['isUserMessage'] ? 20 : 0,
),
),
color: widget.messages[index]['isUserMessage']
? Colors.grey.shade800
: Colors.grey.shade900.withOpacity(0.8),
),
constraints: BoxConstraints(maxWidth: w * 2 / 3),
child: Text(widget.messages[index]['message'].text.text[0]),
),
),
],
),
);
},
separatorBuilder: (_, i) => const Padding(padding: EdgeInsets.only(top: 10)),
itemCount: widget.messages.length,
);
}
}

full source code available here,

That’s it for this article. As part of my research, I collected information from multiple websites from various sources. In case of inaccuracies or misinterpretations, please let me know by commenting below. Your insights contribute to the content’s continuous improvement and accuracy.

--

--

Shirsh Shukla

SDE at Reliance Jio | Mobile Application Developer | Speaker | Technical Writer | community member at Stack Overflow | Organizer @FlutterIndore