เอกสารประกอบ

Flutter SDK

client แบบ Dart ล้วนสำหรับแชทซัพพอร์ต Respondo — ไม่มีโค้ดเนทีฟของแพลตฟอร์มให้คอมไพล์ หรือดีบัก

ข้อกำหนด#

  • Dart >=3.4.0 <4.0.0
  • Flutter >=3.16.0 (สาย 3.x)
  • Dart ล้วน: ไม่มี native bridge, ไม่ต้อง pod install, ไม่ต้องแก้ Gradle dependency ทางอ้อมล้วนเป็น package ของ Dart (http, web_socket_channel, uuid)

การติดตั้ง#

เพิ่ม package จาก pub.dev:

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

เริ่มต้นใช้งาน#

ผูก Respondo.navigatorKey เข้ากับ MaterialApp ของคุณ เพื่อให้ SDK สามารถเปิด chat sheet ได้โดยไม่ต้องใช้ 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 ยังคงเป็น Dart ล้วน
  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 ทั้งหมดเป็น idempotent, ปลอดภัยที่จะเรียกก่อน init (จะบัฟเฟอร์ไว้และเล่นซ้ำ) และไม่มีการโยน exception เข้าสู่แอปของคุณ

การระบุตัวตนผู้ใช้#

โดยค่าเริ่มต้นผู้เข้าชมทุกคนเป็นนิรนาม เมื่อเปิดครั้งแรก SDK จะสร้าง visitor_id ที่เสถียรและเก็บไว้ในที่จัดเก็บภายในเครื่อง ดังนั้นผู้ใช้ที่กลับมาจะพบบทสนทนาของตนอีกครั้ง ไม่มี API key ให้ฝัง — แต่ละบทสนทนาถูกปกป้องด้วย session token ต่อบทสนทนา ที่ backend สร้างขึ้นและเลื่อนไปข้างหน้าในทุกข้อความ ดังนั้นผู้เข้าชมนิรนามไม่ต้องยืนยันตัวตนใหม่

เรียก identify เมื่อผู้ใช้ของคุณล็อกอินแล้ว การกระทำนี้จะแนบตัวตนจริงของพวกเขา เพื่อให้ประวัติติดตามไปกับ พวกเขาข้ามอุปกรณ์และการติดตั้งใหม่ และชื่อกับอีเมลของพวกเขาจะปรากฏถัดจากบทสนทนาในกล่องข้อความ ของคุณแทนที่จะเป็นผู้เข้าชมนิรนาม

userHash คือลายเซ็นที่ backend ของคุณ คำนวณจาก identity_secret ของเอเจนต์ — HMAC-SHA256(secret, userId) (หรืออีเมลเมื่อไม่มี userId) เข้ารหัสเป็น hex ตัวพิมพ์เล็ก secret เป็นเครื่องพิสูจน์ว่าตัวตนนั้นเป็นของจริง จึงต้องอยู่บน backend ของคุณเท่านั้น และต้องไม่ถูกส่งไปในแอปเด็ดขาด ดูหน้า การยืนยันตัวตนสำหรับสูตรเต็มและตัวอย่างฝั่งเซิร์ฟเวอร์

Dartdart
// 1. ล็อกอินกับ backend ของคุณเองและอ่าน hash ที่คำนวณไว้ล่วงหน้า
//    (เช่น ฟิลด์ที่คืนมาพร้อมกับ response ของการล็อกอิน)
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. เมื่อออกจากระบบ: เพิกถอน session และเริ่มผู้เข้าชมนิรนามใหม่
Respondo.reset();

หากไม่มี hash หรือ hash ผิด จะไม่มีการโยน exception ใด ๆ: backend จะเก็บผู้เข้าชมให้เป็นนิรนามอย่างเงียบ ๆ แชทยังทำงานต่อไป และคุณเพียงเสียลิงก์ข้ามอุปกรณ์ จนกว่าจะมีการส่ง hash ที่ถูกต้องมา การยืนยันจะทำงานก็ต่อเมื่อเอเจนต์มี identity_secret ตั้งไว้ — ปล่อยว่างไว้ระหว่างการพัฒนา แล้ว userId / อีเมล จะถูกยอมรับตามที่เป็น

Observable และ callback#

ทุกอย่างมีให้ในรูปแบบ broadcast Stream, callback setter และ getter ของค่าปัจจุบัน

Dartdart
// stream แบบ reactive ของจำนวนที่ยังไม่อ่าน (สำหรับ badge)
Respondo.unreadCountStream.listen((n) => setBadge(n));

// หรือใช้ callback setter
Respondo.onUnreadChanged = (n) => setBadge(n);

// ดักลิงก์/CTA; คืน true หากโฮสต์เปิด URL ด้วยตนเอง
Respondo.onUrlRequested = (url) {
  openInAppBrowser(url);
  return true;
};

การติดตามหน้าจอ#

รายงานหน้าจอปัจจุบันในทุกการนำทาง เพื่อให้ teaser เชิงรุกและการกำหนดเป้าหมายระดับหน้าจับคู่กับมันได้ ส่ง null เพื่อล้างค่า; ในแต่ละการเปลี่ยนแปลง teaser เชิงรุกจะถูกประเมินใหม่สำหรับหน้าจอใหม่

ชื่อเดียวกันนี้ใช้เทียบกับกฎหน้าจอของแบบสำรวจป๊อปอัป จึงควรใช้ตัวระบุที่คงที่ เช่น «Checkout» แทนชื่อที่แปลแล้ว กฎที่อยู่หน้าเว็บใช้กับเว็บไซต์เท่านั้น

Dartdart
Respondo.setCurrentScreen('pricing');

เปิดแบบสำรวจจากโค้ด#

เปิดแบบสำรวจป๊อปอัปที่เผยแพร่อยู่ทันที ไม่ว่าผู้ใช้จะอยู่หน้าจอใด โดยข้าม Show on กฎของหน้าจอ เวลาบนหน้าจอ อีเวนต์ทริกเกอร์ และกลุ่มเป้าหมาย คัดลอก id จากตัวแก้ไขแบบสำรวจ (Additional ways to share) แบบสำรวจที่ผู้ใช้ตอบแล้วจะไม่แสดงอีก

Dartdart
Respondo.startSurvey('<survey-id>');

ขั้นตอนถัดไป#

เพิ่ม พุชการแจ้งเตือน และ การยืนยันตัวตนผิวสัมผัส API เต็มรูปแบบ, ผิวสัมผัสด้าน engagement และการแก้ปัญหา ครอบคลุมอยู่ในคู่มือเริ่มต้นใช้งาน Flutter SDK บน หน้า package บน pub.dev