เมนูคู่มือ

React Native

แพ็กเกจ @kavchat/react-native เพิ่มแชทบริการลูกค้าตามสคริปต์ให้แอป พร้อม Provider หน้าจอแชท และปุ่มลอยที่เลือกใช้ได้ คำตอบมาจากสคริปต์ที่เผยแพร่ในแดชบอร์ด และทำงานบนอุปกรณ์

การติดตั้ง

แพ็กเกจเขียนด้วย JavaScript ทั้งหมด ไม่มีโค้ดเนทีฟของตัวเองและไม่ใช้ไลบรารีไอคอน จึงทำงานเหมือนกันทั้งในแอป React Native ทั่วไปและ Expo แพ็กเกจที่ต้องติดตั้งร่วมกัน (peer dependencies): react ตั้งแต่เวอร์ชัน 18 และ react-native ตั้งแต่เวอร์ชัน 0.72

React Native CLI (ไม่ใช้ Expo)

Terminal
yarn add @kavchat/react-native @react-native-async-storage/async-storage
cd ios && pod install

AsyncStorage เป็นโมดูลเนทีฟ: pod install จะเชื่อมโมดูลบน iOS ส่วน Android จะเชื่อมให้อัตโนมัติ

Expo

ใช้งานได้ใน Expo Go และบิลด์สำหรับการพัฒนา:

Terminal
yarn add @kavchat/react-native
npx expo install @react-native-async-storage/async-storage

การใช้งานโดยไม่มี AsyncStorage

AsyncStorage เก็บเวอร์ชันที่เผยแพร่และบทสนทนาไว้ระหว่างการเปิดแอปแต่ละครั้ง ไม่จำเป็นต้องติดตั้งก็ได้ หากไม่มี แพ็กเกจจะเก็บทุกอย่างไว้ในหน่วยความจำ บอทจึงยังทำงานได้ แต่จะดาวน์โหลดเวอร์ชันใหม่ทุกครั้งที่เปิดแอป หากต้องการใช้ที่เก็บข้อมูลอื่น เช่น MMKV ให้ส่งออบเจ็กต์ { getItem, setItem, removeItem? } แบบซิงโครนัสหรืออะซิงโครนัสผ่าน prop storage:

TSX
import { MMKV } from 'react-native-mmkv';
const mmkv = new MMKV();
const storage = {
  getItem: (k: string) => mmkv.getString(k) ?? null,
  setItem: (k: string, v: string) => mmkv.set(k, v),
  removeItem: (k: string) => mmkv.delete(k),
};

<KavchatProvider publicKey="pk_live_..." storage={storage}>

การใช้งาน

TSX
import { KavchatProvider, KavchatChat, KavchatLauncher, useKavchat } from '@kavchat/react-native';

export default function App() {
  return (
    <KavchatProvider publicKey="pk_live_..." onScreen={(screen, id) => navigation.navigate(screen, { id })}>
      <Navigation />
      {/* floating button, bottom end corner; opens the chat in a modal */}
      <KavchatLauncher />
    </KavchatProvider>
  );
}

// or as a screen in your own navigator
function SupportScreen() {
  return <KavchatChat />;
}

// or your own button
function HelpButton() {
  const { available, open } = useKavchat();
  if (!available) return null; // bot is off, limited to testers, or over quota
  return <Button title="Help" onPress={open} />;
}

Props ของ KavchatProvider

Propคำอธิบาย
publicKeypk_live_... จากแดชบอร์ด สามารถใส่ไว้ในแอปได้
apiBaseค่าเริ่มต้น: https://api.kavchat.com
localeภาษาของอินเทอร์เฟซ (he, en, ar, ru, es, fr, de, pt, it, tr) ค่าเริ่มต้นคือภาษาของอุปกรณ์ หากไม่มีคำแปลในภาษานั้น จะใช้ภาษาของบอท การจับคู่กับสคริปต์ใช้ภาษาของบอทเสมอ
userToken, userNameการระบุตัวตนผู้ใช้ ดูรายละเอียดด้านล่าง
onScreen(screen, targetId?)เรียกใช้เมื่อกดปุ่มประเภท "หน้าจอ" ในสคริปต์ หากไม่ได้กำหนด ปุ่มเหล่านี้จะไม่ทำอะไร
screensหน้าจอที่แอปเปิดได้ สำหรับรายการแบบเลื่อนลงในตัวแก้ไข ดู รายการหน้าจอในตัวแก้ไข
onEvent(event)ready, unavailable, effect, ticket
storageออบเจ็กต์ { getItem, setItem, removeItem? } ใดก็ได้ แบบซิงโครนัสหรืออะซิงโครนัส ค่าเริ่มต้นคือ AsyncStorage หากไม่ได้ติดตั้ง จะใช้หน่วยความจำ
themeการเปลี่ยนสี ดู สีและ RTL

