You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将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:

Solution: Integrate tawk.to with Compact Icon, Fullscreen Toggle & Notifications

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 04:38:23