เมนูคู่มือ

วิดเจ็ตสำหรับเว็บไซต์

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

การติดตั้ง

วางบรรทัดนี้ไว้ก่อน </body> ในทุกหน้าที่ต้องการให้บอตปรากฏ ดูบรรทัดนี้พร้อมคีย์ของคุณได้ในหน้า การติดตั้ง บนแดชบอร์ด

HTML
<script src="https://cdn.kavchat.com/v1/kavchat.js" data-key="pk_live_..." async></script>

ใส่คีย์สาธารณะ (pk_live_...) ในหน้าเว็บได้ แต่ห้ามใส่คีย์ลับ (sk_live_...) ในหน้าเว็บเด็ดขาด

แอตทริบิวต์

แอตทริบิวต์ค่าเริ่มต้นคำอธิบาย
data-keyจำเป็นคีย์สาธารณะของคุณ
data-apihttps://api.kavchat.comที่อยู่ API
data-localeภาษาของเบราว์เซอร์ภาษาของส่วนติดต่อผู้ใช้ในวิดเจ็ต (ปุ่ม แบบฟอร์ม ข้อความแจ้ง): he, en, ar, ru, es, fr, de, pt, it, tr หากไม่มีคำแปลในภาษานั้น จะใช้ภาษาของบอต เนื้อหาสคริปต์จะแสดงตามที่คุณเขียนไว้เสมอ ส่วน he และ ar จะแสดงจากขวาไปซ้าย
data-user-tokenไม่มีโทเค็นระบุตัวตนของผู้ใช้ที่เข้าสู่ระบบ ดู การระบุตัวตนผู้ใช้
data-user-nameไม่มีแสดงในคำทักทาย ({name}) และกรอกล่วงหน้าในแบบฟอร์มติดต่อ
data-openfalseเมื่อเป็น "true" แชทจะเปิดทันทีที่โหลดเสร็จ
HTML
<script
  src="https://cdn.kavchat.com/v1/kavchat.js"
  data-key="pk_live_..."
  data-locale="he"
  data-user-token="<identity JWT>"
  data-user-name="Dana"
  data-open="false"
  async></script>

JavaScript API

สคริปต์จะติดตั้ง window.Kavchat:

JavaScript
Kavchat.init({
  publicKey: 'pk_live_...',
  apiBase: 'https://api.kavchat.com', // optional
  locale: 'he',                       // optional
  userToken: '<identity JWT>',        // optional
  userName: 'Dana',                   // optional
  open: false,                        // optional
  onScreen(screen, targetId) {},      // optional: "screen" buttons in your scripts
  onEvent(event) {},                  // optional: ready, unavailable, open, close, effect, ticket
});
Kavchat.open();
Kavchat.close();
Kavchat.toggle();
Kavchat.setUser({ token: '<identity JWT>', name: 'Dana' }); // on login; setUser(null) on logout
Kavchat.offset({ bottom: 80 });       // lift the launcher, e.g. above a cookie banner; offset(null) resets
Kavchat.destroy();

ไม่จำเป็นต้องเรียก init หากแท็กสคริปต์มี data-key อยู่แล้ว การเรียก init อีกครั้งจะแทนที่วิดเจ็ตที่กำลังทำงาน

การเรียก API ก่อนสคริปต์โหลดเสร็จ

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

HTML
<script>
  window.Kavchat = window.Kavchat || { q: [] };
  Kavchat.q.push(['init', { publicKey: 'pk_live_...', onScreen: function (s, id) { location.href = '/' + s + '/' + id; } }]);
  Kavchat.q.push(['setUser', { token: '<identity JWT>', name: 'Dana' }]);
</script>
<script src="https://cdn.kavchat.com/v1/kavchat.js" async></script>

แต่ละรายการในคิวอยู่ในรูปแบบ [methodName, ...args] แม้สคริปต์จะโหลดเสร็จแล้ว Kavchat.q.push(...) ก็ยังใช้งานได้และจะเรียกคำสั่งทันที จึงใช้โค้ดเดียวกันได้ทั้งสองกรณี

เว้นที่ให้แบนเนอร์คุกกี้

หากเว็บไซต์มีองค์ประกอบที่ตรึงอยู่ด้านล่างของหน้าจอ เช่น แบนเนอร์คุกกี้ คุณสามารถเลื่อนปุ่ม หน้าต่าง และบับเบิลขึ้นไปอยู่เหนือองค์ประกอบนั้นได้ โดยใช้ได้สองวิธี: ตัวแปร CSS ชื่อ --kavchat-bottom หรือคำสั่ง Kavchat.offset ซึ่งรับค่าเป็นตัวเลขในหน่วยพิกเซลหรือค่าความยาว เช่น 5rem ระยะที่เลื่อนจะบวกเพิ่มจากความสูงที่ตั้งไว้ในหน้าจัดการ เมื่อปิดแบนเนอร์แล้ว ให้ลบตัวแปรหรือเรียก offset(null) ทั้งสองวิธีใช้ได้กับเว็บไซต์ที่มี CSP แบบเข้มงวดด้วย บนโทรศัพท์ หน้าต่างจะเปิดเต็มหน้าจอและไม่เลื่อนตำแหน่ง