useKavchat() คืนค่า { status, available, offline, locale, isOpen, open, close, toggle, setUser, startNewConversation, openContactForm, controller }

Props ของ KavchatChat: onClose? (แสดงปุ่มปิด), hideHeader? และ style? Props ของ KavchatLauncher: style? (ตำแหน่ง), onPress? (เปิดหน้าจอของคุณเองแทนหน้าต่างที่มีให้) และ attention? (false ปิดข้อความ)

เมื่อตั้งค่าข้อความข้างปุ่มแชทในหน้าจัดการ (กรอบคำพูดหรือข้อความโค้งเหนือปุ่ม) KavchatLauncher จะแสดงข้อความหลังจากหน่วงเวลาตามที่กำหนด สูงสุดวันละครั้ง การปิดข้อความหรือเปิดแชทจะซ่อนข้อความไว้จนถึงวันถัดไป ข้อความจะไม่แสดงขณะแชทเปิดอยู่ หากอุปกรณ์ตั้งค่าให้ลดการเคลื่อนไหว ข้อความจะแสดงโดยไม่มีการเคลื่อนไหว เมื่อเปิดตัวเลือก "ไม่แสดงบนโทรศัพท์" ข้อความจะแสดงเฉพาะบนแท็บเล็ต (เมื่อด้านสั้นของหน้าจอมีขนาดตั้งแต่ 600 พอยต์ขึ้นไป)

โทเค็นระบุตัวตน

หากไม่มีโทเค็น ผู้ใช้จะเป็นผู้เยี่ยมชม และแบบฟอร์มติดต่อจะขออีเมลหรือเบอร์โทรศัพท์ หากต้องการระบุตัวตนของผู้ใช้ที่เข้าสู่ระบบ ให้ลงนาม JWT อายุสั้นบนเซิร์ฟเวอร์ของคุณด้วยคีย์ลับ (ห้ามทำในแอป ดู การระบุตัวตนผู้ใช้) แล้วส่งค่าดังนี้:

TSX
<KavchatProvider publicKey="pk_live_..." userToken={session?.kavchatToken} userName={session?.firstName}>

การเปลี่ยน userToken (เข้าสู่ระบบหรือออกจากระบบ) จะโหลดเวอร์ชันใหม่ เพราะกลุ่มผู้ใช้ทดสอบขึ้นอยู่กับตัวตนของผู้ใช้ นอกจากนี้ยังเรียก useKavchat().setUser({ token, name }) ได้ โทเค็นจะส่งผ่านเฮดเดอร์ Authorization: Bearer เท่านั้น และไม่บันทึกไว้ในอุปกรณ์ บทสนทนาที่บันทึกไว้ผูกกับลายนิ้วมือของโทเค็น ดังนั้นผู้ใช้อื่นบนอุปกรณ์เดียวกันจะเริ่มบทสนทนาใหม่

ลิงก์ หน้าจอ และแบบฟอร์มติดต่อ

  • ปุ่มประเภท link เปิดเฉพาะ URL แบบ https: และ tel: ผ่าน Linking.openURL โดยไม่เปิด URL ประเภทอื่น
  • ปุ่มประเภท screen เรียก onScreen แชทยังคงอยู่ที่เดิม
  • ปุ่ม "ติดต่อทีมงาน" เปิดแบบฟอร์มติดต่อพร้อมแนบบทสนทนา หลังส่งจะแสดงหมายเลขคำร้อง

รายการหน้าจอในตัวแก้ไข

ประกาศหน้าจอที่แอปเปิดได้ครั้งเดียวใน prop screens ของ KavchatProvider โดย SDK จะส่งรายการไปยัง Kavchat ให้เอง และตัวแก้ไขสคริปต์จะแสดงชื่อหน้าจอเหล่านี้ในรายการแบบเลื่อนลง แทนช่องกรอกข้อความอิสระ ตัวแก้ไขยังขอรหัสรายการเมื่อหน้าจอนั้นจำเป็นต้องใช้ และแจ้งเตือนเมื่อปุ่มนำไปยังหน้าจอที่ยังไม่ได้ประกาศ ไม่ต้องพิมพ์รายการหน้าจอเองในแดชบอร์ด

