MySampark

mysampark_chat

pub version pub points pub likes MIT License Flutter

Official MySampark Chat Flutter plugin — Add AI-powered live chat with human agent takeover, typing indicators, pre-chat surveys, lead forms, and real-time WebSocket support to any Flutter app in minutes.


✨ Features

  • 🤖 AI-powered replies — instant responses via your trained chatbot
  • 👨‍💼 Human agent live takeover — agents reply in real-time via WebSocket
  • ⌨️ Typing indicator — animated 3-dot bounce while AI/agent is responding
  • 🏠 Home tab — branded greeting screen with Offers / Chat / Track Order cards, same layout as the web widget
  • 🎁 Offers card — live deals & discount codes fetched from your store, tap-to-copy code
  • 📦 Order tracking card — visitors check an order's status, carrier & tracking link without leaving the chat
  • 📋 Pre-chat survey gate — collect visitor info before first message (admin controlled)
  • 📝 In-chat lead form — name / email / phone capture after N messages
  • 💬 Conversation starters — quick-reply chips to help visitors start a chat
  • 📜 Chat history — load previous messages with scroll-up pagination
  • 🟢 Online / Offline status — live indicator in the chat header
  • 🖼️ Logo & branding — logo, colors, widget name all synced from your admin dashboard
  • 🔐 HMAC identity — verified logged-in users skip survey, lead form & order-tracking email prompt automatically
  • 💾 Session persistence — conversation resumes across app restarts
  • 🫧 Floating bubble launcher — drop-in FAB that opens chat as a bottom sheet

🔑 Getting Your Widget Key

Every widget below needs a widgetKey from your MySampark account:

  1. Sign up / log in at mysampark.com (dashboard: socialadmin.mysampark.com).
  2. Open the Chatbot section of your dashboard and create (or select) a widget.
  3. Copy its Widget Key (starts with pk_) — this is public and safe to embed in your app, same as the data-key used in the website embed script.
  4. The widget also has a Widget Secret (starts with sk_) — used only for identifying logged-in users (see below). Never put this in your Flutter app's source. It belongs on your own backend.

Exact menu labels may differ slightly as the dashboard evolves — if a step above doesn't match what you see, the Chatbot → Widgets area is the place to look.

Identifying logged-in users (optional)

If you want returning/logged-in users to skip the pre-chat survey and be recognized automatically, your own backend (not the Flutter app) computes a verification hash for the current user and sends it to the app:

// your_backend — an authenticated endpoint, e.g. POST /me/chat-hash
return hash_hmac('sha256', $user->id, env('MYSAMPARK_WIDGET_SECRET'));

Then pass the result as userHash (see Usage below). Anonymous visitors can skip userId/userHash entirely.

Only a valid userHash marks the visitor as logged in and brings back their earlier conversation, on any device. Without one, userName, userEmail, userPhone, userTags and userProperties are still saved, but only as lead info on that visitor's own chat (the same trust as the pre-chat survey). They are never used to open anyone else's conversation.


🚀 Installation

Add to your pubspec.yaml:

dependencies:
  mysampark_chat: ^1.3.0

Run:

flutter pub get

📱 Platform Setup

Android Setup

To allow links (URLs) in chat messages to open in external browsers on Android 11+ (API Level 30+), add the following <queries> configuration inside <manifest> in your app's android/app/src/main/AndroidManifest.xml:

<manifest xmlns:android="http://schemas.android.com/apk/res/android">
    <queries>
        <intent>
            <action android:name="android.intent.action.VIEW" />
            <data android:scheme="https" />
        </intent>
        <intent>
            <action android:name="android.intent.action.VIEW" />
            <data android:scheme="http" />
        </intent>
    </queries>
</manifest>

🔧 Usage

Drop it as your Scaffold's floatingActionButton and it renders a branded chat bubble:

import 'package:mysampark_chat/mysampark_chat.dart';

Scaffold(
  body: YourAppBody(),
  floatingActionButton: MySamparkChatBubble(
    widgetKey: 'YOUR_WIDGET_KEY',   // from MySampark dashboard

    // ── Optional: User identity parameters ───────────────────────────
    userId:    currentUser.id,
    userHash:  currentUser.chatHash,  // Verification hash from your backend
    userName:  currentUser.name,
    userEmail: currentUser.email,
    userPhone: currentUser.phone,
    userTags:  ['vip'],                         // labels for your support team
    userProperties: {'plan': 'pro', 'orders': 12}, // any extra details
    // ───────────────────────────────────────────────────────────────────
  ),
);

Option B — Full Screen Chat Page

Navigator.push(
  context,
  MaterialPageRoute(
    builder: (_) => MySamparkChatScreen(
      widgetKey: 'YOUR_WIDGET_KEY',

      // Optional: User identity parameters
      userId:    currentUser.id,
      userHash:  currentUser.chatHash,
      userName:  currentUser.name,
      userEmail: currentUser.email,
      userPhone: currentUser.phone,
    ),
  ),
);