CSS
/* while your cookie banner is shown */
body.cookie-banner-open { --kavchat-bottom: 80px; }
JavaScript
// works before or after the widget script loads
window.Kavchat = window.Kavchat || { q: [] };
Kavchat.q.push(['offset', { bottom: banner.offsetHeight + 12 }]);

// after the visitor makes a choice
Kavchat.q.push(['offset', null]);

อีเวนต์

ฟังก์ชัน onEvent จะรับอีเวนต์ใดอีเวนต์หนึ่งต่อไปนี้:

typeฟิลด์เกิดขึ้นเมื่อ
readyversion, offlineบอตโหลดเสร็จจากเครือข่าย หรือจากสำเนาที่บันทึกไว้เมื่อไม่มีเครือข่าย
unavailablereason? ('quota')บอตถูกปิด เปิดให้เฉพาะผู้ใช้ทดสอบ หรือใช้โควตาหมดแล้ว จะไม่มีอะไรแสดงขึ้นมา
open, closeหน้าต่างเปิดหรือปิด
effecteffectปุ่มส่งคำสั่งให้เปิดแบบฟอร์มติดต่อ ลิงก์ หรือหน้าจอ
ticketid, numberสร้างคำร้องแล้ว
livestate, idสถานะการสนทนากับเจ้าหน้าที่เปลี่ยนเป็น: queued, active, closed หรือ ticket
JavaScript
Kavchat.init({
  publicKey: 'pk_live_...',
  onEvent(event) {
    if (event.type === 'ready') console.log('Bot version', event.version, event.offline ? '(offline copy)' : '');
    if (event.type === 'ticket') console.log('Request opened', event.number);
  },
});

การดำเนินการในสคริปต์

  • ติดต่อ: เปิดแบบฟอร์มติดต่อภายในแชท พร้อมแนบประวัติการสนทนาไปกับคำร้อง
  • ลิงก์: เปิดลิงก์ https: และ tel: ในแท็บใหม่ (rel="noopener noreferrer") โดยจะไม่เปิดลิงก์ประเภทอื่น
  • หน้าจอ: เรียกฟังก์ชัน onScreen(screen, targetId) ของคุณ หากไม่มีฟังก์ชันนี้ ปุ่มจะไม่ทำอะไรบนเว็บไซต์

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

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

JavaScript
Kavchat.init({
  publicKey: 'pk_live_...',
  screens: [
    { id: 'orders', label: 'My orders' },
    { id: 'product', label: 'Product page', needsTarget: true }, // the button also carries a product id
  ],
  onScreen(screen, targetId) {
    location.href = targetId ? `/${screen}/${targetId}` : `/${screen}`;
  },
});
  • id คือค่าที่ส่งไปยัง onScreen: ใช้ตัวอักษรละติน ตัวเลข _, . และ - ได้ไม่เกิน 40 อักขระ ส่วน label คือชื่อที่ผู้ดูแลเห็น ยาวไม่เกิน 60 อักขระ รองรับสูงสุด 100 หน้าจอ รายการที่ไม่ถูกต้องและรหัสที่ซ้ำกันจะถูกตัดออก
  • needsTarget: ปุ่มจะมีรหัสรายการด้วย (เช่น รหัสสินค้า) และส่งไปยัง onScreen เป็น targetId
  • รายการจะถูกส่งในเบื้องหลังหลังจากโหลดเวอร์ชันเสร็จ เฉพาะเมื่อมีการเปลี่ยนแปลงหรือสัปดาห์ละครั้ง หากส่งไม่สำเร็จ จะไม่มีการแจ้งเตือน และจะลองส่งอีกครั้งเมื่อเปิดใช้งานครั้งถัดไป ผู้ใช้จะไม่เห็นอะไร
  • หน้าจอที่ลงทะเบียนไว้จะปรากฏในแดชบอร์ดที่ บอต, การตั้งค่า, "หน้าจอแอป" พร้อมแพลตฟอร์มที่รายงานแต่ละหน้าจอ หากนำหน้าจอออกจากแอปแล้ว ก็ลบออกจากรายการนี้ได้

การระบุตัวตนผู้ใช้ของคุณ