TSX
const screens = [
  { id: 'orders', label: 'My orders' },
  { id: 'product', label: 'Product page', needsTarget: true }, // the button also carries a product id
];

<KavchatProvider
  publicKey="pk_live_..."
  screens={screens}
  onScreen={(screen, targetId) => navigation.navigate(screen, targetId ? { id: targetId } : undefined)}
>
  • id คือค่าที่ส่งไปยัง onScreen: ใช้อักษรละติน ตัวเลข _, . และ - ได้สูงสุด 40 อักขระ ส่วน label คือชื่อที่ผู้ดูแลเห็น สูงสุด 60 อักขระ รองรับสูงสุด 100 หน้าจอ รายการที่ไม่ถูกต้องและรหัสที่ซ้ำกันจะถูกตัดออก
  • needsTarget: ปุ่มจะส่งรหัสรายการมาด้วย (เช่น รหัสสินค้า) และ onScreen จะรับค่านี้เป็น targetId
  • รายการจะส่งในเบื้องหลังหลังจากโหลดเวอร์ชันแล้ว เฉพาะเมื่อรายการเปลี่ยนหรือสัปดาห์ละครั้ง หากส่งไม่สำเร็จ จะไม่มีการแจ้งเตือน และจะลองส่งใหม่เมื่อเปิดแอปครั้งถัดไป ผู้ใช้จะไม่เห็นอะไร
  • หน้าจอที่ลงทะเบียนไว้จะแสดงในแดชบอร์ดที่ บอท การตั้งค่า "หน้าจอแอป" พร้อมแพลตฟอร์มที่รายงานแต่ละหน้าจอ หน้าจอที่นำออกจากแอปแล้วสามารถลบได้ที่นี่

สีและ RTL

สีมาจากการตั้งค่าบอทในแดชบอร์ด (primaryColor) ส่วนสีข้อความที่อยู่บนสีนั้นจะเลือกตามคอนทราสต์ WCAG สามารถเปลี่ยนแต่ละสีได้: primary, background, botBubble, userBubble, text, muted, accent, onPrimary และ error:

TSX
<KavchatProvider
  publicKey="pk_live_..."
  theme={{ primary: '#0f766e', background: '#ffffff' }}
>

แพ็กเกจจะไม่เปลี่ยนทิศทางเลย์เอาต์ของแอป แต่จะทำงานตาม I18nManager.isRTL (สไตล์ start และ end) และจัดแนวข้อความแต่ละข้อความตามภาษาของข้อความนั้น ภาษาฮีบรูและอาหรับจึงอ่านได้ถูกต้องแม้ในแอปที่จัดวางจากซ้ายไปขวา หากแอปใช้ภาษาฮีบรูหรืออาหรับ ให้ตั้งค่า RTL ในแอปครั้งเดียวตามปกติ: I18nManager.forceRTL(true) แล้วเปิดแอปใหม่

ป้าย "ขับเคลื่อนโดย Kavchat by maxsave" แสดงในทุกแพ็กเกจ พร้อมลิงก์ไปยัง kavchat.com สำหรับ Premium สามารถซ่อนป้ายได้ในการตั้งค่าบอท

แชทกับเจ้าหน้าที่

