React Native
แพ็กเกจ @kavchat/react-native เพิ่มแชทบริการลูกค้าตามสคริปต์ให้แอป พร้อม Provider หน้าจอแชท และปุ่มลอยที่เลือกใช้ได้ คำตอบมาจากสคริปต์ที่เผยแพร่ในแดชบอร์ด และทำงานบนอุปกรณ์
การติดตั้ง
แพ็กเกจเขียนด้วย JavaScript ทั้งหมด ไม่มีโค้ดเนทีฟของตัวเองและไม่ใช้ไลบรารีไอคอน จึงทำงานเหมือนกันทั้งในแอป React Native ทั่วไปและ Expo แพ็กเกจที่ต้องติดตั้งร่วมกัน (peer dependencies): react ตั้งแต่เวอร์ชัน 18 และ react-native ตั้งแต่เวอร์ชัน 0.72
React Native CLI (ไม่ใช้ Expo)
yarn add @kavchat/react-native @react-native-async-storage/async-storage
cd ios && pod installAsyncStorage เป็นโมดูลเนทีฟ: pod install จะเชื่อมโมดูลบน iOS ส่วน Android จะเชื่อมให้อัตโนมัติ
Expo
ใช้งานได้ใน Expo Go และบิลด์สำหรับการพัฒนา:
yarn add @kavchat/react-native
npx expo install @react-native-async-storage/async-storageการใช้งานโดยไม่มี AsyncStorage
AsyncStorage เก็บเวอร์ชันที่เผยแพร่และบทสนทนาไว้ระหว่างการเปิดแอปแต่ละครั้ง ไม่จำเป็นต้องติดตั้งก็ได้ หากไม่มี แพ็กเกจจะเก็บทุกอย่างไว้ในหน่วยความจำ บอทจึงยังทำงานได้ แต่จะดาวน์โหลดเวอร์ชันใหม่ทุกครั้งที่เปิดแอป หากต้องการใช้ที่เก็บข้อมูลอื่น เช่น MMKV ให้ส่งออบเจ็กต์ { getItem, setItem, removeItem? } แบบซิงโครนัสหรืออะซิงโครนัสผ่าน prop storage:
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}>การใช้งาน
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 | คำอธิบาย |
|---|---|
publicKey | pk_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 อายุสั้นบนเซิร์ฟเวอร์ของคุณด้วยคีย์ลับ (ห้ามทำในแอป ดู การระบุตัวตนผู้ใช้) แล้วส่งค่าดังนี้:
<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 ให้เอง และตัวแก้ไขสคริปต์จะแสดงชื่อหน้าจอเหล่านี้ในรายการแบบเลื่อนลง แทนช่องกรอกข้อความอิสระ ตัวแก้ไขยังขอรหัสรายการเมื่อหน้าจอนั้นจำเป็นต้องใช้ และแจ้งเตือนเมื่อปุ่มนำไปยังหน้าจอที่ยังไม่ได้ประกาศ ไม่ต้องพิมพ์รายการหน้าจอเองในแดชบอร์ด
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:
<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 ข้อมูลรับรองจะบันทึกในที่เก็บข้อมูลเดียวกับบทสนทนา ปุ่มคุยกับเจ้าหน้าที่ที่สร้างเองจะเปิดแบบฟอร์มขอคุยกับเจ้าหน้าที่เมื่อมีเจ้าหน้าที่ว่าง หากไม่มีเจ้าหน้าที่ว่าง จะเปิดแบบฟอร์มติดต่อพร้อมคำอธิบาย:
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