chatwoot_flutter_sdk 0.1.1 copy "chatwoot_flutter_sdk: ^0.1.1" to clipboard
chatwoot_flutter_sdk: ^0.1.1 copied to clipboard

A flutter client sdk for chatwoot. Integrate Chatwoot flutter client into your flutter app and talk to your visitors/users in real time.

Pub Version

Chatwoot Flutter SDK #

Integrate Chatwoot's real-time messaging capabilities into your Flutter app with ease. This comprehensive SDK provides both WebView-based widgets and native Flutter implementations for seamless customer support integration.

Chatwoot is an open-source customer engagement platform that helps you connect with your visitors and provide exceptional support in real time.

chatwoot screenshot

✨ Features #

  • πŸš€ Easy Integration - Simple setup with WebView or native Flutter widgets
  • πŸ’¬ Real-time Messaging - WebSocket-powered live chat
  • πŸ“± Cross Platform - Works on iOS, Android, and other Flutter platforms
  • πŸ’Ύ Offline Support - Local message persistence with Hive
  • πŸ“Ž File Attachments - Support for image and file sharing
  • 🎨 Customizable UI - Build your own chat interface or use pre-built widgets (full native components coming soon)
  • πŸ”” Event Callbacks - Handle typing indicators, message status, and more
  • 🌍 Internationalization - Multi-language support

πŸ“¦ Installation #

Add this to your pubspec.yaml:

dependencies:
  chatwoot_flutter_sdk: ^0.1.0

Or install via command line:

flutter pub add chatwoot_flutter_sdk

πŸš€ Quick Start #

The easiest way to integrate Chatwoot is using the ChatwootWidget, which provides a full-featured chat interface in a WebView.

Setup:

  1. Create a Website Channel in your Chatwoot dashboard (Guide)
  2. Get your websiteToken and baseUrl
import 'package:chatwoot_flutter_sdk/chatwoot_sdk.dart';
import 'package:flutter/material.dart';
import 'package:file_picker/file_picker.dart';

class ChatPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Customer Support')),
      body: ChatwootWidget(
        websiteToken: 'your-website-token-here',
        baseUrl: 'https://your-chatwoot-instance.com',
        user: ChatwootUser(
          identifier: 'user@example.com',
          name: 'John Doe',
          email: 'user@example.com',
        ),
        locale: 'en',
        onAttachFile: () async {
          // File picker implementation
          final result = await FilePicker.platform.pickFiles(
            allowMultiple: true,
            type: FileType.any,
          );
          return result?.paths.where((path) => path != null).cast<String>().toList() ?? [];
        },
        onLoadStarted: () => print('Chat loading...'),
        onLoadCompleted: () => print('Chat loaded!'),
      ),
    );
  }
}

That's it! Your chat widget is ready. πŸŽ‰

Option 2: Native Flutter Implementation #

For more control over the UI and advanced features, use ChatwootClient to build your own chat interface.

⚠️ Note: Full native chat UI components are currently in development. The example below shows how to implement a basic chat interface. A complete native chat widget with advanced features will be available in future releases.

Setup:

  1. Create an API Channel in your Chatwoot dashboard (Guide)
  2. Get your inboxIdentifier and baseUrl

Example: Custom Chat Page

import 'package:chatwoot_flutter_sdk/chatwoot_sdk.dart';
import 'package:flutter/material.dart';

class CustomChatPage extends StatefulWidget {
  @override
  _CustomChatPageState createState() => _CustomChatPageState();
}

class _CustomChatPageState extends State<CustomChatPage> {
  ChatwootClient? _client;
  final List<ChatwootMessage> _messages = [];
  final TextEditingController _controller = TextEditingController();

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

  void _initializeChat() async {
    try {
      _client = await ChatwootClient.create(
        baseUrl: 'https://your-chatwoot-instance.com',
        inboxIdentifier: 'your-inbox-identifier',
        user: ChatwootUser(
          identifier: 'user@example.com',
          name: 'John Doe',
          email: 'user@example.com',
        ),
        enablePersistence: true,
        callbacks: ChatwootCallbacks(
          onWelcome: () => print('Chat connected! πŸŽ‰'),
          onMessageReceived: (message) {
            setState(() {
              _messages.add(message);
            });
          },
          onMessageSent: (message, echoId) => print('Message sent βœ…'),
          onMessageDelivered: (message, echoId) => print('Message delivered βœ…'),
          onConversationStartedTyping: () => print('Agent is typing...'),
          onConversationStoppedTyping: () => print('Agent stopped typing'),
          onError: (error) => print('Error: ${error.cause}'),
        ),
      );

      // Load previous messages
      _client?.loadMessages();
    } catch (error) {
      print('Failed to initialize chat: $error');
    }
  }