หากต้องการผูกรหัสผู้ใช้ของคุณกับการสนทนาและคำร้อง หรือแสดงบอตเฉพาะกับผู้ใช้ทดสอบ ให้ลงลายเซ็น JWT บนเซิร์ฟเวอร์แล้วส่งผ่าน data-user-token หรือ userToken เมื่อผู้ใช้เข้าสู่ระบบหรือออกจากระบบ ให้เรียก Kavchat.setUser(...) วิดเจ็ตจะส่งโทเค็นในส่วนหัว Authorization: Bearer <token> ทุกครั้งที่เรียก และผู้ใช้ที่เข้าสู่ระบบจะสร้างคำร้องได้โดยไม่ต้องระบุอีเมลหรือเบอร์โทร ดูวิธีสร้างโทเค็นได้ที่ การระบุตัวตนผู้ใช้

นโยบาย CSP

วิดเจ็ตทำงานบนเว็บไซต์ที่ใช้ CSP แบบเข้มงวดได้ โดยไม่ต้องใช้ 'unsafe-inline' หรือ 'unsafe-eval' เพียงอนุญาตแหล่งที่มาทั้งสองของเรา:

CSP
script-src https://cdn.kavchat.com;
connect-src https://api.kavchat.com;

สไตล์จะโหลดเป็น constructable stylesheets ภายใน Shadow DOM จึงไม่จำเป็นต้องแก้ไข style-src หากบอตมีรูปภาพของตัวเอง หรือมีรูปภาพในสคริปต์ ให้เพิ่มเซิร์ฟเวอร์ที่ใช้โหลดรูปภาพเหล่านั้นใน img-src วิดเจ็ตไม่โหลดสิ่งใดจากแหล่งที่มาอื่น และไม่เปิด iframe

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

ไม่ต้องตั้งค่าอะไรบนเว็บไซต์ เมื่อเปิดแชทกับเจ้าหน้าที่ในหน้าจัดการ วิดเจ็ตจะโหลดไฟล์เพิ่มเติมชื่อ kavchat-live.js จากโฟลเดอร์เดียวกันและเวอร์ชันเดียวกันกับ kavchat.js เว็บไซต์ที่ไม่ได้ใช้แชทกับเจ้าหน้าที่จะไม่ดาวน์โหลดไฟล์นี้เลย

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

คำตอบจาก AI (พรีเมียม)

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

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

การทำงานของวิดเจ็ต

  • การแยกส่วน: ทุกอย่างแสดงภายใน Shadow DOM ทำให้ CSS ของคุณไม่ส่งผลต่อวิดเจ็ต และ CSS ของวิดเจ็ตไม่ส่งผลต่อหน้าเว็บ
  • แคช: บอตที่เผยแพร่แล้วจะบันทึกใน localStorage แยกตามคีย์สาธารณะ พร้อม ETag ทุกครั้งที่โหลดจะส่งส่วนหัว If-None-Match และหากไม่มีอะไรเปลี่ยนแปลง เซิร์ฟเวอร์จะตอบกลับด้วย 304 เมื่อไม่มีเครือข่าย วิดเจ็ตจะใช้สำเนาที่บันทึกไว้และแสดงข้อความแจ้ง
  • การสนทนา: รหัสการสนทนาแบบสุ่มจะเก็บใน sessionStorage จึงสนทนาต่อเนื่องได้เมื่อเปลี่ยนหน้า
  • แชทกับเจ้าหน้าที่: การสนทนาที่ยังเปิดอยู่จะเก็บใน localStorage และกู้คืนในหน้าถัดไป
  • ข้อมูล: ลำดับการสนทนาจะถูกรายงานประมาณ 2 วินาทีหลังแต่ละการดำเนินการ และเมื่อหน้าเว็บถูกซ่อนด้วย
  • ป้าย Kavchat: แสดงในทุกแพ็กเกจ สำหรับพรีเมียม สามารถซ่อนได้ในการตั้งค่าบอต
  • การเข้าถึง: หน้าต่างเป็นกล่องโต้ตอบที่มีป้ายกำกับ โฟกัสจะย้ายเข้าและกลับออกจากหน้าต่าง กด Esc เพื่อปิด ปุ่มต่าง ๆ เป็นองค์ประกอบปุ่มจริง ข้อความใหม่จากบอตจะถูกอ่านออกเสียง และจะลดภาพเคลื่อนไหวเมื่อผู้เข้าชมตั้งค่าไว้

ติดตั้งจาก npm

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

Terminal
yarn add @kavchat/widget
# or: npm install @kavchat/widget
JavaScript
import { createWidget } from '@kavchat/widget';

const widget = createWidget({ publicKey: 'pk_live_...' });
await widget.ready;
widget.open();