Option C — Anonymous Visitor (No login required)

// Just the widgetKey — everything else is optional
MySamparkChatBubble(widgetKey: 'YOUR_WIDGET_KEY');

Visitor details, login and logout

Parameter What it's for
userId + userHash Logs the visitor in (see above).
userName, userEmail, userPhone Shown to your support team. If any of them is set, the pre-chat survey is skipped, since it would only ask for what you already know. A malformed userEmail is ignored.
userTags Labels such as vip or trial. Added to the visitor's existing tags (max 20).
userProperties Custom details (String / number / bool values, max 50 keys). Merged into what's already stored; null removes a key.

Login after the app has started: just rebuild MySamparkChatBubble / MySamparkChatScreen with the new userId / userHash. An open chat restarts on its own for the new user.

Logout: call resetVisitor so the next person on the device starts as a new visitor. They won't see the previous user's chat, and won't get their agent's replies as notifications:

Future<void> logout() async {
  await myAuth.signOut();
  await ChatService.resetVisitor('YOUR_WIDGET_KEY');
  // then rebuild your UI without userId / userHash, as usual
}

🛒 Opening Products Inside Your App

When the AI recommends a product, the card opens the merchant's website in a browser. If your app already sells that product, onProductTap lets you open your own product screen instead — keeping the visitor's cart, session and analytics intact.

MySamparkChatBubble(
  widgetKey: 'YOUR_WIDGET_KEY',
  onProductTap: (chatContext, product) {
    final id = product.externalId;

    // Not in your catalogue (or a hand-entered product with no id at all)
    // — return false and the package opens the website, as it always has.
    if (id == null || !myCatalog.contains(id)) return false;

    Navigator.pop(chatContext);                  // close the chat sheet
    Navigator.pushNamed(context, '/product/$id');
    return true;                                 // handled — no browser
  },
)

Three things worth knowing:

  • Match on product.externalId, not product.id. id is MySampark's internal id and means nothing in your catalogue. externalId is your id for the product — the SKU you pushed over the product sync API, or the Shopify / WooCommerce product id. product.source tells you which ('api', 'shopify', 'woocommerce'), and those id spaces are unrelated, so check it before treating them as one namespace.
  • Returning false is a normal outcome, not an error path — you only write code for the products you stock, and everything else keeps its old behaviour. externalId is null for products the merchant typed into the dashboard by hand, and for cards restored from conversations that happened before this feature shipped.
  • Use the chatContext you're handed to close the chat. MySamparkChatBubble opens the chat as a modal bottom sheet, and only that context can pop it — pushing from your own context leaves your product page behind the sheet, where nobody sees it.

The same parameter exists on MySamparkChatScreen when you push the chat as a full-screen route.


🏠 Home Tab, Offers & Order Tracking

MySamparkChatScreen opens on a Home tab by default — a greeting header plus up to three cards:

Card Shown when What it does
Offers Admin has show_offers on + an offers source connected Fetches GET /api/chatbot/offers, shows a bottom sheet of live deals with tap-to-copy discount codes
Chat with us Always Switches to the normal chat conversation view
Track your order Admin has show_order_tracking on + an order source connected Opens a form (order number + email — email is skipped for HMAC-identified users), calls POST /api/chatbot/track-order, and shows status / carrier / tracking link

This is entirely admin-controlled — nothing to configure in Flutter. If a merchant hasn't enabled Offers or Order Tracking in the dashboard, those cards simply don't render and only "Chat with us" is shown.

The header back arrow (and the Android hardware back button) returns from the Chat view to Home instead of closing the screen; closing the screen itself is the ✕ button on the Home header.


🎨 What the Admin Dashboard Controls

Everything is configured from your MySampark dashboard — no code changes needed in the Flutter app:

Admin Setting Effect in Flutter App
Primary color Home header, chat header, buttons, focus borders
Action color Send button, bubbles, active nav item, cards' icon badges
Widget name AppBar title
Logo AppBar avatar & survey screen
Welcome message Empty state text
Home greeting title / subtitle Home tab header text
Show Offers + offers source Offers card visibility on Home tab
Show Order Tracking + tracking source Track your order card visibility on Home tab
Online / Offline text Status indicator in header
Conversation starters Quick-reply chips
Pre-chat survey Survey overlay before first message
Collect name / email / phone Lead form fields
Lead form skippable Skip button visibility
AI on / off AI reply vs human-only mode

📦 Package Structure

lib/
├── mysampark_chat.dart           ← Public exports
└── src/
    ├── models.dart               ← ChatMessage, WidgetConfig, OfferItem, OrderTrackResult
    ├── chat_service.dart         ← REST API + WebSocket handler (incl. offers & order tracking)
    ├── chat_screen.dart          ← Home tab + full-screen chat UI
    └── chat_bubble_launcher.dart ← Floating bubble widget

📄 License

MIT License © 2026 MySampark

Libraries

mysampark_chat
Official MySampark Chat Widget for Flutter.