Introduction
In this tutorial, we will create a simple chatbot application using the Murmuration framework and Flutter. This application will allow users to interact with a chatbot, sending messages and receiving responses in real-time. We will also implement local storage to save chat history using the shared_preferences package.
Prerequisites
- Flutter SDK installed on your machine.
- A basic understanding of Dart and Flutter.
- Gemini API key.
Step 1: Setting Up Your Flutter Project
- Create a new Flutter project:
flutter create murmuration_chatbot cd murmuration_chatbot
- Add dependencies: Open
pubspec.yamland add the following dependencies:dependencies: flutter: sdk: flutter murmuration: ^latest_version shared_preferences: ^latest_version - Install the dependencies:
flutter pub get
Step 2: Building the Chatbot Application
2.1 Main Application Entry Point
In lib/main.dart, we will set up the main entry point of our application:
import 'package:flutter/material.dart';
import 'package:murmuration/murmuration.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'dart:convert';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Murmuration Chatbot',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: ChatScreen(),
);
}
}
2.2 Creating the Chat Screen
Next, we will create the ChatScreen widget, which will handle user interactions and display chat messages.
class ChatScreen extends StatefulWidget {
@override
_ChatScreenState createState() => _ChatScreenState();
}
class _ChatScreenState extends State {
final TextEditingController _controller = TextEditingController();
final List _messages = [];
late Agent _agent;
String _selectedLanguage = 'en';
@override
void initState() {
super.initState();
_initializeAgent();
_loadMessages();
}
Future _initializeAgent() async {
final config = MurmurationConfig(apiKey: 'add-your-api-key');
_agent = await Murmuration(config).createAgent({
'role': 'Assistant',
'language': _selectedLanguage,
});
}
Future _loadMessages() async {
final prefs = await SharedPreferences.getInstance();
final savedMessages = prefs.getStringList('chat_history') ?? [];
setState(() {
_messages.addAll(savedMessages.map((msg) => Message.fromJson(msg)).toList());
});
}
Future _saveMessage(Message message) async {
final prefs = await SharedPreferences.getInstance();
final savedMessages = prefs.getStringList('chat_history') ?? [];
savedMessages.add(message.toJson());
await prefs.setStringList('chat_history', savedMessages);
}
Future _sendMessage() async {
if (_controller.text.isEmpty) return;
final userMessage = Message(role: 'user', content: _controller.text);
setState(() {
_messages.add(userMessage);
});
_controller.clear();
await _saveMessage(userMessage);
final result = await _agent.call(userMessage.content);
final assistantMessage = Message(role: 'assistant', content: result.output);
setState(() {
_messages.add(assistantMessage);
});
await _saveMessage(assistantMessage);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Murmuration Chatbot'),
actions: [
DropdownButton(
value: _selectedLanguage,
items: ['en', 'es', 'fr', 'de']
.map>((String value) {
return DropdownMenuItem(
value: value,
child: Text(value),
);
}).toList(),
onChanged: (String? newValue) {
setState(() {
_selectedLanguage = newValue!;
_initializeAgent();
});
},
),
],
),
body: Column(
children: [
Expanded(
child: ListView.builder(
padding: const EdgeInsets.all(8.0),
itemCount: _messages.length,
itemBuilder: (context, index) {
final message = _messages[index];
return _buildMessageTile(message);
},
),
),
_buildInputField(),
],
),
);
}
Widget _buildMessageTile(Message message) {
final isUser Message = message.role == 'user';
return Container(
margin: const EdgeInsets.symmetric(vertical: 4.0),
padding: const EdgeInsets.all(10.0),
decoration: BoxDecoration(
color: isUser Message ? Colors.blue[100] : Colors.grey[200],
borderRadius: BorderRadius.circular(8.0),
),
alignment: isUser Message ? Alignment.centerRight : Alignment.centerLeft,
child: Column(
crossAxisAlignment: isUser Message ? CrossAxisAlignment.end : CrossAxisAlignment.start,
children: [
Text(
message.role,
style: TextStyle(
fontWeight: FontWeight.bold,
color: isUser Message ? Colors.blue : Colors.black,
),
),
SizedBox(height: 4.0),
Text(
message.content,
style: TextStyle(fontSize: 16.0),
),
],
),
);
}
Widget _buildInputField() {
return Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
children: [
Expanded(
child: TextField(
controller: _controller,
decoration: InputDecoration(
hintText: 'Type your message...',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(30.0),
borderSide: BorderSide(color: Colors.blue),
),
filled: true,
fillColor: Colors.white,
),
),
),
const SizedBox(width: 8.0),
IconButton(
icon: const Icon(Icons.send, color: Colors.blue),
onPressed: _sendMessage,
),
],
),
);
}
}
// Message class to represent a chat message
class Message {
final String role;
final String content;
Message({required this.role, required this.content});
String toJson() {
return '{"role": "$role", "content": "$content"}';
}
static Message fromJson(String json) {
final data = jsonDecode(json);
return Message(role: data['role'], content: data['content']);
}
}
Conclusion
Congratulations! You have successfully built a simple chatbot application using the Murmuration framework and Flutter. This application allows users to send messages and receive responses from a chatbot, with chat history saved locally.
Feel free to expand upon this example by adding more features, such as user authentication, advanced message handling, or integrating additional APIs.