เริ่มใช้งานได้โดยไม่ต้องตั้งค่า เมื่อเปิดแชทกับเจ้าหน้าที่ในหน้าจัดการ ตัวเลือกนี้จะปรากฏในแชทของแอปเช่นเดียวกับวิดเจ็ตบนเว็บไซต์

  • ตัวเลือก: "คุยกับเจ้าหน้าที่" จะแสดงก่อน "ติดต่อทีมงาน" และแสดงเฉพาะหลังจากเซิร์ฟเวอร์ยืนยันว่ามีเจ้าหน้าที่ว่าง ระบบจะตรวจสอบความพร้อมอีกครั้งเมื่อแตะปุ่ม นอกเวลาทำการหรือเมื่อเจ้าหน้าที่ทุกคนไม่ว่าง จะแสดงเฉพาะแบบฟอร์มติดต่อพร้อมคำอธิบายสั้น ๆ และเวลาที่ทีมงานจะกลับมา หากทราบ เมื่อใช้โควตารายเดือนหมดแล้ว จะแสดงแบบฟอร์มโดยไม่มีคำอธิบาย
  • คำขอ: ผู้เยี่ยมชมระบุอีเมลหรือเบอร์โทรศัพท์ไว้ เผื่อไม่มีเจ้าหน้าที่ว่างทันเวลา และสามารถเพิ่มชื่อกับข้อความแรกได้ หากมีแผนกเปิดให้บริการมากกว่าหนึ่งแผนก ให้เลือกแผนก ผู้ใช้ที่ระบุตัวตนแล้ว (userToken) ไม่ต้องกรอกข้อมูลติดต่อ หากไม่มีเจ้าหน้าที่รับแชทได้ แบบฟอร์มติดต่อจะเปิดขึ้นพร้อมข้อมูลที่กรอกไว้แล้ว
  • ระหว่างรอ: แสดง "กำลังรอเจ้าหน้าที่" พร้อมนับถอยหลังจนหมดเวลารอที่กำหนด และปุ่ม "ฝากข้อความแทน" กับ "จบการสนทนา" ผู้ใช้พิมพ์ข้อความระหว่างรอได้ เมื่อหมดเวลา แชทจะเปลี่ยนเป็นคำร้องโดยอัตโนมัติ พร้อมแสดงหมายเลขคำร้องและคำอธิบายว่าไม่มีเจ้าหน้าที่ว่างทันเวลา
  • การสนทนา: ชื่อเจ้าหน้าที่ ข้อความ สถานะกำลังพิมพ์ การโอนไปยังเจ้าหน้าที่คนอื่น และการจบการสนทนา ทุกอย่างที่มาจากเซิร์ฟเวอร์จะแสดงเป็นข้อความธรรมดา ไม่มีลิงก์
  • แบบเรียลไทม์: เชื่อมต่อ Server-Sent Events ผ่าน XMLHttpRequest (หรือ fetch แบบสตรีมเมื่อรองรับ) หากการเชื่อมต่อหลุด แชทจะเชื่อมต่อใหม่โดยเพิ่มช่วงเวลารอขึ้นเรื่อย ๆ และดึงข้อมูลที่พลาดไปทั้งหมด จึงไม่มีข้อความสูญหายหรือแสดงซ้ำ ในเครือข่ายที่บล็อกการเชื่อมต่อแบบนี้ แชทจะเปลี่ยนไปตรวจสอบซ้ำ (long-poll) ทุกข้อความมีรหัส การลองส่งใหม่จึงไม่ทำให้เกิดข้อความซ้ำ ข้อความที่ส่งไม่สำเร็จจะมีเครื่องหมายกำกับ และแตะเพื่อส่งใหม่ได้
  • การทำงานเบื้องหลังและการเปิดแอปใหม่: เมื่อแอปเข้าสู่เบื้องหลัง การเชื่อมต่อจะปิดลง เมื่อกลับมาเปิดแอป แชทจะดึงข้อมูลที่พลาดไป ข้อมูลรับรองการเข้าถึงแชทมีอายุสูงสุด 12 ชั่วโมงหรือจนกว่าการสนทนาจะจบ และบันทึกไว้ในที่เก็บข้อมูลที่เลือก ดังนั้นเมื่อเปิดแอปใหม่ แชทที่ยังไม่จบจะกลับมาแสดงบนหน้าจอ ข้อมูลรับรองนี้จะไม่บันทึกใน URL หรือเขียนลงล็อก
  • เวอร์ชันนี้ไม่มีการแจ้งเตือนแบบพุช: ข้อความจากเจ้าหน้าที่จะมาถึงเฉพาะขณะที่แอปเปิดอยู่

แนะนำให้เก็บข้อมูลรับรองการเข้าถึงไว้ในที่เก็บข้อมูลที่ปลอดภัย (Keychain บน iOS, Keystore บน Android) หากไม่ได้กำหนด secureStorage ข้อมูลรับรองจะบันทึกในที่เก็บข้อมูลเดียวกับบทสนทนา ปุ่มคุยกับเจ้าหน้าที่ที่สร้างเองจะเปิดแบบฟอร์มขอคุยกับเจ้าหน้าที่เมื่อมีเจ้าหน้าที่ว่าง หากไม่มีเจ้าหน้าที่ว่าง จะเปิดแบบฟอร์มติดต่อพร้อมคำอธิบาย:

TSX
import * as SecureStore from 'expo-secure-store';

// expo-secure-store allows only [A-Za-z0-9._-] in keys
const safe = (k: string) => k.replace(/[^A-Za-z0-9._-]/g, '_');
const secureStorage = {
  getItem: (k: string) => SecureStore.getItemAsync(safe(k)),
  setItem: (k: string, v: string) => SecureStore.setItemAsync(safe(k), v),
  removeItem: (k: string) => SecureStore.deleteItemAsync(safe(k)),
};

