如何将tawk.to集成到Flutter应用导航栏并实现消息提醒?
Hey there! Let's get your tawk.to chat integrated into your Flutter app exactly how you want it—keeping it synced with your existing website setup so you don't have to manage two separate chat systems. Here's a step-by-step solution that covers all your requirements:
First off, add these dependencies to your pubspec.yaml—they'll handle the WebView, notifications, vibration, and required permissions:
dependencies: flutter: sdk: flutter webview_flutter: ^4.4.0 # Use the latest stable version flutter_local_notifications: ^16.1.0 # For local chat notifications vibration: ^1.7.6 # For vibration alerts permission_handler: ^10.2.0 # To request notification/vibration permissions
Step 1: Build a Reusable Tawk Chat Widget
This widget will toggle between a compact chat icon and a fullscreen WebView, plus handle incoming chat events to trigger alerts.
import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:webview_flutter/webview_flutter.dart'; import 'package:flutter_local_notifications/flutter_local_notifications.dart'; import 'package:vibration/vibration.dart'; import 'package:permission_handler/permission_handler.dart'; class TawkChatWidget extends StatefulWidget { final String tawkEmbedUrl; // Your unique tawk embed URL from the script const TawkChatWidget({super.key, required this.tawkEmbedUrl}); @override State<TawkChatWidget> createState() => _TawkChatWidgetState(); } class _TawkChatWidgetState extends State<TawkChatWidget> { late WebViewController _webViewController; bool _isFullscreen = false; final FlutterLocalNotificationsPlugin _notificationsPlugin = FlutterLocalNotificationsPlugin(); @override void initState() { super.initState(); _initNotificationSetup(); _requestRequiredPermissions(); } // Initialize local notification settings Future<void> _initNotificationSetup() async { const AndroidInitializationSettings androidInit = AndroidInitializationSettings('@mipmap/ic_launcher'); const InitializationSettings initSettings = InitializationSettings(android: androidInit); await _notificationsPlugin.initialize(initSettings); } // Request permissions for notifications and vibration Future<void> _requestRequiredPermissions() async { await Permission.notification.request(); if (await Vibration.hasVibrator()!) { await Permission.vibrate.request(); } } // Build custom HTML with tawk script embedded (hides tawk's default launcher) String _buildTawkHtml() { return ''' <!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <style> body { margin: 0; padding: 0; } /* Hide tawk's default chat button so our custom icon is the only entry point */ #tawkchat-minified { display: none !important; } </style> </head> <body> <script type="text/javascript"> var Tawk_API=Tawk_API||{}, Tawk_LoadStart=new Date(); (function(){ var s1=document.createElement("script"),s0=document.getElementsByTagName("script")[0]; s1.async=true; s1.src='${widget.tawkEmbedUrl}'; s1.charset='UTF-8'; s1.setAttribute('crossorigin','*'); s0.parentNode.insertBefore(s1,s0); })(); // Send new chat messages to Flutter via JS channel Tawk_API.onChatMessageReceived = function(message){ window.flutter_inappwebview.callHandler('onChatMessage', JSON.stringify(message)); }; </script> </body> </html> '''; } @override Widget build(BuildContext context) { return _isFullscreen ? _buildFullscreenChat() : _buildCompactLauncher(); } // Compact chat icon launcher Widget _buildCompactLauncher() { return Center( child: FloatingActionButton( onPressed: () => setState(() => _isFullscreen = true), child: const Icon(Icons.chat), backgroundColor: Colors.blue, ), ); } // Fullscreen chat WebView with close button Widget _buildFullscreenChat() { return Stack( children: [ WebViewWidget( controller: _webViewController = WebViewController() ..setJavaScriptMode(JavaScriptMode.unrestricted) ..addJavaScriptChannel( 'flutter_inappwebview', onMessageReceived: (JavaScriptMessage message) { _handleIncomingChat(jsonDecode(message.message)); }, ) ..loadHtmlString(_buildTawkHtml()), ), Positioned( top: 40, right: 20, child: FloatingActionButton( mini: true, onPressed: () => setState(() => _isFullscreen = false), child: const Icon(Icons.close), backgroundColor: Colors.white.withOpacity(0.8), ), ), ], ); } // Trigger vibration and notification for new chat messages void _handleIncomingChat(Map<String, dynamic> message) async { // Vibrate if device supports it if (await Vibration.hasVibrator()!) { Vibration.vibrate(duration: 500); } // Show local notification const AndroidNotificationDetails androidDetails = AndroidNotificationDetails( 'tawk_chat_channel', 'Tawk Chat Alerts', channelDescription: 'Notifications for new incoming chat messages', importance: Importance.high, priority: Priority.high, ); const NotificationDetails notificationDetails = NotificationDetails(android: androidDetails); await _notificationsPlugin.show( 0, 'New Chat Message', message['text'] ?? 'You have a new chat message', notificationDetails, ); } }
Step 2: Update Your Home Widget
Replace the placeholder chat tab with your new TawkChatWidget, and fix the constructor issues in your existing code:
// Updated Home Widget code import 'package:flutter/material.dart'; import 'placeholder_widget.dart'; import 'homepage.dart'; import 'reader.dart'; import 'tawk_chat_widget.dart'; // Import the new chat widget import 'package:firebase_analytics/firebase_analytics.dart'; import 'package:firebase_analytics/observer.dart'; class Home extends StatefulWidget { final FirebaseAnalytics analytics; final FirebaseAnalyticsObserver observer; const Home({super.key, required this.analytics, required this.observer}); @override State<StatefulWidget> createState() => _HomeState(); } class _HomeState extends State<Home> { int _currentIndex = 0; final List<Widget> _children = [ const Homepage(), const MyApp(), // Replace placeholder with your tawk chat widget TawkChatWidget( tawkEmbedUrl: 'https://embed.tawk.to/5c8306ab101df77a8be1a645/default', ) ]; @override Widget build(BuildContext context) { return Scaffold( body: _children[_currentIndex], bottomNavigationBar: BottomNavigationBar( onTap: onTabTapped, currentIndex: _currentIndex, items: const [ BottomNavigationBarItem( icon: Icon(Icons.home), label: 'Home', ), BottomNavigationBarItem( icon: Icon(Icons.photo_camera), label: 'blah', ), BottomNavigationBarItem( icon: Icon(Icons.person), label: 'Chat' ) ], ), ); } void onTabTapped(int index) { setState(() { _currentIndex = index; }); } }
Step 3: Fix Your Main.dart
Your existing Main.dart had a missing closing bracket—here's the corrected version:
// Updated Main.dart import 'package:flutter/material.dart'; import 'home_widget.dart'; import 'package:firebase_analytics/firebase_analytics.dart'; import 'package:firebase_analytics/observer.dart'; void main() => runApp(const App()); class App extends StatelessWidget { static FirebaseAnalytics analytics = FirebaseAnalytics(); static FirebaseAnalyticsObserver observer = FirebaseAnalyticsObserver(analytics: analytics); const App({super.key}); @override Widget build(BuildContext context) { return MaterialApp( title: 'My Flutter App', navigatorObservers: <NavigatorObserver>[observer], home: Home( analytics: analytics, observer: observer, ), ); } }
Key Details to Note:
- Shared Tawk Setup: Uses your exact website embed URL, so all chat history, agents, and settings are synced—no separate chat system to manage.
- Toggle Behavior: The third tab starts with a clean chat icon; tapping it opens the full tawk chat overlay, with a close button to return to compact mode.
- Alert Triggers: When a new chat message arrives, the app vibrates (if supported) and shows a local notification. For background notifications, you'll need additional platform-specific setup (Android background services, iOS push permissions), but this handles foreground alerts perfectly.
- Customized UI: Hides tawk's default chat button so your app's UI stays consistent.
内容的提问来源于stack exchange,提问作者veglinus