  void _sendMessage() {
    if (_controller.text.trim().isNotEmpty) {
      _client?.sendMessage(
        content: _controller.text.trim(),
        echoId: DateTime.now().millisecondsSinceEpoch.toString(),
      );
      _controller.clear();
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Custom Chat')),
      body: Column(
        children: [
          // Connection status
          Container(
            padding: EdgeInsets.all(8),
            color: _client != null ? Colors.green.shade100 : Colors.red.shade100,
            child: Row(
              children: [
                Icon(_client != null ? Icons.check_circle : Icons.error),
                SizedBox(width: 8),
                Text(_client != null ? 'Connected' : 'Connecting...'),
              ],
            ),
          ),

          // Messages list
          Expanded(
            child: ListView.builder(
              itemCount: _messages.length,
              itemBuilder: (context, index) {
                final message = _messages[index];
                final isUser = message.messageType == 1;

                return Container(
                  margin: EdgeInsets.symmetric(horizontal: 8, vertical: 4),
                  child: Row(
                    mainAxisAlignment: isUser ? MainAxisAlignment.end : MainAxisAlignment.start,
                    children: [
                      Container(
                        constraints: BoxConstraints(maxWidth: MediaQuery.of(context).size.width * 0.7),
                        padding: EdgeInsets.all(12),
                        decoration: BoxDecoration(
                          color: isUser ? Colors.blue : Colors.grey.shade200,
                          borderRadius: BorderRadius.circular(16),
                        ),
                        child: Text(
                          message.content ?? '',
                          style: TextStyle(
                            color: isUser ? Colors.white : Colors.black,
                          ),
                        ),
                      ),
                    ],
                  ),
                );
              },
            ),
          ),

          // Message input
          Container(
            padding: EdgeInsets.all(8),
            decoration: BoxDecoration(
              border: Border(top: BorderSide(color: Colors.grey.shade300)),
            ),
            child: Row(
              children: [
                Expanded(
                  child: TextField(
                    controller: _controller,
                    decoration: InputDecoration(
                      hintText: 'Type a message...',
                      border: OutlineInputBorder(
                        borderRadius: BorderRadius.circular(24),
                      ),
                      contentPadding: EdgeInsets.symmetric(horizontal: 16, vertical: 8),
                    ),
                    onSubmitted: (_) => _sendMessage(),
                  ),
                ),
                SizedBox(width: 8),
                FloatingActionButton(
                  mini: true,
                  onPressed: _sendMessage,
                  child: Icon(Icons.send),
                ),
              ],
            ),
          ),
        ],
      ),
    );
  }

  @override
  void dispose() {
    _client?.dispose();
    _controller.dispose();
    super.dispose();
  }
}

πŸ“‹ Widget Parameters #

ChatwootWidget Parameters #

Parameter Type Required Description
websiteToken String βœ… Website inbox channel token
baseUrl String βœ… Your Chatwoot instance URL
user ChatwootUser βœ… User information (email, name, etc.)
locale String ❌ User locale (default: 'en')
customAttributes Map<String, dynamic> ❌ Additional customer information
onAttachFile Future<List<String>> Function() ❌ File attachment handler
onLoadStarted void Function() ❌ Widget load start callback
onLoadProgress void Function(int) ❌ Widget load progress callback
onLoadCompleted void Function() ❌ Widget load completed callback
closeWidget void Function() ❌ Widget close callback

ChatwootClient Parameters #

Parameter Type Required Description
baseUrl String βœ… Your Chatwoot instance URL
inboxIdentifier String βœ… API inbox identifier
user ChatwootUser βœ… User information
enablePersistence bool ❌ Enable local data storage (default: true)
callbacks ChatwootCallbacks ❌ Event callbacks

πŸ”” Available Callbacks #

The ChatwootCallbacks class provides handlers for various chat events:

ChatwootCallbacks(
  onWelcome: () => print('Welcome! Chat is ready πŸŽ‰'),
  onPing: () => print('Connection ping received'),
  onConfirmedSubscription: () => print('Successfully connected to chat'),
  onConversationStartedTyping: () => print('Agent is typing...'),
  onConversationStoppedTyping: () => print('Agent stopped typing'),
  onConversationIsOnline: () => print('Agent is online'),
  onConversationIsOffline: () => print('Agent is offline'),
  onMessageReceived: (message) => print('New message: ${message.content}'),
  onMessageSent: (message, echoId) => print('Message sent successfully'),
  onMessageDelivered: (message, echoId) => print('Message delivered'),
  onPersistedMessagesRetrieved: (messages) => print('Loaded ${messages.length} cached messages'),
  onMessagesRetrieved: (messages) => print('Loaded ${messages.length} messages from server'),
  onConversationResolved: () => print('Conversation resolved'),
  onError: (error) => print('Chat error: ${error.cause}'),
)

πŸ’Ύ Data Persistence #

The SDK uses Hive for local storage, providing:

  • Offline Message Access: View previous conversations without internet
  • Seamless Experience: Continue conversations across app sessions
  • Automatic Sync: Messages sync when connection is restored
// Enable persistence (default: true)
ChatwootClient.create(
  enablePersistence: true,
  // ... other parameters
);

// Clear local data
await client.clearClientData();  // Clear current user's data
await ChatwootClient.clearAllData();  // Clear all stored data

πŸ“š Example App #

Check out our comprehensive example app that demonstrates:

  • βœ… WebView Chat Widget - Full-featured chat interface
  • 🚧 Custom Flutter Chat - Native Flutter implementation using flutter_chat_ui (basic example)
  • βœ… File Attachments - Image and file sharing
  • βœ… Real-time Events - Connection status, typing indicators
  • βœ… Persistence - Offline message access
  • βœ… Error Handling - Graceful error management

Run the example:

cd example
flutter run

🀝 Contributing #

We welcome contributions! Please see our Development Guide for details on:

  • Setting up the development environment
  • Running tests
  • Submitting pull requests
  • Code style guidelines

πŸ“„ License #

This project is licensed under the MIT License - see the LICENSE file for details.

πŸ†˜ Support #


Made with ❀️ by the Chatwoot team

6
likes
120
points
166
downloads

Publisher

verified publisherpermanentinnovations.africa

Weekly Downloads

A flutter client sdk for chatwoot. Integrate Chatwoot flutter client into your flutter app and talk to your visitors/users in real time.

Repository (GitHub)
View/report issues

Documentation

API reference

License

MIT (license)

Dependencies

dio, equatable, flutter, flutter_chat_ui, flutter_secure_storage, hive, hive_flutter, json_annotation, riverpod, synchronized, web_socket_channel, webview_flutter, webview_flutter_android, webview_flutter_wkwebview

More

Packages that depend on chatwoot_flutter_sdk