<KavchatProvider publicKey="pk_live_..." secureStorage={secureStorage} livePage="checkout">

// your own button
const { openLive } = useKavchat();
<Button title="Chat with us" onPress={openLive} />

อีเวนต์: onEvent รับค่า { type: 'live', phase } ทุกครั้งที่สถานะการสนทนาเปลี่ยน (queued, active, closed, ticket, replaced, expired)

คำถาม เงื่อนไข และข้อมูลผู้สนใจ

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

  • แป้นพิมพ์ที่เหมาะสม: เมื่อบอทรอคำตอบ ช่องข้อความจะแสดงแป้นพิมพ์สำหรับเบอร์โทรศัพท์ อีเมล หรือตัวเลข พร้อมการเติมข้อความอัตโนมัติ หากคำตอบไม่ถูกต้อง บอทจะอธิบายว่าขาดอะไร และทำเครื่องหมายที่ช่องนั้น คำถามที่ข้ามได้จะแสดงปุ่ม "ข้าม"
  • ข้อมูลผู้สนใจ: เมื่อมีข้อความขอความยินยอม จะแสดงปุ่ม "ส่ง" และ "ไม่ ขอบคุณ" หากไม่มีการเชื่อมต่อเครือข่าย ข้อมูลผู้สนใจจะบันทึกไว้บนอุปกรณ์ และส่งเมื่อเชื่อมต่อได้อีกครั้งโดยไม่ซ้ำกัน
  • การกรอกล่วงหน้า: คำตอบที่ผู้ใช้ให้ไว้แล้วจะนำไปกรอกในแบบฟอร์มติดต่อและแบบฟอร์มขอคุยกับเจ้าหน้าที่ พร้อมแนบไปกับคำร้องและแชทกับเจ้าหน้าที่ ชื่อ อีเมล และเบอร์โทรศัพท์จากโทเค็นระบุตัวตนจะถือเป็นคำตอบที่ทราบแล้ว บอทจึงไม่ถามซ้ำ
  • หน้าจอปัจจุบัน: livePage ยังระบุหน้าจอที่ใช้ตรวจสอบเงื่อนไขและส่งไปพร้อมข้อมูลผู้สนใจด้วย การเปลี่ยน prop จะอัปเดตค่านี้

คำตอบจาก AI (Premium)

ไม่ต้องตั้งค่าอะไรในแอป เมื่อเปิดคำตอบจาก AI ในหน้าจัดการ (ด้วยคีย์ผู้ให้บริการ AI ของคุณเอง) คำถามที่ไม่มีสคริปต์ใดตอบได้จะส่งไปยัง Kavchat และระหว่างรอสูงสุด 20 วินาที แชทจะแสดงว่าบอทกำลังพิมพ์ คำตอบจะแสดงเป็นข้อความธรรมดาพร้อมป้ายเล็ก ๆ ว่า "คำตอบจาก AI" ในภาษาของอินเทอร์เฟซ ใต้คำตอบมีปุ่มหัวข้อที่เกี่ยวข้อง หากมี และปุ่ม "ติดต่อทีมงาน"

หากไม่มีคำตอบ คำขอล้มเหลว ใช้เวลานานเกินไป หรือเกินขีดจำกัด (10 คำตอบต่อบทสนทนาในทุก 15 นาที) แชทจะแสดงข้อความ "ไม่พบคำตอบ" ตามปกติ คำถามยังคงปรากฏในรายงานคำถามที่ไม่มีคำตอบ และคำตอบจาก AI จะเก็บไว้ในบทสนทนาที่บันทึกไว้เช่นเดียวกับข้อความอื่น

ลักษณะการทำงาน

  • เวอร์ชันที่เผยแพร่จะเก็บในแคชพร้อม ETag (If-None-Match, 304) เมื่อไม่มีเครือข่าย จะแสดงเวอร์ชันที่บันทึกไว้พร้อมข้อความแจ้ง
  • บทสนทนาจะบันทึกไว้บนอุปกรณ์และกู้คืนได้ภายใน 24 ชั่วโมง ตราบใดที่เวอร์ชันและผู้ใช้ยังไม่เปลี่ยน
  • ลำดับการสนทนาจะรายงานหลังการกระทำล่าสุด 2 วินาที และเมื่อแอปเข้าสู่เบื้องหลัง
  • คำขอไม่ส่งเฮดเดอร์ที่กำหนดเอง ส่งเฉพาะ Authorization, Content-Type และ If-None-Match