مستندات

Flutter SDK

یک کلاینت تماماً Dart برای چت پشتیبانی Respondo — هیچ کد بومی پلتفرمی نیست که مجبور باشید کامپایل یا اشکال‌زدایی کنید.

پیش‌نیازها#

  • Dart >=3.4.0 <4.0.0.
  • Flutter >=3.16.0 (خط نسخهٔ 3.x).
  • Dart خالص: بدون پل بومی، بدون pod install، بدون دست‌کاری Gradle. وابستگی‌های غیرمستقیم هم پکیج‌های سادهٔ Dart هستند (http، web_socket_channel، uuid).

نصب#

پکیج را از pub.dev اضافه کنید:

pubspec.yamlyaml
dependencies:
  respondo_sdk: ^0.1.2
Dartdart
import 'package:respondo_sdk/respondo_sdk.dart';

راه‌اندازی اولیه#

Respondo.navigatorKey را به MaterialApp خود وصل کنید تا SDK بتواند شیت چت را بدون BuildContext شما باز کند، یک‌بار Respondo.init را صدا بزنید و بعد Respondo.open().

main.dartdart
import 'package:flutter/material.dart';
import 'package:path_provider/path_provider.dart';
import 'package:respondo_sdk/respondo_sdk.dart';

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();

  // مسیر ذخیره‌سازی فایل از پلاگین اپلیکیشن میزبان می‌آید؛ خود SDK خالص می‌ماند.
  final dir = await getApplicationSupportDirectory();

  await Respondo.init(
    RespondoConfig(
      agentId: '<agent-uuid>',
      channelId: '<channel-uuid>',
      storageDirectory: dir.path,
    ),
  );

  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      navigatorKey: Respondo.navigatorKey, // لازم است تا SDK بتواند چت را باز کند
      home: Scaffold(
        body: Center(
          child: FilledButton(
            onPressed: () => Respondo.open(),
            child: const Text('Support'),
          ),
        ),
      ),
    );
  }
}

همهٔ متدهای این نما (facade) خودتوان‌اند، صدا زدنشان پیش از init هم بی‌خطر است (بافر می‌شوند و بعد دوباره اجرا می‌شوند) و هرگز استثنایی به اپلیکیشن شما پرتاب نمی‌کنند.

شناسایی کاربران#

به‌طور پیش‌فرض هر بازدیدکننده ناشناس است. در نخستین اجرا، SDK یک visitor_id پایدار می‌سازد و آن را در حافظهٔ محلی نگه می‌دارد، پس کاربری که برمی‌گردد دوباره گفت‌وگوی خودش را پیدا می‌کند. هیچ کلید API‌ای برای جاسازی وجود ندارد — هر گفت‌وگو با یک توکن نشستِ مخصوص همان گفت‌وگو محافظت می‌شود که backend صادر می‌کند و با هر پیام جلو می‌برد، بنابراین بازدیدکنندهٔ ناشناس هرگز مجبور نیست دوباره احراز هویت کند.

به‌محض اینکه کاربرتان وارد شد، identify را صدا بزنید. این کار هویت واقعی او را وصل می‌کند تا تاریخچه‌اش روی دستگاه‌های مختلف و پس از نصب دوباره هم همراهش بیاید، و نام و ایمیلش به‌جای یک بازدیدکنندهٔ ناشناس کنار گفت‌وگو در صندوق ورودی شما دیده شود.

userHash امضایی است که backend خودتان از identity_secret عامل حساب می‌کند — HMAC-SHA256(secret, userId) (یا ایمیل، وقتی userId وجود ندارد)، کدشده به‌صورت hex با حروف کوچک. این سِر ثابت می‌کند هویت واقعی است، پس باید فقط روی backend شما بماند و هرگز داخل اپلیکیشن ارسال نشود. فرمول کامل و نمونه‌های سمت سرور را در صفحهٔ تأیید هویت ببینید.

Dartdart
// 1. با backend خودتان وارد شوید و هش از پیش محاسبه‌شده را بخوانید
//    (مثلاً فیلدی که همراه پاسخ ورود برگردانده می‌شود).
final session = await api.login(email, password);

// 2. userHash آمادهٔ نهایی را به SDK بدهید — هرگز آن را در اپلیکیشن حساب نکنید.
Respondo.identify(RespondoIdentity(
  userId: session.userId,
  email: session.email,
  name: session.fullName,
  userHash: session.respondoUserHash,
));

// 3. هنگام خروج: نشست را باطل کنید و یک بازدیدکنندهٔ ناشناس تازه شروع کنید.
Respondo.reset();

اگر هش نباشد یا اشتباه باشد، چیزی پرتاب نمی‌شود: backend بی‌سروصدا بازدیدکننده را ناشناس نگه می‌دارد، چت به کارش ادامه می‌دهد و شما فقط پیوند بین‌دستگاهی را تا زمان رسیدن یک هش معتبر از دست می‌دهید. بررسی فقط وقتی اجرا می‌شود که برای عامل یک identity_secret تنظیم شده باشد — هنگام توسعه آن را خالی بگذارید تا userId / ایمیل همان‌طور که هستند پذیرفته شوند.

Observableها و callbackها#

همه‌چیز هم به شکل Stream از نوع broadcast، هم به شکل setter برای callback و هم به شکل getter مقدار جاری در دسترس است.

Dartdart
// جریان واکنشی شمار پیام‌های خوانده‌نشده (برای نشان روی آیکون).
Respondo.unreadCountStream.listen((n) => setBadge(n));

// یا setter برای callback.
Respondo.onUnreadChanged = (n) => setBadge(n);

// رهگیری لینک‌ها/CTAها؛ اگر خود میزبان URL را باز کرد، true برگردانید.
Respondo.onUrlRequested = (url) {
  openInAppBrowser(url);
  return true;
};

ردیابی صفحه#

در هر ناوبری، صفحهٔ جاری را گزارش کنید تا تیزرهای پیش‌دستانه و هدف‌گیری سطح صفحه بتوانند با آن تطبیق داده شوند. برای پاک‌کردن مقدار null بفرستید؛ با هر تغییر، تیزر پیش‌دستانه برای صفحهٔ تازه دوباره ارزیابی می‌شود.

Dartdart
Respondo.setCurrentScreen('pricing');

گام‌های بعدی#

نوتیفیکیشن‌های پوش و تأیید هویت را اضافه کنید. کل سطح API، سطوح تعامل با کاربر و رفع اشکال در راهنمای شروع کار Flutter SDK روی صفحهٔ پکیج در pub.dev پوشش داده شده است.